UNPKG

6.16 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.AureliaDependenciesPlugin = void 0;
4const IncludeDependency_1 = require("./IncludeDependency");
5const webpack = require("webpack");
6const PreserveExportsPlugin_1 = require("./PreserveExportsPlugin");
7const BasicEvaluatedExpression = require("webpack/lib/javascript/BasicEvaluatedExpression");
8const TAP_NAME = "Aurelia:Dependencies";
9class AureliaDependency extends IncludeDependency_1.IncludeDependency {
10 constructor(request, range, options) {
11 super(request, options);
12 this.range = range;
13 }
14 get type() {
15 return `${super.type}/AureliaDependency`;
16 }
17 get [PreserveExportsPlugin_1.dependencyImports]() {
18 return webpack.Dependency.EXPORTS_OBJECT_REFERENCED;
19 }
20}
21class Template {
22 apply(dep, source) {
23 source.replace(dep.range[0], dep.range[1] - 1, "'" + dep.request.replace(/^async(?:\?[^!]*)?!/, "") + "'");
24 }
25 ;
26}
27class ParserPlugin {
28 constructor(methods) {
29 this.methods = methods;
30 }
31 apply(parser) {
32 function addDependency(module, range, options) {
33 let dep = new AureliaDependency(module, range, options);
34 parser.state.current.addDependency(dep);
35 return true;
36 }
37 // The parser will only apply "call PLATFORM.moduleName" on free variables.
38 // So we must first trick it into thinking PLATFORM.moduleName is an unbound identifier
39 // in the various situations where it is not.
40 const hooks = parser.hooks;
41 hooks.evaluate.for('MemberExpression').tap(TAP_NAME, (expr) => {
42 if (expr.property.type === 'Identifier'
43 && expr.property.name === 'moduleName'
44 // PLATFORM.moduleName(...)
45 && (expr.object.type === 'Identifier' && expr.object.name === 'PLATFORM'
46 // _aureliaPal.PLATFORM.moduleName(...)
47 // require('aurelia-pal').PLATFORM.moduleName(...)
48 // import('aurelia-pal').then(pal => pal.PLATFORM.moduleName(...))
49 // import('aurelia-pal').then({ PLATFORM } => PLATFORM.moduleName(...))
50 || expr.object.type === 'MemberExpression'
51 && expr.object.property.type === 'Identifier'
52 && expr.object.property.name === 'PLATFORM')) {
53 return new BasicEvaluatedExpression()
54 .setIdentifier('PLATFORM.moduleName', undefined, () => [])
55 .setRange(expr.range);
56 }
57 return undefined;
58 });
59 for (let method of this.methods) {
60 hooks.call.for(method).tap(TAP_NAME, (expr) => {
61 if (expr.arguments.length === 0 || expr.arguments.length > 2) {
62 return;
63 }
64 let [arg1, arg2] = expr.arguments;
65 let param1 = parser.evaluateExpression(arg1);
66 if (!param1.isString())
67 return;
68 if (expr.arguments.length === 1) {
69 // Normal module dependency
70 // PLATFORM.moduleName('some-module')
71 return addDependency(param1.string, expr.range);
72 }
73 let options;
74 let param2 = parser.evaluateExpression(arg2);
75 if (param2.isString()) {
76 // Async module dependency
77 // PLATFORM.moduleName('some-module', 'chunk name');
78 options = { chunk: param2.string };
79 }
80 else if (arg2.type === "ObjectExpression") {
81 // Module dependency with extended options
82 // PLATFORM.moduleName('some-module', { option: value });
83 options = {};
84 for (let prop of arg2.properties) {
85 if (prop.type !== 'Property' || prop.key.type !== "Identifier")
86 continue;
87 let value = parser.evaluateExpression(prop.value);
88 switch (prop.key.name) {
89 case "chunk":
90 if (value.isString())
91 options.chunk = value.string;
92 break;
93 case "exports":
94 if (value.isArray() && value.items.every(v => v.isString()))
95 options.exports = value.items.map(v => v.string);
96 break;
97 }
98 }
99 }
100 else {
101 // Unknown PLATFORM.moduleName() signature
102 return;
103 }
104 return addDependency(param1.string, expr.range, options);
105 });
106 }
107 }
108}
109class AureliaDependenciesPlugin {
110 constructor(...methods) {
111 // Always include PLATFORM.moduleName as it's what used in libs.
112 if (!methods.includes("PLATFORM.moduleName")) {
113 methods.push("PLATFORM.moduleName");
114 }
115 this.parserPlugin = new ParserPlugin(methods);
116 }
117 apply(compiler) {
118 compiler.hooks.compilation.tap(TAP_NAME, (compilation, params) => {
119 const normalModuleFactory = params.normalModuleFactory;
120 compilation.dependencyFactories.set(AureliaDependency, normalModuleFactory);
121 compilation.dependencyTemplates.set(AureliaDependency, new Template());
122 const handler = (parser) => {
123 this.parserPlugin.apply(parser);
124 };
125 normalModuleFactory.hooks.parser.for("javascript/dynamic").tap(TAP_NAME, handler);
126 normalModuleFactory.hooks.parser.for("javascript/auto").tap(TAP_NAME, handler);
127 normalModuleFactory.hooks.parser.for("javascript/esm").tap(TAP_NAME, handler);
128 });
129 }
130}
131exports.AureliaDependenciesPlugin = AureliaDependenciesPlugin;