1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | "use strict";
|
7 |
|
8 | const { pathToFileURL } = require("url");
|
9 | const ModuleDependencyWarning = require("../ModuleDependencyWarning");
|
10 | const Template = require("../Template");
|
11 | const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
|
12 | const {
|
13 | evaluateToIdentifier,
|
14 | toConstantDependency,
|
15 | evaluateToString,
|
16 | evaluateToNumber
|
17 | } = require("../javascript/JavascriptParserHelpers");
|
18 | const memoize = require("../util/memoize");
|
19 | const propertyAccess = require("../util/propertyAccess");
|
20 | const ConstDependency = require("./ConstDependency");
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | const getCriticalDependencyWarning = memoize(() =>
|
29 | require("./CriticalDependencyWarning")
|
30 | );
|
31 |
|
32 | class ImportMetaPlugin {
|
33 | |
34 |
|
35 |
|
36 | apply(compiler) {
|
37 | compiler.hooks.compilation.tap(
|
38 | "ImportMetaPlugin",
|
39 | (compilation, { normalModuleFactory }) => {
|
40 | |
41 |
|
42 |
|
43 |
|
44 | const getUrl = module => {
|
45 | return pathToFileURL(module.resource).toString();
|
46 | };
|
47 | |
48 |
|
49 |
|
50 |
|
51 |
|
52 | const parserHandler = (parser, { importMeta }) => {
|
53 | if (importMeta === false) {
|
54 | const { importMetaName } = compilation.outputOptions;
|
55 | if (importMetaName === "import.meta") return;
|
56 |
|
57 | parser.hooks.expression
|
58 | .for("import.meta")
|
59 | .tap("ImportMetaPlugin", metaProperty => {
|
60 | const dep = new ConstDependency(
|
61 | importMetaName,
|
62 | metaProperty.range
|
63 | );
|
64 | dep.loc = metaProperty.loc;
|
65 | parser.state.module.addPresentationalDependency(dep);
|
66 | return true;
|
67 | });
|
68 | return;
|
69 | }
|
70 |
|
71 |
|
72 | parser.hooks.typeof
|
73 | .for("import.meta")
|
74 | .tap(
|
75 | "ImportMetaPlugin",
|
76 | toConstantDependency(parser, JSON.stringify("object"))
|
77 | );
|
78 | parser.hooks.expression
|
79 | .for("import.meta")
|
80 | .tap("ImportMetaPlugin", metaProperty => {
|
81 | const CriticalDependencyWarning = getCriticalDependencyWarning();
|
82 | parser.state.module.addWarning(
|
83 | new ModuleDependencyWarning(
|
84 | parser.state.module,
|
85 | new CriticalDependencyWarning(
|
86 | "Accessing import.meta directly is unsupported (only property access is supported)"
|
87 | ),
|
88 | metaProperty.loc
|
89 | )
|
90 | );
|
91 | const dep = new ConstDependency(
|
92 | `${parser.isAsiPosition(metaProperty.range[0]) ? ";" : ""}({})`,
|
93 | metaProperty.range
|
94 | );
|
95 | dep.loc = metaProperty.loc;
|
96 | parser.state.module.addPresentationalDependency(dep);
|
97 | return true;
|
98 | });
|
99 | parser.hooks.evaluateTypeof
|
100 | .for("import.meta")
|
101 | .tap("ImportMetaPlugin", evaluateToString("object"));
|
102 | parser.hooks.evaluateIdentifier.for("import.meta").tap(
|
103 | "ImportMetaPlugin",
|
104 | evaluateToIdentifier("import.meta", "import.meta", () => [], true)
|
105 | );
|
106 |
|
107 |
|
108 | parser.hooks.typeof
|
109 | .for("import.meta.url")
|
110 | .tap(
|
111 | "ImportMetaPlugin",
|
112 | toConstantDependency(parser, JSON.stringify("string"))
|
113 | );
|
114 | parser.hooks.expression
|
115 | .for("import.meta.url")
|
116 | .tap("ImportMetaPlugin", expr => {
|
117 | const dep = new ConstDependency(
|
118 | JSON.stringify(getUrl(parser.state.module)),
|
119 | expr.range
|
120 | );
|
121 | dep.loc = expr.loc;
|
122 | parser.state.module.addPresentationalDependency(dep);
|
123 | return true;
|
124 | });
|
125 | parser.hooks.evaluateTypeof
|
126 | .for("import.meta.url")
|
127 | .tap("ImportMetaPlugin", evaluateToString("string"));
|
128 | parser.hooks.evaluateIdentifier
|
129 | .for("import.meta.url")
|
130 | .tap("ImportMetaPlugin", expr => {
|
131 | return new BasicEvaluatedExpression()
|
132 | .setString(getUrl(parser.state.module))
|
133 | .setRange(expr.range);
|
134 | });
|
135 |
|
136 |
|
137 | const webpackVersion = parseInt(
|
138 | require("../../package.json").version,
|
139 | 10
|
140 | );
|
141 | parser.hooks.typeof
|
142 | .for("import.meta.webpack")
|
143 | .tap(
|
144 | "ImportMetaPlugin",
|
145 | toConstantDependency(parser, JSON.stringify("number"))
|
146 | );
|
147 | parser.hooks.expression
|
148 | .for("import.meta.webpack")
|
149 | .tap(
|
150 | "ImportMetaPlugin",
|
151 | toConstantDependency(parser, JSON.stringify(webpackVersion))
|
152 | );
|
153 | parser.hooks.evaluateTypeof
|
154 | .for("import.meta.webpack")
|
155 | .tap("ImportMetaPlugin", evaluateToString("number"));
|
156 | parser.hooks.evaluateIdentifier
|
157 | .for("import.meta.webpack")
|
158 | .tap("ImportMetaPlugin", evaluateToNumber(webpackVersion));
|
159 |
|
160 |
|
161 | parser.hooks.unhandledExpressionMemberChain
|
162 | .for("import.meta")
|
163 | .tap("ImportMetaPlugin", (expr, members) => {
|
164 | const dep = new ConstDependency(
|
165 | `${Template.toNormalComment(
|
166 | "unsupported import.meta." + members.join(".")
|
167 | )} undefined${propertyAccess(members, 1)}`,
|
168 | expr.range
|
169 | );
|
170 | dep.loc = expr.loc;
|
171 | parser.state.module.addPresentationalDependency(dep);
|
172 | return true;
|
173 | });
|
174 | parser.hooks.evaluate
|
175 | .for("MemberExpression")
|
176 | .tap("ImportMetaPlugin", expression => {
|
177 | const expr = (expression);
|
178 | if (
|
179 | expr.object.type === "MetaProperty" &&
|
180 | expr.object.meta.name === "import" &&
|
181 | expr.object.property.name === "meta" &&
|
182 | expr.property.type ===
|
183 | (expr.computed ? "Literal" : "Identifier")
|
184 | ) {
|
185 | return new BasicEvaluatedExpression()
|
186 | .setUndefined()
|
187 | .setRange(expr.range);
|
188 | }
|
189 | });
|
190 | };
|
191 |
|
192 | normalModuleFactory.hooks.parser
|
193 | .for("javascript/auto")
|
194 | .tap("ImportMetaPlugin", parserHandler);
|
195 | normalModuleFactory.hooks.parser
|
196 | .for("javascript/esm")
|
197 | .tap("ImportMetaPlugin", parserHandler);
|
198 | }
|
199 | );
|
200 | }
|
201 | }
|
202 |
|
203 | module.exports = ImportMetaPlugin;
|