UNPKG

12.2 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.buildNamespaceInitStatements = buildNamespaceInitStatements;
7exports.ensureStatementsHoisted = ensureStatementsHoisted;
8Object.defineProperty(exports, "getModuleName", {
9 enumerable: true,
10 get: function () {
11 return _getModuleName.default;
12 }
13});
14Object.defineProperty(exports, "hasExports", {
15 enumerable: true,
16 get: function () {
17 return _normalizeAndLoadMetadata.hasExports;
18 }
19});
20Object.defineProperty(exports, "isModule", {
21 enumerable: true,
22 get: function () {
23 return _helperModuleImports.isModule;
24 }
25});
26Object.defineProperty(exports, "isSideEffectImport", {
27 enumerable: true,
28 get: function () {
29 return _normalizeAndLoadMetadata.isSideEffectImport;
30 }
31});
32exports.rewriteModuleStatementsAndPrepareHeader = rewriteModuleStatementsAndPrepareHeader;
33Object.defineProperty(exports, "rewriteThis", {
34 enumerable: true,
35 get: function () {
36 return _rewriteThis.default;
37 }
38});
39exports.wrapInterop = wrapInterop;
40
41var _assert = require("assert");
42
43var _t = require("@babel/types");
44
45var _template = require("@babel/template");
46
47var _helperModuleImports = require("@babel/helper-module-imports");
48
49var _rewriteThis = require("./rewrite-this");
50
51var _rewriteLiveReferences = require("./rewrite-live-references");
52
53var _normalizeAndLoadMetadata = require("./normalize-and-load-metadata");
54
55var _getModuleName = require("./get-module-name");
56
57const {
58 booleanLiteral,
59 callExpression,
60 cloneNode,
61 directive,
62 directiveLiteral,
63 expressionStatement,
64 identifier,
65 isIdentifier,
66 memberExpression,
67 stringLiteral,
68 valueToNode,
69 variableDeclaration,
70 variableDeclarator
71} = _t;
72
73function rewriteModuleStatementsAndPrepareHeader(path, {
74 loose,
75 exportName,
76 strict,
77 allowTopLevelThis,
78 strictMode,
79 noInterop,
80 importInterop = noInterop ? "none" : "babel",
81 lazy,
82 esNamespaceOnly,
83 filename,
84 constantReexports = loose,
85 enumerableModuleMeta = loose,
86 noIncompleteNsImportDetection
87}) {
88 (0, _normalizeAndLoadMetadata.validateImportInteropOption)(importInterop);
89
90 _assert((0, _helperModuleImports.isModule)(path), "Cannot process module statements in a script");
91
92 path.node.sourceType = "script";
93 const meta = (0, _normalizeAndLoadMetadata.default)(path, exportName, {
94 importInterop,
95 initializeReexports: constantReexports,
96 lazy,
97 esNamespaceOnly,
98 filename
99 });
100
101 if (!allowTopLevelThis) {
102 (0, _rewriteThis.default)(path);
103 }
104
105 (0, _rewriteLiveReferences.default)(path, meta);
106
107 if (strictMode !== false) {
108 const hasStrict = path.node.directives.some(directive => {
109 return directive.value.value === "use strict";
110 });
111
112 if (!hasStrict) {
113 path.unshiftContainer("directives", directive(directiveLiteral("use strict")));
114 }
115 }
116
117 const headers = [];
118
119 if ((0, _normalizeAndLoadMetadata.hasExports)(meta) && !strict) {
120 headers.push(buildESModuleHeader(meta, enumerableModuleMeta));
121 }
122
123 const nameList = buildExportNameListDeclaration(path, meta);
124
125 if (nameList) {
126 meta.exportNameListName = nameList.name;
127 headers.push(nameList.statement);
128 }
129
130 headers.push(...buildExportInitializationStatements(path, meta, constantReexports, noIncompleteNsImportDetection));
131 return {
132 meta,
133 headers
134 };
135}
136
137function ensureStatementsHoisted(statements) {
138 statements.forEach(header => {
139 header._blockHoist = 3;
140 });
141}
142
143function wrapInterop(programPath, expr, type) {
144 if (type === "none") {
145 return null;
146 }
147
148 if (type === "node-namespace") {
149 return callExpression(programPath.hub.addHelper("interopRequireWildcard"), [expr, booleanLiteral(true)]);
150 } else if (type === "node-default") {
151 return null;
152 }
153
154 let helper;
155
156 if (type === "default") {
157 helper = "interopRequireDefault";
158 } else if (type === "namespace") {
159 helper = "interopRequireWildcard";
160 } else {
161 throw new Error(`Unknown interop: ${type}`);
162 }
163
164 return callExpression(programPath.hub.addHelper(helper), [expr]);
165}
166
167function buildNamespaceInitStatements(metadata, sourceMetadata, constantReexports = false) {
168 const statements = [];
169 let srcNamespace = identifier(sourceMetadata.name);
170 if (sourceMetadata.lazy) srcNamespace = callExpression(srcNamespace, []);
171
172 for (const localName of sourceMetadata.importsNamespace) {
173 if (localName === sourceMetadata.name) continue;
174 statements.push(_template.default.statement`var NAME = SOURCE;`({
175 NAME: localName,
176 SOURCE: cloneNode(srcNamespace)
177 }));
178 }
179
180 if (constantReexports) {
181 statements.push(...buildReexportsFromMeta(metadata, sourceMetadata, true));
182 }
183
184 for (const exportName of sourceMetadata.reexportNamespace) {
185 statements.push((sourceMetadata.lazy ? _template.default.statement`
186 Object.defineProperty(EXPORTS, "NAME", {
187 enumerable: true,
188 get: function() {
189 return NAMESPACE;
190 }
191 });
192 ` : _template.default.statement`EXPORTS.NAME = NAMESPACE;`)({
193 EXPORTS: metadata.exportName,
194 NAME: exportName,
195 NAMESPACE: cloneNode(srcNamespace)
196 }));
197 }
198
199 if (sourceMetadata.reexportAll) {
200 const statement = buildNamespaceReexport(metadata, cloneNode(srcNamespace), constantReexports);
201 statement.loc = sourceMetadata.reexportAll.loc;
202 statements.push(statement);
203 }
204
205 return statements;
206}
207
208const ReexportTemplate = {
209 constant: _template.default.statement`EXPORTS.EXPORT_NAME = NAMESPACE_IMPORT;`,
210 constantComputed: _template.default.statement`EXPORTS["EXPORT_NAME"] = NAMESPACE_IMPORT;`,
211 spec: _template.default.statement`
212 Object.defineProperty(EXPORTS, "EXPORT_NAME", {
213 enumerable: true,
214 get: function() {
215 return NAMESPACE_IMPORT;
216 },
217 });
218 `
219};
220
221const buildReexportsFromMeta = (meta, metadata, constantReexports) => {
222 const namespace = metadata.lazy ? callExpression(identifier(metadata.name), []) : identifier(metadata.name);
223 const {
224 stringSpecifiers
225 } = meta;
226 return Array.from(metadata.reexports, ([exportName, importName]) => {
227 let NAMESPACE_IMPORT = cloneNode(namespace);
228
229 if (importName === "default" && metadata.interop === "node-default") {} else if (stringSpecifiers.has(importName)) {
230 NAMESPACE_IMPORT = memberExpression(NAMESPACE_IMPORT, stringLiteral(importName), true);
231 } else {
232 NAMESPACE_IMPORT = memberExpression(NAMESPACE_IMPORT, identifier(importName));
233 }
234
235 const astNodes = {
236 EXPORTS: meta.exportName,
237 EXPORT_NAME: exportName,
238 NAMESPACE_IMPORT
239 };
240
241 if (constantReexports || isIdentifier(NAMESPACE_IMPORT)) {
242 if (stringSpecifiers.has(exportName)) {
243 return ReexportTemplate.constantComputed(astNodes);
244 } else {
245 return ReexportTemplate.constant(astNodes);
246 }
247 } else {
248 return ReexportTemplate.spec(astNodes);
249 }
250 });
251};
252
253function buildESModuleHeader(metadata, enumerableModuleMeta = false) {
254 return (enumerableModuleMeta ? _template.default.statement`
255 EXPORTS.__esModule = true;
256 ` : _template.default.statement`
257 Object.defineProperty(EXPORTS, "__esModule", {
258 value: true,
259 });
260 `)({
261 EXPORTS: metadata.exportName
262 });
263}
264
265function buildNamespaceReexport(metadata, namespace, constantReexports) {
266 return (constantReexports ? _template.default.statement`
267 Object.keys(NAMESPACE).forEach(function(key) {
268 if (key === "default" || key === "__esModule") return;
269 VERIFY_NAME_LIST;
270 if (key in EXPORTS && EXPORTS[key] === NAMESPACE[key]) return;
271
272 EXPORTS[key] = NAMESPACE[key];
273 });
274 ` : _template.default.statement`
275 Object.keys(NAMESPACE).forEach(function(key) {
276 if (key === "default" || key === "__esModule") return;
277 VERIFY_NAME_LIST;
278 if (key in EXPORTS && EXPORTS[key] === NAMESPACE[key]) return;
279
280 Object.defineProperty(EXPORTS, key, {
281 enumerable: true,
282 get: function() {
283 return NAMESPACE[key];
284 },
285 });
286 });
287 `)({
288 NAMESPACE: namespace,
289 EXPORTS: metadata.exportName,
290 VERIFY_NAME_LIST: metadata.exportNameListName ? (0, _template.default)`
291 if (Object.prototype.hasOwnProperty.call(EXPORTS_LIST, key)) return;
292 `({
293 EXPORTS_LIST: metadata.exportNameListName
294 }) : null
295 });
296}
297
298function buildExportNameListDeclaration(programPath, metadata) {
299 const exportedVars = Object.create(null);
300
301 for (const data of metadata.local.values()) {
302 for (const name of data.names) {
303 exportedVars[name] = true;
304 }
305 }
306
307 let hasReexport = false;
308
309 for (const data of metadata.source.values()) {
310 for (const exportName of data.reexports.keys()) {
311 exportedVars[exportName] = true;
312 }
313
314 for (const exportName of data.reexportNamespace) {
315 exportedVars[exportName] = true;
316 }
317
318 hasReexport = hasReexport || !!data.reexportAll;
319 }
320
321 if (!hasReexport || Object.keys(exportedVars).length === 0) return null;
322 const name = programPath.scope.generateUidIdentifier("exportNames");
323 delete exportedVars.default;
324 return {
325 name: name.name,
326 statement: variableDeclaration("var", [variableDeclarator(name, valueToNode(exportedVars))])
327 };
328}
329
330function buildExportInitializationStatements(programPath, metadata, constantReexports = false, noIncompleteNsImportDetection = false) {
331 const initStatements = [];
332
333 for (const [localName, data] of metadata.local) {
334 if (data.kind === "import") {} else if (data.kind === "hoisted") {
335 initStatements.push([data.names[0], buildInitStatement(metadata, data.names, identifier(localName))]);
336 } else if (!noIncompleteNsImportDetection) {
337 for (const exportName of data.names) {
338 initStatements.push([exportName, null]);
339 }
340 }
341 }
342
343 for (const data of metadata.source.values()) {
344 if (!constantReexports) {
345 const reexportsStatements = buildReexportsFromMeta(metadata, data, false);
346 const reexports = [...data.reexports.keys()];
347
348 for (let i = 0; i < reexportsStatements.length; i++) {
349 initStatements.push([reexports[i], reexportsStatements[i]]);
350 }
351 }
352
353 if (!noIncompleteNsImportDetection) {
354 for (const exportName of data.reexportNamespace) {
355 initStatements.push([exportName, null]);
356 }
357 }
358 }
359
360 initStatements.sort(([a], [b]) => {
361 if (a < b) return -1;
362 if (b < a) return 1;
363 return 0;
364 });
365 const results = [];
366
367 if (noIncompleteNsImportDetection) {
368 for (const [, initStatement] of initStatements) {
369 results.push(initStatement);
370 }
371 } else {
372 const chunkSize = 100;
373
374 for (let i = 0; i < initStatements.length; i += chunkSize) {
375 let uninitializedExportNames = [];
376
377 for (let j = 0; j < chunkSize && i + j < initStatements.length; j++) {
378 const [exportName, initStatement] = initStatements[i + j];
379
380 if (initStatement !== null) {
381 if (uninitializedExportNames.length > 0) {
382 results.push(buildInitStatement(metadata, uninitializedExportNames, programPath.scope.buildUndefinedNode()));
383 uninitializedExportNames = [];
384 }
385
386 results.push(initStatement);
387 } else {
388 uninitializedExportNames.push(exportName);
389 }
390 }
391
392 if (uninitializedExportNames.length > 0) {
393 results.push(buildInitStatement(metadata, uninitializedExportNames, programPath.scope.buildUndefinedNode()));
394 }
395 }
396 }
397
398 return results;
399}
400
401const InitTemplate = {
402 computed: _template.default.expression`EXPORTS["NAME"] = VALUE`,
403 default: _template.default.expression`EXPORTS.NAME = VALUE`
404};
405
406function buildInitStatement(metadata, exportNames, initExpr) {
407 const {
408 stringSpecifiers,
409 exportName: EXPORTS
410 } = metadata;
411 return expressionStatement(exportNames.reduce((acc, exportName) => {
412 const params = {
413 EXPORTS,
414 NAME: exportName,
415 VALUE: acc
416 };
417
418 if (stringSpecifiers.has(exportName)) {
419 return InitTemplate.computed(params);
420 } else {
421 return InitTemplate.default(params);
422 }
423 }, initExpr));
424}
425
426//# sourceMappingURL=index.js.map