1 |
|
2 |
|
3 |
|
4 |
|
5 | "use strict";
|
6 |
|
7 | const path = require("path");
|
8 | const ParserHelpers = require("./ParserHelpers");
|
9 | const ConstDependency = require("./dependencies/ConstDependency");
|
10 |
|
11 | const NullFactory = require("./NullFactory");
|
12 |
|
13 | class NodeStuffPlugin {
|
14 | constructor(options) {
|
15 | this.options = options;
|
16 | }
|
17 |
|
18 | apply(compiler) {
|
19 | const options = this.options;
|
20 | compiler.hooks.compilation.tap(
|
21 | "NodeStuffPlugin",
|
22 | (compilation, { normalModuleFactory }) => {
|
23 | compilation.dependencyFactories.set(ConstDependency, new NullFactory());
|
24 | compilation.dependencyTemplates.set(
|
25 | ConstDependency,
|
26 | new ConstDependency.Template()
|
27 | );
|
28 |
|
29 | const handler = (parser, parserOptions) => {
|
30 | if (parserOptions.node === false) return;
|
31 |
|
32 | let localOptions = options;
|
33 | if (parserOptions.node) {
|
34 | localOptions = Object.assign({}, localOptions, parserOptions.node);
|
35 | }
|
36 |
|
37 | const setConstant = (expressionName, value) => {
|
38 | parser.hooks.expression
|
39 | .for(expressionName)
|
40 | .tap("NodeStuffPlugin", () => {
|
41 | parser.state.current.addVariable(
|
42 | expressionName,
|
43 | JSON.stringify(value)
|
44 | );
|
45 | return true;
|
46 | });
|
47 | };
|
48 |
|
49 | const setModuleConstant = (expressionName, fn) => {
|
50 | parser.hooks.expression
|
51 | .for(expressionName)
|
52 | .tap("NodeStuffPlugin", () => {
|
53 | parser.state.current.addVariable(
|
54 | expressionName,
|
55 | JSON.stringify(fn(parser.state.module))
|
56 | );
|
57 | return true;
|
58 | });
|
59 | };
|
60 | const context = compiler.context;
|
61 | if (localOptions.__filename) {
|
62 | if (localOptions.__filename === "mock") {
|
63 | setConstant("__filename", "/index.js");
|
64 | } else {
|
65 | setModuleConstant("__filename", module =>
|
66 | path.relative(context, module.resource)
|
67 | );
|
68 | }
|
69 | parser.hooks.evaluateIdentifier
|
70 | .for("__filename")
|
71 | .tap("NodeStuffPlugin", expr => {
|
72 | if (!parser.state.module) return;
|
73 | const resource = parser.state.module.resource;
|
74 | const i = resource.indexOf("?");
|
75 | return ParserHelpers.evaluateToString(
|
76 | i < 0 ? resource : resource.substr(0, i)
|
77 | )(expr);
|
78 | });
|
79 | }
|
80 | if (localOptions.__dirname) {
|
81 | if (localOptions.__dirname === "mock") {
|
82 | setConstant("__dirname", "/");
|
83 | } else {
|
84 | setModuleConstant("__dirname", module =>
|
85 | path.relative(context, module.context)
|
86 | );
|
87 | }
|
88 | parser.hooks.evaluateIdentifier
|
89 | .for("__dirname")
|
90 | .tap("NodeStuffPlugin", expr => {
|
91 | if (!parser.state.module) return;
|
92 | return ParserHelpers.evaluateToString(
|
93 | parser.state.module.context
|
94 | )(expr);
|
95 | });
|
96 | }
|
97 | parser.hooks.expression
|
98 | .for("require.extensions")
|
99 | .tap(
|
100 | "NodeStuffPlugin",
|
101 | ParserHelpers.expressionIsUnsupported(
|
102 | parser,
|
103 | "require.extensions is not supported by webpack. Use a loader instead."
|
104 | )
|
105 | );
|
106 | };
|
107 |
|
108 | normalModuleFactory.hooks.parser
|
109 | .for("javascript/auto")
|
110 | .tap("NodeStuffPlugin", handler);
|
111 | normalModuleFactory.hooks.parser
|
112 | .for("javascript/dynamic")
|
113 | .tap("NodeStuffPlugin", handler);
|
114 | }
|
115 | );
|
116 | }
|
117 | }
|
118 | module.exports = NodeStuffPlugin;
|