diff --git a/packages/babel-cli/test/fixtures/babel-external-helpers/--whitelist/stdout.txt b/packages/babel-cli/test/fixtures/babel-external-helpers/--whitelist/stdout.txt index 1068d127fe..8b78039c1a 100644 --- a/packages/babel-cli/test/fixtures/babel-external-helpers/--whitelist/stdout.txt +++ b/packages/babel-cli/test/fixtures/babel-external-helpers/--whitelist/stdout.txt @@ -17,5 +17,5 @@ return Constructor; } - babelHelpers.createClass = _createClass + babelHelpers.createClass = _createClass; })(typeof global === "undefined" ? self : global); diff --git a/packages/babel-core/src/transformation/file/index.js b/packages/babel-core/src/transformation/file/index.js index 6c2ab6044f..38947d5397 100644 --- a/packages/babel-core/src/transformation/file/index.js +++ b/packages/babel-core/src/transformation/file/index.js @@ -178,49 +178,13 @@ export default class File extends Store { return source; } - addImport( - source: string, - imported?: string = "", - name?: string = imported, - ): Object | null { - const prependDeclaration = ( - specifiers: Array, - ): void => { - const declar = t.importDeclaration(specifiers, t.stringLiteral(source)); - declar._blockHoist = 3; - - this.path.unshiftContainer("body", declar); - }; - - // import "module-name"; - if (!imported) { - prependDeclaration([]); - return null; - } - - const alias = `${source}:${imported}`; - let id = this.dynamicImportIds[alias]; - - if (!id) { - source = this.resolveModuleSource(source); - id = this.dynamicImportIds[alias] = this.scope.generateUidIdentifier( - name, - ); - - const specifiers = []; - - if (imported === "*") { - specifiers.push(t.importNamespaceSpecifier(id)); - } else if (imported === "default") { - specifiers.push(t.importDefaultSpecifier(id)); - } else { - specifiers.push(t.importSpecifier(id, t.identifier(imported))); - } - - prependDeclaration(specifiers); - } - - return t.identifier(id.name); + addImport() { + throw new Error( + "This API has been removed. If you're looking for this " + + "functionality in Babel 7, you should import the " + + "'babel-helper-module-imports' module and use the functions exposed " + + " from that module, such as 'addNamed' or 'addDefault'.", + ); } addHelper(name: string): Object { diff --git a/packages/babel-core/src/transformation/internal-plugins/block-hoist.js b/packages/babel-core/src/transformation/internal-plugins/block-hoist.js index 4813b18d22..1682670314 100644 --- a/packages/babel-core/src/transformation/internal-plugins/block-hoist.js +++ b/packages/babel-core/src/transformation/internal-plugins/block-hoist.js @@ -10,6 +10,7 @@ export default { * - 1 Default node position * - 2 Priority over normal nodes * - 3 We want this to be at the **very** top + * - 4 Reserved for the helpers used to implement module imports. */ name: "internal.blockHoist", diff --git a/packages/babel-core/test/fixtures/plugins/file-add-import/exec.js b/packages/babel-core/test/fixtures/plugins/file-add-import/exec.js deleted file mode 100644 index 72108171cb..0000000000 --- a/packages/babel-core/test/fixtures/plugins/file-add-import/exec.js +++ /dev/null @@ -1,30 +0,0 @@ -var res = transform("", { - plugins: [ - function (b) { - return { - visitor: { - Program: function(path, state) { - var file = state.file; - file.addImport("import-star", "*", "lib"); - file.addImport("import-default", "default", "foo"); - file.addImport("import-alias", "bar", "baz"); - file.addImport("import-default-alias", "quux"); - file.addImport("import-empty", ""); - file.addImport("import-none"); - } - } - }; - } - ] -}); - -var expected = multiline([ - 'import "import-none";', - 'import "import-empty";', - 'import { quux as _quux } from "import-default-alias";', - 'import { bar as _baz } from "import-alias";', - 'import _foo from "import-default";', - 'import * as _lib from "import-star";', -]); - -assert.equal(res.code, expected); diff --git a/packages/babel-helper-module-imports/.npmignore b/packages/babel-helper-module-imports/.npmignore new file mode 100644 index 0000000000..f980694583 --- /dev/null +++ b/packages/babel-helper-module-imports/.npmignore @@ -0,0 +1,3 @@ +src +test +*.log diff --git a/packages/babel-helper-module-imports/README.md b/packages/babel-helper-module-imports/README.md new file mode 100644 index 0000000000..37b3b59db0 --- /dev/null +++ b/packages/babel-helper-module-imports/README.md @@ -0,0 +1,27 @@ +# babel-helper-module-imports + +## Usage + +### Adding a named import + +``` +import { addNamed } from "babel-helper-module-imports"; + +export default function({ types: t }) { + return { + visitor: { + ReferencedIdentifier(path) { + let importName = this.importName; + if (importName) { + importName = t.cloneDeep(importName); + } else { + // require('bluebird').coroutine + importName = this.importName = addName(path, 'coroutine', 'bluebird'); + } + + path.replaceWith(importName); + } + }, + }; +} +``` diff --git a/packages/babel-helper-module-imports/package.json b/packages/babel-helper-module-imports/package.json new file mode 100644 index 0000000000..e9db64557a --- /dev/null +++ b/packages/babel-helper-module-imports/package.json @@ -0,0 +1,14 @@ +{ + "name": "babel-helper-module-imports", + "version": "7.0.0-beta.2", + "description": "Babel helper functions for inserting module loads", + "author": "Logan Smyth ", + "homepage": "https://babeljs.io/", + "license": "MIT", + "repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-module-imports", + "main": "lib/index.js", + "dependencies": { + "babel-types": "7.0.0-beta.2", + "lodash": "^4.2.0" + } +} diff --git a/packages/babel-helper-module-imports/src/import-builder.js b/packages/babel-helper-module-imports/src/import-builder.js new file mode 100644 index 0000000000..bbde6fdef9 --- /dev/null +++ b/packages/babel-helper-module-imports/src/import-builder.js @@ -0,0 +1,142 @@ +import assert from "assert"; +import * as t from "babel-types"; + +/** + * A class to track and accumulate mutations to the AST that will eventually + * output a new require/import statement list. + */ +export default class ImportBuilder { + _statements = []; + _resultName = null; + + _scope = null; + _file = null; + + constructor(importedSource, scope, file) { + this._scope = scope; + this._file = file; + this._importedSource = importedSource; + } + + done() { + return { + statements: this._statements, + resultName: this._resultName, + }; + } + + import() { + const importedSource = this._file.resolveModuleSource(this._importedSource); + + this._statements.push( + t.importDeclaration([], t.stringLiteral(importedSource)), + ); + return this; + } + + require() { + const importedSource = this._file.resolveModuleSource(this._importedSource); + + this._statements.push( + t.expressionStatement( + t.callExpression(t.identifier("require"), [ + t.stringLiteral(importedSource), + ]), + ), + ); + return this; + } + + namespace(name) { + name = this._scope.generateUidIdentifier(name); + + const statement = this._statements[this._statements.length - 1]; + assert(statement.type === "ImportDeclaration"); + assert(statement.specifiers.length === 0); + statement.specifiers = [t.importNamespaceSpecifier(name)]; + this._resultName = t.clone(name); + return this; + } + default(name) { + name = this._scope.generateUidIdentifier(name); + const statement = this._statements[this._statements.length - 1]; + assert(statement.type === "ImportDeclaration"); + assert(statement.specifiers.length === 0); + statement.specifiers = [t.importDefaultSpecifier(name)]; + this._resultName = t.clone(name); + return this; + } + named(name, importName) { + if (importName === "default") return this.default(name); + + name = this._scope.generateUidIdentifier(name); + const statement = this._statements[this._statements.length - 1]; + assert(statement.type === "ImportDeclaration"); + assert(statement.specifiers.length === 0); + statement.specifiers = [t.importSpecifier(name, t.identifier(importName))]; + this._resultName = t.clone(name); + return this; + } + + var(name) { + name = this._scope.generateUidIdentifier(name); + let statement = this._statements[this._statements.length - 1]; + if (statement.type !== "ExpressionStatement") { + assert(this._resultName); + statement = t.expressionStatement(this._resultName); + this._statements.push(statement); + } + this._statements[ + this._statements.length - 1 + ] = t.variableDeclaration("var", [ + t.variableDeclarator(name, statement.expression), + ]); + this._resultName = t.clone(name); + return this; + } + + defaultInterop() { + return this._interop(this._file.addHelper("interopRequireDefault")); + } + wildcardInterop() { + return this._interop(this._file.addHelper("interopRequireWildcard")); + } + + _interop(callee) { + const statement = this._statements[this._statements.length - 1]; + if (statement.type === "ExpressionStatement") { + statement.expression = t.callExpression(callee, [statement.expression]); + } else if (statement.type === "VariableDeclaration") { + assert(statement.declarations.length === 1); + statement.declarations[0].init = t.callExpression(callee, [ + statement.declarations[0].init, + ]); + } else { + assert.fail("Unexpected type."); + } + return this; + } + + prop(name) { + const statement = this._statements[this._statements.length - 1]; + if (statement.type === "ExpressionStatement") { + statement.expression = t.memberExpression( + statement.expression, + t.identifier(name), + ); + } else if (statement.type === "VariableDeclaration") { + assert(statement.declarations.length === 1); + statement.declarations[0].init = t.memberExpression( + statement.declarations[0].init, + t.identifier(name), + ); + } else { + assert.fail("Unexpected type:" + statement.type); + } + return this; + } + + read(name) { + this._resultName = t.memberExpression(this._resultName, t.identifier(name)); + } +} diff --git a/packages/babel-helper-module-imports/src/import-injector.js b/packages/babel-helper-module-imports/src/import-injector.js new file mode 100644 index 0000000000..f8326c1abd --- /dev/null +++ b/packages/babel-helper-module-imports/src/import-injector.js @@ -0,0 +1,425 @@ +import assert from "assert"; +import * as t from "babel-types"; + +import ImportBuilder from "./import-builder"; +import isModule from "./is-module"; + +export type ImportOptions = { + /** + * The module being referenced. + */ + importedSource: string | null, + + /** + * The type of module being imported: + * + * * 'es6' - An ES6 module. + * * 'commonjs' - A CommonJS module. (Default) + */ + importedType: "es6" | "commonjs", + + /** + * The type of interop behavior for namespace/default/named when loading + * CommonJS modules. + * + * ## 'babel' (Default) + * + * Load using Babel's interop. + * + * If '.__esModule' is true, treat as 'compiled', else: + * + * * Namespace: A copy of the module.exports with .default + * populated by the module.exports object. + * * Default: The module.exports value. + * * Named: The .named property of module.exports. + * + * The 'ensureLiveReference' has no effect on the liveness of these. + * + * ## 'compiled' + * + * Assume the module is ES6 compiled to CommonJS. Useful to avoid injecting + * interop logic if you are confident that the module is a certain format. + * + * * Namespace: The root module.exports object. + * * Default: The .default property of the namespace. + * * Named: The .named property of the namespace. + * + * Will return erroneous results if the imported module is _not_ compiled + * from ES6 with Babel. + * + * ## 'uncompiled' + * + * Assume the module is _not_ ES6 compiled to CommonJS. Used a simplified + * access pattern that doesn't require additional function calls. + * + * Will return erroneous results if the imported module _is_ compiled + * from ES6 with Babel. + * + * * Namespace: The module.exports object. + * * Default: The module.exports object. + * * Named: The .named property of module.exports. + */ + importedInterop: "babel" | "node" | "compiled" | "uncompiled", + + /** + * The type of CommonJS interop included in the environment that will be + * loading the output code. + * + * * 'babel' - CommonJS modules load with Babel's interop. (Default) + * * 'node' - CommonJS modules load with Node's interop. + * + * See descriptions in 'importedInterop' for more details. + */ + importingInterop: "babel" | "node", + + /** + * Define whether we explicitly care that the import be a live reference. + * Only applies when importing default and named imports, not the namespace. + * + * * true - Force imported values to be live references. + * * false - No particular requirements. Keeps the code simplest. (Default) + */ + ensureLiveReference: boolean, + + /** + * Define if we explicitly care that the result not be a property reference. + * + * * true - Force calls to exclude context. Useful if the value is going to + * be used as function callee. + * * false - No particular requirements for context of the access. (Default) + */ + ensureNoContext: boolean, +}; + +/** + * A general helper classes add imports via transforms. See README for usage. + */ +export default class ImportInjector { + /** + * The path used for manipulation. + */ + _programPath: NodePath; + + /** + * The scope used to generate unique variable names. + */ + _programScope; + + /** + * The file used to inject helpers and resolve paths. + */ + _file; + + /** + * The default options to use with this instance when imports are added. + */ + _defaultOpts: ImportOptions = { + importedSource: null, + importedType: "commonjs", + importedInterop: "babel", + importingInterop: "babel", + ensureLiveReference: false, + ensureNoContext: false, + }; + + constructor(path, importedSource, opts) { + const programPath = path.find(p => p.isProgram()); + + this._programPath = programPath; + this._programScope = programPath.scope; + this._file = programPath.hub.file; + + this._defaultOpts = this._applyDefaults(importedSource, opts, true); + } + + addDefault(importedSourceIn, opts) { + return this.addNamed("default", importedSourceIn, opts); + } + + addNamed(importName, importedSourceIn, opts) { + assert(typeof importName === "string"); + + return this._generateImport( + this._applyDefaults(importedSourceIn, opts), + importName, + ); + } + + addNamespace(importedSourceIn, opts) { + return this._generateImport( + this._applyDefaults(importedSourceIn, opts), + null, + ); + } + + addSideEffect(importedSourceIn, opts) { + return this._generateImport( + this._applyDefaults(importedSourceIn, opts), + false, + ); + } + + _applyDefaults(importedSource, opts, isInit = false) { + const optsList = []; + if (typeof importedSource === "string") { + optsList.push({ importedSource }); + optsList.push(opts); + } else { + assert(!opts, "Unexpected secondary arguments."); + + optsList.push(importedSource); + } + + const newOpts = Object.assign({}, this._defaultOpts); + for (const opts of optsList) { + if (!opts) continue; + Object.keys(newOpts).forEach(key => { + if (opts[key] !== undefined) newOpts[key] = opts[key]; + }); + + if (!isInit) { + if (opts.nameHint !== undefined) newOpts.nameHint = opts.nameHint; + if (opts.blockHoist !== undefined) newOpts.blockHoist = opts.blockHoist; + } + } + return newOpts; + } + + _generateImport(opts, importName) { + const isDefault = importName === "default"; + const isNamed = !!importName && !isDefault; + const isNamespace = importName === null; + + const { + importedSource, + importedType, + importedInterop, + importingInterop, + ensureLiveReference, + ensureNoContext, + + // Provide a hint for generateUidIdentifier for the local variable name + // to use for the import, if the code will generate a simple assignment + // to a variable. + nameHint = importName, + + // Not meant for public usage. Allows code that absolutely must control + // ordering to set a specific hoist value on the import nodes. + blockHoist, + } = opts; + + const isMod = isModule(this._programPath, true); + const isModuleForNode = isMod && importingInterop === "node"; + const isModuleForBabel = isMod && importingInterop === "babel"; + + const builder = new ImportBuilder( + importedSource, + this._programScope, + this._file, + ); + + if (importedType === "es6") { + if (!isModuleForNode && !isModuleForBabel) { + throw new Error("Cannot import an ES6 module from CommonJS"); + } + + // import * as namespace from ''; namespace + // import def from ''; def + // import { named } from ''; named + builder.import(); + if (isNamespace) { + builder.namespace("namespace"); + } else if (isDefault || isNamed) { + builder.named(nameHint, importName); + } + } else if (importedType !== "commonjs") { + throw new Error(`Unexpected interopType "${importedType}"`); + } else if (importedInterop === "babel") { + if (isModuleForNode) { + // import _tmp from ''; var namespace = interopRequireWildcard(_tmp); namespace + // import _tmp from ''; var def = interopRequireDefault(_tmp).default; def + // import _tmp from ''; _tmp.named + + builder.import(); + if (isNamespace) { + builder + .default("es6Default") + .var(nameHint || "namespace") + .wildcardInterop(); + } else if (isDefault) { + if (ensureLiveReference) { + builder + .default("es6Default") + .var("namespace") + .defaultInterop() + .read("default"); + } else { + builder + .default("es6Default") + .var(nameHint) + .defaultInterop() + .prop(importName); + } + } else if (isNamed) { + builder.default("es6Default").read(importName); + } + } else if (isModuleForBabel) { + // import * as namespace from ''; namespace + // import def from ''; def + // import { named } from ''; named + builder.import(); + if (isNamespace) { + builder.namespace("namespace"); + } else if (isDefault || isNamed) { + builder.named(nameHint, importName); + } + } else { + // var namespace = interopRequireWildcard(require('')); + // var def = interopRequireDefault(require('')).default; def + // var named = require('').named; named + builder.require(); + if (isNamespace) { + builder.var("namespace").wildcardInterop(); + } else if ((isDefault || isNamed) && ensureLiveReference) { + builder.var("namespace").read(importName); + + if (isDefault) builder.defaultInterop(); + } else if (isDefault) { + builder + .var(nameHint) + .defaultInterop() + .prop(importName); + } else if (isNamed) { + builder.var(nameHint).prop(importName); + } + } + } else if (importedInterop === "compiled") { + if (isModuleForNode) { + // import namespace from ''; namespace + // import namespace from ''; namespace.default + // import namespace from ''; namespace.named + + builder.import(); + if (isNamespace) { + builder.default("namespace"); + } else if (isDefault || isNamed) { + builder.default("namespace").read(importName); + } + } else if (isModuleForBabel) { + // import * as namespace from ''; namespace + // import def from ''; def + // import { named } from ''; named + // Note: These lookups will break if the module has no __esModule set, + // hence the warning that 'compiled' will not work on standard CommonJS. + + builder.import(); + if (isNamespace) { + builder.namespace("namespace"); + } else if (isDefault || isNamed) { + builder.named(nameHint, importName); + } + } else { + // var namespace = require(''); namespace + // var namespace = require(''); namespace.default + // var namespace = require(''); namespace.named + // var named = require('').named; + + builder.require(); + if (isNamespace) { + builder.var("namespace"); + } else if (isDefault || isNamed) { + if (ensureLiveReference) { + builder.var("namespace").read(importName); + } else { + builder.prop(importName).var(nameHint); + } + } + } + } else if (importedInterop === "uncompiled") { + if (isDefault && ensureLiveReference) { + throw new Error("No live reference for commonjs default"); + } + + if (isModuleForNode) { + // import namespace from ''; namespace + // import def from ''; def; + // import namespace from ''; namespace.named + + builder.import(); + if (isNamespace) { + builder.default("namespace"); + } else if (isDefault) { + builder.default(nameHint); + } else if (isNamed) { + builder.default("namespace").read(importName); + } + } else if (isModuleForBabel) { + // import namespace from ''; + // import def from ''; + // import { named } from ''; named; + // Note: These lookups will break if the module has __esModule set, + // hence the warning that 'uncompiled' will not work on ES6 transpiled + // to CommonJS. + + builder.import(); + if (isNamespace) { + builder.default("namespace"); + } else if (isDefault) { + builder.default(nameHint); + } else if (isNamed) { + builder.named(nameHint, importName); + } + } else { + // var namespace = require(''); namespace + // var def = require(''); def + // var namespace = require(''); namespace.named + // var named = require('').named; + + builder.require(); + if (isNamespace) { + builder.var("namespace"); + } else if (isDefault) { + builder.var(nameHint); + } else if (isNamed) { + if (ensureLiveReference) { + builder.var("namespace").read(importName); + } else { + builder.var(nameHint).prop(importName); + } + } + } + } else { + throw new Error(`Unknown importedInterop "${importedInterop}".`); + } + + const { statements, resultName } = builder.done(); + + this._insertStatements(statements, blockHoist); + + if ( + (isDefault || isNamed) && + ensureNoContext && + resultName.type !== "Identifier" + ) { + return t.sequenceExpression([t.numericLiteral(0), resultName]); + } + return resultName; + } + + _insertStatements(statements, blockHoist = 3) { + statements.forEach(node => { + node._blockHoist = blockHoist; + }); + + const targetPath = this._programPath.get("body").filter(p => { + const val = p.node._blockHoist; + return Number.isFinite(val) && val < 4; + })[0]; + + if (targetPath) { + targetPath.insertBefore(statements); + } else { + this._programPath.unshiftContainer("body", statements); + } + } +} diff --git a/packages/babel-helper-module-imports/src/index.js b/packages/babel-helper-module-imports/src/index.js new file mode 100644 index 0000000000..722631adce --- /dev/null +++ b/packages/babel-helper-module-imports/src/index.js @@ -0,0 +1,21 @@ +import ImportInjector from "./import-injector"; + +export { ImportInjector }; + +export { default as isModule } from "./is-module"; + +export function addDefault(path, importedSource, opts) { + return new ImportInjector(path).addDefault(importedSource, opts); +} + +export function addNamed(path, name, importedSource, opts) { + return new ImportInjector(path).addNamed(name, importedSource, opts); +} + +export function addNamespace(path, importedSource, opts) { + return new ImportInjector(path).addNamespace(importedSource, opts); +} + +export function addSideEffect(path, importedSource, opts) { + return new ImportInjector(path).addSideEffect(importedSource, opts); +} diff --git a/packages/babel-helper-module-imports/src/is-module.js b/packages/babel-helper-module-imports/src/is-module.js new file mode 100644 index 0000000000..8e20fb2472 --- /dev/null +++ b/packages/babel-helper-module-imports/src/is-module.js @@ -0,0 +1,31 @@ +/** + * A small utility to check if a file qualifies as a module, based on a few + * possible conditions. + */ +export default function isModule( + path: NodePath, + requireUnambiguous: boolean = false, +) { + const { sourceType } = path.node; + if (sourceType !== "module" && sourceType !== "script") { + throw path.buildCodeFrameError( + `Unknown sourceType "${sourceType}", cannot transform.`, + ); + } + + const filename = path.hub.file.opts.filename; + if (/\.mjs$/.test(filename)) { + requireUnambiguous = false; + } + + return ( + path.node.sourceType === "module" && + (!requireUnambiguous || isUnambiguousModule(path)) + ); +} + +// This approach is not ideal. It is here to preserve compatibility for now, +// but really this should just return true or be deleted. +function isUnambiguousModule(path) { + return path.get("body").some(p => p.isModuleDeclaration()); +} diff --git a/packages/babel-helper-module-imports/test/index.js b/packages/babel-helper-module-imports/test/index.js new file mode 100644 index 0000000000..c60490da1c --- /dev/null +++ b/packages/babel-helper-module-imports/test/index.js @@ -0,0 +1,1100 @@ +import chai from "chai"; +import * as babel from "babel-core"; + +import { ImportInjector } from "../"; + +function test(sourceType, opts, initializer, expectedCode) { + if (typeof opts === "function") { + expectedCode = initializer; + initializer = opts; + opts = null; + } + + const result = babel.transform("", { + sourceType, + filename: "example" + (sourceType === "module" ? ".mjs" : ".js"), + babelrc: false, + plugins: [ + function({ types: t }) { + return { + pre(file) { + file.set("helpersNamespace", t.identifier("babelHelpers")); + }, + visitor: { + Program(path) { + const manager = new ImportInjector(path, opts); + + const ref = initializer(manager); + if (ref) path.pushContainer("body", t.expressionStatement(ref)); + }, + }, + }; + }, + ], + }); + + chai + .expect(result.code.replace(/\s+/g, " ").trim()) + .to.equal((expectedCode || "").replace(/\s+/g, " ").trim()); +} +const testScript = test.bind(undefined, "script"); +const testModule = test.bind(undefined, "module"); + +describe("babel-helper-module-imports", () => { + describe("namespace import", () => { + const addNamespace = opts => m => m.addNamespace("source", opts); + + describe("loading an ES6 module", () => { + const importedType = "es6"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedType }, + addNamespace(), + ` + import * as _namespace from "source"; + _namespace; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedType }, + addNamespace(), + ` + import * as _namespace from "source"; + _namespace; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + chai + .expect(() => { + testScript({ importedType }, addNamespace()); + }) + .to.throw(Error, "Cannot import an ES6 module from CommonJS"); + }); + }); + }); + + describe("loading CommonJS with 'uncompiled'", () => { + const importedInterop = "uncompiled"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamespace(), + ` + import _namespace from "source"; + _namespace; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamespace(), + ` + import _namespace from "source"; + _namespace; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addNamespace(), + ` + var _namespace = require("source"); + _namespace; + `, + ); + }); + }); + }); + + describe("loading CommonJS with 'compiled'", () => { + const importedInterop = "compiled"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamespace(), + ` + import _namespace from "source"; + _namespace; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamespace(), + ` + import * as _namespace from "source"; + _namespace; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addNamespace(), + ` + var _namespace = require("source"); + _namespace; + `, + ); + }); + }); + }); + + describe("loading CommonJS with 'babel'", () => { + const importedInterop = "babel"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamespace(), + ` + import _es6Default from "source"; + var _namespace = babelHelpers.interopRequireWildcard(_es6Default); + _namespace; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamespace(), + ` + import * as _namespace from "source"; + _namespace; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addNamespace(), + ` + var _namespace = babelHelpers.interopRequireWildcard(require("source")); + _namespace; + `, + ); + }); + }); + }); + }); + + describe("default imports", () => { + const addDefault = opts => m => m.addDefault("source", opts); + + describe("loading an ES6 module", () => { + const importedType = "es6"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedType }, + addDefault(), + ` + import _default from "source"; + _default; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedType }, + addDefault({ nameHint: "hintedName" }), + ` + import _hintedName from "source"; + _hintedName; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedType }, + addDefault(), + ` + import _default from "source"; + _default; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedType }, + addDefault({ nameHint: "hintedName" }), + ` + import _hintedName from "source"; + _hintedName; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + chai + .expect(() => { + testScript({ importedType }, addDefault()); + }) + .to.throw(Error, "Cannot import an ES6 module from CommonJS"); + }); + }); + }); + + describe("loading CommonJS with 'uncompiled'", () => { + const importedInterop = "uncompiled"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addDefault(), + ` + import _default from "source"; + _default; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedInterop }, + addDefault({ nameHint: "hintedName" }), + ` + import _hintedName from "source"; + _hintedName; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addDefault(), + ` + import _default from "source"; + _default; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedInterop }, + addDefault({ nameHint: "hintedName" }), + ` + import _hintedName from "source"; + _hintedName; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addDefault(), + ` + var _default = require("source"); + _default; + `, + ); + }); + + it("should import with a name hint", () => { + testScript( + { importedInterop }, + addDefault({ nameHint: "hintedName" }), + ` + var _hintedName = require("source"); + _hintedName; + `, + ); + }); + + it("should fail to import with force-enabled liveness", () => { + chai + .expect(() => { + testScript( + { importedInterop, ensureLiveReference: true }, + addDefault(), + ); + }) + .to.throw(Error, "No live reference for commonjs default"); + }); + }); + }); + + describe("loading CommonJS with 'compiled'", () => { + const importedInterop = "compiled"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addDefault(), + ` + import _namespace from "source"; + _namespace.default; + `, + ); + }); + + it("should import with a force-disabled context", () => { + testModule( + { importingInterop, importedInterop, ensureNoContext: true }, + addDefault(), + ` + import _namespace from "source"; + 0, _namespace.default; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addDefault(), + ` + import _default from "source"; + _default; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedInterop }, + addDefault({ nameHint: "hintedName" }), + ` + import _hintedName from "source"; + _hintedName; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addDefault(), + ` + var _default = require("source").default; + _default; + `, + ); + }); + + it("should import with a name hint", () => { + testScript( + { importedInterop }, + addDefault({ nameHint: "hintedName" }), + ` + var _hintedName = require("source").default; + _hintedName; + `, + ); + }); + + it("should import with force-enabled liveness", () => { + testScript( + { importedInterop, ensureLiveReference: true }, + addDefault(), + ` + var _namespace = require("source"); + _namespace.default; + `, + ); + }); + }); + }); + + describe("loading CommonJS with 'babel'", () => { + const importedInterop = "babel"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addDefault(), + ` + import _es6Default from "source"; + var _default = babelHelpers.interopRequireDefault(_es6Default).default; + _default; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedInterop }, + addDefault({ nameHint: "hintedName" }), + ` + import _es6Default from "source"; + var _hintedName = babelHelpers.interopRequireDefault(_es6Default).default; + _hintedName; + `, + ); + }); + + it("should import with force-enabled liveness", () => { + testModule( + { importingInterop, importedInterop, ensureLiveReference: true }, + addDefault(), + ` + import _es6Default from "source"; + var _namespace = babelHelpers.interopRequireDefault(_es6Default); + _namespace.default; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addDefault(), + ` + import _default from "source"; + _default; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedInterop }, + addDefault({ nameHint: "hintedName" }), + ` + import _hintedName from "source"; + _hintedName; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addDefault(), + ` + var _default = babelHelpers.interopRequireDefault(require("source")).default; + _default; + `, + ); + }); + + it("should import with a name hint", () => { + testScript( + { importedInterop }, + addDefault({ nameHint: "hintedName" }), + ` + var _hintedName = babelHelpers.interopRequireDefault(require("source")).default; + _hintedName; + `, + ); + }); + + it("should import with force-enabled liveness", () => { + testScript( + { importedInterop, ensureLiveReference: true }, + addDefault(), + ` + var _namespace = babelHelpers.interopRequireDefault(require("source")); + _namespace.default; + `, + ); + }); + }); + }); + }); + + describe("named imports", () => { + const addNamed = opts => m => m.addNamed("read", "source", opts); + + describe("loading an ES6 module", () => { + const importedType = "es6"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedType }, + addNamed(), + ` + import { read as _read } from "source"; + _read; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedType }, + addNamed({ nameHint: "hintedName" }), + ` + import { read as _hintedName } from "source"; + _hintedName; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedType }, + addNamed(), + ` + import { read as _read } from "source"; + _read; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedType }, + addNamed({ nameHint: "hintedName" }), + ` + import { read as _hintedName } from "source"; + _hintedName; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + chai + .expect(() => { + testScript({ importedType }, addNamed()); + }) + .to.throw(Error, "Cannot import an ES6 module from CommonJS"); + }); + }); + }); + + describe("loading CommonJS with 'uncompiled'", () => { + const importedInterop = "uncompiled"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamed(), + ` + import _namespace from "source"; + _namespace.read; + `, + ); + }); + + it("should import with a force-disabled context", () => { + testModule( + { importingInterop, importedInterop, ensureNoContext: true }, + addNamed(), + ` + import _namespace from "source"; + 0, _namespace.read; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamed(), + ` + import { read as _read } from "source"; + _read; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedInterop }, + addNamed({ nameHint: "hintedName" }), + ` + import { read as _hintedName } from "source"; + _hintedName; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addNamed(), + ` + var _read = require("source").read; + _read; + `, + ); + }); + + it("should import with a name hint", () => { + testScript( + { importedInterop }, + addNamed({ nameHint: "hintedName" }), + ` + var _hintedName = require("source").read; + _hintedName; + `, + ); + }); + + it("should import with force-enabled liveness", () => { + testScript( + { importedInterop, ensureLiveReference: true }, + addNamed(), + ` + var _namespace = require("source"); + _namespace.read; + `, + ); + }); + }); + }); + + describe("loading CommonJS with 'compiled'", () => { + const importedInterop = "compiled"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamed(), + ` + import _namespace from "source"; + _namespace.read; + `, + ); + }); + + it("should import with a force-disabled context", () => { + testModule( + { importingInterop, importedInterop, ensureNoContext: true }, + addNamed(), + ` + import _namespace from "source"; + 0, _namespace.read; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamed(), + ` + import { read as _read } from "source"; + _read; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedInterop }, + addNamed({ nameHint: "hintedName" }), + ` + import { read as _hintedName } from "source"; + _hintedName; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addNamed(), + ` + var _read = require("source").read; + _read; + `, + ); + }); + + it("should import with a name hint", () => { + testScript( + { importedInterop }, + addNamed({ nameHint: "hintedName" }), + ` + var _hintedName = require("source").read; + _hintedName; + `, + ); + }); + + it("should import with force-enabled liveness", () => { + testScript( + { importedInterop, ensureLiveReference: true }, + addNamed(), + ` + var _namespace = require("source"); + _namespace.read; + `, + ); + }); + }); + }); + + describe("loading CommonJS with 'babel'", () => { + const importedInterop = "babel"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamed(), + ` + import _es6Default from "source"; + _es6Default.read; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addNamed(), + ` + import { read as _read } from "source"; + _read; + `, + ); + }); + + it("should import with a name hint", () => { + testModule( + { importingInterop, importedInterop }, + addNamed({ nameHint: "hintedName" }), + ` + import { read as _hintedName } from "source"; + _hintedName; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addNamed(), + ` + var _read = require("source").read; + _read; + `, + ); + }); + + it("should import with a name hint", () => { + testScript( + { importedInterop }, + addNamed({ nameHint: "hintedName" }), + ` + var _hintedName = require("source").read; + _hintedName; + `, + ); + }); + + it("should import with force-enabled liveness", () => { + testScript( + { importedInterop, ensureLiveReference: true }, + addNamed(), + ` + var _namespace = require("source"); + _namespace.read; + `, + ); + }); + }); + }); + }); + + describe("side-effectful imports", () => { + const addSideEffect = opts => m => m.addSideEffect("source", opts); + + describe("loading an ES6 module", () => { + const importedType = "es6"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedType }, + addSideEffect(), + ` + import "source"; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedType }, + addSideEffect(), + ` + import "source"; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + chai + .expect(() => { + testScript({ importedType }, addSideEffect()); + }) + .to.throw(Error, "Cannot import an ES6 module from CommonJS"); + }); + }); + }); + + describe("loading CommonJS with 'uncompiled'", () => { + const importedInterop = "uncompiled"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addSideEffect(), + ` + import "source"; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addSideEffect(), + ` + import "source"; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addSideEffect(), + ` + require("source"); + `, + ); + }); + }); + }); + + describe("loading CommonJS with 'compiled'", () => { + const importedInterop = "compiled"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addSideEffect(), + ` + import "source"; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addSideEffect(), + ` + import "source"; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addSideEffect(), + ` + require("source"); + `, + ); + }); + }); + }); + + describe("loading CommonJS with 'babel'", () => { + const importedInterop = "babel"; + + describe("using Node's interop", () => { + const importingInterop = "node"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addSideEffect(), + ` + import "source"; + `, + ); + }); + }); + + describe("using Babel's interop", () => { + const importingInterop = "babel"; + + it("should import", () => { + testModule( + { importingInterop, importedInterop }, + addSideEffect(), + ` + import "source"; + `, + ); + }); + }); + + describe("using a CommonJS loader", () => { + it("should import", () => { + testScript( + { importedInterop }, + addSideEffect(), + ` + require("source"); + `, + ); + }); + }); + }); + }); +}); diff --git a/packages/babel-helper-module-transforms/package.json b/packages/babel-helper-module-transforms/package.json index 86b75232a9..f989c44eee 100644 --- a/packages/babel-helper-module-transforms/package.json +++ b/packages/babel-helper-module-transforms/package.json @@ -8,6 +8,7 @@ "repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-module-transforms", "main": "lib/index.js", "dependencies": { + "babel-helper-module-imports": "7.0.0-beta.2", "babel-template": "7.0.0-beta.2", "babel-types": "7.0.0-beta.2", "lodash": "^4.2.0" diff --git a/packages/babel-helper-module-transforms/src/index.js b/packages/babel-helper-module-transforms/src/index.js index f868c01fc3..0055273bc5 100644 --- a/packages/babel-helper-module-transforms/src/index.js +++ b/packages/babel-helper-module-transforms/src/index.js @@ -3,6 +3,8 @@ import * as t from "babel-types"; import template from "babel-template"; import chunk from "lodash/chunk"; +import { isModule } from "babel-helper-module-imports"; + import rewriteThis from "./rewrite-this"; import rewriteLiveReferences from "./rewrite-live-references"; import normalizeAndLoadModuleMetadata, { @@ -10,32 +12,7 @@ import normalizeAndLoadModuleMetadata, { isSideEffectImport, } from "./normalize-and-load-metadata"; -export { hasExports, isSideEffectImport }; - -export function isModule(path: NodePath, requireUnambiguous: boolean = false) { - const { sourceType } = path.node; - if (sourceType !== "module" && sourceType !== "script") { - throw path.buildCodeFrameError( - `Unknown sourceType "${sourceType}", cannot transform.`, - ); - } - - const filename = path.hub.file.opts.filename; - if (/\.mjs$/.test(filename)) { - requireUnambiguous = false; - } - - return ( - path.node.sourceType === "module" && - (!requireUnambiguous || isUnambiguousModule(path)) - ); -} - -// This approach is not ideal. It is here to preserve compatibility for now, -// but really this should just return true or be deleted. -function isUnambiguousModule(path) { - return path.get("body").some(p => p.isModuleDeclaration()); -} +export { hasExports, isSideEffectImport, isModule }; /** * Perform all of the generic ES6 module rewriting needed to handle initial diff --git a/packages/babel-helpers/src/index.js b/packages/babel-helpers/src/index.js index 8f067fc137..d71d11dfae 100644 --- a/packages/babel-helpers/src/index.js +++ b/packages/babel-helpers/src/index.js @@ -157,10 +157,14 @@ function permuteHelperAST(file, metadata, id, localBindings) { exp.replaceWith(decl); path.pushContainer( "body", - t.assignmentExpression("=", id, t.identifier(exportName)), + t.expressionStatement( + t.assignmentExpression("=", id, t.identifier(exportName)), + ), ); } else { - exp.replaceWith(t.assignmentExpression("=", id, decl.node)); + exp.replaceWith( + t.expressionStatement(t.assignmentExpression("=", id, decl.node)), + ); } } else { throw new Error("Unexpected helper format."); diff --git a/packages/babel-plugin-transform-async-to-module-method/package.json b/packages/babel-plugin-transform-async-to-module-method/package.json index b05dbf0498..2821e0c377 100644 --- a/packages/babel-plugin-transform-async-to-module-method/package.json +++ b/packages/babel-plugin-transform-async-to-module-method/package.json @@ -10,6 +10,7 @@ ], "dependencies": { "babel-helper-remap-async-to-generator": "7.0.0-beta.2", + "babel-helper-module-imports": "7.0.0-beta.2", "babel-plugin-syntax-async-functions": "7.0.0-beta.0", "babel-types": "7.0.0-beta.2" }, diff --git a/packages/babel-plugin-transform-async-to-module-method/src/index.js b/packages/babel-plugin-transform-async-to-module-method/src/index.js index 1eda016ef5..d32f9b0a89 100644 --- a/packages/babel-plugin-transform-async-to-module-method/src/index.js +++ b/packages/babel-plugin-transform-async-to-module-method/src/index.js @@ -1,7 +1,9 @@ import remapAsyncToGenerator from "babel-helper-remap-async-to-generator"; import syntaxAsyncFunctions from "babel-plugin-syntax-async-functions"; -export default function() { +import { addNamed } from "babel-helper-module-imports"; + +export default function({ types: t }) { return { inherits: syntaxAsyncFunctions, @@ -9,8 +11,17 @@ export default function() { Function(path, state) { if (!path.node.async || path.node.generator) return; + const { module, method } = state.opts; + + let wrapAsync = state.methodWrapper; + if (wrapAsync) { + wrapAsync = t.cloneDeep(wrapAsync); + } else { + wrapAsync = state.methodWrapper = addNamed(path, method, module); + } + remapAsyncToGenerator(path, state.file, { - wrapAsync: state.addImport(state.opts.module, state.opts.method), + wrapAsync, }); }, }, diff --git a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/arrow-function/expected.js b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/arrow-function/expected.js index fd2485114e..a5e45c929d 100644 --- a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/arrow-function/expected.js +++ b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/arrow-function/expected.js @@ -1,4 +1,4 @@ -import { coroutine as _coroutine } from "bluebird"; +var _coroutine = require("bluebird").coroutine; _coroutine(function* () { yield foo(); diff --git a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/class/expected.js b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/class/expected.js index 2bcbd54c95..c169c87cce 100644 --- a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/class/expected.js +++ b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/class/expected.js @@ -1,4 +1,4 @@ -import { coroutine as _coroutine } from "bluebird"; +var _coroutine = require("bluebird").coroutine; class Foo { foo() { diff --git a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/expression/expected.js b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/expression/expected.js index 168d702dc6..e347008cbb 100644 --- a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/expression/expected.js +++ b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/expression/expected.js @@ -1,4 +1,4 @@ -import { coroutine as _coroutine } from "bluebird"; +var _coroutine = require("bluebird").coroutine; var foo = (() => { var _ref = _coroutine(function* () { diff --git a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/named-expression/expected.js b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/named-expression/expected.js index 640f0f576b..d3bfbda8a3 100644 --- a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/named-expression/expected.js +++ b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/named-expression/expected.js @@ -1,4 +1,4 @@ -import { coroutine as _coroutine } from "bluebird"; +var _coroutine = require("bluebird").coroutine; var foo = (() => { var _ref = _coroutine(function* () { diff --git a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/statement/expected.js b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/statement/expected.js index ecbbba1715..c5dc8a29ef 100644 --- a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/statement/expected.js +++ b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/statement/expected.js @@ -1,4 +1,4 @@ -import { coroutine as _coroutine } from "bluebird"; +var _coroutine = require("bluebird").coroutine; let foo = (() => { var _ref = _coroutine(function* () { diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/imports-hoisting/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/imports-hoisting/expected.js index c48d60f6e2..03d6a86460 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/imports-hoisting/expected.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/imports-hoisting/expected.js @@ -1,9 +1,5 @@ -"use strict"; +var _taggedTemplateLiteral = require("babel-runtime/helpers/taggedTemplateLiteral"); -var _taggedTemplateLiteral2 = _interopRequireDefault(require("babel-runtime/helpers/taggedTemplateLiteral")); - -var _templateObject = (0, _taggedTemplateLiteral2.default)(["foo"], ["foo"]); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _templateObject = _taggedTemplateLiteral(["foo"], ["foo"]); tag(_templateObject); diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/actual.js new file mode 100644 index 0000000000..c21dca024a --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/actual.js @@ -0,0 +1,3 @@ +export {}; + +console.log(helper); diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/expected.js new file mode 100644 index 0000000000..9a77982e45 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/expected.js @@ -0,0 +1,7 @@ +"use strict"; + +var _interopRequireDefault3 = require("babel-runtime/helpers/interopRequireDefault"); + +var _interopRequireDefault2 = _interopRequireDefault3(require("babel-runtime/helpers/interopRequireDefault")); + +console.log(_interopRequireDefault2.default); diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/options.json b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/options.json new file mode 100644 index 0000000000..a967c87acd --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "transform-es2015-modules-commonjs", + "transform-runtime", + "./plugin" + ] +} diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/plugin.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/plugin.js new file mode 100644 index 0000000000..22a13dab2d --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/multi-load/plugin.js @@ -0,0 +1,11 @@ +module.exports = function() { + return { + visitor: { + Identifier: function(path) { + if (path.node.name !== "helper") return; + + path.replaceWith(this.addHelper("interopRequireDefault")); + }, + }, + }; +}; diff --git a/packages/babel-plugin-transform-regenerator/test/fixtures/regression/T7041/expected.js b/packages/babel-plugin-transform-regenerator/test/fixtures/regression/T7041/expected.js index a92d32a6a9..ca7c85f631 100644 --- a/packages/babel-plugin-transform-regenerator/test/fixtures/regression/T7041/expected.js +++ b/packages/babel-plugin-transform-regenerator/test/fixtures/regression/T7041/expected.js @@ -1,19 +1,15 @@ -"use strict"; +var _regeneratorRuntime = require("babel-runtime/regenerator"); -var _regenerator = _interopRequireDefault(require("babel-runtime/regenerator")); - -var _keys = _interopRequireDefault(require("babel-runtime/core-js/object/keys")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _Object$keys = require("babel-runtime/core-js/object/keys"); var _marked = /*#__PURE__*/ -_regenerator.default.mark(fn); +_regeneratorRuntime.mark(fn); -(0, _keys.default)({}); +_Object$keys({}); function fn() { - return _regenerator.default.wrap(function fn$(_context) { + return _regeneratorRuntime.wrap(function fn$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: diff --git a/packages/babel-plugin-transform-runtime/package.json b/packages/babel-plugin-transform-runtime/package.json index c153cba2ff..0ec49afe6f 100644 --- a/packages/babel-plugin-transform-runtime/package.json +++ b/packages/babel-plugin-transform-runtime/package.json @@ -8,6 +8,9 @@ "keywords": [ "babel-plugin" ], + "dependencies": { + "babel-helper-module-imports": "7.0.0-beta.2" + }, "devDependencies": { "babel-helper-plugin-test-runner": "7.0.0-beta.2" } diff --git a/packages/babel-plugin-transform-runtime/src/index.js b/packages/babel-plugin-transform-runtime/src/index.js index bc327ab90a..ed830e7b8d 100644 --- a/packages/babel-plugin-transform-runtime/src/index.js +++ b/packages/babel-plugin-transform-runtime/src/index.js @@ -1,3 +1,5 @@ +import { addDefault, isModule } from "babel-helper-module-imports"; + import definitions from "./definitions"; export default function({ types: t }) { @@ -9,7 +11,7 @@ export default function({ types: t }) { return Object.prototype.hasOwnProperty.call(obj, key); } - const HELPER_BLACKLIST = ["interopRequireWildcard", "interopRequireDefault"]; + const HEADER_HELPERS = ["interopRequireWildcard", "interopRequireDefault"]; return { pre(file) { @@ -22,14 +24,20 @@ export default function({ types: t }) { const helpersDir = this.opts.useESModules ? `${baseHelpersDir}/es6` : baseHelpersDir; - file.set("helperGenerator", function(name) { - if (HELPER_BLACKLIST.indexOf(name) < 0) { - return file.addImport( - `${moduleName}/${helpersDir}/${name}`, - "default", - name, - ); - } + file.set("helperGenerator", name => { + const isInteropHelper = HEADER_HELPERS.indexOf(name) !== -1; + + // Explicitly set the CommonJS interop helpers to their reserve + // blockHoist of 4 so they are guaranteed to exist + // when other things used them to import. + const blockHoist = + isInteropHelper && !isModule(file.path) ? 4 : undefined; + + return this.addDefaultImport( + `${moduleName}/${helpersDir}/${name}`, + name, + blockHoist, + ); }); } @@ -40,6 +48,30 @@ export default function({ types: t }) { } this.moduleName = moduleName; + + const cache = new Map(); + + this.addDefaultImport = (source, nameHint, blockHoist) => { + // If something on the page adds a helper when the file is an ES6 + // file, we can't reused the cached helper name after things have been + // transformed because it has almost certainly been renamed. + const cacheKey = isModule(file.path); + const key = `${source}:${nameHint}:${cacheKey || ""}`; + + let cached = cache.get(key); + if (cached) { + cached = t.cloneDeep(cached); + } else { + cached = addDefault(file.path, source, { + importedInterop: "uncompiled", + nameHint, + blockHoist, + }); + + cache.set(key, cached); + } + return cached; + }; }, visitor: { @@ -50,9 +82,8 @@ export default function({ types: t }) { state.opts.regenerator !== false ) { path.replaceWith( - this.file.addImport( + this.addDefaultImport( `${this.moduleName}/regenerator`, - "default", "regeneratorRuntime", ), ); @@ -68,9 +99,8 @@ export default function({ types: t }) { // Symbol() -> _core.Symbol(); new Promise -> new _core.Promise const moduleName = getRuntimeModuleName(state.opts); path.replaceWith( - state.addImport( + this.addDefaultImport( `${moduleName}/core-js/${definitions.builtins[node.name]}`, - "default", node.name, ), ); @@ -93,9 +123,8 @@ export default function({ types: t }) { const moduleName = getRuntimeModuleName(state.opts); path.replaceWith( t.callExpression( - state.addImport( + this.addDefaultImport( `${moduleName}/core-js/get-iterator`, - "default", "getIterator", ), [callee.object], @@ -113,9 +142,8 @@ export default function({ types: t }) { const moduleName = getRuntimeModuleName(state.opts); path.replaceWith( t.callExpression( - state.addImport( + this.addDefaultImport( `${moduleName}/core-js/is-iterable`, - "default", "isIterable", ), [path.node.right], @@ -157,9 +185,8 @@ export default function({ types: t }) { const moduleName = getRuntimeModuleName(state.opts); path.replaceWith( - state.addImport( + this.addDefaultImport( `${moduleName}/core-js/${methods[prop.name]}`, - "default", `${obj.name}$${prop.name}`, ), ); @@ -178,9 +205,8 @@ export default function({ types: t }) { const moduleName = getRuntimeModuleName(state.opts); path.replaceWith( t.memberExpression( - state.addImport( + this.addDefaultImport( `${moduleName}/core-js/${definitions.builtins[obj.name]}`, - "default", obj.name, ), node.property, diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/aliased-constructors/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/aliased-constructors/expected.js index 1cb089296d..d8b89dcd68 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/aliased-constructors/expected.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/aliased-constructors/expected.js @@ -1,6 +1,9 @@ -import _Map from "babel-runtime/core-js/map"; -import _Symbol from "babel-runtime/core-js/symbol"; -import _Promise from "babel-runtime/core-js/promise"; +var _Map = require("babel-runtime/core-js/map"); + +var _Symbol = require("babel-runtime/core-js/symbol"); + +var _Promise = require("babel-runtime/core-js/promise"); + obj.constructor === Object; obj.constructor === _Promise; diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/catch-all/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/catch-all/expected.js index 97b8bf8e3b..df0e29ed23 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/catch-all/expected.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/catch-all/expected.js @@ -1,2 +1,3 @@ -import _Promise from "babel-runtime/core-js/promise"; +var _Promise = require("babel-runtime/core-js/promise"); + _Promise.resolve; diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/class/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/class/expected.js index 698463f783..f9d5e22905 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/class/expected.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/class/expected.js @@ -1,4 +1,4 @@ -import _classCallCheck from "babel-runtime/helpers/classCallCheck"; +var _classCallCheck = require("babel-runtime/helpers/classCallCheck"); let Foo = function Foo() { _classCallCheck(this, Foo); diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/expected.js index 838e15fd3d..df86703577 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/expected.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/es6-for-of/expected.js @@ -1,4 +1,5 @@ -import _getIterator from "babel-runtime/core-js/get-iterator"; +var _getIterator = require("babel-runtime/core-js/get-iterator"); + var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules-helpers/actual.mjs b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules-helpers/actual.mjs new file mode 100644 index 0000000000..368b106310 --- /dev/null +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules-helpers/actual.mjs @@ -0,0 +1,5 @@ +import foo from "foo"; + +class Example { + method() {} +} diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules-helpers/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules-helpers/expected.js new file mode 100644 index 0000000000..a49ec5c3fb --- /dev/null +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules-helpers/expected.js @@ -0,0 +1,23 @@ +"use strict"; + +var _interopRequireDefault = require("babel-runtime/helpers/interopRequireDefault"); + +var _classCallCheck2 = _interopRequireDefault(require("babel-runtime/helpers/classCallCheck")); + +var _createClass2 = _interopRequireDefault(require("babel-runtime/helpers/createClass")); + +var _foo = _interopRequireDefault(require("foo")); + +let Example = +/*#__PURE__*/ +function () { + function Example() { + (0, _classCallCheck2.default)(this, Example); + } + + (0, _createClass2.default)(Example, [{ + key: "method", + value: function method() {} + }]); + return Example; +}(); diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules-helpers/options.json b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules-helpers/options.json new file mode 100644 index 0000000000..304a7fdde2 --- /dev/null +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules-helpers/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "transform-runtime", + "transform-es2015-modules-commonjs", + "transform-es2015-classes" + ] +} diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/actual.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/actual.js index 5847dc2875..ce4c7df806 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/actual.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/actual.js @@ -1,2 +1,4 @@ import foo from "bar"; foo; + +export * from "mod"; diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/expected.js index bbd4e001f8..76f4b638cc 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/expected.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/expected.js @@ -1,7 +1,28 @@ "use strict"; +var _interopRequireDefault = require("babel-runtime/helpers/interopRequireDefault"); + +var _Object$defineProperty = require("babel-runtime/core-js/object/define-property"); + +var _Object$keys = require("babel-runtime/core-js/object/keys"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); + var _bar = _interopRequireDefault(require("bar")); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _mod = require("mod"); + +_Object$keys(_mod).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + + _Object$defineProperty(exports, key, { + enumerable: true, + get: function () { + return _mod[key]; + } + }); +}); _bar.default; diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/regenerator-runtime/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/regenerator-runtime/expected.js index a5046aeb3b..7a950eeb9e 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/regenerator-runtime/expected.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/regenerator-runtime/expected.js @@ -1,4 +1,5 @@ -import _regeneratorRuntime from "babel-runtime/regenerator"; +var _regeneratorRuntime = require("babel-runtime/regenerator"); + void /*#__PURE__*/ _regeneratorRuntime.mark(function _callee() { diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/symbol-iterator-in/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/symbol-iterator-in/expected.js index 97b293263d..3f88e54f37 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/symbol-iterator-in/expected.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/symbol-iterator-in/expected.js @@ -1,3 +1,3 @@ -import _isIterable from "babel-runtime/core-js/is-iterable"; +var _isIterable = require("babel-runtime/core-js/is-iterable"); _isIterable(Object(arr)); diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/symbol-iterator/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/symbol-iterator/expected.js index 5b72708826..938c68f556 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/symbol-iterator/expected.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/symbol-iterator/expected.js @@ -1,2 +1,3 @@ -import _Symbol$iterator from "babel-runtime/core-js/symbol/iterator"; +var _Symbol$iterator = require("babel-runtime/core-js/symbol/iterator"); + _Symbol$iterator; diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useBuiltIns-useESModules/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useBuiltIns-useESModules/expected.js index 17c83a4dc1..b36e987aaf 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useBuiltIns-useESModules/expected.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useBuiltIns-useESModules/expected.js @@ -1,6 +1,8 @@ -import _classCallCheck from "babel-runtime/helpers/builtin/es6/classCallCheck"; -import _possibleConstructorReturn from "babel-runtime/helpers/builtin/es6/possibleConstructorReturn"; -import _inherits from "babel-runtime/helpers/builtin/es6/inherits"; +var _classCallCheck = require("babel-runtime/helpers/builtin/es6/classCallCheck"); + +var _possibleConstructorReturn = require("babel-runtime/helpers/builtin/es6/possibleConstructorReturn"); + +var _inherits = require("babel-runtime/helpers/builtin/es6/inherits"); let Foo = /*#__PURE__*/ diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useBuiltIns/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useBuiltIns/expected.js index 6213695eff..b8667cfcb5 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useBuiltIns/expected.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useBuiltIns/expected.js @@ -1,6 +1,8 @@ -import _classCallCheck from "babel-runtime/helpers/builtin/classCallCheck"; -import _possibleConstructorReturn from "babel-runtime/helpers/builtin/possibleConstructorReturn"; -import _inherits from "babel-runtime/helpers/builtin/inherits"; +var _classCallCheck = require("babel-runtime/helpers/builtin/classCallCheck"); + +var _possibleConstructorReturn = require("babel-runtime/helpers/builtin/possibleConstructorReturn"); + +var _inherits = require("babel-runtime/helpers/builtin/inherits"); let Foo = /*#__PURE__*/ diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useESModules/expected.js b/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useESModules/expected.js index 4c28b4f76e..b12682a0e3 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useESModules/expected.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/use-options/useESModules/expected.js @@ -1,7 +1,10 @@ -import _Object$getPrototypeOf from "babel-runtime/core-js/object/get-prototype-of"; -import _classCallCheck from "babel-runtime/helpers/es6/classCallCheck"; -import _possibleConstructorReturn from "babel-runtime/helpers/es6/possibleConstructorReturn"; -import _inherits from "babel-runtime/helpers/es6/inherits"; +var _Object$getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of"); + +var _classCallCheck = require("babel-runtime/helpers/es6/classCallCheck"); + +var _possibleConstructorReturn = require("babel-runtime/helpers/es6/possibleConstructorReturn"); + +var _inherits = require("babel-runtime/helpers/es6/inherits"); let Foo = /*#__PURE__*/ diff --git a/packages/babel-runtime/core-js.js b/packages/babel-runtime/core-js.js index 7d5664380a..709f7e3252 100644 --- a/packages/babel-runtime/core-js.js +++ b/packages/babel-runtime/core-js.js @@ -1,4 +1 @@ -module.exports = { - "default": require("core-js/library"), - __esModule: true -}; +module.exports = require("core-js/library"); diff --git a/packages/babel-runtime/core-js/map.js b/packages/babel-runtime/core-js/map.js index ed02186fe6..7dd2ac72c6 100644 --- a/packages/babel-runtime/core-js/map.js +++ b/packages/babel-runtime/core-js/map.js @@ -1 +1 @@ -module.exports = { "default": require("core-js/library/fn/map"), __esModule: true }; \ No newline at end of file +module.exports = require("core-js/library/fn/map"); \ No newline at end of file diff --git a/packages/babel-runtime/helpers/builtin/toArray.js b/packages/babel-runtime/helpers/builtin/toArray.js index 96df336ff8..97107ebfeb 100644 --- a/packages/babel-runtime/helpers/builtin/toArray.js +++ b/packages/babel-runtime/helpers/builtin/toArray.js @@ -1,6 +1,5 @@ -exports.__esModule = true; -exports.default = _toArray; - function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); -} \ No newline at end of file +} + +module.exports = _toArray; \ No newline at end of file diff --git a/packages/babel-runtime/helpers/toArray.js b/packages/babel-runtime/helpers/toArray.js index 8b61c3a119..6709feb464 100644 --- a/packages/babel-runtime/helpers/toArray.js +++ b/packages/babel-runtime/helpers/toArray.js @@ -1,10 +1,7 @@ -exports.__esModule = true; -exports.default = _toArray; - -var _from = _interopRequireDefault(require("../core-js/array/from")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _Array$from = require("../core-js/array/from"); function _toArray(arr) { - return Array.isArray(arr) ? arr : (0, _from.default)(arr); -} \ No newline at end of file + return Array.isArray(arr) ? arr : _Array$from(arr); +} + +module.exports = _toArray; \ No newline at end of file diff --git a/packages/babel-runtime/scripts/build-dist.js b/packages/babel-runtime/scripts/build-dist.js index f581bdb4a3..2fb365e94c 100644 --- a/packages/babel-runtime/scripts/build-dist.js +++ b/packages/babel-runtime/scripts/build-dist.js @@ -33,7 +33,7 @@ function relative(filename) { } function defaultify(name) { - return `module.exports = { "default": ${name}, __esModule: true };`; + return `module.exports = ${name};`; } function writeRootFile(filename, content) { @@ -57,14 +57,6 @@ function makeTransformOpts(modules, useBuiltIns) { ], ], }; - if (modules === "commonjs") { - opts.plugins.push([ - require("../../babel-plugin-transform-es2015-modules-commonjs"), - { loose: true, strictMode: false }, - ]); - } else if (modules !== false) { - throw new Error("Unsupported module type"); - } return opts; } @@ -104,8 +96,13 @@ function buildRuntimeRewritePlugin(relativePath, helperName) { } function buildHelper(helperName, modules, useBuiltIns) { - const tree = t.program(helpers.get(helperName).nodes, [], "module"); + const id = + modules === "commonjs" + ? t.memberExpression(t.identifier("module"), t.identifier("exports")) + : null; + const sourceType = modules === "commonjs" ? "script" : "module"; + const tree = t.program(helpers.get(helperName, id).nodes, [], sourceType); const transformOpts = makeTransformOpts(modules, useBuiltIns); const relative = useBuiltIns ? "../.." : "..";