1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | "use strict";
|
7 |
|
8 | const { approve } = require("../javascript/JavascriptParserHelpers");
|
9 | const InnerGraph = require("../optimize/InnerGraph");
|
10 | const URLDependency = require("./URLDependency");
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | class URLPlugin {
|
17 | |
18 |
|
19 |
|
20 | apply(compiler) {
|
21 | compiler.hooks.compilation.tap(
|
22 | "URLPlugin",
|
23 | (compilation, { normalModuleFactory }) => {
|
24 | compilation.dependencyFactories.set(URLDependency, normalModuleFactory);
|
25 | compilation.dependencyTemplates.set(
|
26 | URLDependency,
|
27 | new URLDependency.Template()
|
28 | );
|
29 |
|
30 | |
31 |
|
32 |
|
33 |
|
34 | const parserCallback = (parser, parserOptions) => {
|
35 | if (parserOptions.url === false) return;
|
36 | const relative = parserOptions.url === "relative";
|
37 |
|
38 | |
39 |
|
40 |
|
41 |
|
42 | const getUrlRequest = expr => {
|
43 | if (expr.arguments.length !== 2) return;
|
44 |
|
45 | const [arg1, arg2] = expr.arguments;
|
46 |
|
47 | if (
|
48 | arg2.type !== "MemberExpression" ||
|
49 | arg1.type === "SpreadElement"
|
50 | )
|
51 | return;
|
52 |
|
53 | const chain = parser.extractMemberExpressionChain(arg2);
|
54 |
|
55 | if (
|
56 | chain.members.length !== 1 ||
|
57 | chain.object.type !== "MetaProperty" ||
|
58 | chain.object.meta.name !== "import" ||
|
59 | chain.object.property.name !== "meta" ||
|
60 | chain.members[0] !== "url"
|
61 | )
|
62 | return;
|
63 |
|
64 | const request = parser.evaluateExpression(arg1).asString();
|
65 |
|
66 | return request;
|
67 | };
|
68 |
|
69 | parser.hooks.canRename.for("URL").tap("URLPlugin", approve);
|
70 | parser.hooks.new.for("URL").tap("URLPlugin", _expr => {
|
71 | const expr = (_expr);
|
72 |
|
73 | const request = getUrlRequest(expr);
|
74 |
|
75 | if (!request) return;
|
76 |
|
77 | const [arg1, arg2] = expr.arguments;
|
78 | const dep = new URLDependency(
|
79 | request,
|
80 | [arg1.range[0], arg2.range[1]],
|
81 | expr.range,
|
82 | relative
|
83 | );
|
84 | dep.loc = expr.loc;
|
85 | parser.state.current.addDependency(dep);
|
86 | InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
|
87 | return true;
|
88 | });
|
89 | parser.hooks.isPure.for("NewExpression").tap("URLPlugin", _expr => {
|
90 | const expr = (_expr);
|
91 | const { callee } = expr;
|
92 | if (callee.type !== "Identifier") return;
|
93 | const calleeInfo = parser.getFreeInfoFromVariable(callee.name);
|
94 | if (!calleeInfo || calleeInfo.name !== "URL") return;
|
95 |
|
96 | const request = getUrlRequest(expr);
|
97 |
|
98 | if (request) return true;
|
99 | });
|
100 | };
|
101 |
|
102 | normalModuleFactory.hooks.parser
|
103 | .for("javascript/auto")
|
104 | .tap("URLPlugin", parserCallback);
|
105 |
|
106 | normalModuleFactory.hooks.parser
|
107 | .for("javascript/esm")
|
108 | .tap("URLPlugin", parserCallback);
|
109 | }
|
110 | );
|
111 | }
|
112 | }
|
113 |
|
114 | module.exports = URLPlugin;
|