diff --git a/packages/babel-core/src/parser/util/missing-plugin-helper.js b/packages/babel-core/src/parser/util/missing-plugin-helper.js index 5a5f7082f253..10b813ee756d 100644 --- a/packages/babel-core/src/parser/util/missing-plugin-helper.js +++ b/packages/babel-core/src/parser/util/missing-plugin-helper.js @@ -135,6 +135,12 @@ const pluginNameMap = { url: "https://git.io/JfK3k", }, }, + moduleStringNames: { + syntax: { + name: "@babel/plugin-syntax-module-string-names", + url: "https://git.io/JTL8G", + }, + }, numericSeparator: { syntax: { name: "@babel/plugin-syntax-numeric-separator", diff --git a/packages/babel-helper-module-transforms/package.json b/packages/babel-helper-module-transforms/package.json index d94542bd7116..6522e1d3bf69 100644 --- a/packages/babel-helper-module-transforms/package.json +++ b/packages/babel-helper-module-transforms/package.json @@ -19,6 +19,7 @@ "@babel/helper-replace-supers": "workspace:^7.10.4", "@babel/helper-simple-access": "workspace:^7.10.4", "@babel/helper-split-export-declaration": "workspace:^7.11.0", + "@babel/helper-validator-identifier": "workspace:^7.10.4", "@babel/template": "workspace:^7.10.4", "@babel/types": "workspace:^7.11.0", "lodash": "^4.17.19" diff --git a/packages/babel-helper-module-transforms/src/index.js b/packages/babel-helper-module-transforms/src/index.js index 81983f773c09..164462ee0450 100644 --- a/packages/babel-helper-module-transforms/src/index.js +++ b/packages/babel-helper-module-transforms/src/index.js @@ -10,6 +10,8 @@ import rewriteLiveReferences from "./rewrite-live-references"; import normalizeAndLoadModuleMetadata, { hasExports, isSideEffectImport, + type ModuleMetadata, + type SourceModuleMetadata, } from "./normalize-and-load-metadata"; export { default as getModuleName } from "./get-module-name"; @@ -180,33 +182,58 @@ export function buildNamespaceInitStatements( return statements; } -const getTemplateForReexport = loose => { - return loose - ? template.statement`EXPORTS.EXPORT_NAME = NAMESPACE.IMPORT_NAME;` - : template` - Object.defineProperty(EXPORTS, "EXPORT_NAME", { - enumerable: true, - get: function() { - return NAMESPACE.IMPORT_NAME; - }, - }); - `; +const ReexportTemplate = { + loose: template.statement`EXPORTS.EXPORT_NAME = NAMESPACE_IMPORT;`, + looseComputed: template.statement`EXPORTS["EXPORT_NAME"] = NAMESPACE_IMPORT;`, + spec: template` + Object.defineProperty(EXPORTS, "EXPORT_NAME", { + enumerable: true, + get: function() { + return NAMESPACE_IMPORT; + }, + }); + `, }; -const buildReexportsFromMeta = (meta, metadata, loose) => { +const buildReexportsFromMeta = ( + meta: ModuleMetadata, + metadata: SourceModuleMetadata, + loose, +) => { const namespace = metadata.lazy ? t.callExpression(t.identifier(metadata.name), []) : t.identifier(metadata.name); - const templateForCurrentMode = getTemplateForReexport(loose); - return Array.from(metadata.reexports, ([exportName, importName]) => - templateForCurrentMode({ + const { stringSpecifiers } = meta; + return Array.from(metadata.reexports, ([exportName, importName]) => { + let NAMESPACE_IMPORT; + if (stringSpecifiers.has(importName)) { + NAMESPACE_IMPORT = t.memberExpression( + t.cloneNode(namespace), + t.stringLiteral(importName), + true, + ); + } else { + NAMESPACE_IMPORT = NAMESPACE_IMPORT = t.memberExpression( + t.cloneNode(namespace), + t.identifier(importName), + ); + } + const astNodes = { EXPORTS: meta.exportName, EXPORT_NAME: exportName, - NAMESPACE: t.cloneNode(namespace), - IMPORT_NAME: importName, - }), - ); + NAMESPACE_IMPORT, + }; + if (loose) { + if (stringSpecifiers.has(exportName)) { + return ReexportTemplate.looseComputed(astNodes); + } else { + return ReexportTemplate.loose(astNodes); + } + } else { + return ReexportTemplate.spec(astNodes); + } + }); }; /** @@ -363,16 +390,25 @@ function buildExportInitializationStatements( * Given a set of export names, create a set of nested assignments to * initialize them all to a given expression. */ -function buildInitStatement(metadata, exportNames, initExpr) { +const InitTemplate = { + computed: template.expression`EXPORTS["NAME"] = VALUE`, + default: template.expression`EXPORTS.NAME = VALUE`, +}; + +function buildInitStatement(metadata: ModuleMetadata, exportNames, initExpr) { + const { stringSpecifiers, exportName: EXPORTS } = metadata; return t.expressionStatement( - exportNames.reduce( - (acc, exportName) => - template.expression`EXPORTS.NAME = VALUE`({ - EXPORTS: metadata.exportName, - NAME: exportName, - VALUE: acc, - }), - initExpr, - ), + exportNames.reduce((acc, exportName) => { + const params = { + EXPORTS, + NAME: exportName, + VALUE: acc, + }; + if (stringSpecifiers.has(exportName)) { + return InitTemplate.computed(params); + } else { + return InitTemplate.default(params); + } + }, initExpr), ); } diff --git a/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.js b/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.js index 18fe439ce59e..c95e0b188cb2 100644 --- a/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.js +++ b/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.js @@ -1,5 +1,6 @@ import { basename, extname } from "path"; +import { isIdentifierName } from "@babel/helper-validator-identifier"; import splitExportDeclaration from "@babel/helper-split-export-declaration"; export type ModuleMetadata = { @@ -15,6 +16,12 @@ export type ModuleMetadata = { // Lookup of source file to source file metadata. source: Map, + + // List of names that should only be printed as string literals. + // i.e. `import { "any unicode" as foo } from "some-module"` + // `stringSpecifiers` is Set(1) ["any unicode"] + // In most cases `stringSpecifiers` is an empty Set + stringSpecifiers: Set, }; export type InteropType = "default" | "namespace" | "none"; @@ -87,13 +94,18 @@ export default function normalizeModuleAndLoadMetadata( if (!exportName) { exportName = programPath.scope.generateUidIdentifier("exports").name; } + const stringSpecifiers = new Set(); nameAnonymousExports(programPath); - const { local, source, hasExports } = getModuleMetadata(programPath, { - loose, - lazy, - }); + const { local, source, hasExports } = getModuleMetadata( + programPath, + { + loose, + lazy, + }, + stringSpecifiers, + ); removeModuleDeclarations(programPath); @@ -124,17 +136,48 @@ export default function normalizeModuleAndLoadMetadata( hasExports, local, source, + stringSpecifiers, }; } +function getExportSpecifierName( + path: NodePath, + stringSpecifiers: Set, +): string { + if (path.isIdentifier()) { + return path.node.name; + } else if (path.isStringLiteral()) { + const stringValue = path.node.value; + // add specifier value to `stringSpecifiers` only when it can not be converted to an identifier name + // i.e In `import { "foo" as bar }` + // we do not consider `"foo"` to be a `stringSpecifier` because we can treat it as + // `import { foo as bar }` + // This helps minimize the size of `stringSpecifiers` and reduce overhead of checking valid identifier names + // when building transpiled code from metadata + if (!isIdentifierName(stringValue)) { + stringSpecifiers.add(stringValue); + } + return stringValue; + } else { + throw new Error( + `Expected export specifier to be either Identifier or StringLiteral, got ${path.node.type}`, + ); + } +} + /** * Get metadata about the imports and exports present in this module. */ function getModuleMetadata( programPath: NodePath, { loose, lazy }: { loose: boolean, lazy: boolean }, + stringSpecifiers: Set, ) { - const localData = getLocalExportMetadata(programPath, loose); + const localData = getLocalExportMetadata( + programPath, + loose, + stringSpecifiers, + ); const sourceData = new Map(); const getData = sourceNode => { @@ -199,7 +242,10 @@ function getModuleMetadata( }); } } else if (spec.isImportSpecifier()) { - const importName = spec.get("imported").node.name; + const importName = getExportSpecifierName( + spec.get("imported"), + stringSpecifiers, + ); const localName = spec.get("local").node.name; data.imports.set(localName, importName); @@ -231,8 +277,14 @@ function getModuleMetadata( if (!spec.isExportSpecifier()) { throw spec.buildCodeFrameError("Unexpected export specifier type"); } - const importName = spec.get("local").node.name; - const exportName = spec.get("exported").node.name; + const importName = getExportSpecifierName( + spec.get("local"), + stringSpecifiers, + ); + const exportName = getExportSpecifierName( + spec.get("exported"), + stringSpecifiers, + ); data.reexports.set(exportName, importName); @@ -310,6 +362,7 @@ function getModuleMetadata( function getLocalExportMetadata( programPath: NodePath, loose: boolean, + stringSpecifiers: Set, ): Map { const bindingKindLookup = new Map(); @@ -392,11 +445,13 @@ function getLocalExportMetadata( child.get("specifiers").forEach(spec => { const local = spec.get("local"); const exported = spec.get("exported"); + const localMetadata = getLocalMetadata(local); + const exportName = getExportSpecifierName(exported, stringSpecifiers); - if (exported.node.name === "__esModule") { + if (exportName === "__esModule") { throw exported.buildCodeFrameError('Illegal export "__esModule".'); } - getLocalMetadata(local).names.push(exported.node.name); + localMetadata.names.push(exportName); }); } } else if (child.isExportDefaultDeclaration()) { diff --git a/packages/babel-helper-module-transforms/src/rewrite-live-references.js b/packages/babel-helper-module-transforms/src/rewrite-live-references.js index 6bf4aaad3cb5..4f31fd926c7b 100644 --- a/packages/babel-helper-module-transforms/src/rewrite-live-references.js +++ b/packages/babel-helper-module-transforms/src/rewrite-live-references.js @@ -3,7 +3,7 @@ import * as t from "@babel/types"; import template from "@babel/template"; import simplifyAccess from "@babel/helper-simple-access"; -import type { ModuleMetadata } from "./"; +import type { ModuleMetadata } from "./normalize-and-load-metadata"; export default function rewriteLiveReferences( programPath: NodePath, @@ -71,7 +71,13 @@ export default function rewriteLiveReferences( let namespace = t.identifier(meta.name); if (meta.lazy) namespace = t.callExpression(namespace, []); - return t.memberExpression(namespace, t.identifier(importName)); + const computed = metadata.stringSpecifiers.has(importName); + + return t.memberExpression( + namespace, + computed ? t.stringLiteral(importName) : t.identifier(importName), + computed, + ); }, }); } @@ -135,11 +141,14 @@ const buildBindingExportAssignmentExpression = ( // class Foo {} export { Foo, Foo as Bar }; // as // class Foo {} exports.Foo = exports.Bar = Foo; + const { stringSpecifiers } = metadata; + const computed = stringSpecifiers.has(exportName); return t.assignmentExpression( "=", t.memberExpression( t.identifier(metadata.exportName), - t.identifier(exportName), + computed ? t.stringLiteral(exportName) : t.identifier(exportName), + /* computed */ computed, ), expr, ); diff --git a/packages/babel-parser/ast/spec.md b/packages/babel-parser/ast/spec.md index 0484bc9f1faa..5d23fa7ded35 100644 --- a/packages/babel-parser/ast/spec.md +++ b/packages/babel-parser/ast/spec.md @@ -1291,7 +1291,7 @@ interface ImportDeclaration <: ModuleDeclaration { type: "ImportDeclaration"; importKind: null | "type" | "typeof" | "value"; specifiers: [ ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier ]; - source: Literal; + source: StringLiteral; attributes?: [ ImportAttribute ]; } ``` @@ -1305,7 +1305,7 @@ An import declaration, e.g., `import foo from "mod";`. ```js interface ImportSpecifier <: ModuleSpecifier { type: "ImportSpecifier"; - imported: Identifier; + imported: Identifier | StringLiteral; } ``` @@ -1352,21 +1352,24 @@ interface ExportNamedDeclaration <: ModuleDeclaration { type: "ExportNamedDeclaration"; declaration: Declaration | null; specifiers: [ ExportSpecifier ]; - source: Literal | null; + source: StringLiteral | null; } ``` An export named declaration, e.g., `export {foo, bar};`, `export {foo} from "mod";`, `export var foo = 1;` or `export * as foo from "bar";`. -_Note: Having `declaration` populated with non-empty `specifiers` or non-null `source` results in an invalid state._ +Note: + +- Having `declaration` populated with non-empty `specifiers` or non-null `source` results in an invalid state. +- If `source` is `null`, for each `specifier` of `specifiers`, `specifier.local` can not be a `StringLiteral`. ### ExportSpecifier ```js interface ExportSpecifier <: ModuleSpecifier { type: "ExportSpecifier"; - exported: Identifier; - local?: Identifier; + exported: Identifier | StringLiteral; + local?: Identifier | StringLiteral; } ``` @@ -1396,7 +1399,7 @@ An export default declaration, e.g., `export default function () {};` or `export ```js interface ExportAllDeclaration <: ModuleDeclaration { type: "ExportAllDeclaration"; - source: Literal; + source: StringLiteral; } ``` diff --git a/packages/babel-parser/src/parser/error-message.js b/packages/babel-parser/src/parser/error-message.js index 05518147755a..e74cfe766033 100644 --- a/packages/babel-parser/src/parser/error-message.js +++ b/packages/babel-parser/src/parser/error-message.js @@ -43,6 +43,8 @@ export const ErrorMessages = Object.freeze({ DuplicateRegExpFlags: "Duplicate regular expression flag", ElementAfterRest: "Rest element must be last element", EscapedCharNotAnIdentifier: "Invalid Unicode escape", + ExportBindingIsString: + "A string literal cannot be used as an exported binding without `from`.\n- Did you mean `export { %0 as '%1' } from 'some-module'`?", ExportDefaultFromAsIdentifier: "'from' is not allowed as an identifier after 'export default'", ForInOfLoopInitializer: @@ -53,6 +55,8 @@ export const ErrorMessages = Object.freeze({ IllegalLanguageModeDirective: "Illegal 'use strict' directive in function with non-simple parameter list", IllegalReturn: "'return' outside of function", + ImportBindingIsString: + 'A string literal cannot be used as an imported binding.\n- Did you mean `import { "%0" as foo }`?', ImportCallArgumentTrailingComma: "Trailing comma is disallowed inside import(...) arguments", ImportCallArity: "import() requires exactly %0", @@ -95,6 +99,8 @@ export const ErrorMessages = Object.freeze({ "Only string literals are allowed as module attribute values", ModuleAttributesWithDuplicateKeys: 'Duplicate key "%0" is not allowed in module attributes', + ModuleExportNameHasLoneSurrogate: + "An export name cannot include a lone surrogate, found '\\u%0'", ModuleExportUndefined: "Export '%0' is not defined", MultipleDefaultsInSwitch: "Multiple default clauses", NewlineAfterThrow: "Illegal newline after throw", diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index 4e2f7a513010..425bc7f0ec28 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.js @@ -39,6 +39,8 @@ const FUNC_NO_FLAGS = 0b000, FUNC_HANGING_STATEMENT = 0b010, FUNC_NULLABLE_ID = 0b100; +const loneSurrogate = /[\uD800-\uDFFF]/u; + export default class StatementParser extends ExpressionParser { // ### Statement parsing @@ -1745,7 +1747,7 @@ export default class StatementParser extends ExpressionParser { this.next(); - specifier.exported = this.parseIdentifier(true); + specifier.exported = this.parseModuleExportName(); node.specifiers.push( this.finishNode(specifier, "ExportNamespaceSpecifier"), ); @@ -1938,19 +1940,27 @@ export default class StatementParser extends ExpressionParser { } else if (node.specifiers && node.specifiers.length) { // Named exports for (const specifier of node.specifiers) { - this.checkDuplicateExports(specifier, specifier.exported.name); + const { exported } = specifier; + const exportedName = + exported.type === "Identifier" ? exported.name : exported.value; + this.checkDuplicateExports(specifier, exportedName); // $FlowIgnore if (!isFrom && specifier.local) { - // check for keywords used as local names - this.checkReservedWord( - specifier.local.name, - specifier.local.start, - true, - false, - ); - // check if export is defined - // $FlowIgnore - this.scope.checkLocalExport(specifier.local); + const { local } = specifier; + if (local.type === "StringLiteral") { + this.raise( + specifier.start, + Errors.ExportBindingIsString, + local.extra.raw, + exportedName, + ); + } else { + // check for keywords used as local names + this.checkReservedWord(local.name, local.start, true, false); + // check if export is defined + // $FlowIgnore + this.scope.checkLocalExport(local); + } } } } else if (node.declaration) { @@ -2006,6 +2016,7 @@ export default class StatementParser extends ExpressionParser { checkDuplicateExports( node: | N.Identifier + | N.StringLiteral | N.ExportNamedDeclaration | N.ExportSpecifier | N.ExportDefaultSpecifier, @@ -2041,9 +2052,9 @@ export default class StatementParser extends ExpressionParser { } const node = this.startNode(); - node.local = this.parseIdentifier(true); + node.local = this.parseModuleExportName(); node.exported = this.eatContextual("as") - ? this.parseIdentifier(true) + ? this.parseModuleExportName() : node.local.__clone(); nodes.push(this.finishNode(node, "ExportSpecifier")); } @@ -2051,6 +2062,27 @@ export default class StatementParser extends ExpressionParser { return nodes; } + // https://tc39.es/ecma262/#prod-ModuleExportName + parseModuleExportName(): N.StringLiteral | N.Identifier { + if (this.match(tt.string)) { + this.expectPlugin("moduleStringNames"); + const result = this.parseLiteral( + this.state.value, + "StringLiteral", + ); + const surrogate = result.value.match(loneSurrogate); + if (surrogate) { + this.raise( + result.start, + Errors.ModuleExportNameHasLoneSurrogate, + surrogate[0].charCodeAt(0).toString(16), + ); + } + return result; + } + return this.parseIdentifier(true); + } + // Parses import declaration. // https://tc39.es/ecma262/#prod-ImportDeclaration @@ -2220,17 +2252,20 @@ export default class StatementParser extends ExpressionParser { // https://tc39.es/ecma262/#prod-ImportSpecifier parseImportSpecifier(node: N.ImportDeclaration): void { const specifier = this.startNode(); - specifier.imported = this.parseIdentifier(true); + specifier.imported = this.parseModuleExportName(); if (this.eatContextual("as")) { specifier.local = this.parseIdentifier(); } else { - this.checkReservedWord( - specifier.imported.name, - specifier.start, - true, - true, - ); - specifier.local = specifier.imported.__clone(); + const { imported } = specifier; + if (imported.type === "StringLiteral") { + throw this.raise( + specifier.start, + Errors.ImportBindingIsString, + imported.value, + ); + } + this.checkReservedWord(imported.name, specifier.start, true, true); + specifier.local = imported.__clone(); } this.checkLVal( specifier.local, diff --git a/packages/babel-parser/src/types.js b/packages/babel-parser/src/types.js index 6d77c5c0d00d..f3dc15ed2167 100644 --- a/packages/babel-parser/src/types.js +++ b/packages/babel-parser/src/types.js @@ -842,7 +842,7 @@ export type ImportDeclaration = NodeBase & { export type ImportSpecifier = ModuleSpecifier & { type: "ImportSpecifier", - imported: Identifier, + imported: Identifier | StringLiteral, }; export type ImportDefaultSpecifier = ModuleSpecifier & { @@ -866,7 +866,7 @@ export type ExportNamedDeclaration = NodeBase & { export type ExportSpecifier = NodeBase & { type: "ExportSpecifier", - exported: Identifier, + exported: Identifier | StringLiteral, local: Identifier, }; diff --git a/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-export/input.js b/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-export/input.js new file mode 100644 index 000000000000..0eed97348183 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-export/input.js @@ -0,0 +1,2 @@ +export { foo as "some exports" }; +var foo; diff --git a/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-export/options.json b/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-export/options.json new file mode 100644 index 000000000000..577ec6148c27 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-export/options.json @@ -0,0 +1,5 @@ +{ + "throws": "This experimental syntax requires enabling the parser plugin: 'moduleStringNames' (1:16)", + "sourceType": "module", + "plugins": [] +} diff --git a/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-import/input.js b/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-import/input.js new file mode 100644 index 000000000000..79106029227c --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-import/input.js @@ -0,0 +1 @@ +import { "foo" as bar, "default" as qux } from "module-a"; diff --git a/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-import/options.json b/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-import/options.json new file mode 100644 index 000000000000..e6b9c1ad0636 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/_no-plugin/module-string-names-import/options.json @@ -0,0 +1,5 @@ +{ + "throws": "This experimental syntax requires enabling the parser plugin: 'moduleStringNames' (1:9)", + "sourceType": "module", + "plugins": [] +} diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/default-import/input.js b/packages/babel-parser/test/fixtures/experimental/module-string-names/default-import/input.js new file mode 100644 index 000000000000..1317bee62b01 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/default-import/input.js @@ -0,0 +1 @@ +import {"default" as quotation} from "Confucius"; diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/default-import/output.json b/packages/babel-parser/test/fixtures/experimental/module-string-names/default-import/output.json new file mode 100644 index 000000000000..5bc63b5f245d --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/default-import/output.json @@ -0,0 +1,46 @@ +{ + "type": "File", + "start":0,"end":49,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":49}}, + "program": { + "type": "Program", + "start":0,"end":49,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":49}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ImportDeclaration", + "start":0,"end":49,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":49}}, + "specifiers": [ + { + "type": "ImportSpecifier", + "start":8,"end":30,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":30}}, + "imported": { + "type": "StringLiteral", + "start":8,"end":17,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":17}}, + "extra": { + "rawValue": "default", + "raw": "\"default\"" + }, + "value": "default" + }, + "local": { + "type": "Identifier", + "start":21,"end":30,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":30},"identifierName":"quotation"}, + "name": "quotation" + } + } + ], + "source": { + "type": "StringLiteral", + "start":37,"end":48,"loc":{"start":{"line":1,"column":37},"end":{"line":1,"column":48}}, + "extra": { + "rawValue": "Confucius", + "raw": "\"Confucius\"" + }, + "value": "Confucius" + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/duplicate-exported-binding-check/input.js b/packages/babel-parser/test/fixtures/experimental/module-string-names/duplicate-exported-binding-check/input.js new file mode 100644 index 000000000000..27ae13c28a13 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/duplicate-exported-binding-check/input.js @@ -0,0 +1,2 @@ +const foo = 42, bar = 42; +export { foo, bar as "foo" } diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/duplicate-exported-binding-check/output.json b/packages/babel-parser/test/fixtures/experimental/module-string-names/duplicate-exported-binding-check/output.json new file mode 100644 index 000000000000..3888df67614c --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/duplicate-exported-binding-check/output.json @@ -0,0 +1,99 @@ +{ + "type": "File", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":28}}, + "errors": [ + "SyntaxError: `foo` has already been exported. Exported identifiers must be unique. (2:14)" + ], + "program": { + "type": "Program", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":28}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "VariableDeclaration", + "start":0,"end":25,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":25}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":6,"end":14,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":14}}, + "id": { + "type": "Identifier", + "start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"foo"}, + "name": "foo" + }, + "init": { + "type": "NumericLiteral", + "start":12,"end":14,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":14}}, + "extra": { + "rawValue": 42, + "raw": "42" + }, + "value": 42 + } + }, + { + "type": "VariableDeclarator", + "start":16,"end":24,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":24}}, + "id": { + "type": "Identifier", + "start":16,"end":19,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":19},"identifierName":"bar"}, + "name": "bar" + }, + "init": { + "type": "NumericLiteral", + "start":22,"end":24,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":24}}, + "extra": { + "rawValue": 42, + "raw": "42" + }, + "value": 42 + } + } + ], + "kind": "const" + }, + { + "type": "ExportNamedDeclaration", + "start":26,"end":54,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":28}}, + "specifiers": [ + { + "type": "ExportSpecifier", + "start":35,"end":38,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12}}, + "local": { + "type": "Identifier", + "start":35,"end":38,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12},"identifierName":"foo"}, + "name": "foo" + }, + "exported": { + "type": "Identifier", + "start":35,"end":38,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12},"identifierName":"foo"}, + "name": "foo" + } + }, + { + "type": "ExportSpecifier", + "start":40,"end":52,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":26}}, + "local": { + "type": "Identifier", + "start":40,"end":43,"loc":{"start":{"line":2,"column":14},"end":{"line":2,"column":17},"identifierName":"bar"}, + "name": "bar" + }, + "exported": { + "type": "StringLiteral", + "start":47,"end":52,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":26}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + } + } + ], + "source": null, + "declaration": null + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/export-from/input.js b/packages/babel-parser/test/fixtures/experimental/module-string-names/export-from/input.js new file mode 100644 index 000000000000..2a2dde7fc955 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/export-from/input.js @@ -0,0 +1 @@ +export { "學而時習之,不亦說乎?", "吾道一以貫之。" as "忠恕。" } from "Confucius"; diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/export-from/output.json b/packages/babel-parser/test/fixtures/experimental/module-string-names/export-from/output.json new file mode 100644 index 000000000000..32fecf6af32d --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/export-from/output.json @@ -0,0 +1,73 @@ +{ + "type": "File", + "start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":62}}, + "program": { + "type": "Program", + "start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":62}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":62}}, + "specifiers": [ + { + "type": "ExportSpecifier", + "start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}}, + "local": { + "type": "StringLiteral", + "start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}}, + "extra": { + "rawValue": "學而時習之,不亦說乎?", + "raw": "\"學而時習之,不亦說乎?\"" + }, + "value": "學而時習之,不亦說乎?" + }, + "exported": { + "type": "StringLiteral", + "start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}}, + "extra": { + "rawValue": "學而時習之,不亦說乎?", + "raw": "\"學而時習之,不亦說乎?\"" + }, + "value": "學而時習之,不亦說乎?" + } + }, + { + "type": "ExportSpecifier", + "start":24,"end":42,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":42}}, + "local": { + "type": "StringLiteral", + "start":24,"end":33,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":33}}, + "extra": { + "rawValue": "吾道一以貫之。", + "raw": "\"吾道一以貫之。\"" + }, + "value": "吾道一以貫之。" + }, + "exported": { + "type": "StringLiteral", + "start":37,"end":42,"loc":{"start":{"line":1,"column":37},"end":{"line":1,"column":42}}, + "extra": { + "rawValue": "忠恕。", + "raw": "\"忠恕。\"" + }, + "value": "忠恕。" + } + } + ], + "source": { + "type": "StringLiteral", + "start":50,"end":61,"loc":{"start":{"line":1,"column":50},"end":{"line":1,"column":61}}, + "extra": { + "rawValue": "Confucius", + "raw": "\"Confucius\"" + }, + "value": "Confucius" + }, + "declaration": null + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/export-name-has-lone-surrogate/input.js b/packages/babel-parser/test/fixtures/experimental/module-string-names/export-name-has-lone-surrogate/input.js new file mode 100644 index 000000000000..075f0b440e61 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/export-name-has-lone-surrogate/input.js @@ -0,0 +1,3 @@ +const foo = 42, bar = 42; +export { foo as "\ud800\udbff" } // should throw +export { bar as "\udbff\udfff" } // should not throw diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/export-name-has-lone-surrogate/output.json b/packages/babel-parser/test/fixtures/experimental/module-string-names/export-name-has-lone-surrogate/output.json new file mode 100644 index 000000000000..8beba46012b2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/export-name-has-lone-surrogate/output.json @@ -0,0 +1,144 @@ +{ + "type": "File", + "start":0,"end":127,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":52}}, + "errors": [ + "SyntaxError: An export name cannot include a lone surrogate, found '\\ud800' (2:16)" + ], + "program": { + "type": "Program", + "start":0,"end":127,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":52}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "VariableDeclaration", + "start":0,"end":25,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":25}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":6,"end":14,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":14}}, + "id": { + "type": "Identifier", + "start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"foo"}, + "name": "foo" + }, + "init": { + "type": "NumericLiteral", + "start":12,"end":14,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":14}}, + "extra": { + "rawValue": 42, + "raw": "42" + }, + "value": 42 + } + }, + { + "type": "VariableDeclarator", + "start":16,"end":24,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":24}}, + "id": { + "type": "Identifier", + "start":16,"end":19,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":19},"identifierName":"bar"}, + "name": "bar" + }, + "init": { + "type": "NumericLiteral", + "start":22,"end":24,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":24}}, + "extra": { + "rawValue": 42, + "raw": "42" + }, + "value": 42 + } + } + ], + "kind": "const" + }, + { + "type": "ExportNamedDeclaration", + "start":26,"end":58,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":32}}, + "trailingComments": [ + { + "type": "CommentLine", + "value": " should throw", + "start":59,"end":74,"loc":{"start":{"line":2,"column":33},"end":{"line":2,"column":48}} + } + ], + "specifiers": [ + { + "type": "ExportSpecifier", + "start":35,"end":56,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":30}}, + "local": { + "type": "Identifier", + "start":35,"end":38,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":12},"identifierName":"foo"}, + "name": "foo" + }, + "exported": { + "type": "StringLiteral", + "start":42,"end":56,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":30}}, + "extra": { + "rawValue": "\ud800\udbff", + "raw": "\"\\ud800\\udbff\"" + }, + "value": "\ud800\udbff" + } + } + ], + "source": null, + "declaration": null + }, + { + "type": "ExportNamedDeclaration", + "start":75,"end":107,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":32}}, + "leadingComments": [ + { + "type": "CommentLine", + "value": " should throw", + "start":59,"end":74,"loc":{"start":{"line":2,"column":33},"end":{"line":2,"column":48}} + } + ], + "trailingComments": [ + { + "type": "CommentLine", + "value": " should not throw", + "start":108,"end":127,"loc":{"start":{"line":3,"column":33},"end":{"line":3,"column":52}} + } + ], + "specifiers": [ + { + "type": "ExportSpecifier", + "start":84,"end":105,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":30}}, + "local": { + "type": "Identifier", + "start":84,"end":87,"loc":{"start":{"line":3,"column":9},"end":{"line":3,"column":12},"identifierName":"bar"}, + "name": "bar" + }, + "exported": { + "type": "StringLiteral", + "start":91,"end":105,"loc":{"start":{"line":3,"column":16},"end":{"line":3,"column":30}}, + "extra": { + "rawValue": "􏿿", + "raw": "\"\\udbff\\udfff\"" + }, + "value": "􏿿" + } + } + ], + "source": null, + "declaration": null + } + ], + "directives": [] + }, + "comments": [ + { + "type": "CommentLine", + "value": " should throw", + "start":59,"end":74,"loc":{"start":{"line":2,"column":33},"end":{"line":2,"column":48}} + }, + { + "type": "CommentLine", + "value": " should not throw", + "start":108,"end":127,"loc":{"start":{"line":3,"column":33},"end":{"line":3,"column":52}} + } + ] +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/import-local-is-string/input.js b/packages/babel-parser/test/fixtures/experimental/module-string-names/import-local-is-string/input.js new file mode 100644 index 000000000000..e00933b0a910 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/import-local-is-string/input.js @@ -0,0 +1 @@ +import { "foo" } from "foo"; diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/import-local-is-string/options.json b/packages/babel-parser/test/fixtures/experimental/module-string-names/import-local-is-string/options.json new file mode 100644 index 000000000000..95aa9af461dc --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/import-local-is-string/options.json @@ -0,0 +1,7 @@ +{ + "sourceType": "module", + "plugins": [ + "moduleStringNames" + ], + "throws": "A string literal cannot be used as an imported binding.\n- Did you mean `import { \"foo\" as foo }`? (1:9)" +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/mixed/input.js b/packages/babel-parser/test/fixtures/experimental/module-string-names/mixed/input.js new file mode 100644 index 000000000000..a6cfd5e177b6 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/mixed/input.js @@ -0,0 +1,2 @@ +import { "foo" as bar, "default" as qux } from "module-a"; +export * as "foo", { default as "quux" } from "module-b"; diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/mixed/output.json b/packages/babel-parser/test/fixtures/experimental/module-string-names/mixed/output.json new file mode 100644 index 000000000000..c2532f0c19ac --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/mixed/output.json @@ -0,0 +1,111 @@ +{ + "type": "File", + "start":0,"end":116,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":57}}, + "program": { + "type": "Program", + "start":0,"end":116,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":57}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ImportDeclaration", + "start":0,"end":58,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":58}}, + "specifiers": [ + { + "type": "ImportSpecifier", + "start":9,"end":21,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":21}}, + "imported": { + "type": "StringLiteral", + "start":9,"end":14,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":14}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "local": { + "type": "Identifier", + "start":18,"end":21,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":21},"identifierName":"bar"}, + "name": "bar" + } + }, + { + "type": "ImportSpecifier", + "start":23,"end":39,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":39}}, + "imported": { + "type": "StringLiteral", + "start":23,"end":32,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":32}}, + "extra": { + "rawValue": "default", + "raw": "\"default\"" + }, + "value": "default" + }, + "local": { + "type": "Identifier", + "start":36,"end":39,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":39},"identifierName":"qux"}, + "name": "qux" + } + } + ], + "source": { + "type": "StringLiteral", + "start":47,"end":57,"loc":{"start":{"line":1,"column":47},"end":{"line":1,"column":57}}, + "extra": { + "rawValue": "module-a", + "raw": "\"module-a\"" + }, + "value": "module-a" + } + }, + { + "type": "ExportNamedDeclaration", + "start":59,"end":116,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":57}}, + "specifiers": [ + { + "type": "ExportNamespaceSpecifier", + "start":66,"end":76,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":17}}, + "exported": { + "type": "StringLiteral", + "start":71,"end":76,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":17}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + } + }, + { + "type": "ExportSpecifier", + "start":80,"end":97,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":38}}, + "local": { + "type": "Identifier", + "start":80,"end":87,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":28},"identifierName":"default"}, + "name": "default" + }, + "exported": { + "type": "StringLiteral", + "start":91,"end":97,"loc":{"start":{"line":2,"column":32},"end":{"line":2,"column":38}}, + "extra": { + "rawValue": "quux", + "raw": "\"quux\"" + }, + "value": "quux" + } + } + ], + "source": { + "type": "StringLiteral", + "start":105,"end":115,"loc":{"start":{"line":2,"column":46},"end":{"line":2,"column":56}}, + "extra": { + "rawValue": "module-b", + "raw": "\"module-b\"" + }, + "value": "module-b" + }, + "declaration": null + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/named-export/input.js b/packages/babel-parser/test/fixtures/experimental/module-string-names/named-export/input.js new file mode 100644 index 000000000000..542fac9959b2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/named-export/input.js @@ -0,0 +1,2 @@ +const quotation = ""; +export { quotation as "學而時習之,不亦說乎?" }; diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/named-export/output.json b/packages/babel-parser/test/fixtures/experimental/module-string-names/named-export/output.json new file mode 100644 index 000000000000..16da7361fef6 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/named-export/output.json @@ -0,0 +1,64 @@ +{ + "type": "File", + "start":0,"end":60,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":38}}, + "program": { + "type": "Program", + "start":0,"end":60,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":38}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "VariableDeclaration", + "start":0,"end":21,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":21}}, + "declarations": [ + { + "type": "VariableDeclarator", + "start":6,"end":20,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":20}}, + "id": { + "type": "Identifier", + "start":6,"end":15,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":15},"identifierName":"quotation"}, + "name": "quotation" + }, + "init": { + "type": "StringLiteral", + "start":18,"end":20,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":20}}, + "extra": { + "rawValue": "", + "raw": "\"\"" + }, + "value": "" + } + } + ], + "kind": "const" + }, + { + "type": "ExportNamedDeclaration", + "start":22,"end":60,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":38}}, + "specifiers": [ + { + "type": "ExportSpecifier", + "start":31,"end":57,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":35}}, + "local": { + "type": "Identifier", + "start":31,"end":40,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":18},"identifierName":"quotation"}, + "name": "quotation" + }, + "exported": { + "type": "StringLiteral", + "start":44,"end":57,"loc":{"start":{"line":2,"column":22},"end":{"line":2,"column":35}}, + "extra": { + "rawValue": "學而時習之,不亦說乎?", + "raw": "\"學而時習之,不亦說乎?\"" + }, + "value": "學而時習之,不亦說乎?" + } + } + ], + "source": null, + "declaration": null + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/named-import/input.js b/packages/babel-parser/test/fixtures/experimental/module-string-names/named-import/input.js new file mode 100644 index 000000000000..74d6bc295369 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/named-import/input.js @@ -0,0 +1 @@ +import {"學而時習之,不亦說乎?" as quotation} from "Confucius"; diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/named-import/output.json b/packages/babel-parser/test/fixtures/experimental/module-string-names/named-import/output.json new file mode 100644 index 000000000000..8d1a61c81e8e --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/named-import/output.json @@ -0,0 +1,46 @@ +{ + "type": "File", + "start":0,"end":53,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":53}}, + "program": { + "type": "Program", + "start":0,"end":53,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":53}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ImportDeclaration", + "start":0,"end":53,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":53}}, + "specifiers": [ + { + "type": "ImportSpecifier", + "start":8,"end":34,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":34}}, + "imported": { + "type": "StringLiteral", + "start":8,"end":21,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":21}}, + "extra": { + "rawValue": "學而時習之,不亦說乎?", + "raw": "\"學而時習之,不亦說乎?\"" + }, + "value": "學而時習之,不亦說乎?" + }, + "local": { + "type": "Identifier", + "start":25,"end":34,"loc":{"start":{"line":1,"column":25},"end":{"line":1,"column":34},"identifierName":"quotation"}, + "name": "quotation" + } + } + ], + "source": { + "type": "StringLiteral", + "start":41,"end":52,"loc":{"start":{"line":1,"column":41},"end":{"line":1,"column":52}}, + "extra": { + "rawValue": "Confucius", + "raw": "\"Confucius\"" + }, + "value": "Confucius" + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/namespace-export/input.js b/packages/babel-parser/test/fixtures/experimental/module-string-names/namespace-export/input.js new file mode 100644 index 000000000000..556309390758 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/namespace-export/input.js @@ -0,0 +1 @@ +export * as "忠恕。" from "Confucius"; diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/namespace-export/output.json b/packages/babel-parser/test/fixtures/experimental/module-string-names/namespace-export/output.json new file mode 100644 index 000000000000..078b9d4716e1 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/namespace-export/output.json @@ -0,0 +1,41 @@ +{ + "type": "File", + "start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}}, + "program": { + "type": "Program", + "start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start":0,"end":35,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}}, + "specifiers": [ + { + "type": "ExportNamespaceSpecifier", + "start":7,"end":17,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":17}}, + "exported": { + "type": "StringLiteral", + "start":12,"end":17,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":17}}, + "extra": { + "rawValue": "忠恕。", + "raw": "\"忠恕。\"" + }, + "value": "忠恕。" + } + } + ], + "source": { + "type": "StringLiteral", + "start":23,"end":34,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":34}}, + "extra": { + "rawValue": "Confucius", + "raw": "\"Confucius\"" + }, + "value": "Confucius" + } + } + ], + "directives": [] + } +} diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/options.json b/packages/babel-parser/test/fixtures/experimental/module-string-names/options.json new file mode 100644 index 000000000000..db7db2aa9480 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/options.json @@ -0,0 +1,4 @@ +{ + "sourceType": "module", + "plugins": ["moduleStringNames"] +} diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/string-exported-binding-without-from/input.js b/packages/babel-parser/test/fixtures/experimental/module-string-names/string-exported-binding-without-from/input.js new file mode 100644 index 000000000000..a3d180e5caee --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/string-exported-binding-without-from/input.js @@ -0,0 +1 @@ +export { "學而時習之,不亦說乎?", "吾道一以貫之。" as "忠恕。" }; diff --git a/packages/babel-parser/test/fixtures/experimental/module-string-names/string-exported-binding-without-from/output.json b/packages/babel-parser/test/fixtures/experimental/module-string-names/string-exported-binding-without-from/output.json new file mode 100644 index 000000000000..ddab0a530b70 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/module-string-names/string-exported-binding-without-from/output.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start":0,"end":45,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":45}}, + "errors": [ + "SyntaxError: A string literal cannot be used as an exported binding without `from`.\n- Did you mean `export { \"學而時習之,不亦說乎?\" as '學而時習之,不亦說乎?' } from 'some-module'`? (1:9)", + "SyntaxError: A string literal cannot be used as an exported binding without `from`.\n- Did you mean `export { \"吾道一以貫之。\" as '忠恕。' } from 'some-module'`? (1:24)" + ], + "program": { + "type": "Program", + "start":0,"end":45,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":45}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ExportNamedDeclaration", + "start":0,"end":45,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":45}}, + "specifiers": [ + { + "type": "ExportSpecifier", + "start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}}, + "local": { + "type": "StringLiteral", + "start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}}, + "extra": { + "rawValue": "學而時習之,不亦說乎?", + "raw": "\"學而時習之,不亦說乎?\"" + }, + "value": "學而時習之,不亦說乎?" + }, + "exported": { + "type": "StringLiteral", + "start":9,"end":22,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":22}}, + "extra": { + "rawValue": "學而時習之,不亦說乎?", + "raw": "\"學而時習之,不亦說乎?\"" + }, + "value": "學而時習之,不亦說乎?" + } + }, + { + "type": "ExportSpecifier", + "start":24,"end":42,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":42}}, + "local": { + "type": "StringLiteral", + "start":24,"end":33,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":33}}, + "extra": { + "rawValue": "吾道一以貫之。", + "raw": "\"吾道一以貫之。\"" + }, + "value": "吾道一以貫之。" + }, + "exported": { + "type": "StringLiteral", + "start":37,"end":42,"loc":{"start":{"line":1,"column":37},"end":{"line":1,"column":42}}, + "extra": { + "rawValue": "忠恕。", + "raw": "\"忠恕。\"" + }, + "value": "忠恕。" + } + } + ], + "source": null, + "declaration": null + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/typings/babel-parser.d.ts b/packages/babel-parser/typings/babel-parser.d.ts index 60fabcc52510..ed63d17fc9f3 100644 --- a/packages/babel-parser/typings/babel-parser.d.ts +++ b/packages/babel-parser/typings/babel-parser.d.ts @@ -116,6 +116,7 @@ export type ParserPlugin = 'jsx' | 'logicalAssignment' | 'moduleAttributes' | + 'moduleStringNames' | 'nullishCoalescingOperator' | 'numericSeparator' | 'objectRestSpread' | diff --git a/packages/babel-plugin-proposal-export-namespace-from/src/index.js b/packages/babel-plugin-proposal-export-namespace-from/src/index.js index b028abcb721f..75da6425d550 100644 --- a/packages/babel-plugin-proposal-export-namespace-from/src/index.js +++ b/packages/babel-plugin-proposal-export-namespace-from/src/index.js @@ -27,7 +27,9 @@ export default declare(api => { const specifier = specifiers.shift(); const { exported } = specifier; - const uid = scope.generateUidIdentifier(exported.name); + const uid = scope.generateUidIdentifier( + exported.name ?? exported.value, + ); nodes.push( t.importDeclaration( diff --git a/packages/babel-plugin-proposal-export-namespace-from/test/fixtures/export-namespace/namespace-string/input.mjs b/packages/babel-plugin-proposal-export-namespace-from/test/fixtures/export-namespace/namespace-string/input.mjs new file mode 100644 index 000000000000..b7e78146b529 --- /dev/null +++ b/packages/babel-plugin-proposal-export-namespace-from/test/fixtures/export-namespace/namespace-string/input.mjs @@ -0,0 +1 @@ +export * as "some exports" from "foo"; diff --git a/packages/babel-plugin-proposal-export-namespace-from/test/fixtures/export-namespace/namespace-string/options.json b/packages/babel-plugin-proposal-export-namespace-from/test/fixtures/export-namespace/namespace-string/options.json new file mode 100644 index 000000000000..fe3d1d2159ff --- /dev/null +++ b/packages/babel-plugin-proposal-export-namespace-from/test/fixtures/export-namespace/namespace-string/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "external-helpers", + "proposal-export-namespace-from", + "syntax-module-string-names" + ] +} diff --git a/packages/babel-plugin-proposal-export-namespace-from/test/fixtures/export-namespace/namespace-string/output.mjs b/packages/babel-plugin-proposal-export-namespace-from/test/fixtures/export-namespace/namespace-string/output.mjs new file mode 100644 index 000000000000..d0683e3568d5 --- /dev/null +++ b/packages/babel-plugin-proposal-export-namespace-from/test/fixtures/export-namespace/namespace-string/output.mjs @@ -0,0 +1,2 @@ +import * as _someExports from "foo"; +export { _someExports as "some exports" }; diff --git a/packages/babel-plugin-syntax-module-string-names/.npmignore b/packages/babel-plugin-syntax-module-string-names/.npmignore new file mode 100644 index 000000000000..2b1fceba679b --- /dev/null +++ b/packages/babel-plugin-syntax-module-string-names/.npmignore @@ -0,0 +1,3 @@ +*.log +src +test diff --git a/packages/babel-plugin-syntax-module-string-names/README.md b/packages/babel-plugin-syntax-module-string-names/README.md new file mode 100644 index 000000000000..ab61740923b3 --- /dev/null +++ b/packages/babel-plugin-syntax-module-string-names/README.md @@ -0,0 +1,19 @@ +# @babel/plugin-syntax-module-string-names + +> Allow parsing `import { 'any unicode' as bar }` and `export { foo as 'any unicode' }`" + +See our website [@babel/plugin-syntax-module-string-names](https://babeljs.io/docs/en/next/babel-plugin-syntax-module-string-names.html) for more information. + +## Install + +Using npm: + +```sh +npm install --save-dev @babel/plugin-syntax-module-string-names +``` + +or using yarn: + +```sh +yarn add @babel/plugin-syntax-module-string-names --dev +``` diff --git a/packages/babel-plugin-syntax-module-string-names/package.json b/packages/babel-plugin-syntax-module-string-names/package.json new file mode 100644 index 000000000000..12d9b070192c --- /dev/null +++ b/packages/babel-plugin-syntax-module-string-names/package.json @@ -0,0 +1,28 @@ +{ + "name": "@babel/plugin-syntax-module-string-names", + "version": "0.0.0", + "description": "Allow parsing `import { 'any unicode' as bar }` and `export { foo as 'any unicode' }`", + "repository": { + "type": "git", + "url": "https://github.com/babel/babel.git", + "directory": "packages/babel-plugin-syntax-module-string-names" + }, + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "main": "./lib/index.js", + "exports": "./lib/index.js", + "keywords": [ + "babel-plugin" + ], + "dependencies": { + "@babel/helper-plugin-utils": "workspace:^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + }, + "devDependencies": { + "@babel/core": "workspace:^7.10.4" + } +} diff --git a/packages/babel-plugin-syntax-module-string-names/src/index.js b/packages/babel-plugin-syntax-module-string-names/src/index.js new file mode 100644 index 000000000000..25cf00d45fee --- /dev/null +++ b/packages/babel-plugin-syntax-module-string-names/src/index.js @@ -0,0 +1,13 @@ +import { declare } from "@babel/helper-plugin-utils"; + +export default declare(api => { + api.assertVersion(7); + + return { + name: "syntax-module-string-names", + + manipulateOptions(opts, parserOpts) { + parserOpts.plugins.push("moduleStringNames"); + }, + }; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/input.mjs new file mode 100644 index 000000000000..9af06dedb8e3 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/input.mjs @@ -0,0 +1 @@ +export { "some imports" as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/output.js new file mode 100644 index 000000000000..cb0bd45edbfd --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/output.js @@ -0,0 +1,7 @@ +define(["exports", "foo"], function (_exports, _foo) { + "use strict"; + + _exports.__esModule = true; + _exports["some exports"] = void 0; + _exports["some exports"] = _foo["some imports"]; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string/input.mjs new file mode 100644 index 000000000000..cf064000fd95 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string/input.mjs @@ -0,0 +1 @@ +export { "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string/output.js new file mode 100644 index 000000000000..a4e225a9d4c7 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from-string/output.js @@ -0,0 +1,7 @@ +define(["exports", "foo"], function (_exports, _foo) { + "use strict"; + + _exports.__esModule = true; + _exports["some exports"] = void 0; + _exports["some exports"] = _foo["some exports"]; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from/input.mjs new file mode 100644 index 000000000000..2dc9ce983e0f --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from/input.mjs @@ -0,0 +1 @@ +export { foo as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from/output.js new file mode 100644 index 000000000000..9ec7e9a84f5e --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-from/output.js @@ -0,0 +1,7 @@ +define(["exports", "foo"], function (_exports, _foo) { + "use strict"; + + _exports.__esModule = true; + _exports["some exports"] = void 0; + _exports["some exports"] = _foo.foo; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..ee4aa01e3988 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "defaultExports", bar}; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..6b287f0edc4c --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/output.js @@ -0,0 +1,9 @@ +define(["exports"], function (_exports) { + "use strict"; + + _exports.__esModule = true; + _exports.bar = _exports.defaultExports = void 0; + var foo, bar; + _exports.bar = bar; + _exports.defaultExports = foo; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named/input.mjs new file mode 100644 index 000000000000..f36164d076f9 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "default exports", bar}; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named/output.js new file mode 100644 index 000000000000..4dc3a095a381 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/export-named/output.js @@ -0,0 +1,9 @@ +define(["exports"], function (_exports) { + "use strict"; + + _exports.__esModule = true; + _exports.bar = _exports["default exports"] = void 0; + var foo, bar; + _exports.bar = bar; + _exports["default exports"] = foo; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..c6975c24a9a7 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/input.mjs @@ -0,0 +1,3 @@ +import { "defaultImports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..5953ebd14777 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/output.js @@ -0,0 +1,5 @@ +define(["foo"], function (_foo) { + "use strict"; + + _foo.defaultImports; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named/input.mjs new file mode 100644 index 000000000000..97932c921132 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named/input.mjs @@ -0,0 +1,3 @@ +import {"default imports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named/output.js new file mode 100644 index 000000000000..58eb3ad75aea --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/import-named/output.js @@ -0,0 +1,5 @@ +define(["foo"], function (_foo) { + "use strict"; + + _foo["default imports"]; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/options.json b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/options.json new file mode 100644 index 000000000000..3571c3be3117 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names-loose/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "external-helpers", + ["transform-modules-amd", { "loose": true }], + "syntax-module-string-names" + ] +} diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs new file mode 100644 index 000000000000..9af06dedb8e3 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs @@ -0,0 +1 @@ +export { "some imports" as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string-as-string/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string-as-string/output.js new file mode 100644 index 000000000000..b622e0b88a36 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string-as-string/output.js @@ -0,0 +1,13 @@ +define(["exports", "foo"], function (_exports, _foo) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.defineProperty(_exports, "some exports", { + enumerable: true, + get: function () { + return _foo["some imports"]; + } + }); +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string/input.mjs new file mode 100644 index 000000000000..cf064000fd95 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string/input.mjs @@ -0,0 +1 @@ +export { "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string/output.js new file mode 100644 index 000000000000..3f97fa49e3f0 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from-string/output.js @@ -0,0 +1,13 @@ +define(["exports", "foo"], function (_exports, _foo) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.defineProperty(_exports, "some exports", { + enumerable: true, + get: function () { + return _foo["some exports"]; + } + }); +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from/input.mjs new file mode 100644 index 000000000000..2dc9ce983e0f --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from/input.mjs @@ -0,0 +1 @@ +export { foo as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from/output.js new file mode 100644 index 000000000000..b3d7826e5e58 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-from/output.js @@ -0,0 +1,13 @@ +define(["exports", "foo"], function (_exports, _foo) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.defineProperty(_exports, "some exports", { + enumerable: true, + get: function () { + return _foo.foo; + } + }); +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..ee4aa01e3988 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "defaultExports", bar}; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..4b9d00616b08 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.js @@ -0,0 +1,11 @@ +define(["exports"], function (_exports) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.bar = _exports.defaultExports = void 0; + var foo, bar; + _exports.bar = bar; + _exports.defaultExports = foo; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named/input.mjs new file mode 100644 index 000000000000..f36164d076f9 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "default exports", bar}; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named/output.js new file mode 100644 index 000000000000..de6f074c65b6 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/export-named/output.js @@ -0,0 +1,11 @@ +define(["exports"], function (_exports) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.bar = _exports["default exports"] = void 0; + var foo, bar; + _exports.bar = bar; + _exports["default exports"] = foo; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..c6975c24a9a7 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs @@ -0,0 +1,3 @@ +import { "defaultImports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..5953ebd14777 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.js @@ -0,0 +1,5 @@ +define(["foo"], function (_foo) { + "use strict"; + + _foo.defaultImports; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named/input.mjs b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named/input.mjs new file mode 100644 index 000000000000..97932c921132 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named/input.mjs @@ -0,0 +1,3 @@ +import {"default imports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named/output.js new file mode 100644 index 000000000000..58eb3ad75aea --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/import-named/output.js @@ -0,0 +1,5 @@ +define(["foo"], function (_foo) { + "use strict"; + + _foo["default imports"]; +}); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/options.json b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/options.json new file mode 100644 index 000000000000..f3ec3e4ef677 --- /dev/null +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/interop-module-string-names/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "external-helpers", + "transform-modules-amd", + "syntax-module-string-names" + ] +} diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/input.mjs new file mode 100644 index 000000000000..9af06dedb8e3 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/input.mjs @@ -0,0 +1 @@ +export { "some imports" as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/output.js new file mode 100644 index 000000000000..2f890df0c7f8 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/output.js @@ -0,0 +1,8 @@ +"use strict"; + +exports.__esModule = true; +exports["some exports"] = void 0; + +var _foo = require("foo"); + +exports["some exports"] = _foo["some imports"]; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string/input.mjs new file mode 100644 index 000000000000..cf064000fd95 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string/input.mjs @@ -0,0 +1 @@ +export { "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string/output.js new file mode 100644 index 000000000000..7e2edb6d3d68 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from-string/output.js @@ -0,0 +1,8 @@ +"use strict"; + +exports.__esModule = true; +exports["some exports"] = void 0; + +var _foo = require("foo"); + +exports["some exports"] = _foo["some exports"]; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from/input.mjs new file mode 100644 index 000000000000..2dc9ce983e0f --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from/input.mjs @@ -0,0 +1 @@ +export { foo as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from/output.js new file mode 100644 index 000000000000..5d681ab00212 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-from/output.js @@ -0,0 +1,8 @@ +"use strict"; + +exports.__esModule = true; +exports["some exports"] = void 0; + +var _foo = require("foo"); + +exports["some exports"] = _foo.foo; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..ee4aa01e3988 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "defaultExports", bar}; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..feb1e3fcb380 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/output.js @@ -0,0 +1,7 @@ +"use strict"; + +exports.__esModule = true; +exports.bar = exports.defaultExports = void 0; +var foo, bar; +exports.bar = bar; +exports.defaultExports = foo; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named/input.mjs new file mode 100644 index 000000000000..f36164d076f9 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "default exports", bar}; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named/output.js new file mode 100644 index 000000000000..2549e2e6d118 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/export-named/output.js @@ -0,0 +1,7 @@ +"use strict"; + +exports.__esModule = true; +exports.bar = exports["default exports"] = void 0; +var foo, bar; +exports.bar = bar; +exports["default exports"] = foo; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..c6975c24a9a7 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/input.mjs @@ -0,0 +1,3 @@ +import { "defaultImports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..b8cbff3d1bc8 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/output.js @@ -0,0 +1,5 @@ +"use strict"; + +var _foo = require("foo"); + +_foo.defaultImports; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named/input.mjs new file mode 100644 index 000000000000..97932c921132 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named/input.mjs @@ -0,0 +1,3 @@ +import {"default imports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named/output.js new file mode 100644 index 000000000000..285f7ab68543 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/import-named/output.js @@ -0,0 +1,5 @@ +"use strict"; + +var _foo = require("foo"); + +_foo["default imports"]; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/options.json b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/options.json new file mode 100644 index 000000000000..255ad4b1bdcf --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names-loose/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "external-helpers", + ["transform-modules-commonjs", { "loose": true }], + "syntax-module-string-names" + ] +} diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs new file mode 100644 index 000000000000..9af06dedb8e3 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs @@ -0,0 +1 @@ +export { "some imports" as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string-as-string/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string-as-string/output.js new file mode 100644 index 000000000000..e15634b5f722 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string-as-string/output.js @@ -0,0 +1,13 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "some exports", { + enumerable: true, + get: function () { + return _foo["some imports"]; + } +}); + +var _foo = require("foo"); diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string/input.mjs new file mode 100644 index 000000000000..cf064000fd95 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string/input.mjs @@ -0,0 +1 @@ +export { "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string/output.js new file mode 100644 index 000000000000..e771d8b879c1 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from-string/output.js @@ -0,0 +1,13 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "some exports", { + enumerable: true, + get: function () { + return _foo["some exports"]; + } +}); + +var _foo = require("foo"); diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from/input.mjs new file mode 100644 index 000000000000..2dc9ce983e0f --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from/input.mjs @@ -0,0 +1 @@ +export { foo as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from/output.js new file mode 100644 index 000000000000..a92c51cbee69 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-from/output.js @@ -0,0 +1,13 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "some exports", { + enumerable: true, + get: function () { + return _foo.foo; + } +}); + +var _foo = require("foo"); diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..ee4aa01e3988 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "defaultExports", bar}; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..f7012942afa0 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.js @@ -0,0 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.bar = exports.defaultExports = void 0; +var foo, bar; +exports.bar = bar; +exports.defaultExports = foo; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named/input.mjs new file mode 100644 index 000000000000..f36164d076f9 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "default exports", bar}; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named/output.js new file mode 100644 index 000000000000..25095c45da76 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/export-named/output.js @@ -0,0 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.bar = exports["default exports"] = void 0; +var foo, bar; +exports.bar = bar; +exports["default exports"] = foo; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..c6975c24a9a7 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs @@ -0,0 +1,3 @@ +import { "defaultImports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..b8cbff3d1bc8 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.js @@ -0,0 +1,5 @@ +"use strict"; + +var _foo = require("foo"); + +_foo.defaultImports; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named/input.mjs new file mode 100644 index 000000000000..97932c921132 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named/input.mjs @@ -0,0 +1,3 @@ +import {"default imports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named/output.js new file mode 100644 index 000000000000..285f7ab68543 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/import-named/output.js @@ -0,0 +1,5 @@ +"use strict"; + +var _foo = require("foo"); + +_foo["default imports"]; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/options.json b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/options.json new file mode 100644 index 000000000000..392fd3cecc16 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-module-string-names/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "external-helpers", + "transform-modules-commonjs", + "syntax-module-string-names" + ] +} diff --git a/packages/babel-plugin-transform-modules-systemjs/package.json b/packages/babel-plugin-transform-modules-systemjs/package.json index 0149d44733e2..a26f6b10078c 100644 --- a/packages/babel-plugin-transform-modules-systemjs/package.json +++ b/packages/babel-plugin-transform-modules-systemjs/package.json @@ -16,6 +16,7 @@ "@babel/helper-hoist-variables": "workspace:^7.10.4", "@babel/helper-module-transforms": "workspace:^7.10.5", "@babel/helper-plugin-utils": "workspace:^7.10.4", + "@babel/helper-validator-identifier": "workspace:^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" }, "keywords": [ diff --git a/packages/babel-plugin-transform-modules-systemjs/src/index.js b/packages/babel-plugin-transform-modules-systemjs/src/index.js index 56e9001428b1..f30daf04b52d 100644 --- a/packages/babel-plugin-transform-modules-systemjs/src/index.js +++ b/packages/babel-plugin-transform-modules-systemjs/src/index.js @@ -3,6 +3,7 @@ import hoistVariables from "@babel/helper-hoist-variables"; import { template, types as t } from "@babel/core"; import { getImportSource } from "babel-plugin-dynamic-import-node/utils"; import { rewriteThis, getModuleName } from "@babel/helper-module-transforms"; +import { isIdentifierName } from "@babel/helper-validator-identifier"; const buildTemplate = template(` SYSTEM_REGISTER(MODULE_NAME, SOURCES, function (EXPORT_IDENTIFIER, CONTEXT_IDENTIFIER) { @@ -29,12 +30,50 @@ WARNING: Dynamic import() transformation must be enabled using the no longer transform import() without using that plugin. `; +//todo: use getExportSpecifierName in `helper-module-transforms` when this library is refactored to NodePath usage. + +export function getExportSpecifierName( + node: Node, + stringSpecifiers: Set, +): string { + if (node.type === "Identifier") { + return node.name; + } else if (node.type === "StringLiteral") { + const stringValue = node.value; + // add specifier value to `stringSpecifiers` only when it can not be converted to an identifier name + // i.e In `import { "foo" as bar }` + // we do not consider `"foo"` to be a `stringSpecifier` because we can treat it as + // `import { foo as bar }` + // This helps minimize the size of `stringSpecifiers` and reduce overhead of checking valid identifier names + // when building transpiled code from metadata + if (!isIdentifierName(stringValue)) { + stringSpecifiers.add(stringValue); + } + return stringValue; + } else { + throw new Error( + `Expected export specifier to be either Identifier or StringLiteral, got ${node.type}`, + ); + } +} + +type PluginState = {| + contextIdent: string, + + // List of names that should only be printed as string literals. + // i.e. `import { "any unicode" as foo } from "some-module"` + // `stringSpecifiers` is Set(1) ["any unicode"] + // In most cases `stringSpecifiers` is an empty Set + stringSpecifiers: Set, +|}; + function constructExportCall( path, exportIdent, exportNames, exportValues, exportStarTarget, + stringSpecifiers: Set, ) { const statements = []; if (exportNames.length === 1) { @@ -52,7 +91,12 @@ function constructExportCall( const exportName = exportNames[i]; const exportValue = exportValues[i]; objectProperties.push( - t.objectProperty(t.identifier(exportName), exportValue), + t.objectProperty( + stringSpecifiers.has(exportName) + ? t.stringLiteral(exportName) + : t.identifier(exportName), + exportValue, + ), ); } statements.push( @@ -179,7 +223,7 @@ export default declare((api, options) => { }, visitor: { - CallExpression(path, state) { + CallExpression(path, state: PluginState) { if (t.isImport(path.node.callee)) { if (!this.file.has("@babel/plugin-proposal-dynamic-import")) { console.warn(MISSING_PLUGIN_WARNING); @@ -197,7 +241,7 @@ export default declare((api, options) => { } }, - MetaProperty(path, state) { + MetaProperty(path, state: PluginState) { if ( path.node.meta.name === "import" && path.node.property.name === "meta" @@ -228,14 +272,15 @@ export default declare((api, options) => { Program: { enter(path, state) { state.contextIdent = path.scope.generateUid("context"); + state.stringSpecifiers = new Set(); if (!allowTopLevelThis) { rewriteThis(path); } }, - exit(path, state) { + exit(path, state: PluginState) { const scope = path.scope; const exportIdent = scope.generateUid("export"); - const contextIdent = state.contextIdent; + const { contextIdent, stringSpecifiers } = state; const exportMap = Object.create(null); const modules = []; @@ -389,28 +434,25 @@ export default declare((api, options) => { const nodes = []; for (const specifier of specifiers) { - const binding = scope.getBinding(specifier.local.name); + const { local, exported } = specifier; + const binding = scope.getBinding(local.name); + const exportedName = getExportSpecifierName( + exported, + stringSpecifiers, + ); // hoisted function export if ( binding && t.isFunctionDeclaration(binding.path.node) ) { - exportNames.push(specifier.exported.name); - exportValues.push(t.cloneNode(specifier.local)); + exportNames.push(exportedName); + exportValues.push(t.cloneNode(local)); } // only globals also exported this way else if (!binding) { - nodes.push( - buildExportCall( - specifier.exported.name, - specifier.local, - ), - ); + nodes.push(buildExportCall(exportedName, local)); } - addExportName( - specifier.local.name, - specifier.exported.name, - ); + addExportName(local.name, exportedName); } path.replaceWithMultiple(nodes); @@ -445,6 +487,7 @@ export default declare((api, options) => { } if (t.isImportSpecifier(specifier)) { + const { imported } = specifier; setterBody.push( t.expressionStatement( t.assignmentExpression( @@ -453,6 +496,7 @@ export default declare((api, options) => { t.memberExpression( t.identifier(target), specifier.imported, + /* computed */ imported.type === "StringLiteral", ), ), ), @@ -469,9 +513,17 @@ export default declare((api, options) => { if (t.isExportAllDeclaration(node)) { hasExportStar = true; } else if (t.isExportSpecifier(node)) { - exportNames.push(node.exported.name); + const exportedName = getExportSpecifierName( + node.exported, + stringSpecifiers, + ); + exportNames.push(exportedName); exportValues.push( - t.memberExpression(t.identifier(target), node.local), + t.memberExpression( + t.identifier(target), + node.local, + t.isStringLiteral(node.local), + ), ); } else { // todo @@ -485,6 +537,7 @@ export default declare((api, options) => { exportNames, exportValues, hasExportStar ? t.identifier(target) : null, + stringSpecifiers, ), ); } @@ -533,6 +586,7 @@ export default declare((api, options) => { exportNames, exportValues, null, + stringSpecifiers, ), ); } diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs new file mode 100644 index 000000000000..9af06dedb8e3 --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs @@ -0,0 +1 @@ +export { "some imports" as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string-as-string/output.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string-as-string/output.mjs new file mode 100644 index 000000000000..a05cb4a573b1 --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string-as-string/output.mjs @@ -0,0 +1,10 @@ +System.register(["foo"], function (_export, _context) { + "use strict"; + + return { + setters: [function (_foo) { + _export("some exports", _foo["some imports"]); + }], + execute: function () {} + }; +}); diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string/input.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string/input.mjs new file mode 100644 index 000000000000..cf064000fd95 --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string/input.mjs @@ -0,0 +1 @@ +export { "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string/output.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string/output.mjs new file mode 100644 index 000000000000..958e879b24fc --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from-string/output.mjs @@ -0,0 +1,10 @@ +System.register(["foo"], function (_export, _context) { + "use strict"; + + return { + setters: [function (_foo) { + _export("some exports", _foo["some exports"]); + }], + execute: function () {} + }; +}); diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from/input.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from/input.mjs new file mode 100644 index 000000000000..2dc9ce983e0f --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from/input.mjs @@ -0,0 +1 @@ +export { foo as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from/output.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from/output.mjs new file mode 100644 index 000000000000..3f7e3c9f4bad --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-from/output.mjs @@ -0,0 +1,10 @@ +System.register(["foo"], function (_export, _context) { + "use strict"; + + return { + setters: [function (_foo) { + _export("some exports", _foo.foo); + }], + execute: function () {} + }; +}); diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..ee4aa01e3988 --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "defaultExports", bar}; diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.mjs new file mode 100644 index 000000000000..2d291cb07e76 --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.mjs @@ -0,0 +1,15 @@ +System.register([], function (_export, _context) { + "use strict"; + + var foo, bar; + + _export({ + defaultExports: void 0, + bar: void 0 + }); + + return { + setters: [], + execute: function () {} + }; +}); diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named/input.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named/input.mjs new file mode 100644 index 000000000000..f36164d076f9 --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "default exports", bar}; diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named/output.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named/output.mjs new file mode 100644 index 000000000000..786b6c24d89f --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/export-named/output.mjs @@ -0,0 +1,15 @@ +System.register([], function (_export, _context) { + "use strict"; + + var foo, bar; + + _export({ + "default exports": void 0, + bar: void 0 + }); + + return { + setters: [], + execute: function () {} + }; +}); diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..c6975c24a9a7 --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs @@ -0,0 +1,3 @@ +import { "defaultImports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.mjs new file mode 100644 index 000000000000..9e58fa1fca5b --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.mjs @@ -0,0 +1,13 @@ +System.register(["foo"], function (_export, _context) { + "use strict"; + + var bar; + return { + setters: [function (_foo) { + bar = _foo["defaultImports"]; + }], + execute: function () { + bar; + } + }; +}); diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named/input.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named/input.mjs new file mode 100644 index 000000000000..97932c921132 --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named/input.mjs @@ -0,0 +1,3 @@ +import {"default imports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named/output.mjs b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named/output.mjs new file mode 100644 index 000000000000..19d3adb757d5 --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/import-named/output.mjs @@ -0,0 +1,13 @@ +System.register(["foo"], function (_export, _context) { + "use strict"; + + var bar; + return { + setters: [function (_foo) { + bar = _foo["default imports"]; + }], + execute: function () { + bar; + } + }; +}); diff --git a/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/options.json b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/options.json new file mode 100644 index 000000000000..e1251d0ca2b0 --- /dev/null +++ b/packages/babel-plugin-transform-modules-systemjs/test/fixtures/interop-module-string-names/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "external-helpers", + "transform-modules-systemjs", + "syntax-module-string-names" + ] +} diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/input.mjs new file mode 100644 index 000000000000..9af06dedb8e3 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/input.mjs @@ -0,0 +1 @@ +export { "some imports" as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/output.js new file mode 100644 index 000000000000..a89cf3c3587b --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string-as-string/output.js @@ -0,0 +1,19 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["exports", "foo"], factory); + } else if (typeof exports !== "undefined") { + factory(exports, require("foo")); + } else { + var mod = { + exports: {} + }; + factory(mod.exports, global.foo); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _foo) { + "use strict"; + + _exports.__esModule = true; + _exports["some exports"] = void 0; + _exports["some exports"] = _foo["some imports"]; +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string/input.mjs new file mode 100644 index 000000000000..cf064000fd95 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string/input.mjs @@ -0,0 +1 @@ +export { "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string/output.js new file mode 100644 index 000000000000..1a3fbef8dca2 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from-string/output.js @@ -0,0 +1,19 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["exports", "foo"], factory); + } else if (typeof exports !== "undefined") { + factory(exports, require("foo")); + } else { + var mod = { + exports: {} + }; + factory(mod.exports, global.foo); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _foo) { + "use strict"; + + _exports.__esModule = true; + _exports["some exports"] = void 0; + _exports["some exports"] = _foo["some exports"]; +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from/input.mjs new file mode 100644 index 000000000000..2dc9ce983e0f --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from/input.mjs @@ -0,0 +1 @@ +export { foo as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from/output.js new file mode 100644 index 000000000000..3fa46f7bde32 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-from/output.js @@ -0,0 +1,19 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["exports", "foo"], factory); + } else if (typeof exports !== "undefined") { + factory(exports, require("foo")); + } else { + var mod = { + exports: {} + }; + factory(mod.exports, global.foo); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _foo) { + "use strict"; + + _exports.__esModule = true; + _exports["some exports"] = void 0; + _exports["some exports"] = _foo.foo; +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..ee4aa01e3988 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "defaultExports", bar}; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..5cca9b396963 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named-string-can-be-identifier/output.js @@ -0,0 +1,21 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["exports"], factory); + } else if (typeof exports !== "undefined") { + factory(exports); + } else { + var mod = { + exports: {} + }; + factory(mod.exports); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports) { + "use strict"; + + _exports.__esModule = true; + _exports.bar = _exports.defaultExports = void 0; + var foo, bar; + _exports.bar = bar; + _exports.defaultExports = foo; +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named/input.mjs new file mode 100644 index 000000000000..f36164d076f9 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "default exports", bar}; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named/output.js new file mode 100644 index 000000000000..4106ba476556 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/export-named/output.js @@ -0,0 +1,21 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["exports"], factory); + } else if (typeof exports !== "undefined") { + factory(exports); + } else { + var mod = { + exports: {} + }; + factory(mod.exports); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports) { + "use strict"; + + _exports.__esModule = true; + _exports.bar = _exports["default exports"] = void 0; + var foo, bar; + _exports.bar = bar; + _exports["default exports"] = foo; +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..c6975c24a9a7 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/input.mjs @@ -0,0 +1,3 @@ +import { "defaultImports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..a1e65790cd7c --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named-string-can-be-identifier/output.js @@ -0,0 +1,17 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["foo"], factory); + } else if (typeof exports !== "undefined") { + factory(require("foo")); + } else { + var mod = { + exports: {} + }; + factory(global.foo); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_foo) { + "use strict"; + + _foo.defaultImports; +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named/input.mjs new file mode 100644 index 000000000000..97932c921132 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named/input.mjs @@ -0,0 +1,3 @@ +import {"default imports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named/output.js new file mode 100644 index 000000000000..6f853fc9c5cb --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/import-named/output.js @@ -0,0 +1,17 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["foo"], factory); + } else if (typeof exports !== "undefined") { + factory(require("foo")); + } else { + var mod = { + exports: {} + }; + factory(global.foo); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_foo) { + "use strict"; + + _foo["default imports"]; +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/options.json b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/options.json new file mode 100644 index 000000000000..03d2a130053a --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names-loose/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "external-helpers", + ["transform-modules-umd", { "loose": true }], + "syntax-module-string-names" + ] +} diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs new file mode 100644 index 000000000000..9af06dedb8e3 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string-as-string/input.mjs @@ -0,0 +1 @@ +export { "some imports" as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string-as-string/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string-as-string/output.js new file mode 100644 index 000000000000..e5b6f3ec270d --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string-as-string/output.js @@ -0,0 +1,25 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["exports", "foo"], factory); + } else if (typeof exports !== "undefined") { + factory(exports, require("foo")); + } else { + var mod = { + exports: {} + }; + factory(mod.exports, global.foo); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _foo) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.defineProperty(_exports, "some exports", { + enumerable: true, + get: function () { + return _foo["some imports"]; + } + }); +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string/input.mjs new file mode 100644 index 000000000000..cf064000fd95 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string/input.mjs @@ -0,0 +1 @@ +export { "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string/output.js new file mode 100644 index 000000000000..57aa7797930a --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from-string/output.js @@ -0,0 +1,25 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["exports", "foo"], factory); + } else if (typeof exports !== "undefined") { + factory(exports, require("foo")); + } else { + var mod = { + exports: {} + }; + factory(mod.exports, global.foo); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _foo) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.defineProperty(_exports, "some exports", { + enumerable: true, + get: function () { + return _foo["some exports"]; + } + }); +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from/input.mjs new file mode 100644 index 000000000000..2dc9ce983e0f --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from/input.mjs @@ -0,0 +1 @@ +export { foo as "some exports" } from "foo"; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from/output.js new file mode 100644 index 000000000000..c36c8c762467 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-from/output.js @@ -0,0 +1,25 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["exports", "foo"], factory); + } else if (typeof exports !== "undefined") { + factory(exports, require("foo")); + } else { + var mod = { + exports: {} + }; + factory(mod.exports, global.foo); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _foo) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + Object.defineProperty(_exports, "some exports", { + enumerable: true, + get: function () { + return _foo.foo; + } + }); +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..ee4aa01e3988 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "defaultExports", bar}; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..6941dfae21dc --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named-string-can-be-identifier/output.js @@ -0,0 +1,23 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["exports"], factory); + } else if (typeof exports !== "undefined") { + factory(exports); + } else { + var mod = { + exports: {} + }; + factory(mod.exports); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.bar = _exports.defaultExports = void 0; + var foo, bar; + _exports.bar = bar; + _exports.defaultExports = foo; +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named/input.mjs new file mode 100644 index 000000000000..f36164d076f9 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named/input.mjs @@ -0,0 +1,2 @@ +var foo, bar; +export {foo as "default exports", bar}; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named/output.js new file mode 100644 index 000000000000..b9af0a8cd204 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/export-named/output.js @@ -0,0 +1,23 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["exports"], factory); + } else if (typeof exports !== "undefined") { + factory(exports); + } else { + var mod = { + exports: {} + }; + factory(mod.exports); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports) { + "use strict"; + + Object.defineProperty(_exports, "__esModule", { + value: true + }); + _exports.bar = _exports["default exports"] = void 0; + var foo, bar; + _exports.bar = bar; + _exports["default exports"] = foo; +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs new file mode 100644 index 000000000000..c6975c24a9a7 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/input.mjs @@ -0,0 +1,3 @@ +import { "defaultImports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.js new file mode 100644 index 000000000000..a1e65790cd7c --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named-string-can-be-identifier/output.js @@ -0,0 +1,17 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["foo"], factory); + } else if (typeof exports !== "undefined") { + factory(require("foo")); + } else { + var mod = { + exports: {} + }; + factory(global.foo); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_foo) { + "use strict"; + + _foo.defaultImports; +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named/input.mjs b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named/input.mjs new file mode 100644 index 000000000000..97932c921132 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named/input.mjs @@ -0,0 +1,3 @@ +import {"default imports" as bar} from "foo"; + +bar; diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named/output.js new file mode 100644 index 000000000000..6f853fc9c5cb --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/import-named/output.js @@ -0,0 +1,17 @@ +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define(["foo"], factory); + } else if (typeof exports !== "undefined") { + factory(require("foo")); + } else { + var mod = { + exports: {} + }; + factory(global.foo); + global.input = mod.exports; + } +})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_foo) { + "use strict"; + + _foo["default imports"]; +}); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/options.json b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/options.json new file mode 100644 index 000000000000..7d7a0d93ec46 --- /dev/null +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/interop-module-string-names/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "external-helpers", + "transform-modules-umd", + "syntax-module-string-names" + ] +} diff --git a/packages/babel-types/src/definitions/core.js b/packages/babel-types/src/definitions/core.js index 03e16da49226..02bee8745b6e 100644 --- a/packages/babel-types/src/definitions/core.js +++ b/packages/babel-types/src/definitions/core.js @@ -1503,7 +1503,7 @@ defineType("ExportSpecifier", { validate: assertNodeType("Identifier"), }, exported: { - validate: assertNodeType("Identifier"), + validate: assertNodeType("Identifier", "StringLiteral"), }, }, }); @@ -1611,7 +1611,7 @@ defineType("ImportSpecifier", { validate: assertNodeType("Identifier"), }, imported: { - validate: assertNodeType("Identifier"), + validate: assertNodeType("Identifier", "StringLiteral"), }, importKind: { // Handle Flowtype's extension "import {typeof foo} from" diff --git a/yarn.lock b/yarn.lock index 5c3de2769f87..72667374c036 100644 --- a/yarn.lock +++ b/yarn.lock @@ -593,6 +593,7 @@ __metadata: "@babel/helper-replace-supers": "workspace:^7.10.4" "@babel/helper-simple-access": "workspace:^7.10.4" "@babel/helper-split-export-declaration": "workspace:^7.11.0" + "@babel/helper-validator-identifier": "workspace:^7.10.4" "@babel/template": "workspace:^7.10.4" "@babel/types": "workspace:^7.11.0" lodash: ^4.17.19 @@ -1595,6 +1596,17 @@ __metadata: languageName: unknown linkType: soft +"@babel/plugin-syntax-module-string-names@workspace:packages/babel-plugin-syntax-module-string-names": + version: 0.0.0-use.local + resolution: "@babel/plugin-syntax-module-string-names@workspace:packages/babel-plugin-syntax-module-string-names" + dependencies: + "@babel/core": "workspace:^7.10.4" + "@babel/helper-plugin-utils": "workspace:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + languageName: unknown + linkType: soft + "@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.0": version: 7.8.3 resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3" @@ -2217,6 +2229,7 @@ __metadata: "@babel/helper-module-transforms": "workspace:^7.10.5" "@babel/helper-plugin-test-runner": "workspace:^7.10.4" "@babel/helper-plugin-utils": "workspace:^7.10.4" + "@babel/helper-validator-identifier": "workspace:^7.10.4" "@babel/plugin-syntax-dynamic-import": ^7.8.0 babel-plugin-dynamic-import-node: ^2.3.3 peerDependencies: