[6a3a178] | 1 | "use strict";
|
---|
| 2 |
|
---|
| 3 | Object.defineProperty(exports, "__esModule", {
|
---|
| 4 | value: true
|
---|
| 5 | });
|
---|
| 6 | exports.hasExports = hasExports;
|
---|
| 7 | exports.isSideEffectImport = isSideEffectImport;
|
---|
| 8 | exports.validateImportInteropOption = validateImportInteropOption;
|
---|
| 9 | exports.default = normalizeModuleAndLoadMetadata;
|
---|
| 10 |
|
---|
| 11 | var _path = require("path");
|
---|
| 12 |
|
---|
| 13 | var _helperValidatorIdentifier = require("@babel/helper-validator-identifier");
|
---|
| 14 |
|
---|
| 15 | var _helperSplitExportDeclaration = require("@babel/helper-split-export-declaration");
|
---|
| 16 |
|
---|
| 17 | function hasExports(metadata) {
|
---|
| 18 | return metadata.hasExports;
|
---|
| 19 | }
|
---|
| 20 |
|
---|
| 21 | function isSideEffectImport(source) {
|
---|
| 22 | return source.imports.size === 0 && source.importsNamespace.size === 0 && source.reexports.size === 0 && source.reexportNamespace.size === 0 && !source.reexportAll;
|
---|
| 23 | }
|
---|
| 24 |
|
---|
| 25 | function validateImportInteropOption(importInterop) {
|
---|
| 26 | if (typeof importInterop !== "function" && importInterop !== "none" && importInterop !== "babel" && importInterop !== "node") {
|
---|
| 27 | throw new Error(`.importInterop must be one of "none", "babel", "node", or a function returning one of those values (received ${importInterop}).`);
|
---|
| 28 | }
|
---|
| 29 |
|
---|
| 30 | return importInterop;
|
---|
| 31 | }
|
---|
| 32 |
|
---|
| 33 | function resolveImportInterop(importInterop, source) {
|
---|
| 34 | if (typeof importInterop === "function") {
|
---|
| 35 | return validateImportInteropOption(importInterop(source));
|
---|
| 36 | }
|
---|
| 37 |
|
---|
| 38 | return importInterop;
|
---|
| 39 | }
|
---|
| 40 |
|
---|
| 41 | function normalizeModuleAndLoadMetadata(programPath, exportName, {
|
---|
| 42 | importInterop,
|
---|
| 43 | initializeReexports = false,
|
---|
| 44 | lazy = false,
|
---|
| 45 | esNamespaceOnly = false
|
---|
| 46 | }) {
|
---|
| 47 | if (!exportName) {
|
---|
| 48 | exportName = programPath.scope.generateUidIdentifier("exports").name;
|
---|
| 49 | }
|
---|
| 50 |
|
---|
| 51 | const stringSpecifiers = new Set();
|
---|
| 52 | nameAnonymousExports(programPath);
|
---|
| 53 | const {
|
---|
| 54 | local,
|
---|
| 55 | source,
|
---|
| 56 | hasExports
|
---|
| 57 | } = getModuleMetadata(programPath, {
|
---|
| 58 | initializeReexports,
|
---|
| 59 | lazy
|
---|
| 60 | }, stringSpecifiers);
|
---|
| 61 | removeModuleDeclarations(programPath);
|
---|
| 62 |
|
---|
| 63 | for (const [, metadata] of source) {
|
---|
| 64 | if (metadata.importsNamespace.size > 0) {
|
---|
| 65 | metadata.name = metadata.importsNamespace.values().next().value;
|
---|
| 66 | }
|
---|
| 67 |
|
---|
| 68 | const resolvedInterop = resolveImportInterop(importInterop, metadata.source);
|
---|
| 69 |
|
---|
| 70 | if (resolvedInterop === "none") {
|
---|
| 71 | metadata.interop = "none";
|
---|
| 72 | } else if (resolvedInterop === "node" && metadata.interop === "namespace") {
|
---|
| 73 | metadata.interop = "node-namespace";
|
---|
| 74 | } else if (resolvedInterop === "node" && metadata.interop === "default") {
|
---|
| 75 | metadata.interop = "node-default";
|
---|
| 76 | } else if (esNamespaceOnly && metadata.interop === "namespace") {
|
---|
| 77 | metadata.interop = "default";
|
---|
| 78 | }
|
---|
| 79 | }
|
---|
| 80 |
|
---|
| 81 | return {
|
---|
| 82 | exportName,
|
---|
| 83 | exportNameListName: null,
|
---|
| 84 | hasExports,
|
---|
| 85 | local,
|
---|
| 86 | source,
|
---|
| 87 | stringSpecifiers
|
---|
| 88 | };
|
---|
| 89 | }
|
---|
| 90 |
|
---|
| 91 | function getExportSpecifierName(path, stringSpecifiers) {
|
---|
| 92 | if (path.isIdentifier()) {
|
---|
| 93 | return path.node.name;
|
---|
| 94 | } else if (path.isStringLiteral()) {
|
---|
| 95 | const stringValue = path.node.value;
|
---|
| 96 |
|
---|
| 97 | if (!(0, _helperValidatorIdentifier.isIdentifierName)(stringValue)) {
|
---|
| 98 | stringSpecifiers.add(stringValue);
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | return stringValue;
|
---|
| 102 | } else {
|
---|
| 103 | throw new Error(`Expected export specifier to be either Identifier or StringLiteral, got ${path.node.type}`);
|
---|
| 104 | }
|
---|
| 105 | }
|
---|
| 106 |
|
---|
| 107 | function assertExportSpecifier(path) {
|
---|
| 108 | if (path.isExportSpecifier()) {
|
---|
| 109 | return;
|
---|
| 110 | } else if (path.isExportNamespaceSpecifier()) {
|
---|
| 111 | throw path.buildCodeFrameError("Export namespace should be first transformed by `@babel/plugin-proposal-export-namespace-from`.");
|
---|
| 112 | } else {
|
---|
| 113 | throw path.buildCodeFrameError("Unexpected export specifier type");
|
---|
| 114 | }
|
---|
| 115 | }
|
---|
| 116 |
|
---|
| 117 | function getModuleMetadata(programPath, {
|
---|
| 118 | lazy,
|
---|
| 119 | initializeReexports
|
---|
| 120 | }, stringSpecifiers) {
|
---|
| 121 | const localData = getLocalExportMetadata(programPath, initializeReexports, stringSpecifiers);
|
---|
| 122 | const sourceData = new Map();
|
---|
| 123 |
|
---|
| 124 | const getData = sourceNode => {
|
---|
| 125 | const source = sourceNode.value;
|
---|
| 126 | let data = sourceData.get(source);
|
---|
| 127 |
|
---|
| 128 | if (!data) {
|
---|
| 129 | data = {
|
---|
| 130 | name: programPath.scope.generateUidIdentifier((0, _path.basename)(source, (0, _path.extname)(source))).name,
|
---|
| 131 | interop: "none",
|
---|
| 132 | loc: null,
|
---|
| 133 | imports: new Map(),
|
---|
| 134 | importsNamespace: new Set(),
|
---|
| 135 | reexports: new Map(),
|
---|
| 136 | reexportNamespace: new Set(),
|
---|
| 137 | reexportAll: null,
|
---|
| 138 | lazy: false,
|
---|
| 139 | source
|
---|
| 140 | };
|
---|
| 141 | sourceData.set(source, data);
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | return data;
|
---|
| 145 | };
|
---|
| 146 |
|
---|
| 147 | let hasExports = false;
|
---|
| 148 | programPath.get("body").forEach(child => {
|
---|
| 149 | if (child.isImportDeclaration()) {
|
---|
| 150 | const data = getData(child.node.source);
|
---|
| 151 | if (!data.loc) data.loc = child.node.loc;
|
---|
| 152 | child.get("specifiers").forEach(spec => {
|
---|
| 153 | if (spec.isImportDefaultSpecifier()) {
|
---|
| 154 | const localName = spec.get("local").node.name;
|
---|
| 155 | data.imports.set(localName, "default");
|
---|
| 156 | const reexport = localData.get(localName);
|
---|
| 157 |
|
---|
| 158 | if (reexport) {
|
---|
| 159 | localData.delete(localName);
|
---|
| 160 | reexport.names.forEach(name => {
|
---|
| 161 | data.reexports.set(name, "default");
|
---|
| 162 | });
|
---|
| 163 | }
|
---|
| 164 | } else if (spec.isImportNamespaceSpecifier()) {
|
---|
| 165 | const localName = spec.get("local").node.name;
|
---|
| 166 | data.importsNamespace.add(localName);
|
---|
| 167 | const reexport = localData.get(localName);
|
---|
| 168 |
|
---|
| 169 | if (reexport) {
|
---|
| 170 | localData.delete(localName);
|
---|
| 171 | reexport.names.forEach(name => {
|
---|
| 172 | data.reexportNamespace.add(name);
|
---|
| 173 | });
|
---|
| 174 | }
|
---|
| 175 | } else if (spec.isImportSpecifier()) {
|
---|
| 176 | const importName = getExportSpecifierName(spec.get("imported"), stringSpecifiers);
|
---|
| 177 | const localName = spec.get("local").node.name;
|
---|
| 178 | data.imports.set(localName, importName);
|
---|
| 179 | const reexport = localData.get(localName);
|
---|
| 180 |
|
---|
| 181 | if (reexport) {
|
---|
| 182 | localData.delete(localName);
|
---|
| 183 | reexport.names.forEach(name => {
|
---|
| 184 | data.reexports.set(name, importName);
|
---|
| 185 | });
|
---|
| 186 | }
|
---|
| 187 | }
|
---|
| 188 | });
|
---|
| 189 | } else if (child.isExportAllDeclaration()) {
|
---|
| 190 | hasExports = true;
|
---|
| 191 | const data = getData(child.node.source);
|
---|
| 192 | if (!data.loc) data.loc = child.node.loc;
|
---|
| 193 | data.reexportAll = {
|
---|
| 194 | loc: child.node.loc
|
---|
| 195 | };
|
---|
| 196 | } else if (child.isExportNamedDeclaration() && child.node.source) {
|
---|
| 197 | hasExports = true;
|
---|
| 198 | const data = getData(child.node.source);
|
---|
| 199 | if (!data.loc) data.loc = child.node.loc;
|
---|
| 200 | child.get("specifiers").forEach(spec => {
|
---|
| 201 | assertExportSpecifier(spec);
|
---|
| 202 | const importName = getExportSpecifierName(spec.get("local"), stringSpecifiers);
|
---|
| 203 | const exportName = getExportSpecifierName(spec.get("exported"), stringSpecifiers);
|
---|
| 204 | data.reexports.set(exportName, importName);
|
---|
| 205 |
|
---|
| 206 | if (exportName === "__esModule") {
|
---|
| 207 | throw spec.get("exported").buildCodeFrameError('Illegal export "__esModule".');
|
---|
| 208 | }
|
---|
| 209 | });
|
---|
| 210 | } else if (child.isExportNamedDeclaration() || child.isExportDefaultDeclaration()) {
|
---|
| 211 | hasExports = true;
|
---|
| 212 | }
|
---|
| 213 | });
|
---|
| 214 |
|
---|
| 215 | for (const metadata of sourceData.values()) {
|
---|
| 216 | let needsDefault = false;
|
---|
| 217 | let needsNamed = false;
|
---|
| 218 |
|
---|
| 219 | if (metadata.importsNamespace.size > 0) {
|
---|
| 220 | needsDefault = true;
|
---|
| 221 | needsNamed = true;
|
---|
| 222 | }
|
---|
| 223 |
|
---|
| 224 | if (metadata.reexportAll) {
|
---|
| 225 | needsNamed = true;
|
---|
| 226 | }
|
---|
| 227 |
|
---|
| 228 | for (const importName of metadata.imports.values()) {
|
---|
| 229 | if (importName === "default") needsDefault = true;else needsNamed = true;
|
---|
| 230 | }
|
---|
| 231 |
|
---|
| 232 | for (const importName of metadata.reexports.values()) {
|
---|
| 233 | if (importName === "default") needsDefault = true;else needsNamed = true;
|
---|
| 234 | }
|
---|
| 235 |
|
---|
| 236 | if (needsDefault && needsNamed) {
|
---|
| 237 | metadata.interop = "namespace";
|
---|
| 238 | } else if (needsDefault) {
|
---|
| 239 | metadata.interop = "default";
|
---|
| 240 | }
|
---|
| 241 | }
|
---|
| 242 |
|
---|
| 243 | for (const [source, metadata] of sourceData) {
|
---|
| 244 | if (lazy !== false && !(isSideEffectImport(metadata) || metadata.reexportAll)) {
|
---|
| 245 | if (lazy === true) {
|
---|
| 246 | metadata.lazy = !/\./.test(source);
|
---|
| 247 | } else if (Array.isArray(lazy)) {
|
---|
| 248 | metadata.lazy = lazy.indexOf(source) !== -1;
|
---|
| 249 | } else if (typeof lazy === "function") {
|
---|
| 250 | metadata.lazy = lazy(source);
|
---|
| 251 | } else {
|
---|
| 252 | throw new Error(`.lazy must be a boolean, string array, or function`);
|
---|
| 253 | }
|
---|
| 254 | }
|
---|
| 255 | }
|
---|
| 256 |
|
---|
| 257 | return {
|
---|
| 258 | hasExports,
|
---|
| 259 | local: localData,
|
---|
| 260 | source: sourceData
|
---|
| 261 | };
|
---|
| 262 | }
|
---|
| 263 |
|
---|
| 264 | function getLocalExportMetadata(programPath, initializeReexports, stringSpecifiers) {
|
---|
| 265 | const bindingKindLookup = new Map();
|
---|
| 266 | programPath.get("body").forEach(child => {
|
---|
| 267 | let kind;
|
---|
| 268 |
|
---|
| 269 | if (child.isImportDeclaration()) {
|
---|
| 270 | kind = "import";
|
---|
| 271 | } else {
|
---|
| 272 | if (child.isExportDefaultDeclaration()) child = child.get("declaration");
|
---|
| 273 |
|
---|
| 274 | if (child.isExportNamedDeclaration()) {
|
---|
| 275 | if (child.node.declaration) {
|
---|
| 276 | child = child.get("declaration");
|
---|
| 277 | } else if (initializeReexports && child.node.source && child.get("source").isStringLiteral()) {
|
---|
| 278 | child.get("specifiers").forEach(spec => {
|
---|
| 279 | assertExportSpecifier(spec);
|
---|
| 280 | bindingKindLookup.set(spec.get("local").node.name, "block");
|
---|
| 281 | });
|
---|
| 282 | return;
|
---|
| 283 | }
|
---|
| 284 | }
|
---|
| 285 |
|
---|
| 286 | if (child.isFunctionDeclaration()) {
|
---|
| 287 | kind = "hoisted";
|
---|
| 288 | } else if (child.isClassDeclaration()) {
|
---|
| 289 | kind = "block";
|
---|
| 290 | } else if (child.isVariableDeclaration({
|
---|
| 291 | kind: "var"
|
---|
| 292 | })) {
|
---|
| 293 | kind = "var";
|
---|
| 294 | } else if (child.isVariableDeclaration()) {
|
---|
| 295 | kind = "block";
|
---|
| 296 | } else {
|
---|
| 297 | return;
|
---|
| 298 | }
|
---|
| 299 | }
|
---|
| 300 |
|
---|
| 301 | Object.keys(child.getOuterBindingIdentifiers()).forEach(name => {
|
---|
| 302 | bindingKindLookup.set(name, kind);
|
---|
| 303 | });
|
---|
| 304 | });
|
---|
| 305 | const localMetadata = new Map();
|
---|
| 306 |
|
---|
| 307 | const getLocalMetadata = idPath => {
|
---|
| 308 | const localName = idPath.node.name;
|
---|
| 309 | let metadata = localMetadata.get(localName);
|
---|
| 310 |
|
---|
| 311 | if (!metadata) {
|
---|
| 312 | const kind = bindingKindLookup.get(localName);
|
---|
| 313 |
|
---|
| 314 | if (kind === undefined) {
|
---|
| 315 | throw idPath.buildCodeFrameError(`Exporting local "${localName}", which is not declared.`);
|
---|
| 316 | }
|
---|
| 317 |
|
---|
| 318 | metadata = {
|
---|
| 319 | names: [],
|
---|
| 320 | kind
|
---|
| 321 | };
|
---|
| 322 | localMetadata.set(localName, metadata);
|
---|
| 323 | }
|
---|
| 324 |
|
---|
| 325 | return metadata;
|
---|
| 326 | };
|
---|
| 327 |
|
---|
| 328 | programPath.get("body").forEach(child => {
|
---|
| 329 | if (child.isExportNamedDeclaration() && (initializeReexports || !child.node.source)) {
|
---|
| 330 | if (child.node.declaration) {
|
---|
| 331 | const declaration = child.get("declaration");
|
---|
| 332 | const ids = declaration.getOuterBindingIdentifierPaths();
|
---|
| 333 | Object.keys(ids).forEach(name => {
|
---|
| 334 | if (name === "__esModule") {
|
---|
| 335 | throw declaration.buildCodeFrameError('Illegal export "__esModule".');
|
---|
| 336 | }
|
---|
| 337 |
|
---|
| 338 | getLocalMetadata(ids[name]).names.push(name);
|
---|
| 339 | });
|
---|
| 340 | } else {
|
---|
| 341 | child.get("specifiers").forEach(spec => {
|
---|
| 342 | const local = spec.get("local");
|
---|
| 343 | const exported = spec.get("exported");
|
---|
| 344 | const localMetadata = getLocalMetadata(local);
|
---|
| 345 | const exportName = getExportSpecifierName(exported, stringSpecifiers);
|
---|
| 346 |
|
---|
| 347 | if (exportName === "__esModule") {
|
---|
| 348 | throw exported.buildCodeFrameError('Illegal export "__esModule".');
|
---|
| 349 | }
|
---|
| 350 |
|
---|
| 351 | localMetadata.names.push(exportName);
|
---|
| 352 | });
|
---|
| 353 | }
|
---|
| 354 | } else if (child.isExportDefaultDeclaration()) {
|
---|
| 355 | const declaration = child.get("declaration");
|
---|
| 356 |
|
---|
| 357 | if (declaration.isFunctionDeclaration() || declaration.isClassDeclaration()) {
|
---|
| 358 | getLocalMetadata(declaration.get("id")).names.push("default");
|
---|
| 359 | } else {
|
---|
| 360 | throw declaration.buildCodeFrameError("Unexpected default expression export.");
|
---|
| 361 | }
|
---|
| 362 | }
|
---|
| 363 | });
|
---|
| 364 | return localMetadata;
|
---|
| 365 | }
|
---|
| 366 |
|
---|
| 367 | function nameAnonymousExports(programPath) {
|
---|
| 368 | programPath.get("body").forEach(child => {
|
---|
| 369 | if (!child.isExportDefaultDeclaration()) return;
|
---|
| 370 | (0, _helperSplitExportDeclaration.default)(child);
|
---|
| 371 | });
|
---|
| 372 | }
|
---|
| 373 |
|
---|
| 374 | function removeModuleDeclarations(programPath) {
|
---|
| 375 | programPath.get("body").forEach(child => {
|
---|
| 376 | if (child.isImportDeclaration()) {
|
---|
| 377 | child.remove();
|
---|
| 378 | } else if (child.isExportNamedDeclaration()) {
|
---|
| 379 | if (child.node.declaration) {
|
---|
| 380 | child.node.declaration._blockHoist = child.node._blockHoist;
|
---|
| 381 | child.replaceWith(child.node.declaration);
|
---|
| 382 | } else {
|
---|
| 383 | child.remove();
|
---|
| 384 | }
|
---|
| 385 | } else if (child.isExportDefaultDeclaration()) {
|
---|
| 386 | const declaration = child.get("declaration");
|
---|
| 387 |
|
---|
| 388 | if (declaration.isFunctionDeclaration() || declaration.isClassDeclaration()) {
|
---|
| 389 | declaration._blockHoist = child.node._blockHoist;
|
---|
| 390 | child.replaceWith(declaration);
|
---|
| 391 | } else {
|
---|
| 392 | throw declaration.buildCodeFrameError("Unexpected default expression export.");
|
---|
| 393 | }
|
---|
| 394 | } else if (child.isExportAllDeclaration()) {
|
---|
| 395 | child.remove();
|
---|
| 396 | }
|
---|
| 397 | });
|
---|
| 398 | } |
---|