UNPKG

18.8 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = void 0;
7exports.getExportSpecifierName = getExportSpecifierName;
8var _helperPluginUtils = require("@babel/helper-plugin-utils");
9var _core = require("@babel/core");
10var _helperModuleTransforms = require("@babel/helper-module-transforms");
11var _helperValidatorIdentifier = require("@babel/helper-validator-identifier");
12const buildTemplate = _core.template.statement(`
13 SYSTEM_REGISTER(MODULE_NAME, SOURCES, function (EXPORT_IDENTIFIER, CONTEXT_IDENTIFIER) {
14 "use strict";
15 BEFORE_BODY;
16 return {
17 setters: SETTERS,
18 execute: EXECUTE,
19 };
20 });
21`);
22const buildExportAll = _core.template.statement(`
23 for (var KEY in TARGET) {
24 if (KEY !== "default" && KEY !== "__esModule") EXPORT_OBJ[KEY] = TARGET[KEY];
25 }
26`);
27const MISSING_PLUGIN_WARNING = `\
28WARNING: Dynamic import() transformation must be enabled using the
29 @babel/plugin-transform-dynamic-import plugin. Babel 8 will
30 no longer transform import() without using that plugin.
31`;
32const MISSING_PLUGIN_ERROR = `\
33ERROR: Dynamic import() transformation must be enabled using the
34 @babel/plugin-transform-dynamic-import plugin. Babel 8
35 no longer transforms import() without using that plugin.
36`;
37function getExportSpecifierName(node, stringSpecifiers) {
38 if (node.type === "Identifier") {
39 return node.name;
40 } else if (node.type === "StringLiteral") {
41 const stringValue = node.value;
42 if (!(0, _helperValidatorIdentifier.isIdentifierName)(stringValue)) {
43 stringSpecifiers.add(stringValue);
44 }
45 return stringValue;
46 } else {
47 throw new Error(`Expected export specifier to be either Identifier or StringLiteral, got ${node.type}`);
48 }
49}
50function constructExportCall(path, exportIdent, exportNames, exportValues, exportStarTarget, stringSpecifiers) {
51 const statements = [];
52 if (!exportStarTarget) {
53 if (exportNames.length === 1) {
54 statements.push(_core.types.expressionStatement(_core.types.callExpression(exportIdent, [_core.types.stringLiteral(exportNames[0]), exportValues[0]])));
55 } else {
56 const objectProperties = [];
57 for (let i = 0; i < exportNames.length; i++) {
58 const exportName = exportNames[i];
59 const exportValue = exportValues[i];
60 objectProperties.push(_core.types.objectProperty(stringSpecifiers.has(exportName) ? _core.types.stringLiteral(exportName) : _core.types.identifier(exportName), exportValue));
61 }
62 statements.push(_core.types.expressionStatement(_core.types.callExpression(exportIdent, [_core.types.objectExpression(objectProperties)])));
63 }
64 } else {
65 const exportObj = path.scope.generateUid("exportObj");
66 statements.push(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(_core.types.identifier(exportObj), _core.types.objectExpression([]))]));
67 statements.push(buildExportAll({
68 KEY: path.scope.generateUidIdentifier("key"),
69 EXPORT_OBJ: _core.types.identifier(exportObj),
70 TARGET: exportStarTarget
71 }));
72 for (let i = 0; i < exportNames.length; i++) {
73 const exportName = exportNames[i];
74 const exportValue = exportValues[i];
75 statements.push(_core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.memberExpression(_core.types.identifier(exportObj), _core.types.identifier(exportName)), exportValue)));
76 }
77 statements.push(_core.types.expressionStatement(_core.types.callExpression(exportIdent, [_core.types.identifier(exportObj)])));
78 }
79 return statements;
80}
81var _default = exports.default = (0, _helperPluginUtils.declare)((api, options) => {
82 api.assertVersion(7);
83 const {
84 systemGlobal = "System",
85 allowTopLevelThis = false
86 } = options;
87 const reassignmentVisited = new WeakSet();
88 const reassignmentVisitor = {
89 "AssignmentExpression|UpdateExpression"(path) {
90 if (reassignmentVisited.has(path.node)) return;
91 reassignmentVisited.add(path.node);
92 const arg = path.isAssignmentExpression() ? path.get("left") : path.get("argument");
93 if (arg.isObjectPattern() || arg.isArrayPattern()) {
94 const exprs = [path.node];
95 for (const name of Object.keys(arg.getBindingIdentifiers())) {
96 if (this.scope.getBinding(name) !== path.scope.getBinding(name)) {
97 return;
98 }
99 const exportedNames = this.exports[name];
100 if (!exportedNames) continue;
101 for (const exportedName of exportedNames) {
102 exprs.push(this.buildCall(exportedName, _core.types.identifier(name)).expression);
103 }
104 }
105 path.replaceWith(_core.types.sequenceExpression(exprs));
106 return;
107 }
108 if (!arg.isIdentifier()) return;
109 const name = arg.node.name;
110 if (this.scope.getBinding(name) !== path.scope.getBinding(name)) return;
111 const exportedNames = this.exports[name];
112 if (!exportedNames) return;
113 let node = path.node;
114 const isPostUpdateExpression = _core.types.isUpdateExpression(node, {
115 prefix: false
116 });
117 if (isPostUpdateExpression) {
118 node = _core.types.binaryExpression(node.operator[0], _core.types.unaryExpression("+", _core.types.cloneNode(node.argument)), _core.types.numericLiteral(1));
119 }
120 for (const exportedName of exportedNames) {
121 node = this.buildCall(exportedName, node).expression;
122 }
123 if (isPostUpdateExpression) {
124 node = _core.types.sequenceExpression([node, path.node]);
125 }
126 path.replaceWith(node);
127 }
128 };
129 return {
130 name: "transform-modules-systemjs",
131 pre() {
132 this.file.set("@babel/plugin-transform-modules-*", "systemjs");
133 },
134 visitor: {
135 ["CallExpression" + (api.types.importExpression ? "|ImportExpression" : "")](path, state) {
136 if (path.isCallExpression() && !_core.types.isImport(path.node.callee)) return;
137 if (path.isCallExpression()) {
138 if (!this.file.has("@babel/plugin-proposal-dynamic-import")) {
139 {
140 console.warn(MISSING_PLUGIN_WARNING);
141 }
142 }
143 } else {
144 if (!this.file.has("@babel/plugin-proposal-dynamic-import")) {
145 throw new Error(MISSING_PLUGIN_ERROR);
146 }
147 }
148 path.replaceWith((0, _helperModuleTransforms.buildDynamicImport)(path.node, false, true, specifier => _core.types.callExpression(_core.types.memberExpression(_core.types.identifier(state.contextIdent), _core.types.identifier("import")), [specifier])));
149 },
150 MetaProperty(path, state) {
151 if (path.node.meta.name === "import" && path.node.property.name === "meta") {
152 path.replaceWith(_core.types.memberExpression(_core.types.identifier(state.contextIdent), _core.types.identifier("meta")));
153 }
154 },
155 ReferencedIdentifier(path, state) {
156 if (path.node.name === "__moduleName" && !path.scope.hasBinding("__moduleName")) {
157 path.replaceWith(_core.types.memberExpression(_core.types.identifier(state.contextIdent), _core.types.identifier("id")));
158 }
159 },
160 Program: {
161 enter(path, state) {
162 state.contextIdent = path.scope.generateUid("context");
163 state.stringSpecifiers = new Set();
164 if (!allowTopLevelThis) {
165 (0, _helperModuleTransforms.rewriteThis)(path);
166 }
167 },
168 exit(path, state) {
169 const scope = path.scope;
170 const exportIdent = scope.generateUid("export");
171 const {
172 contextIdent,
173 stringSpecifiers
174 } = state;
175 const exportMap = Object.create(null);
176 const modules = [];
177 const beforeBody = [];
178 const setters = [];
179 const sources = [];
180 const variableIds = [];
181 const removedPaths = [];
182 function addExportName(key, val) {
183 exportMap[key] = exportMap[key] || [];
184 exportMap[key].push(val);
185 }
186 function pushModule(source, key, specifiers) {
187 let module;
188 modules.forEach(function (m) {
189 if (m.key === source) {
190 module = m;
191 }
192 });
193 if (!module) {
194 modules.push(module = {
195 key: source,
196 imports: [],
197 exports: []
198 });
199 }
200 module[key] = module[key].concat(specifiers);
201 }
202 function buildExportCall(name, val) {
203 return _core.types.expressionStatement(_core.types.callExpression(_core.types.identifier(exportIdent), [_core.types.stringLiteral(name), val]));
204 }
205 const exportNames = [];
206 const exportValues = [];
207 const body = path.get("body");
208 for (const path of body) {
209 if (path.isFunctionDeclaration()) {
210 beforeBody.push(path.node);
211 removedPaths.push(path);
212 } else if (path.isClassDeclaration()) {
213 variableIds.push(_core.types.cloneNode(path.node.id));
214 path.replaceWith(_core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.cloneNode(path.node.id), _core.types.toExpression(path.node))));
215 } else if (path.isVariableDeclaration()) {
216 path.node.kind = "var";
217 } else if (path.isImportDeclaration()) {
218 const source = path.node.source.value;
219 pushModule(source, "imports", path.node.specifiers);
220 for (const name of Object.keys(path.getBindingIdentifiers())) {
221 scope.removeBinding(name);
222 variableIds.push(_core.types.identifier(name));
223 }
224 path.remove();
225 } else if (path.isExportAllDeclaration()) {
226 pushModule(path.node.source.value, "exports", path.node);
227 path.remove();
228 } else if (path.isExportDefaultDeclaration()) {
229 const declar = path.node.declaration;
230 if (_core.types.isClassDeclaration(declar)) {
231 const id = declar.id;
232 if (id) {
233 exportNames.push("default");
234 exportValues.push(scope.buildUndefinedNode());
235 variableIds.push(_core.types.cloneNode(id));
236 addExportName(id.name, "default");
237 path.replaceWith(_core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.cloneNode(id), _core.types.toExpression(declar))));
238 } else {
239 exportNames.push("default");
240 exportValues.push(_core.types.toExpression(declar));
241 removedPaths.push(path);
242 }
243 } else if (_core.types.isFunctionDeclaration(declar)) {
244 const id = declar.id;
245 if (id) {
246 beforeBody.push(declar);
247 exportNames.push("default");
248 exportValues.push(_core.types.cloneNode(id));
249 addExportName(id.name, "default");
250 } else {
251 exportNames.push("default");
252 exportValues.push(_core.types.toExpression(declar));
253 }
254 removedPaths.push(path);
255 } else {
256 path.replaceWith(buildExportCall("default", declar));
257 }
258 } else if (path.isExportNamedDeclaration()) {
259 const declar = path.node.declaration;
260 if (declar) {
261 path.replaceWith(declar);
262 if (_core.types.isFunction(declar)) {
263 const name = declar.id.name;
264 addExportName(name, name);
265 beforeBody.push(declar);
266 exportNames.push(name);
267 exportValues.push(_core.types.cloneNode(declar.id));
268 removedPaths.push(path);
269 } else if (_core.types.isClass(declar)) {
270 const name = declar.id.name;
271 exportNames.push(name);
272 exportValues.push(scope.buildUndefinedNode());
273 variableIds.push(_core.types.cloneNode(declar.id));
274 path.replaceWith(_core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.cloneNode(declar.id), _core.types.toExpression(declar))));
275 addExportName(name, name);
276 } else {
277 if (_core.types.isVariableDeclaration(declar)) {
278 declar.kind = "var";
279 }
280 for (const name of Object.keys(_core.types.getBindingIdentifiers(declar))) {
281 addExportName(name, name);
282 }
283 }
284 } else {
285 const specifiers = path.node.specifiers;
286 if (specifiers != null && specifiers.length) {
287 if (path.node.source) {
288 pushModule(path.node.source.value, "exports", specifiers);
289 path.remove();
290 } else {
291 const nodes = [];
292 for (const specifier of specifiers) {
293 const {
294 local,
295 exported
296 } = specifier;
297 const binding = scope.getBinding(local.name);
298 const exportedName = getExportSpecifierName(exported, stringSpecifiers);
299 if (binding && _core.types.isFunctionDeclaration(binding.path.node)) {
300 exportNames.push(exportedName);
301 exportValues.push(_core.types.cloneNode(local));
302 } else if (!binding) {
303 nodes.push(buildExportCall(exportedName, local));
304 }
305 addExportName(local.name, exportedName);
306 }
307 path.replaceWithMultiple(nodes);
308 }
309 } else {
310 path.remove();
311 }
312 }
313 }
314 }
315 modules.forEach(function (specifiers) {
316 const setterBody = [];
317 const target = scope.generateUid(specifiers.key);
318 for (let specifier of specifiers.imports) {
319 if (_core.types.isImportNamespaceSpecifier(specifier)) {
320 setterBody.push(_core.types.expressionStatement(_core.types.assignmentExpression("=", specifier.local, _core.types.identifier(target))));
321 } else if (_core.types.isImportDefaultSpecifier(specifier)) {
322 specifier = _core.types.importSpecifier(specifier.local, _core.types.identifier("default"));
323 }
324 if (_core.types.isImportSpecifier(specifier)) {
325 const {
326 imported
327 } = specifier;
328 setterBody.push(_core.types.expressionStatement(_core.types.assignmentExpression("=", specifier.local, _core.types.memberExpression(_core.types.identifier(target), specifier.imported, imported.type === "StringLiteral"))));
329 }
330 }
331 if (specifiers.exports.length) {
332 const exportNames = [];
333 const exportValues = [];
334 let hasExportStar = false;
335 for (const node of specifiers.exports) {
336 if (_core.types.isExportAllDeclaration(node)) {
337 hasExportStar = true;
338 } else if (_core.types.isExportSpecifier(node)) {
339 const exportedName = getExportSpecifierName(node.exported, stringSpecifiers);
340 exportNames.push(exportedName);
341 exportValues.push(_core.types.memberExpression(_core.types.identifier(target), node.local, _core.types.isStringLiteral(node.local)));
342 } else {}
343 }
344 setterBody.push(...constructExportCall(path, _core.types.identifier(exportIdent), exportNames, exportValues, hasExportStar ? _core.types.identifier(target) : null, stringSpecifiers));
345 }
346 sources.push(_core.types.stringLiteral(specifiers.key));
347 setters.push(_core.types.functionExpression(null, [_core.types.identifier(target)], _core.types.blockStatement(setterBody)));
348 });
349 let moduleName = (0, _helperModuleTransforms.getModuleName)(this.file.opts, options);
350 if (moduleName) moduleName = _core.types.stringLiteral(moduleName);
351 {
352 var _path$scope, _path$scope$hoistVari;
353 (_path$scope$hoistVari = (_path$scope = path.scope).hoistVariables) != null ? _path$scope$hoistVari : _path$scope.hoistVariables = require("@babel/traverse").Scope.prototype.hoistVariables;
354 }
355 path.scope.hoistVariables((id, hasInit) => {
356 variableIds.push(id);
357 if (!hasInit && id.name in exportMap) {
358 for (const exported of exportMap[id.name]) {
359 exportNames.push(exported);
360 exportValues.push(_core.types.buildUndefinedNode());
361 }
362 }
363 });
364 if (variableIds.length) {
365 beforeBody.unshift(_core.types.variableDeclaration("var", variableIds.map(id => _core.types.variableDeclarator(id))));
366 }
367 if (exportNames.length) {
368 beforeBody.push(...constructExportCall(path, _core.types.identifier(exportIdent), exportNames, exportValues, null, stringSpecifiers));
369 }
370 path.traverse(reassignmentVisitor, {
371 exports: exportMap,
372 buildCall: buildExportCall,
373 scope
374 });
375 for (const path of removedPaths) {
376 path.remove();
377 }
378 let hasTLA = false;
379 path.traverse({
380 AwaitExpression(path) {
381 hasTLA = true;
382 path.stop();
383 },
384 Function(path) {
385 path.skip();
386 },
387 noScope: true
388 });
389 path.node.body = [buildTemplate({
390 SYSTEM_REGISTER: _core.types.memberExpression(_core.types.identifier(systemGlobal), _core.types.identifier("register")),
391 BEFORE_BODY: beforeBody,
392 MODULE_NAME: moduleName,
393 SETTERS: _core.types.arrayExpression(setters),
394 EXECUTE: _core.types.functionExpression(null, [], _core.types.blockStatement(path.node.body), false, hasTLA),
395 SOURCES: _core.types.arrayExpression(sources),
396 EXPORT_IDENTIFIER: _core.types.identifier(exportIdent),
397 CONTEXT_IDENTIFIER: _core.types.identifier(contextIdent)
398 })];
399 path.requeue(path.get("body.0"));
400 }
401 }
402 }
403 };
404});
405
406//# sourceMappingURL=index.js.map