diff --git a/experimental/babel-preset-env/src/use-built-ins-plugin.js b/experimental/babel-preset-env/src/use-built-ins-plugin.js index 098a344346..62c5f3246c 100644 --- a/experimental/babel-preset-env/src/use-built-ins-plugin.js +++ b/experimental/babel-preset-env/src/use-built-ins-plugin.js @@ -25,11 +25,27 @@ function getObjectString(node) { } export default function({ types: t }) { - function addImport(path, builtIn) { - if (builtIn) { + function addImport(path, builtIn, builtIns) { + if (builtIn && !builtIns.has(builtIn)) { + builtIns.add(builtIn); const importDec = t.importDeclaration([], t.stringLiteral(builtIn)); importDec._blockHoist = 3; - path.unshiftContainer("body", importDec); + const programPath = path.find(path => path.isProgram()); + programPath.unshiftContainer("body", importDec); + } + } + + function addUnsupported(path, polyfills, builtIn, builtIns) { + if (Array.isArray(builtIn)) { + for (const i of builtIn) { + if (polyfills.indexOf(i) !== -1) { + addImport(path, `core-js/modules/${i}`, builtIns); + } + } + } else { + if (polyfills.indexOf(builtIn) !== -1) { + addImport(path, `core-js/modules/${builtIn}`, builtIns); + } } } @@ -81,39 +97,19 @@ Please remove the call. } }); }, - // add polyfills - exit(path, state) { - for (const builtIn of Array.from(this.builtIns.keys()).reverse()) { - if (Array.isArray(builtIn)) { - for (const i of builtIn) { - // console.warn(i); - if (state.opts.polyfills.indexOf(i) !== -1) { - addImport(path, `core-js/modules/${i}`); - } - } - } else { - // console.warn(builtIn); - if (state.opts.polyfills.indexOf(builtIn) !== -1) { - addImport(path, `core-js/modules/${builtIn}`); - } - } - } - if (state.opts.regenerator && this.usesRegenerator) { - addImport(path, "babel-polyfill/regenerator-runtime/runtime"); - } - }, }, // Symbol() -> _core.Symbol(); // new Promise -> new _core.Promise - ReferencedIdentifier(path) { + ReferencedIdentifier(path, state) { const { node, parent, scope } = path; if (t.isMemberExpression(parent)) return; if (!has(definitions.builtins, node.name)) return; if (scope.getBindingIdentifier(node.name)) return; - this.builtIns.add(definitions.builtins[node.name]); + const builtIn = definitions.builtins[node.name]; + addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns); }, // Array.from -> _core.Array.from @@ -133,7 +129,8 @@ Please remove the call. if (has(definitions.staticMethods, obj.name)) { const staticMethods = definitions.staticMethods[obj.name]; if (has(staticMethods, prop.name)) { - this.builtIns.add(`${staticMethods[prop.name]}`); + const builtIn = staticMethods[prop.name]; + addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns); } } @@ -143,7 +140,8 @@ Please remove the call. has(definitions.instanceMethods, prop.name) ) { state.opts.debug && warnOnInstanceMethod(getObjectString(node)); - this.builtIns.add(definitions.instanceMethods[prop.name]); + const builtIn = definitions.instanceMethods[prop.name]; + addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns); } else if ( node.computed && t.isStringLiteral(prop) && @@ -151,12 +149,13 @@ Please remove the call. ) { state.opts.debug && warnOnInstanceMethod(`${obj.name}['${prop.value}']`); - this.builtIns.add(definitions.instanceMethods[prop.value]); + const builtIn = definitions.instanceMethods[prop.value]; + addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns); } }, // Symbol.match - exit(path) { + exit(path, state) { if (!path.isReferenced()) return; const { node } = path; @@ -165,7 +164,8 @@ Please remove the call. if (!has(definitions.builtins, obj.name)) return; if (path.scope.getBindingIdentifier(obj.name)) return; - this.builtIns.add(definitions.builtins[obj.name]); + const builtIn = definitions.builtins[obj.name]; + addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns); }, }, @@ -196,14 +196,22 @@ Please remove the call. `${path.parentPath.node.kind} { ${prop.name} } = ${obj.name}`, ); - this.builtIns.add(definitions.instanceMethods[prop.name]); + const builtIn = definitions.instanceMethods[prop.name]; + addUnsupported(path, state.opts.polyfills, builtIn, this.builtIns); } } }, - Function(path) { - if (path.node.generator || path.node.async) { + Function(path, state) { + if (!this.usesRegenerator && (path.node.generator || path.node.async)) { this.usesRegenerator = true; + if (state.opts.regenerator) { + addImport( + path, + "babel-polyfill/regenerator-runtime/runtime", + this.builtIns, + ); + } } }, }; diff --git a/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used-instance-methods/expected.js b/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used-instance-methods/expected.js index 277b6c4eb4..0d40369620 100644 --- a/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used-instance-methods/expected.js +++ b/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used-instance-methods/expected.js @@ -1,15 +1,15 @@ -import 'core-js/modules/es6.array.from'; -import 'core-js/modules/es6.map'; +import 'core-js/modules/es6.string.ends-with'; +import 'core-js/modules/es6.string.code-point-at'; +import 'core-js/modules/es6.string.starts-with'; +import 'core-js/modules/es7.string.pad-end'; +import 'core-js/modules/es7.string.pad-start'; +import 'core-js/modules/es6.array.fill'; +import 'core-js/modules/es6.array.find-index'; +import 'core-js/modules/es6.array.find'; import 'core-js/modules/es7.array.includes'; import 'core-js/modules/es6.string.includes'; -import 'core-js/modules/es6.array.find'; -import 'core-js/modules/es6.array.find-index'; -import 'core-js/modules/es6.array.fill'; -import 'core-js/modules/es7.string.pad-start'; -import 'core-js/modules/es7.string.pad-end'; -import 'core-js/modules/es6.string.starts-with'; -import 'core-js/modules/es6.string.code-point-at'; -import 'core-js/modules/es6.string.ends-with'; +import 'core-js/modules/es6.map'; +import 'core-js/modules/es6.array.from'; Array.from; // static function Map; // top level built-in diff --git a/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used/expected.js b/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used/expected.js index 7ac06f1451..270ecc6055 100644 --- a/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used/expected.js +++ b/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used/expected.js @@ -1,8 +1,8 @@ -import 'core-js/modules/es6.array.from'; -import 'core-js/modules/es6.map'; -import 'core-js/modules/es6.promise'; -import 'core-js/modules/es6.regexp.match'; import 'core-js/modules/es6.symbol'; +import 'core-js/modules/es6.regexp.match'; +import 'core-js/modules/es6.promise'; +import 'core-js/modules/es6.map'; +import 'core-js/modules/es6.array.from'; Array.from; // static method Map; // built-in new Promise(); // new builtin diff --git a/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used/options.json b/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used/options.json index 5d5e4fdd7a..b6301eb2a2 100644 --- a/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used/options.json +++ b/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/builtins-used/options.json @@ -2,8 +2,7 @@ "presets": [ ["../../../../lib", { "useBuiltIns": true, - "modules": false, - "debug": true + "modules": false }] ] } diff --git a/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/regenerator-used-async/expected.js b/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/regenerator-used-async/expected.js index 6a37297086..f344c60e6e 100644 --- a/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/regenerator-used-async/expected.js +++ b/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/regenerator-used-async/expected.js @@ -1,5 +1,5 @@ -import "babel-polyfill/regenerator-runtime/runtime"; import "core-js/modules/es6.promise"; +import "babel-polyfill/regenerator-runtime/runtime"; var a = function () { var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee() { diff --git a/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/test-modules-tranform/expected.js b/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/test-modules-tranform/expected.js index ba3fdf06cf..870ce94f5b 100644 --- a/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/test-modules-tranform/expected.js +++ b/experimental/babel-preset-env/test/fixtures/preset-options-add-used-built-ins/test-modules-tranform/expected.js @@ -1,4 +1,5 @@ "use strict"; -import "core-js/modules/es6.promise"; +require("core-js/modules/es6.promise"); + Promise; \ No newline at end of file diff --git a/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/options.json b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/options.json index bed44453eb..b05901e3e9 100644 --- a/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/options.json +++ b/experimental/babel-preset-env/test/fixtures/preset-options/exclude-built-ins/options.json @@ -5,7 +5,7 @@ "chrome": 55 }, "modules": false, - "useBuiltIns": true, + "useBuiltIns": "entry", "exclude": [ "es7.string.pad-start", "es7.string.pad-end", @@ -15,4 +15,4 @@ ] }] ] -} \ No newline at end of file +}