├── .npmignore ├── README.md ├── babel-helper-module-imports ├── .npmignore ├── README.md ├── lib │ ├── import-builder.js │ ├── import-injector.js │ ├── index.js │ └── is-module.js ├── package.json ├── src │ ├── import-builder.js │ ├── import-injector.js │ ├── index.js │ └── is-module.js └── test │ └── index.js ├── lib ├── definitions.js └── index.js ├── package.json ├── src ├── definitions.js ├── index.js └── options.json └── test ├── fixtures ├── runtime │ ├── aliased-constructors │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json │ ├── catch-all │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json │ ├── class │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json │ ├── custom-runtime │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json │ ├── es6-for-of │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json │ ├── full │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json │ ├── modules-helpers │ │ ├── actual.mjs │ │ ├── expected.js │ │ └── options.json │ ├── modules │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json │ ├── no-helpers │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json │ ├── regenerator-runtime │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json │ ├── symbol-iterator-in │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json │ └── symbol-iterator │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json └── use-options │ ├── useBuiltIns-useESModules │ ├── actual.js │ ├── expected.js │ └── options.json │ ├── useBuiltIns │ ├── actual.js │ ├── expected.js │ └── options.json │ └── useESModules │ ├── actual.js │ ├── expected.js │ └── options.json └── index.js /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | *.log 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # babel-plugin-transform-runtime 2 | 3 | > Externalise references to helpers and built-ins, automatically polyfilling your code without polluting globals. (This plugin is recommended in a library/tool) 4 | 5 | NOTE: Instance methods such as `"foobar".includes("foo")` will not work since that would require modification of existing built-ins (Use [`babel-polyfill`](http://babeljs.io/docs/usage/polyfill) for that). 6 | 7 | ## Why? 8 | 9 | Babel uses very small helpers for common functions such as `_extend`. By default this will be added to every file that requires it. This duplication is sometimes unnecessary, especially when your application is spread out over multiple files. 10 | 11 | This is where the `transform-runtime` plugin comes in: all of the helpers will reference the module `babel-runtime` to avoid duplication across your compiled output. The runtime will be compiled into your build. 12 | 13 | Another purpose of this transformer is to create a sandboxed environment for your code. If you use [babel-polyfill](http://babeljs.io/docs/usage/polyfill/) and the built-ins it provides such as `Promise`, `Set` and `Map`, those will pollute the global scope. While this might be ok for an app or a command line tool, it becomes a problem if your code is a library which you intend to publish for others to use or if you can't exactly control the environment in which your code will run. 14 | 15 | The transformer will alias these built-ins to `core-js` so you can use them seamlessly without having to require the polyfill. 16 | 17 | See the [technical details](#technical-details) section for more information on how this works and the types of transformations that occur. 18 | 19 | ## Installation 20 | 21 | **NOTE - Production vs. development dependencies** 22 | 23 | In most cases, you should install `babel-plugin-transform-runtime` as a development dependency (with `--save-dev`). 24 | 25 | ```sh 26 | npm install --save-dev babel-plugin-transform-runtime 27 | ``` 28 | 29 | and `babel-runtime` as a production dependency (with `--save`). 30 | 31 | ```sh 32 | npm install --save babel-runtime 33 | ``` 34 | 35 | The transformation plugin is typically used only in development, but the runtime itself will be depended on by your deployed/published code. See the examples below for more details. 36 | 37 | ## Usage 38 | 39 | ### Via `.babelrc` (Recommended) 40 | 41 | Add the following line to your `.babelrc` file: 42 | 43 | Without options: 44 | 45 | ```json 46 | { 47 | "plugins": ["transform-runtime"] 48 | } 49 | ``` 50 | 51 | With options: 52 | 53 | ```json 54 | { 55 | "plugins": [ 56 | ["transform-runtime", { 57 | "helpers": false, 58 | "polyfill": false, 59 | "regenerator": true, 60 | "moduleName": "babel-runtime" 61 | }] 62 | ] 63 | } 64 | ``` 65 | 66 | ### Via CLI 67 | 68 | ```sh 69 | babel --plugins transform-runtime script.js 70 | ``` 71 | 72 | ### Via Node API 73 | 74 | ```javascript 75 | require("babel-core").transform("code", { 76 | plugins: ["transform-runtime"] 77 | }); 78 | ``` 79 | 80 | ## Options 81 | 82 | ### `helpers` 83 | 84 | `boolean`, defaults to `true`. 85 | 86 | Toggles whether or not inlined Babel helpers (`classCallCheck`, `extends`, etc.) are replaced with calls to `moduleName`. 87 | 88 | For more information, see [Helper aliasing](#helper-aliasing). 89 | 90 | ### `polyfill` 91 | 92 | `boolean`, defaults to `true`. 93 | 94 | Toggles whether or not new built-ins (`Promise`, `Set`, `Map`, etc.) are transformed to use a non-global polluting polyfill. 95 | 96 | For more information, see [`core-js` aliasing](#core-js-aliasing). 97 | 98 | ### `regenerator` 99 | 100 | `boolean`, defaults to `true`. 101 | 102 | Toggles whether or not generator functions are transformed to use a regenerator runtime that does not pollute the global scope. 103 | 104 | For more information, see [Regenerator aliasing](#regenerator-aliasing). 105 | 106 | ### `moduleName` 107 | 108 | `string`, defaults to `"babel-runtime"`. 109 | 110 | Sets the name/path of the module used when importing helpers. 111 | 112 | Example: 113 | 114 | ```json 115 | { 116 | "moduleName": "flavortown/runtime" 117 | } 118 | ``` 119 | 120 | ```js 121 | import extends from 'flavortown/runtime/helpers/extends'; 122 | ``` 123 | 124 | ### `useBuiltIns` 125 | 126 | `boolean`, defaults to `false`. 127 | 128 | When enabled, the transform will use helpers that do not use _any_ polyfills 129 | from `core-js`. 130 | 131 | For example, here is the `instance` helper with `useBuiltIns` disabled: 132 | 133 | ```js 134 | exports.__esModule = true; 135 | 136 | var _hasInstance = require("../core-js/symbol/has-instance"); 137 | 138 | var _hasInstance2 = _interopRequireDefault(_hasInstance); 139 | 140 | var _symbol = require("../core-js/symbol"); 141 | 142 | var _symbol2 = _interopRequireDefault(_symbol); 143 | 144 | exports.default = function (left, right) { 145 | if (right != null && typeof _symbol2.default !== "undefined" && right[_hasInstance2.default]) { 146 | return right[_hasInstance2.default](left); 147 | } else { 148 | return left instanceof right; 149 | } 150 | }; 151 | 152 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 153 | ``` 154 | 155 | And, with it enabled: 156 | 157 | ```js 158 | exports.__esModule = true; 159 | 160 | exports.default = function (left, right) { 161 | if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { 162 | return right[Symbol.hasInstance](left); 163 | } else { 164 | return left instanceof right; 165 | } 166 | }; 167 | ``` 168 | 169 | ### `useESModules` 170 | 171 | `boolean`, defaults to `false`. 172 | 173 | When enabled, the transform will use helpers that do not get run through 174 | `transform-es2015-modules-commonjs`. This allows for smaller builds in module 175 | systems like webpack, since it doesn't need to preserve commonjs semantics. 176 | 177 | For example, here is the `classCallCheck` helper with `useESModules` disabled: 178 | 179 | ```js 180 | exports.__esModule = true; 181 | 182 | exports.default = function (instance, Constructor) { 183 | if (!(instance instanceof Constructor)) { 184 | throw new TypeError("Cannot call a class as a function"); 185 | } 186 | }; 187 | ``` 188 | 189 | And, with it enabled: 190 | 191 | ```js 192 | export default function (instance, Constructor) { 193 | if (!(instance instanceof Constructor)) { 194 | throw new TypeError("Cannot call a class as a function"); 195 | } 196 | } 197 | ``` 198 | 199 | ## Technical details 200 | 201 | The `runtime` transformer plugin does three things: 202 | 203 | * Automatically requires `babel-runtime/regenerator` when you use generators/async functions. 204 | * Automatically requires `babel-runtime/core-js` and maps ES6 static methods and built-ins. 205 | * Removes the inline Babel helpers and uses the module `babel-runtime/helpers` instead. 206 | 207 | What does this actually mean though? Basically, you can use built-ins such as `Promise`, `Set`, `Symbol`, etc., as well use all the Babel features that require a polyfill seamlessly, without global pollution, making it extremely suitable for libraries. 208 | 209 | Make sure you include `babel-runtime` as a dependency. 210 | 211 | ### Regenerator aliasing 212 | 213 | Whenever you use a generator function or async function: 214 | 215 | ```javascript 216 | function* foo() { 217 | 218 | } 219 | ``` 220 | 221 | the following is generated: 222 | 223 | ```javascript 224 | "use strict"; 225 | 226 | var _marked = [foo].map(regeneratorRuntime.mark); 227 | 228 | function foo() { 229 | return regeneratorRuntime.wrap(function foo$(_context) { 230 | while (1) { 231 | switch (_context.prev = _context.next) { 232 | case 0: 233 | case "end": 234 | return _context.stop(); 235 | } 236 | } 237 | }, _marked[0], this); 238 | } 239 | ``` 240 | 241 | This isn't ideal since it relies on the regenerator runtime being included, which 242 | pollutes the global scope. 243 | 244 | With the `runtime` transformer, however, it is compiled to: 245 | 246 | ```javascript 247 | "use strict"; 248 | 249 | var _regenerator = require("babel-runtime/regenerator"); 250 | 251 | var _regenerator2 = _interopRequireDefault(_regenerator); 252 | 253 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 254 | 255 | var _marked = [foo].map(_regenerator2.default.mark); 256 | 257 | function foo() { 258 | return _regenerator2.default.wrap(function foo$(_context) { 259 | while (1) { 260 | switch (_context.prev = _context.next) { 261 | case 0: 262 | case "end": 263 | return _context.stop(); 264 | } 265 | } 266 | }, _marked[0], this); 267 | } 268 | ``` 269 | 270 | This means that you can use the regenerator runtime without polluting your current environment. 271 | 272 | ### `core-js` aliasing 273 | 274 | Sometimes you may want to use new built-ins such as `Map`, `Set`, `Promise` etc. Your only way 275 | to use these is usually to include a globally polluting polyfill. 276 | 277 | What the `runtime` transformer does is transform the following: 278 | 279 | ```javascript 280 | var sym = Symbol(); 281 | 282 | var promise = new Promise; 283 | 284 | console.log(arr[Symbol.iterator]()); 285 | ``` 286 | 287 | into the following: 288 | 289 | ```javascript 290 | "use strict"; 291 | 292 | var _getIterator2 = require("babel-runtime/core-js/get-iterator"); 293 | 294 | var _getIterator3 = _interopRequireDefault(_getIterator2); 295 | 296 | var _promise = require("babel-runtime/core-js/promise"); 297 | 298 | var _promise2 = _interopRequireDefault(_promise); 299 | 300 | var _symbol = require("babel-runtime/core-js/symbol"); 301 | 302 | var _symbol2 = _interopRequireDefault(_symbol); 303 | 304 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 305 | 306 | var sym = (0, _symbol2.default)(); 307 | 308 | var promise = new _promise2.default(); 309 | 310 | console.log((0, _getIterator3.default)(arr)); 311 | ``` 312 | 313 | This means is that you can seamlessly use these native built-ins and static methods 314 | without worrying about where they come from. 315 | 316 | **NOTE:** Instance methods such as `"foobar".includes("foo")` will **not** work. 317 | 318 | ### Helper aliasing 319 | 320 | Usually Babel will place helpers at the top of your file to do common tasks to avoid 321 | duplicating the code around in the current file. Sometimes these helpers can get a 322 | little bulky and add unnecessary duplication across files. The `runtime` 323 | transformer replaces all the helper calls to a module. 324 | 325 | That means that the following code: 326 | 327 | ```javascript 328 | class Person { 329 | } 330 | ``` 331 | 332 | usually turns into: 333 | 334 | ```javascript 335 | "use strict"; 336 | 337 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 338 | 339 | var Person = function Person() { 340 | _classCallCheck(this, Person); 341 | }; 342 | ``` 343 | 344 | the `runtime` transformer however turns this into: 345 | 346 | ```javascript 347 | "use strict"; 348 | 349 | var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck"); 350 | 351 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); 352 | 353 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 354 | 355 | var Person = function Person() { 356 | (0, _classCallCheck3.default)(this, Person); 357 | }; 358 | ``` 359 | -------------------------------------------------------------------------------- /babel-helper-module-imports/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | *.log 4 | -------------------------------------------------------------------------------- /babel-helper-module-imports/README.md: -------------------------------------------------------------------------------- 1 | # babel-helper-module-imports 2 | 3 | ## Installation 4 | 5 | ```sh 6 | npm install babel-helper-module-imports --save 7 | ``` 8 | 9 | ## Usage 10 | 11 | ### `import "source"` 12 | 13 | ```js 14 | import { addSideEffect } from "babel-helper-module-imports"; 15 | addSideEffect(path, 'source'); 16 | ``` 17 | 18 | ### `import { named } from "source"` 19 | 20 | ```js 21 | import { addNamed } from "babel-helper-module-imports"; 22 | addNamed(path, 'named', 'source'); 23 | ``` 24 | 25 | ### `import { named as _hintedName } from "source"` 26 | 27 | ```js 28 | import { addNamed } from "babel-helper-module-imports"; 29 | addNamed(path, 'named', 'source', { nameHint: "hintedName" }); 30 | ``` 31 | 32 | ### `import _default from "source"` 33 | 34 | ```js 35 | import { addDefault } from "babel-helper-module-imports"; 36 | addDefault(path, 'source'); 37 | ``` 38 | 39 | ### `import hintedName from "source"` 40 | 41 | ```js 42 | import { addDefault } from "babel-helper-module-imports"; 43 | addDefault(path, 'source', { nameHint: "hintedName" }) 44 | ``` 45 | 46 | ### `import * as _namespace from "source"` 47 | 48 | ```js 49 | import { addNamespace } from "babel-helper-module-imports"; 50 | addNamespace(path, 'source'); 51 | ``` 52 | 53 | ## Examples 54 | 55 | ### Adding a named import 56 | 57 | ```js 58 | import { addNamed } from "babel-helper-module-imports"; 59 | 60 | export default function({ types: t }) { 61 | return { 62 | visitor: { 63 | ReferencedIdentifier(path) { 64 | let importName = this.importName; 65 | if (importName) { 66 | importName = t.cloneDeep(importName); 67 | } else { 68 | // require('bluebird').coroutine 69 | importName = this.importName = addNamed(path, 'coroutine', 'bluebird'); 70 | } 71 | 72 | path.replaceWith(importName); 73 | } 74 | }, 75 | }; 76 | } 77 | ``` 78 | -------------------------------------------------------------------------------- /babel-helper-module-imports/lib/import-builder.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | exports.__esModule = true; 4 | exports.default = undefined; 5 | 6 | var _assert = require("assert"); 7 | 8 | var _assert2 = _interopRequireDefault(_assert); 9 | 10 | var _babelTypes = require("babel-types"); 11 | 12 | var t = _interopRequireWildcard(_babelTypes); 13 | 14 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } 15 | 16 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 17 | 18 | var ImportBuilder = function () { 19 | function ImportBuilder(importedSource, scope, file) { 20 | this._statements = []; 21 | this._resultName = null; 22 | this._scope = null; 23 | this._file = null; 24 | this._scope = scope; 25 | this._file = file; 26 | this._importedSource = importedSource; 27 | } 28 | 29 | ImportBuilder.prototype.done = function done() { 30 | return { 31 | statements: this._statements, 32 | resultName: this._resultName 33 | }; 34 | }; 35 | 36 | ImportBuilder.prototype.import = function _import() { 37 | var importedSource = this._file.resolveModuleSource(this._importedSource); 38 | 39 | this._statements.push(t.importDeclaration([], t.stringLiteral(importedSource))); 40 | 41 | return this; 42 | }; 43 | 44 | ImportBuilder.prototype.require = function require() { 45 | var importedSource = this._file.resolveModuleSource(this._importedSource); 46 | 47 | this._statements.push(t.expressionStatement(t.callExpression(t.identifier("require"), [t.stringLiteral(importedSource)]))); 48 | 49 | return this; 50 | }; 51 | 52 | ImportBuilder.prototype.namespace = function namespace(name) { 53 | name = this._scope.generateUidIdentifier(name); 54 | var statement = this._statements[this._statements.length - 1]; 55 | (0, _assert2.default)(statement.type === "ImportDeclaration"); 56 | (0, _assert2.default)(statement.specifiers.length === 0); 57 | statement.specifiers = [t.importNamespaceSpecifier(name)]; 58 | this._resultName = t.clone(name); 59 | return this; 60 | }; 61 | 62 | ImportBuilder.prototype.default = function _default(name) { 63 | name = this._scope.generateUidIdentifier(name); 64 | var statement = this._statements[this._statements.length - 1]; 65 | (0, _assert2.default)(statement.type === "ImportDeclaration"); 66 | (0, _assert2.default)(statement.specifiers.length === 0); 67 | statement.specifiers = [t.importDefaultSpecifier(name)]; 68 | this._resultName = t.clone(name); 69 | return this; 70 | }; 71 | 72 | ImportBuilder.prototype.named = function named(name, importName) { 73 | if (importName === "default") return this.default(name); 74 | name = this._scope.generateUidIdentifier(name); 75 | var statement = this._statements[this._statements.length - 1]; 76 | (0, _assert2.default)(statement.type === "ImportDeclaration"); 77 | (0, _assert2.default)(statement.specifiers.length === 0); 78 | statement.specifiers = [t.importSpecifier(name, t.identifier(importName))]; 79 | this._resultName = t.clone(name); 80 | return this; 81 | }; 82 | 83 | ImportBuilder.prototype.var = function _var(name) { 84 | name = this._scope.generateUidIdentifier(name); 85 | var statement = this._statements[this._statements.length - 1]; 86 | 87 | if (statement.type !== "ExpressionStatement") { 88 | (0, _assert2.default)(this._resultName); 89 | statement = t.expressionStatement(this._resultName); 90 | 91 | this._statements.push(statement); 92 | } 93 | 94 | this._statements[this._statements.length - 1] = t.variableDeclaration("var", [t.variableDeclarator(name, statement.expression)]); 95 | this._resultName = t.clone(name); 96 | return this; 97 | }; 98 | 99 | ImportBuilder.prototype.defaultInterop = function defaultInterop() { 100 | return this._interop(this._file.addHelper("interopRequireDefault")); 101 | }; 102 | 103 | ImportBuilder.prototype.wildcardInterop = function wildcardInterop() { 104 | return this._interop(this._file.addHelper("interopRequireWildcard")); 105 | }; 106 | 107 | ImportBuilder.prototype._interop = function _interop(callee) { 108 | var statement = this._statements[this._statements.length - 1]; 109 | 110 | if (statement.type === "ExpressionStatement") { 111 | statement.expression = t.callExpression(callee, [statement.expression]); 112 | } else if (statement.type === "VariableDeclaration") { 113 | (0, _assert2.default)(statement.declarations.length === 1); 114 | statement.declarations[0].init = t.callExpression(callee, [statement.declarations[0].init]); 115 | } else { 116 | _assert2.default.fail("Unexpected type."); 117 | } 118 | 119 | return this; 120 | }; 121 | 122 | ImportBuilder.prototype.prop = function prop(name) { 123 | var statement = this._statements[this._statements.length - 1]; 124 | 125 | if (statement.type === "ExpressionStatement") { 126 | statement.expression = t.memberExpression(statement.expression, t.identifier(name)); 127 | } else if (statement.type === "VariableDeclaration") { 128 | (0, _assert2.default)(statement.declarations.length === 1); 129 | statement.declarations[0].init = t.memberExpression(statement.declarations[0].init, t.identifier(name)); 130 | } else { 131 | _assert2.default.fail("Unexpected type:" + statement.type); 132 | } 133 | 134 | return this; 135 | }; 136 | 137 | ImportBuilder.prototype.read = function read(name) { 138 | this._resultName = t.memberExpression(this._resultName, t.identifier(name)); 139 | }; 140 | 141 | return ImportBuilder; 142 | }(); 143 | 144 | exports.default = ImportBuilder; -------------------------------------------------------------------------------- /babel-helper-module-imports/lib/import-injector.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | exports.__esModule = true; 4 | exports.default = undefined; 5 | 6 | var _assert = require("assert"); 7 | 8 | var _assert2 = _interopRequireDefault(_assert); 9 | 10 | var _babelTypes = require("babel-types"); 11 | 12 | var t = _interopRequireWildcard(_babelTypes); 13 | 14 | var _importBuilder = require("./import-builder"); 15 | 16 | var _importBuilder2 = _interopRequireDefault(_importBuilder); 17 | 18 | var _isModule = require("./is-module"); 19 | 20 | var _isModule2 = _interopRequireDefault(_isModule); 21 | 22 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } 23 | 24 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 25 | 26 | var ImportInjector = function () { 27 | function ImportInjector(path, importedSource, opts) { 28 | this._defaultOpts = { 29 | importedSource: null, 30 | importedType: "commonjs", 31 | importedInterop: "babel", 32 | importingInterop: "babel", 33 | ensureLiveReference: false, 34 | ensureNoContext: false 35 | }; 36 | var programPath = path.find(function (p) { 37 | return p.isProgram(); 38 | }); 39 | this._programPath = programPath; 40 | this._programScope = programPath.scope; 41 | this._file = programPath.hub.file; 42 | this._defaultOpts = this._applyDefaults(importedSource, opts, true); 43 | } 44 | 45 | ImportInjector.prototype.addDefault = function addDefault(importedSourceIn, opts) { 46 | return this.addNamed("default", importedSourceIn, opts); 47 | }; 48 | 49 | ImportInjector.prototype.addNamed = function addNamed(importName, importedSourceIn, opts) { 50 | (0, _assert2.default)(typeof importName === "string"); 51 | return this._generateImport(this._applyDefaults(importedSourceIn, opts), importName); 52 | }; 53 | 54 | ImportInjector.prototype.addNamespace = function addNamespace(importedSourceIn, opts) { 55 | return this._generateImport(this._applyDefaults(importedSourceIn, opts), null); 56 | }; 57 | 58 | ImportInjector.prototype.addSideEffect = function addSideEffect(importedSourceIn, opts) { 59 | return this._generateImport(this._applyDefaults(importedSourceIn, opts), false); 60 | }; 61 | 62 | ImportInjector.prototype._applyDefaults = function _applyDefaults(importedSource, opts, isInit) { 63 | if (isInit === void 0) { 64 | isInit = false; 65 | } 66 | 67 | var optsList = []; 68 | 69 | if (typeof importedSource === "string") { 70 | optsList.push({ 71 | importedSource: importedSource 72 | }); 73 | optsList.push(opts); 74 | } else { 75 | (0, _assert2.default)(!opts, "Unexpected secondary arguments."); 76 | optsList.push(importedSource); 77 | } 78 | 79 | var newOpts = Object.assign({}, this._defaultOpts); 80 | 81 | var _loop = function _loop(_opts) { 82 | if (!_opts) return "continue"; 83 | Object.keys(newOpts).forEach(function (key) { 84 | if (_opts[key] !== undefined) newOpts[key] = _opts[key]; 85 | }); 86 | 87 | if (!isInit) { 88 | if (_opts.nameHint !== undefined) newOpts.nameHint = _opts.nameHint; 89 | if (_opts.blockHoist !== undefined) newOpts.blockHoist = _opts.blockHoist; 90 | } 91 | }; 92 | 93 | for (var _i = 0; _i < optsList.length; _i++) { 94 | var _opts = optsList[_i]; 95 | 96 | var _ret = _loop(_opts); 97 | 98 | if (_ret === "continue") continue; 99 | } 100 | 101 | return newOpts; 102 | }; 103 | 104 | ImportInjector.prototype._generateImport = function _generateImport(opts, importName) { 105 | var isDefault = importName === "default"; 106 | var isNamed = !!importName && !isDefault; 107 | var isNamespace = importName === null; 108 | var importedSource = opts.importedSource, 109 | importedType = opts.importedType, 110 | importedInterop = opts.importedInterop, 111 | importingInterop = opts.importingInterop, 112 | ensureLiveReference = opts.ensureLiveReference, 113 | ensureNoContext = opts.ensureNoContext, 114 | _opts$nameHint = opts.nameHint, 115 | nameHint = _opts$nameHint === undefined ? importName : _opts$nameHint, 116 | blockHoist = opts.blockHoist; 117 | var isMod = (0, _isModule2.default)(this._programPath, true); 118 | var isModuleForNode = isMod && importingInterop === "node"; 119 | var isModuleForBabel = isMod && importingInterop === "babel"; 120 | var builder = new _importBuilder2.default(importedSource, this._programScope, this._file); 121 | 122 | if (importedType === "es6") { 123 | if (!isModuleForNode && !isModuleForBabel) { 124 | throw new Error("Cannot import an ES6 module from CommonJS"); 125 | } 126 | 127 | builder.import(); 128 | 129 | if (isNamespace) { 130 | builder.namespace("namespace"); 131 | } else if (isDefault || isNamed) { 132 | builder.named(nameHint, importName); 133 | } 134 | } else if (importedType !== "commonjs") { 135 | throw new Error("Unexpected interopType \"" + importedType + "\""); 136 | } else if (importedInterop === "babel") { 137 | if (isModuleForNode) { 138 | builder.import(); 139 | 140 | if (isNamespace) { 141 | builder.default("es6Default").var(nameHint || "namespace").wildcardInterop(); 142 | } else if (isDefault) { 143 | if (ensureLiveReference) { 144 | builder.default("es6Default").var("namespace").defaultInterop().read("default"); 145 | } else { 146 | builder.default("es6Default").var(nameHint).defaultInterop().prop(importName); 147 | } 148 | } else if (isNamed) { 149 | builder.default("es6Default").read(importName); 150 | } 151 | } else if (isModuleForBabel) { 152 | builder.import(); 153 | 154 | if (isNamespace) { 155 | builder.namespace("namespace"); 156 | } else if (isDefault || isNamed) { 157 | builder.named(nameHint, importName); 158 | } 159 | } else { 160 | builder.require(); 161 | 162 | if (isNamespace) { 163 | builder.var("namespace").wildcardInterop(); 164 | } else if ((isDefault || isNamed) && ensureLiveReference) { 165 | builder.var("namespace").read(importName); 166 | if (isDefault) builder.defaultInterop(); 167 | } else if (isDefault) { 168 | builder.var(nameHint).defaultInterop().prop(importName); 169 | } else if (isNamed) { 170 | builder.var(nameHint).prop(importName); 171 | } 172 | } 173 | } else if (importedInterop === "compiled") { 174 | if (isModuleForNode) { 175 | builder.import(); 176 | 177 | if (isNamespace) { 178 | builder.default("namespace"); 179 | } else if (isDefault || isNamed) { 180 | builder.default("namespace").read(importName); 181 | } 182 | } else if (isModuleForBabel) { 183 | builder.import(); 184 | 185 | if (isNamespace) { 186 | builder.namespace("namespace"); 187 | } else if (isDefault || isNamed) { 188 | builder.named(nameHint, importName); 189 | } 190 | } else { 191 | builder.require(); 192 | 193 | if (isNamespace) { 194 | builder.var("namespace"); 195 | } else if (isDefault || isNamed) { 196 | if (ensureLiveReference) { 197 | builder.var("namespace").read(importName); 198 | } else { 199 | builder.prop(importName).var(nameHint); 200 | } 201 | } 202 | } 203 | } else if (importedInterop === "uncompiled") { 204 | if (isDefault && ensureLiveReference) { 205 | throw new Error("No live reference for commonjs default"); 206 | } 207 | 208 | if (isModuleForNode) { 209 | builder.import(); 210 | 211 | if (isNamespace) { 212 | builder.default("namespace"); 213 | } else if (isDefault) { 214 | builder.default(nameHint); 215 | } else if (isNamed) { 216 | builder.default("namespace").read(importName); 217 | } 218 | } else if (isModuleForBabel) { 219 | builder.import(); 220 | 221 | if (isNamespace) { 222 | builder.default("namespace"); 223 | } else if (isDefault) { 224 | builder.default(nameHint); 225 | } else if (isNamed) { 226 | builder.named(nameHint, importName); 227 | } 228 | } else { 229 | builder.require(); 230 | 231 | if (isNamespace) { 232 | builder.var("namespace"); 233 | } else if (isDefault) { 234 | builder.var(nameHint); 235 | } else if (isNamed) { 236 | if (ensureLiveReference) { 237 | builder.var("namespace").read(importName); 238 | } else { 239 | builder.var(nameHint).prop(importName); 240 | } 241 | } 242 | } 243 | } else { 244 | throw new Error("Unknown importedInterop \"" + importedInterop + "\"."); 245 | } 246 | 247 | var _builder$done = builder.done(), 248 | statements = _builder$done.statements, 249 | resultName = _builder$done.resultName; 250 | 251 | this._insertStatements(statements, blockHoist); 252 | 253 | if ((isDefault || isNamed) && ensureNoContext && resultName.type !== "Identifier") { 254 | return t.sequenceExpression([t.numericLiteral(0), resultName]); 255 | } 256 | 257 | return resultName; 258 | }; 259 | 260 | ImportInjector.prototype._insertStatements = function _insertStatements(statements, blockHoist) { 261 | if (blockHoist === void 0) { 262 | blockHoist = 3; 263 | } 264 | 265 | statements.forEach(function (node) { 266 | node._blockHoist = blockHoist; 267 | }); 268 | 269 | var targetPath = this._programPath.get("body").filter(function (p) { 270 | var val = p.node._blockHoist; 271 | return Number.isFinite(val) && val < 4; 272 | })[0]; 273 | 274 | if (targetPath) { 275 | targetPath.insertBefore(statements); 276 | } else { 277 | this._programPath.unshiftContainer("body", statements); 278 | } 279 | }; 280 | 281 | return ImportInjector; 282 | }(); 283 | 284 | exports.default = ImportInjector; -------------------------------------------------------------------------------- /babel-helper-module-imports/lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | exports.__esModule = true; 4 | exports.isModule = exports.ImportInjector = undefined; 5 | 6 | var _isModule = require("./is-module"); 7 | 8 | Object.defineProperty(exports, "isModule", { 9 | enumerable: true, 10 | get: function get() { 11 | return _interopRequireDefault(_isModule).default; 12 | } 13 | }); 14 | exports.addDefault = addDefault; 15 | exports.addNamed = addNamed; 16 | exports.addNamespace = addNamespace; 17 | exports.addSideEffect = addSideEffect; 18 | 19 | var _importInjector = require("./import-injector"); 20 | 21 | var _importInjector2 = _interopRequireDefault(_importInjector); 22 | 23 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 24 | 25 | exports.ImportInjector = _importInjector2.default; 26 | 27 | function addDefault(path, importedSource, opts) { 28 | return new _importInjector2.default(path).addDefault(importedSource, opts); 29 | } 30 | 31 | function addNamed(path, name, importedSource, opts) { 32 | return new _importInjector2.default(path).addNamed(name, importedSource, opts); 33 | } 34 | 35 | function addNamespace(path, importedSource, opts) { 36 | return new _importInjector2.default(path).addNamespace(importedSource, opts); 37 | } 38 | 39 | function addSideEffect(path, importedSource, opts) { 40 | return new _importInjector2.default(path).addSideEffect(importedSource, opts); 41 | } -------------------------------------------------------------------------------- /babel-helper-module-imports/lib/is-module.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | exports.__esModule = true; 4 | exports.default = isModule; 5 | 6 | function isModule(path, requireUnambiguous) { 7 | if (requireUnambiguous === void 0) { 8 | requireUnambiguous = false; 9 | } 10 | 11 | var sourceType = path.node.sourceType; 12 | 13 | if (sourceType !== "module" && sourceType !== "script") { 14 | throw path.buildCodeFrameError("Unknown sourceType \"" + sourceType + "\", cannot transform."); 15 | } 16 | 17 | var filename = path.hub.file.opts.filename; 18 | 19 | if (/\.mjs$/.test(filename)) { 20 | requireUnambiguous = false; 21 | } 22 | 23 | return path.node.sourceType === "module" && (!requireUnambiguous || isUnambiguousModule(path)); 24 | } 25 | 26 | function isUnambiguousModule(path) { 27 | return path.get("body").some(function (p) { 28 | return p.isModuleDeclaration(); 29 | }); 30 | } -------------------------------------------------------------------------------- /babel-helper-module-imports/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-helper-module-imports", 3 | "version": "7.0.0-beta.2", 4 | "description": "Babel helper functions for inserting module loads", 5 | "author": "Logan Smyth ", 6 | "homepage": "https://babeljs.io/", 7 | "license": "MIT", 8 | "repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-module-imports", 9 | "main": "lib/index.js", 10 | "dependencies": { 11 | "babel-types": "7.0.0-beta.2", 12 | "lodash": "^4.2.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /babel-helper-module-imports/src/import-builder.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import * as t from "babel-types"; 3 | 4 | /** 5 | * A class to track and accumulate mutations to the AST that will eventually 6 | * output a new require/import statement list. 7 | */ 8 | export default class ImportBuilder { 9 | _statements = []; 10 | _resultName = null; 11 | 12 | _scope = null; 13 | _file = null; 14 | 15 | constructor(importedSource, scope, file) { 16 | this._scope = scope; 17 | this._file = file; 18 | this._importedSource = importedSource; 19 | } 20 | 21 | done() { 22 | return { 23 | statements: this._statements, 24 | resultName: this._resultName, 25 | }; 26 | } 27 | 28 | import() { 29 | const importedSource = this._file.resolveModuleSource(this._importedSource); 30 | 31 | this._statements.push( 32 | t.importDeclaration([], t.stringLiteral(importedSource)), 33 | ); 34 | return this; 35 | } 36 | 37 | require() { 38 | const importedSource = this._file.resolveModuleSource(this._importedSource); 39 | 40 | this._statements.push( 41 | t.expressionStatement( 42 | t.callExpression(t.identifier("require"), [ 43 | t.stringLiteral(importedSource), 44 | ]), 45 | ), 46 | ); 47 | return this; 48 | } 49 | 50 | namespace(name) { 51 | name = this._scope.generateUidIdentifier(name); 52 | 53 | const statement = this._statements[this._statements.length - 1]; 54 | assert(statement.type === "ImportDeclaration"); 55 | assert(statement.specifiers.length === 0); 56 | statement.specifiers = [t.importNamespaceSpecifier(name)]; 57 | this._resultName = t.clone(name); 58 | return this; 59 | } 60 | default(name) { 61 | name = this._scope.generateUidIdentifier(name); 62 | const statement = this._statements[this._statements.length - 1]; 63 | assert(statement.type === "ImportDeclaration"); 64 | assert(statement.specifiers.length === 0); 65 | statement.specifiers = [t.importDefaultSpecifier(name)]; 66 | this._resultName = t.clone(name); 67 | return this; 68 | } 69 | named(name, importName) { 70 | if (importName === "default") return this.default(name); 71 | 72 | name = this._scope.generateUidIdentifier(name); 73 | const statement = this._statements[this._statements.length - 1]; 74 | assert(statement.type === "ImportDeclaration"); 75 | assert(statement.specifiers.length === 0); 76 | statement.specifiers = [t.importSpecifier(name, t.identifier(importName))]; 77 | this._resultName = t.clone(name); 78 | return this; 79 | } 80 | 81 | var(name) { 82 | name = this._scope.generateUidIdentifier(name); 83 | let statement = this._statements[this._statements.length - 1]; 84 | if (statement.type !== "ExpressionStatement") { 85 | assert(this._resultName); 86 | statement = t.expressionStatement(this._resultName); 87 | this._statements.push(statement); 88 | } 89 | this._statements[ 90 | this._statements.length - 1 91 | ] = t.variableDeclaration("var", [ 92 | t.variableDeclarator(name, statement.expression), 93 | ]); 94 | this._resultName = t.clone(name); 95 | return this; 96 | } 97 | 98 | defaultInterop() { 99 | return this._interop(this._file.addHelper("interopRequireDefault")); 100 | } 101 | wildcardInterop() { 102 | return this._interop(this._file.addHelper("interopRequireWildcard")); 103 | } 104 | 105 | _interop(callee) { 106 | const statement = this._statements[this._statements.length - 1]; 107 | if (statement.type === "ExpressionStatement") { 108 | statement.expression = t.callExpression(callee, [statement.expression]); 109 | } else if (statement.type === "VariableDeclaration") { 110 | assert(statement.declarations.length === 1); 111 | statement.declarations[0].init = t.callExpression(callee, [ 112 | statement.declarations[0].init, 113 | ]); 114 | } else { 115 | assert.fail("Unexpected type."); 116 | } 117 | return this; 118 | } 119 | 120 | prop(name) { 121 | const statement = this._statements[this._statements.length - 1]; 122 | if (statement.type === "ExpressionStatement") { 123 | statement.expression = t.memberExpression( 124 | statement.expression, 125 | t.identifier(name), 126 | ); 127 | } else if (statement.type === "VariableDeclaration") { 128 | assert(statement.declarations.length === 1); 129 | statement.declarations[0].init = t.memberExpression( 130 | statement.declarations[0].init, 131 | t.identifier(name), 132 | ); 133 | } else { 134 | assert.fail("Unexpected type:" + statement.type); 135 | } 136 | return this; 137 | } 138 | 139 | read(name) { 140 | this._resultName = t.memberExpression(this._resultName, t.identifier(name)); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /babel-helper-module-imports/src/import-injector.js: -------------------------------------------------------------------------------- 1 | import assert from "assert"; 2 | import * as t from "babel-types"; 3 | 4 | import ImportBuilder from "./import-builder"; 5 | import isModule from "./is-module"; 6 | 7 | export type ImportOptions = { 8 | /** 9 | * The module being referenced. 10 | */ 11 | importedSource: string | null, 12 | 13 | /** 14 | * The type of module being imported: 15 | * 16 | * * 'es6' - An ES6 module. 17 | * * 'commonjs' - A CommonJS module. (Default) 18 | */ 19 | importedType: "es6" | "commonjs", 20 | 21 | /** 22 | * The type of interop behavior for namespace/default/named when loading 23 | * CommonJS modules. 24 | * 25 | * ## 'babel' (Default) 26 | * 27 | * Load using Babel's interop. 28 | * 29 | * If '.__esModule' is true, treat as 'compiled', else: 30 | * 31 | * * Namespace: A copy of the module.exports with .default 32 | * populated by the module.exports object. 33 | * * Default: The module.exports value. 34 | * * Named: The .named property of module.exports. 35 | * 36 | * The 'ensureLiveReference' has no effect on the liveness of these. 37 | * 38 | * ## 'compiled' 39 | * 40 | * Assume the module is ES6 compiled to CommonJS. Useful to avoid injecting 41 | * interop logic if you are confident that the module is a certain format. 42 | * 43 | * * Namespace: The root module.exports object. 44 | * * Default: The .default property of the namespace. 45 | * * Named: The .named property of the namespace. 46 | * 47 | * Will return erroneous results if the imported module is _not_ compiled 48 | * from ES6 with Babel. 49 | * 50 | * ## 'uncompiled' 51 | * 52 | * Assume the module is _not_ ES6 compiled to CommonJS. Used a simplified 53 | * access pattern that doesn't require additional function calls. 54 | * 55 | * Will return erroneous results if the imported module _is_ compiled 56 | * from ES6 with Babel. 57 | * 58 | * * Namespace: The module.exports object. 59 | * * Default: The module.exports object. 60 | * * Named: The .named property of module.exports. 61 | */ 62 | importedInterop: "babel" | "node" | "compiled" | "uncompiled", 63 | 64 | /** 65 | * The type of CommonJS interop included in the environment that will be 66 | * loading the output code. 67 | * 68 | * * 'babel' - CommonJS modules load with Babel's interop. (Default) 69 | * * 'node' - CommonJS modules load with Node's interop. 70 | * 71 | * See descriptions in 'importedInterop' for more details. 72 | */ 73 | importingInterop: "babel" | "node", 74 | 75 | /** 76 | * Define whether we explicitly care that the import be a live reference. 77 | * Only applies when importing default and named imports, not the namespace. 78 | * 79 | * * true - Force imported values to be live references. 80 | * * false - No particular requirements. Keeps the code simplest. (Default) 81 | */ 82 | ensureLiveReference: boolean, 83 | 84 | /** 85 | * Define if we explicitly care that the result not be a property reference. 86 | * 87 | * * true - Force calls to exclude context. Useful if the value is going to 88 | * be used as function callee. 89 | * * false - No particular requirements for context of the access. (Default) 90 | */ 91 | ensureNoContext: boolean, 92 | }; 93 | 94 | /** 95 | * A general helper classes add imports via transforms. See README for usage. 96 | */ 97 | export default class ImportInjector { 98 | /** 99 | * The path used for manipulation. 100 | */ 101 | _programPath: NodePath; 102 | 103 | /** 104 | * The scope used to generate unique variable names. 105 | */ 106 | _programScope; 107 | 108 | /** 109 | * The file used to inject helpers and resolve paths. 110 | */ 111 | _file; 112 | 113 | /** 114 | * The default options to use with this instance when imports are added. 115 | */ 116 | _defaultOpts: ImportOptions = { 117 | importedSource: null, 118 | importedType: "commonjs", 119 | importedInterop: "babel", 120 | importingInterop: "babel", 121 | ensureLiveReference: false, 122 | ensureNoContext: false, 123 | }; 124 | 125 | constructor(path, importedSource, opts) { 126 | const programPath = path.find(p => p.isProgram()); 127 | 128 | this._programPath = programPath; 129 | this._programScope = programPath.scope; 130 | this._file = programPath.hub.file; 131 | 132 | this._defaultOpts = this._applyDefaults(importedSource, opts, true); 133 | } 134 | 135 | addDefault(importedSourceIn, opts) { 136 | return this.addNamed("default", importedSourceIn, opts); 137 | } 138 | 139 | addNamed(importName, importedSourceIn, opts) { 140 | assert(typeof importName === "string"); 141 | 142 | return this._generateImport( 143 | this._applyDefaults(importedSourceIn, opts), 144 | importName, 145 | ); 146 | } 147 | 148 | addNamespace(importedSourceIn, opts) { 149 | return this._generateImport( 150 | this._applyDefaults(importedSourceIn, opts), 151 | null, 152 | ); 153 | } 154 | 155 | addSideEffect(importedSourceIn, opts) { 156 | return this._generateImport( 157 | this._applyDefaults(importedSourceIn, opts), 158 | false, 159 | ); 160 | } 161 | 162 | _applyDefaults(importedSource, opts, isInit = false) { 163 | const optsList = []; 164 | if (typeof importedSource === "string") { 165 | optsList.push({ importedSource }); 166 | optsList.push(opts); 167 | } else { 168 | assert(!opts, "Unexpected secondary arguments."); 169 | 170 | optsList.push(importedSource); 171 | } 172 | 173 | const newOpts = Object.assign({}, this._defaultOpts); 174 | for (const opts of optsList) { 175 | if (!opts) continue; 176 | Object.keys(newOpts).forEach(key => { 177 | if (opts[key] !== undefined) newOpts[key] = opts[key]; 178 | }); 179 | 180 | if (!isInit) { 181 | if (opts.nameHint !== undefined) newOpts.nameHint = opts.nameHint; 182 | if (opts.blockHoist !== undefined) newOpts.blockHoist = opts.blockHoist; 183 | } 184 | } 185 | return newOpts; 186 | } 187 | 188 | _generateImport(opts, importName) { 189 | const isDefault = importName === "default"; 190 | const isNamed = !!importName && !isDefault; 191 | const isNamespace = importName === null; 192 | 193 | const { 194 | importedSource, 195 | importedType, 196 | importedInterop, 197 | importingInterop, 198 | ensureLiveReference, 199 | ensureNoContext, 200 | 201 | // Provide a hint for generateUidIdentifier for the local variable name 202 | // to use for the import, if the code will generate a simple assignment 203 | // to a variable. 204 | nameHint = importName, 205 | 206 | // Not meant for public usage. Allows code that absolutely must control 207 | // ordering to set a specific hoist value on the import nodes. 208 | blockHoist, 209 | } = opts; 210 | 211 | const isMod = isModule(this._programPath, true); 212 | const isModuleForNode = isMod && importingInterop === "node"; 213 | const isModuleForBabel = isMod && importingInterop === "babel"; 214 | 215 | const builder = new ImportBuilder( 216 | importedSource, 217 | this._programScope, 218 | this._file, 219 | ); 220 | 221 | if (importedType === "es6") { 222 | if (!isModuleForNode && !isModuleForBabel) { 223 | throw new Error("Cannot import an ES6 module from CommonJS"); 224 | } 225 | 226 | // import * as namespace from ''; namespace 227 | // import def from ''; def 228 | // import { named } from ''; named 229 | builder.import(); 230 | if (isNamespace) { 231 | builder.namespace("namespace"); 232 | } else if (isDefault || isNamed) { 233 | builder.named(nameHint, importName); 234 | } 235 | } else if (importedType !== "commonjs") { 236 | throw new Error(`Unexpected interopType "${importedType}"`); 237 | } else if (importedInterop === "babel") { 238 | if (isModuleForNode) { 239 | // import _tmp from ''; var namespace = interopRequireWildcard(_tmp); namespace 240 | // import _tmp from ''; var def = interopRequireDefault(_tmp).default; def 241 | // import _tmp from ''; _tmp.named 242 | 243 | builder.import(); 244 | if (isNamespace) { 245 | builder 246 | .default("es6Default") 247 | .var(nameHint || "namespace") 248 | .wildcardInterop(); 249 | } else if (isDefault) { 250 | if (ensureLiveReference) { 251 | builder 252 | .default("es6Default") 253 | .var("namespace") 254 | .defaultInterop() 255 | .read("default"); 256 | } else { 257 | builder 258 | .default("es6Default") 259 | .var(nameHint) 260 | .defaultInterop() 261 | .prop(importName); 262 | } 263 | } else if (isNamed) { 264 | builder.default("es6Default").read(importName); 265 | } 266 | } else if (isModuleForBabel) { 267 | // import * as namespace from ''; namespace 268 | // import def from ''; def 269 | // import { named } from ''; named 270 | builder.import(); 271 | if (isNamespace) { 272 | builder.namespace("namespace"); 273 | } else if (isDefault || isNamed) { 274 | builder.named(nameHint, importName); 275 | } 276 | } else { 277 | // var namespace = interopRequireWildcard(require('')); 278 | // var def = interopRequireDefault(require('')).default; def 279 | // var named = require('').named; named 280 | builder.require(); 281 | if (isNamespace) { 282 | builder.var("namespace").wildcardInterop(); 283 | } else if ((isDefault || isNamed) && ensureLiveReference) { 284 | builder.var("namespace").read(importName); 285 | 286 | if (isDefault) builder.defaultInterop(); 287 | } else if (isDefault) { 288 | builder 289 | .var(nameHint) 290 | .defaultInterop() 291 | .prop(importName); 292 | } else if (isNamed) { 293 | builder.var(nameHint).prop(importName); 294 | } 295 | } 296 | } else if (importedInterop === "compiled") { 297 | if (isModuleForNode) { 298 | // import namespace from ''; namespace 299 | // import namespace from ''; namespace.default 300 | // import namespace from ''; namespace.named 301 | 302 | builder.import(); 303 | if (isNamespace) { 304 | builder.default("namespace"); 305 | } else if (isDefault || isNamed) { 306 | builder.default("namespace").read(importName); 307 | } 308 | } else if (isModuleForBabel) { 309 | // import * as namespace from ''; namespace 310 | // import def from ''; def 311 | // import { named } from ''; named 312 | // Note: These lookups will break if the module has no __esModule set, 313 | // hence the warning that 'compiled' will not work on standard CommonJS. 314 | 315 | builder.import(); 316 | if (isNamespace) { 317 | builder.namespace("namespace"); 318 | } else if (isDefault || isNamed) { 319 | builder.named(nameHint, importName); 320 | } 321 | } else { 322 | // var namespace = require(''); namespace 323 | // var namespace = require(''); namespace.default 324 | // var namespace = require(''); namespace.named 325 | // var named = require('').named; 326 | 327 | builder.require(); 328 | if (isNamespace) { 329 | builder.var("namespace"); 330 | } else if (isDefault || isNamed) { 331 | if (ensureLiveReference) { 332 | builder.var("namespace").read(importName); 333 | } else { 334 | builder.prop(importName).var(nameHint); 335 | } 336 | } 337 | } 338 | } else if (importedInterop === "uncompiled") { 339 | if (isDefault && ensureLiveReference) { 340 | throw new Error("No live reference for commonjs default"); 341 | } 342 | 343 | if (isModuleForNode) { 344 | // import namespace from ''; namespace 345 | // import def from ''; def; 346 | // import namespace from ''; namespace.named 347 | 348 | builder.import(); 349 | if (isNamespace) { 350 | builder.default("namespace"); 351 | } else if (isDefault) { 352 | builder.default(nameHint); 353 | } else if (isNamed) { 354 | builder.default("namespace").read(importName); 355 | } 356 | } else if (isModuleForBabel) { 357 | // import namespace from ''; 358 | // import def from ''; 359 | // import { named } from ''; named; 360 | // Note: These lookups will break if the module has __esModule set, 361 | // hence the warning that 'uncompiled' will not work on ES6 transpiled 362 | // to CommonJS. 363 | 364 | builder.import(); 365 | if (isNamespace) { 366 | builder.default("namespace"); 367 | } else if (isDefault) { 368 | builder.default(nameHint); 369 | } else if (isNamed) { 370 | builder.named(nameHint, importName); 371 | } 372 | } else { 373 | // var namespace = require(''); namespace 374 | // var def = require(''); def 375 | // var namespace = require(''); namespace.named 376 | // var named = require('').named; 377 | 378 | builder.require(); 379 | if (isNamespace) { 380 | builder.var("namespace"); 381 | } else if (isDefault) { 382 | builder.var(nameHint); 383 | } else if (isNamed) { 384 | if (ensureLiveReference) { 385 | builder.var("namespace").read(importName); 386 | } else { 387 | builder.var(nameHint).prop(importName); 388 | } 389 | } 390 | } 391 | } else { 392 | throw new Error(`Unknown importedInterop "${importedInterop}".`); 393 | } 394 | 395 | const { statements, resultName } = builder.done(); 396 | 397 | this._insertStatements(statements, blockHoist); 398 | 399 | if ( 400 | (isDefault || isNamed) && 401 | ensureNoContext && 402 | resultName.type !== "Identifier" 403 | ) { 404 | return t.sequenceExpression([t.numericLiteral(0), resultName]); 405 | } 406 | return resultName; 407 | } 408 | 409 | _insertStatements(statements, blockHoist = 3) { 410 | statements.forEach(node => { 411 | node._blockHoist = blockHoist; 412 | }); 413 | 414 | const targetPath = this._programPath.get("body").filter(p => { 415 | const val = p.node._blockHoist; 416 | return Number.isFinite(val) && val < 4; 417 | })[0]; 418 | 419 | if (targetPath) { 420 | targetPath.insertBefore(statements); 421 | } else { 422 | this._programPath.unshiftContainer("body", statements); 423 | } 424 | } 425 | } 426 | -------------------------------------------------------------------------------- /babel-helper-module-imports/src/index.js: -------------------------------------------------------------------------------- 1 | import ImportInjector from "./import-injector"; 2 | 3 | export { ImportInjector }; 4 | 5 | export { default as isModule } from "./is-module"; 6 | 7 | export function addDefault(path, importedSource, opts) { 8 | return new ImportInjector(path).addDefault(importedSource, opts); 9 | } 10 | 11 | export function addNamed(path, name, importedSource, opts) { 12 | return new ImportInjector(path).addNamed(name, importedSource, opts); 13 | } 14 | 15 | export function addNamespace(path, importedSource, opts) { 16 | return new ImportInjector(path).addNamespace(importedSource, opts); 17 | } 18 | 19 | export function addSideEffect(path, importedSource, opts) { 20 | return new ImportInjector(path).addSideEffect(importedSource, opts); 21 | } 22 | -------------------------------------------------------------------------------- /babel-helper-module-imports/src/is-module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A small utility to check if a file qualifies as a module, based on a few 3 | * possible conditions. 4 | */ 5 | export default function isModule( 6 | path: NodePath, 7 | requireUnambiguous: boolean = false, 8 | ) { 9 | const { sourceType } = path.node; 10 | if (sourceType !== "module" && sourceType !== "script") { 11 | throw path.buildCodeFrameError( 12 | `Unknown sourceType "${sourceType}", cannot transform.`, 13 | ); 14 | } 15 | 16 | const filename = path.hub.file.opts.filename; 17 | if (/\.mjs$/.test(filename)) { 18 | requireUnambiguous = false; 19 | } 20 | 21 | return ( 22 | path.node.sourceType === "module" && 23 | (!requireUnambiguous || isUnambiguousModule(path)) 24 | ); 25 | } 26 | 27 | // This approach is not ideal. It is here to preserve compatibility for now, 28 | // but really this should just return true or be deleted. 29 | function isUnambiguousModule(path) { 30 | return path.get("body").some(p => p.isModuleDeclaration()); 31 | } 32 | -------------------------------------------------------------------------------- /babel-helper-module-imports/test/index.js: -------------------------------------------------------------------------------- 1 | import chai from "chai"; 2 | import * as babel from "babel-core"; 3 | 4 | import { ImportInjector } from "../"; 5 | 6 | function test(sourceType, opts, initializer, expectedCode) { 7 | if (typeof opts === "function") { 8 | expectedCode = initializer; 9 | initializer = opts; 10 | opts = null; 11 | } 12 | 13 | const result = babel.transform("", { 14 | sourceType, 15 | filename: "example" + (sourceType === "module" ? ".mjs" : ".js"), 16 | babelrc: false, 17 | plugins: [ 18 | function({ types: t }) { 19 | return { 20 | pre(file) { 21 | file.set("helpersNamespace", t.identifier("babelHelpers")); 22 | }, 23 | visitor: { 24 | Program(path) { 25 | const manager = new ImportInjector(path, opts); 26 | 27 | const ref = initializer(manager); 28 | if (ref) path.pushContainer("body", t.expressionStatement(ref)); 29 | }, 30 | }, 31 | }; 32 | }, 33 | ], 34 | }); 35 | 36 | chai 37 | .expect(result.code.replace(/\s+/g, " ").trim()) 38 | .to.equal((expectedCode || "").replace(/\s+/g, " ").trim()); 39 | } 40 | const testScript = test.bind(undefined, "script"); 41 | const testModule = test.bind(undefined, "module"); 42 | 43 | describe("babel-helper-module-imports", () => { 44 | describe("namespace import", () => { 45 | const addNamespace = opts => m => m.addNamespace("source", opts); 46 | 47 | describe("loading an ES6 module", () => { 48 | const importedType = "es6"; 49 | 50 | describe("using Node's interop", () => { 51 | const importingInterop = "node"; 52 | 53 | it("should import", () => { 54 | testModule( 55 | { importingInterop, importedType }, 56 | addNamespace(), 57 | ` 58 | import * as _namespace from "source"; 59 | _namespace; 60 | `, 61 | ); 62 | }); 63 | }); 64 | 65 | describe("using Babel's interop", () => { 66 | const importingInterop = "babel"; 67 | 68 | it("should import", () => { 69 | testModule( 70 | { importingInterop, importedType }, 71 | addNamespace(), 72 | ` 73 | import * as _namespace from "source"; 74 | _namespace; 75 | `, 76 | ); 77 | }); 78 | }); 79 | 80 | describe("using a CommonJS loader", () => { 81 | it("should import", () => { 82 | chai 83 | .expect(() => { 84 | testScript({ importedType }, addNamespace()); 85 | }) 86 | .to.throw(Error, "Cannot import an ES6 module from CommonJS"); 87 | }); 88 | }); 89 | }); 90 | 91 | describe("loading CommonJS with 'uncompiled'", () => { 92 | const importedInterop = "uncompiled"; 93 | 94 | describe("using Node's interop", () => { 95 | const importingInterop = "node"; 96 | 97 | it("should import", () => { 98 | testModule( 99 | { importingInterop, importedInterop }, 100 | addNamespace(), 101 | ` 102 | import _namespace from "source"; 103 | _namespace; 104 | `, 105 | ); 106 | }); 107 | }); 108 | 109 | describe("using Babel's interop", () => { 110 | const importingInterop = "babel"; 111 | 112 | it("should import", () => { 113 | testModule( 114 | { importingInterop, importedInterop }, 115 | addNamespace(), 116 | ` 117 | import _namespace from "source"; 118 | _namespace; 119 | `, 120 | ); 121 | }); 122 | }); 123 | 124 | describe("using a CommonJS loader", () => { 125 | it("should import", () => { 126 | testScript( 127 | { importedInterop }, 128 | addNamespace(), 129 | ` 130 | var _namespace = require("source"); 131 | _namespace; 132 | `, 133 | ); 134 | }); 135 | }); 136 | }); 137 | 138 | describe("loading CommonJS with 'compiled'", () => { 139 | const importedInterop = "compiled"; 140 | 141 | describe("using Node's interop", () => { 142 | const importingInterop = "node"; 143 | 144 | it("should import", () => { 145 | testModule( 146 | { importingInterop, importedInterop }, 147 | addNamespace(), 148 | ` 149 | import _namespace from "source"; 150 | _namespace; 151 | `, 152 | ); 153 | }); 154 | }); 155 | 156 | describe("using Babel's interop", () => { 157 | const importingInterop = "babel"; 158 | 159 | it("should import", () => { 160 | testModule( 161 | { importingInterop, importedInterop }, 162 | addNamespace(), 163 | ` 164 | import * as _namespace from "source"; 165 | _namespace; 166 | `, 167 | ); 168 | }); 169 | }); 170 | 171 | describe("using a CommonJS loader", () => { 172 | it("should import", () => { 173 | testScript( 174 | { importedInterop }, 175 | addNamespace(), 176 | ` 177 | var _namespace = require("source"); 178 | _namespace; 179 | `, 180 | ); 181 | }); 182 | }); 183 | }); 184 | 185 | describe("loading CommonJS with 'babel'", () => { 186 | const importedInterop = "babel"; 187 | 188 | describe("using Node's interop", () => { 189 | const importingInterop = "node"; 190 | 191 | it("should import", () => { 192 | testModule( 193 | { importingInterop, importedInterop }, 194 | addNamespace(), 195 | ` 196 | import _es6Default from "source"; 197 | var _namespace = babelHelpers.interopRequireWildcard(_es6Default); 198 | _namespace; 199 | `, 200 | ); 201 | }); 202 | }); 203 | 204 | describe("using Babel's interop", () => { 205 | const importingInterop = "babel"; 206 | 207 | it("should import", () => { 208 | testModule( 209 | { importingInterop, importedInterop }, 210 | addNamespace(), 211 | ` 212 | import * as _namespace from "source"; 213 | _namespace; 214 | `, 215 | ); 216 | }); 217 | }); 218 | 219 | describe("using a CommonJS loader", () => { 220 | it("should import", () => { 221 | testScript( 222 | { importedInterop }, 223 | addNamespace(), 224 | ` 225 | var _namespace = babelHelpers.interopRequireWildcard(require("source")); 226 | _namespace; 227 | `, 228 | ); 229 | }); 230 | }); 231 | }); 232 | }); 233 | 234 | describe("default imports", () => { 235 | const addDefault = opts => m => m.addDefault("source", opts); 236 | 237 | describe("loading an ES6 module", () => { 238 | const importedType = "es6"; 239 | 240 | describe("using Node's interop", () => { 241 | const importingInterop = "node"; 242 | 243 | it("should import", () => { 244 | testModule( 245 | { importingInterop, importedType }, 246 | addDefault(), 247 | ` 248 | import _default from "source"; 249 | _default; 250 | `, 251 | ); 252 | }); 253 | 254 | it("should import with a name hint", () => { 255 | testModule( 256 | { importingInterop, importedType }, 257 | addDefault({ nameHint: "hintedName" }), 258 | ` 259 | import _hintedName from "source"; 260 | _hintedName; 261 | `, 262 | ); 263 | }); 264 | }); 265 | 266 | describe("using Babel's interop", () => { 267 | const importingInterop = "babel"; 268 | 269 | it("should import", () => { 270 | testModule( 271 | { importingInterop, importedType }, 272 | addDefault(), 273 | ` 274 | import _default from "source"; 275 | _default; 276 | `, 277 | ); 278 | }); 279 | 280 | it("should import with a name hint", () => { 281 | testModule( 282 | { importingInterop, importedType }, 283 | addDefault({ nameHint: "hintedName" }), 284 | ` 285 | import _hintedName from "source"; 286 | _hintedName; 287 | `, 288 | ); 289 | }); 290 | }); 291 | 292 | describe("using a CommonJS loader", () => { 293 | it("should import", () => { 294 | chai 295 | .expect(() => { 296 | testScript({ importedType }, addDefault()); 297 | }) 298 | .to.throw(Error, "Cannot import an ES6 module from CommonJS"); 299 | }); 300 | }); 301 | }); 302 | 303 | describe("loading CommonJS with 'uncompiled'", () => { 304 | const importedInterop = "uncompiled"; 305 | 306 | describe("using Node's interop", () => { 307 | const importingInterop = "node"; 308 | 309 | it("should import", () => { 310 | testModule( 311 | { importingInterop, importedInterop }, 312 | addDefault(), 313 | ` 314 | import _default from "source"; 315 | _default; 316 | `, 317 | ); 318 | }); 319 | 320 | it("should import with a name hint", () => { 321 | testModule( 322 | { importingInterop, importedInterop }, 323 | addDefault({ nameHint: "hintedName" }), 324 | ` 325 | import _hintedName from "source"; 326 | _hintedName; 327 | `, 328 | ); 329 | }); 330 | }); 331 | 332 | describe("using Babel's interop", () => { 333 | const importingInterop = "babel"; 334 | 335 | it("should import", () => { 336 | testModule( 337 | { importingInterop, importedInterop }, 338 | addDefault(), 339 | ` 340 | import _default from "source"; 341 | _default; 342 | `, 343 | ); 344 | }); 345 | 346 | it("should import with a name hint", () => { 347 | testModule( 348 | { importingInterop, importedInterop }, 349 | addDefault({ nameHint: "hintedName" }), 350 | ` 351 | import _hintedName from "source"; 352 | _hintedName; 353 | `, 354 | ); 355 | }); 356 | }); 357 | 358 | describe("using a CommonJS loader", () => { 359 | it("should import", () => { 360 | testScript( 361 | { importedInterop }, 362 | addDefault(), 363 | ` 364 | var _default = require("source"); 365 | _default; 366 | `, 367 | ); 368 | }); 369 | 370 | it("should import with a name hint", () => { 371 | testScript( 372 | { importedInterop }, 373 | addDefault({ nameHint: "hintedName" }), 374 | ` 375 | var _hintedName = require("source"); 376 | _hintedName; 377 | `, 378 | ); 379 | }); 380 | 381 | it("should fail to import with force-enabled liveness", () => { 382 | chai 383 | .expect(() => { 384 | testScript( 385 | { importedInterop, ensureLiveReference: true }, 386 | addDefault(), 387 | ); 388 | }) 389 | .to.throw(Error, "No live reference for commonjs default"); 390 | }); 391 | }); 392 | }); 393 | 394 | describe("loading CommonJS with 'compiled'", () => { 395 | const importedInterop = "compiled"; 396 | 397 | describe("using Node's interop", () => { 398 | const importingInterop = "node"; 399 | 400 | it("should import", () => { 401 | testModule( 402 | { importingInterop, importedInterop }, 403 | addDefault(), 404 | ` 405 | import _namespace from "source"; 406 | _namespace.default; 407 | `, 408 | ); 409 | }); 410 | 411 | it("should import with a force-disabled context", () => { 412 | testModule( 413 | { importingInterop, importedInterop, ensureNoContext: true }, 414 | addDefault(), 415 | ` 416 | import _namespace from "source"; 417 | 0, _namespace.default; 418 | `, 419 | ); 420 | }); 421 | }); 422 | 423 | describe("using Babel's interop", () => { 424 | const importingInterop = "babel"; 425 | 426 | it("should import", () => { 427 | testModule( 428 | { importingInterop, importedInterop }, 429 | addDefault(), 430 | ` 431 | import _default from "source"; 432 | _default; 433 | `, 434 | ); 435 | }); 436 | 437 | it("should import with a name hint", () => { 438 | testModule( 439 | { importingInterop, importedInterop }, 440 | addDefault({ nameHint: "hintedName" }), 441 | ` 442 | import _hintedName from "source"; 443 | _hintedName; 444 | `, 445 | ); 446 | }); 447 | }); 448 | 449 | describe("using a CommonJS loader", () => { 450 | it("should import", () => { 451 | testScript( 452 | { importedInterop }, 453 | addDefault(), 454 | ` 455 | var _default = require("source").default; 456 | _default; 457 | `, 458 | ); 459 | }); 460 | 461 | it("should import with a name hint", () => { 462 | testScript( 463 | { importedInterop }, 464 | addDefault({ nameHint: "hintedName" }), 465 | ` 466 | var _hintedName = require("source").default; 467 | _hintedName; 468 | `, 469 | ); 470 | }); 471 | 472 | it("should import with force-enabled liveness", () => { 473 | testScript( 474 | { importedInterop, ensureLiveReference: true }, 475 | addDefault(), 476 | ` 477 | var _namespace = require("source"); 478 | _namespace.default; 479 | `, 480 | ); 481 | }); 482 | }); 483 | }); 484 | 485 | describe("loading CommonJS with 'babel'", () => { 486 | const importedInterop = "babel"; 487 | 488 | describe("using Node's interop", () => { 489 | const importingInterop = "node"; 490 | 491 | it("should import", () => { 492 | testModule( 493 | { importingInterop, importedInterop }, 494 | addDefault(), 495 | ` 496 | import _es6Default from "source"; 497 | var _default = babelHelpers.interopRequireDefault(_es6Default).default; 498 | _default; 499 | `, 500 | ); 501 | }); 502 | 503 | it("should import with a name hint", () => { 504 | testModule( 505 | { importingInterop, importedInterop }, 506 | addDefault({ nameHint: "hintedName" }), 507 | ` 508 | import _es6Default from "source"; 509 | var _hintedName = babelHelpers.interopRequireDefault(_es6Default).default; 510 | _hintedName; 511 | `, 512 | ); 513 | }); 514 | 515 | it("should import with force-enabled liveness", () => { 516 | testModule( 517 | { importingInterop, importedInterop, ensureLiveReference: true }, 518 | addDefault(), 519 | ` 520 | import _es6Default from "source"; 521 | var _namespace = babelHelpers.interopRequireDefault(_es6Default); 522 | _namespace.default; 523 | `, 524 | ); 525 | }); 526 | }); 527 | 528 | describe("using Babel's interop", () => { 529 | const importingInterop = "babel"; 530 | 531 | it("should import", () => { 532 | testModule( 533 | { importingInterop, importedInterop }, 534 | addDefault(), 535 | ` 536 | import _default from "source"; 537 | _default; 538 | `, 539 | ); 540 | }); 541 | 542 | it("should import with a name hint", () => { 543 | testModule( 544 | { importingInterop, importedInterop }, 545 | addDefault({ nameHint: "hintedName" }), 546 | ` 547 | import _hintedName from "source"; 548 | _hintedName; 549 | `, 550 | ); 551 | }); 552 | }); 553 | 554 | describe("using a CommonJS loader", () => { 555 | it("should import", () => { 556 | testScript( 557 | { importedInterop }, 558 | addDefault(), 559 | ` 560 | var _default = babelHelpers.interopRequireDefault(require("source")).default; 561 | _default; 562 | `, 563 | ); 564 | }); 565 | 566 | it("should import with a name hint", () => { 567 | testScript( 568 | { importedInterop }, 569 | addDefault({ nameHint: "hintedName" }), 570 | ` 571 | var _hintedName = babelHelpers.interopRequireDefault(require("source")).default; 572 | _hintedName; 573 | `, 574 | ); 575 | }); 576 | 577 | it("should import with force-enabled liveness", () => { 578 | testScript( 579 | { importedInterop, ensureLiveReference: true }, 580 | addDefault(), 581 | ` 582 | var _namespace = babelHelpers.interopRequireDefault(require("source")); 583 | _namespace.default; 584 | `, 585 | ); 586 | }); 587 | }); 588 | }); 589 | }); 590 | 591 | describe("named imports", () => { 592 | const addNamed = opts => m => m.addNamed("read", "source", opts); 593 | 594 | describe("loading an ES6 module", () => { 595 | const importedType = "es6"; 596 | 597 | describe("using Node's interop", () => { 598 | const importingInterop = "node"; 599 | 600 | it("should import", () => { 601 | testModule( 602 | { importingInterop, importedType }, 603 | addNamed(), 604 | ` 605 | import { read as _read } from "source"; 606 | _read; 607 | `, 608 | ); 609 | }); 610 | 611 | it("should import with a name hint", () => { 612 | testModule( 613 | { importingInterop, importedType }, 614 | addNamed({ nameHint: "hintedName" }), 615 | ` 616 | import { read as _hintedName } from "source"; 617 | _hintedName; 618 | `, 619 | ); 620 | }); 621 | }); 622 | 623 | describe("using Babel's interop", () => { 624 | const importingInterop = "babel"; 625 | 626 | it("should import", () => { 627 | testModule( 628 | { importingInterop, importedType }, 629 | addNamed(), 630 | ` 631 | import { read as _read } from "source"; 632 | _read; 633 | `, 634 | ); 635 | }); 636 | 637 | it("should import with a name hint", () => { 638 | testModule( 639 | { importingInterop, importedType }, 640 | addNamed({ nameHint: "hintedName" }), 641 | ` 642 | import { read as _hintedName } from "source"; 643 | _hintedName; 644 | `, 645 | ); 646 | }); 647 | }); 648 | 649 | describe("using a CommonJS loader", () => { 650 | it("should import", () => { 651 | chai 652 | .expect(() => { 653 | testScript({ importedType }, addNamed()); 654 | }) 655 | .to.throw(Error, "Cannot import an ES6 module from CommonJS"); 656 | }); 657 | }); 658 | }); 659 | 660 | describe("loading CommonJS with 'uncompiled'", () => { 661 | const importedInterop = "uncompiled"; 662 | 663 | describe("using Node's interop", () => { 664 | const importingInterop = "node"; 665 | 666 | it("should import", () => { 667 | testModule( 668 | { importingInterop, importedInterop }, 669 | addNamed(), 670 | ` 671 | import _namespace from "source"; 672 | _namespace.read; 673 | `, 674 | ); 675 | }); 676 | 677 | it("should import with a force-disabled context", () => { 678 | testModule( 679 | { importingInterop, importedInterop, ensureNoContext: true }, 680 | addNamed(), 681 | ` 682 | import _namespace from "source"; 683 | 0, _namespace.read; 684 | `, 685 | ); 686 | }); 687 | }); 688 | 689 | describe("using Babel's interop", () => { 690 | const importingInterop = "babel"; 691 | 692 | it("should import", () => { 693 | testModule( 694 | { importingInterop, importedInterop }, 695 | addNamed(), 696 | ` 697 | import { read as _read } from "source"; 698 | _read; 699 | `, 700 | ); 701 | }); 702 | 703 | it("should import with a name hint", () => { 704 | testModule( 705 | { importingInterop, importedInterop }, 706 | addNamed({ nameHint: "hintedName" }), 707 | ` 708 | import { read as _hintedName } from "source"; 709 | _hintedName; 710 | `, 711 | ); 712 | }); 713 | }); 714 | 715 | describe("using a CommonJS loader", () => { 716 | it("should import", () => { 717 | testScript( 718 | { importedInterop }, 719 | addNamed(), 720 | ` 721 | var _read = require("source").read; 722 | _read; 723 | `, 724 | ); 725 | }); 726 | 727 | it("should import with a name hint", () => { 728 | testScript( 729 | { importedInterop }, 730 | addNamed({ nameHint: "hintedName" }), 731 | ` 732 | var _hintedName = require("source").read; 733 | _hintedName; 734 | `, 735 | ); 736 | }); 737 | 738 | it("should import with force-enabled liveness", () => { 739 | testScript( 740 | { importedInterop, ensureLiveReference: true }, 741 | addNamed(), 742 | ` 743 | var _namespace = require("source"); 744 | _namespace.read; 745 | `, 746 | ); 747 | }); 748 | }); 749 | }); 750 | 751 | describe("loading CommonJS with 'compiled'", () => { 752 | const importedInterop = "compiled"; 753 | 754 | describe("using Node's interop", () => { 755 | const importingInterop = "node"; 756 | 757 | it("should import", () => { 758 | testModule( 759 | { importingInterop, importedInterop }, 760 | addNamed(), 761 | ` 762 | import _namespace from "source"; 763 | _namespace.read; 764 | `, 765 | ); 766 | }); 767 | 768 | it("should import with a force-disabled context", () => { 769 | testModule( 770 | { importingInterop, importedInterop, ensureNoContext: true }, 771 | addNamed(), 772 | ` 773 | import _namespace from "source"; 774 | 0, _namespace.read; 775 | `, 776 | ); 777 | }); 778 | }); 779 | 780 | describe("using Babel's interop", () => { 781 | const importingInterop = "babel"; 782 | 783 | it("should import", () => { 784 | testModule( 785 | { importingInterop, importedInterop }, 786 | addNamed(), 787 | ` 788 | import { read as _read } from "source"; 789 | _read; 790 | `, 791 | ); 792 | }); 793 | 794 | it("should import with a name hint", () => { 795 | testModule( 796 | { importingInterop, importedInterop }, 797 | addNamed({ nameHint: "hintedName" }), 798 | ` 799 | import { read as _hintedName } from "source"; 800 | _hintedName; 801 | `, 802 | ); 803 | }); 804 | }); 805 | 806 | describe("using a CommonJS loader", () => { 807 | it("should import", () => { 808 | testScript( 809 | { importedInterop }, 810 | addNamed(), 811 | ` 812 | var _read = require("source").read; 813 | _read; 814 | `, 815 | ); 816 | }); 817 | 818 | it("should import with a name hint", () => { 819 | testScript( 820 | { importedInterop }, 821 | addNamed({ nameHint: "hintedName" }), 822 | ` 823 | var _hintedName = require("source").read; 824 | _hintedName; 825 | `, 826 | ); 827 | }); 828 | 829 | it("should import with force-enabled liveness", () => { 830 | testScript( 831 | { importedInterop, ensureLiveReference: true }, 832 | addNamed(), 833 | ` 834 | var _namespace = require("source"); 835 | _namespace.read; 836 | `, 837 | ); 838 | }); 839 | }); 840 | }); 841 | 842 | describe("loading CommonJS with 'babel'", () => { 843 | const importedInterop = "babel"; 844 | 845 | describe("using Node's interop", () => { 846 | const importingInterop = "node"; 847 | 848 | it("should import", () => { 849 | testModule( 850 | { importingInterop, importedInterop }, 851 | addNamed(), 852 | ` 853 | import _es6Default from "source"; 854 | _es6Default.read; 855 | `, 856 | ); 857 | }); 858 | }); 859 | 860 | describe("using Babel's interop", () => { 861 | const importingInterop = "babel"; 862 | 863 | it("should import", () => { 864 | testModule( 865 | { importingInterop, importedInterop }, 866 | addNamed(), 867 | ` 868 | import { read as _read } from "source"; 869 | _read; 870 | `, 871 | ); 872 | }); 873 | 874 | it("should import with a name hint", () => { 875 | testModule( 876 | { importingInterop, importedInterop }, 877 | addNamed({ nameHint: "hintedName" }), 878 | ` 879 | import { read as _hintedName } from "source"; 880 | _hintedName; 881 | `, 882 | ); 883 | }); 884 | }); 885 | 886 | describe("using a CommonJS loader", () => { 887 | it("should import", () => { 888 | testScript( 889 | { importedInterop }, 890 | addNamed(), 891 | ` 892 | var _read = require("source").read; 893 | _read; 894 | `, 895 | ); 896 | }); 897 | 898 | it("should import with a name hint", () => { 899 | testScript( 900 | { importedInterop }, 901 | addNamed({ nameHint: "hintedName" }), 902 | ` 903 | var _hintedName = require("source").read; 904 | _hintedName; 905 | `, 906 | ); 907 | }); 908 | 909 | it("should import with force-enabled liveness", () => { 910 | testScript( 911 | { importedInterop, ensureLiveReference: true }, 912 | addNamed(), 913 | ` 914 | var _namespace = require("source"); 915 | _namespace.read; 916 | `, 917 | ); 918 | }); 919 | }); 920 | }); 921 | }); 922 | 923 | describe("side-effectful imports", () => { 924 | const addSideEffect = opts => m => m.addSideEffect("source", opts); 925 | 926 | describe("loading an ES6 module", () => { 927 | const importedType = "es6"; 928 | 929 | describe("using Node's interop", () => { 930 | const importingInterop = "node"; 931 | 932 | it("should import", () => { 933 | testModule( 934 | { importingInterop, importedType }, 935 | addSideEffect(), 936 | ` 937 | import "source"; 938 | `, 939 | ); 940 | }); 941 | }); 942 | 943 | describe("using Babel's interop", () => { 944 | const importingInterop = "babel"; 945 | 946 | it("should import", () => { 947 | testModule( 948 | { importingInterop, importedType }, 949 | addSideEffect(), 950 | ` 951 | import "source"; 952 | `, 953 | ); 954 | }); 955 | }); 956 | 957 | describe("using a CommonJS loader", () => { 958 | it("should import", () => { 959 | chai 960 | .expect(() => { 961 | testScript({ importedType }, addSideEffect()); 962 | }) 963 | .to.throw(Error, "Cannot import an ES6 module from CommonJS"); 964 | }); 965 | }); 966 | }); 967 | 968 | describe("loading CommonJS with 'uncompiled'", () => { 969 | const importedInterop = "uncompiled"; 970 | 971 | describe("using Node's interop", () => { 972 | const importingInterop = "node"; 973 | 974 | it("should import", () => { 975 | testModule( 976 | { importingInterop, importedInterop }, 977 | addSideEffect(), 978 | ` 979 | import "source"; 980 | `, 981 | ); 982 | }); 983 | }); 984 | 985 | describe("using Babel's interop", () => { 986 | const importingInterop = "babel"; 987 | 988 | it("should import", () => { 989 | testModule( 990 | { importingInterop, importedInterop }, 991 | addSideEffect(), 992 | ` 993 | import "source"; 994 | `, 995 | ); 996 | }); 997 | }); 998 | 999 | describe("using a CommonJS loader", () => { 1000 | it("should import", () => { 1001 | testScript( 1002 | { importedInterop }, 1003 | addSideEffect(), 1004 | ` 1005 | require("source"); 1006 | `, 1007 | ); 1008 | }); 1009 | }); 1010 | }); 1011 | 1012 | describe("loading CommonJS with 'compiled'", () => { 1013 | const importedInterop = "compiled"; 1014 | 1015 | describe("using Node's interop", () => { 1016 | const importingInterop = "node"; 1017 | 1018 | it("should import", () => { 1019 | testModule( 1020 | { importingInterop, importedInterop }, 1021 | addSideEffect(), 1022 | ` 1023 | import "source"; 1024 | `, 1025 | ); 1026 | }); 1027 | }); 1028 | 1029 | describe("using Babel's interop", () => { 1030 | const importingInterop = "babel"; 1031 | 1032 | it("should import", () => { 1033 | testModule( 1034 | { importingInterop, importedInterop }, 1035 | addSideEffect(), 1036 | ` 1037 | import "source"; 1038 | `, 1039 | ); 1040 | }); 1041 | }); 1042 | 1043 | describe("using a CommonJS loader", () => { 1044 | it("should import", () => { 1045 | testScript( 1046 | { importedInterop }, 1047 | addSideEffect(), 1048 | ` 1049 | require("source"); 1050 | `, 1051 | ); 1052 | }); 1053 | }); 1054 | }); 1055 | 1056 | describe("loading CommonJS with 'babel'", () => { 1057 | const importedInterop = "babel"; 1058 | 1059 | describe("using Node's interop", () => { 1060 | const importingInterop = "node"; 1061 | 1062 | it("should import", () => { 1063 | testModule( 1064 | { importingInterop, importedInterop }, 1065 | addSideEffect(), 1066 | ` 1067 | import "source"; 1068 | `, 1069 | ); 1070 | }); 1071 | }); 1072 | 1073 | describe("using Babel's interop", () => { 1074 | const importingInterop = "babel"; 1075 | 1076 | it("should import", () => { 1077 | testModule( 1078 | { importingInterop, importedInterop }, 1079 | addSideEffect(), 1080 | ` 1081 | import "source"; 1082 | `, 1083 | ); 1084 | }); 1085 | }); 1086 | 1087 | describe("using a CommonJS loader", () => { 1088 | it("should import", () => { 1089 | testScript( 1090 | { importedInterop }, 1091 | addSideEffect(), 1092 | ` 1093 | require("source"); 1094 | `, 1095 | ); 1096 | }); 1097 | }); 1098 | }); 1099 | }); 1100 | }); 1101 | -------------------------------------------------------------------------------- /lib/definitions.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | exports.__esModule = true; 4 | exports.default = { 5 | builtins: { 6 | Symbol: "symbol", 7 | Promise: "promise", 8 | Map: "map", 9 | WeakMap: "weak-map", 10 | Set: "set", 11 | WeakSet: "weak-set", 12 | Observable: "observable", 13 | setImmediate: "set-immediate", 14 | clearImmediate: "clear-immediate", 15 | asap: "asap" 16 | }, 17 | methods: { 18 | Array: { 19 | copyWithin: "array/copy-within", 20 | entries: "array/entries", 21 | every: "array/every", 22 | fill: "array/fill", 23 | filter: "array/filter", 24 | findIndex: "array/find-index", 25 | find: "array/find", 26 | forEach: "array/for-each", 27 | from: "array/from", 28 | includes: "array/includes", 29 | indexOf: "array/index-of", 30 | join: "array/join", 31 | keys: "array/keys", 32 | lastIndexOf: "array/last-index-of", 33 | map: "array/map", 34 | of: "array/of", 35 | reduceRight: "array/reduce-right", 36 | reduce: "array/reduce", 37 | some: "array/some", 38 | sort: "array/sort", 39 | splice: "array/splice", 40 | values: "array/values" 41 | }, 42 | JSON: { 43 | stringify: "json/stringify" 44 | }, 45 | Object: { 46 | assign: "object/assign", 47 | create: "object/create", 48 | defineProperties: "object/define-properties", 49 | defineProperty: "object/define-property", 50 | entries: "object/entries", 51 | freeze: "object/freeze", 52 | getOwnPropertyDescriptor: "object/get-own-property-descriptor", 53 | getOwnPropertyDescriptors: "object/get-own-property-descriptors", 54 | getOwnPropertyNames: "object/get-own-property-names", 55 | getOwnPropertySymbols: "object/get-own-property-symbols", 56 | getPrototypeOf: "object/get-prototype-of", 57 | isExtensible: "object/is-extensible", 58 | isFrozen: "object/is-frozen", 59 | isSealed: "object/is-sealed", 60 | is: "object/is", 61 | keys: "object/keys", 62 | preventExtensions: "object/prevent-extensions", 63 | seal: "object/seal", 64 | setPrototypeOf: "object/set-prototype-of", 65 | values: "object/values" 66 | }, 67 | Math: { 68 | acosh: "math/acosh", 69 | asinh: "math/asinh", 70 | atanh: "math/atanh", 71 | cbrt: "math/cbrt", 72 | clz32: "math/clz32", 73 | cosh: "math/cosh", 74 | expm1: "math/expm1", 75 | fround: "math/fround", 76 | hypot: "math/hypot", 77 | imul: "math/imul", 78 | log10: "math/log10", 79 | log1p: "math/log1p", 80 | log2: "math/log2", 81 | sign: "math/sign", 82 | sinh: "math/sinh", 83 | tanh: "math/tanh", 84 | trunc: "math/trunc", 85 | iaddh: "math/iaddh", 86 | isubh: "math/isubh", 87 | imulh: "math/imulh", 88 | umulh: "math/umulh" 89 | }, 90 | Symbol: { 91 | for: "symbol/for", 92 | hasInstance: "symbol/has-instance", 93 | isConcatSpreadable: "symbol/is-concat-spreadable", 94 | iterator: "symbol/iterator", 95 | keyFor: "symbol/key-for", 96 | match: "symbol/match", 97 | replace: "symbol/replace", 98 | search: "symbol/search", 99 | species: "symbol/species", 100 | split: "symbol/split", 101 | toPrimitive: "symbol/to-primitive", 102 | toStringTag: "symbol/to-string-tag", 103 | unscopables: "symbol/unscopables" 104 | }, 105 | String: { 106 | at: "string/at", 107 | codePointAt: "string/code-point-at", 108 | endsWith: "string/ends-with", 109 | fromCodePoint: "string/from-code-point", 110 | includes: "string/includes", 111 | matchAll: "string/match-all", 112 | padStart: "string/pad-start", 113 | padEnd: "string/pad-end", 114 | raw: "string/raw", 115 | repeat: "string/repeat", 116 | startsWith: "string/starts-with", 117 | trim: "string/trim", 118 | trimLeft: "string/trim-left", 119 | trimRight: "string/trim-right", 120 | trimStart: "string/trim-start", 121 | trimEnd: "string/trim-end" 122 | }, 123 | Number: { 124 | EPSILON: "number/epsilon", 125 | isFinite: "number/is-finite", 126 | isInteger: "number/is-integer", 127 | isNaN: "number/is-nan", 128 | isSafeInteger: "number/is-safe-integer", 129 | MAX_SAFE_INTEGER: "number/max-safe-integer", 130 | MIN_SAFE_INTEGER: "number/min-safe-integer", 131 | parseFloat: "number/parse-float", 132 | parseInt: "number/parse-int" 133 | }, 134 | Reflect: { 135 | apply: "reflect/apply", 136 | construct: "reflect/construct", 137 | defineProperty: "reflect/define-property", 138 | deleteProperty: "reflect/delete-property", 139 | getOwnPropertyDescriptor: "reflect/get-own-property-descriptor", 140 | getPrototypeOf: "reflect/get-prototype-of", 141 | get: "reflect/get", 142 | has: "reflect/has", 143 | isExtensible: "reflect/is-extensible", 144 | ownKeys: "reflect/own-keys", 145 | preventExtensions: "reflect/prevent-extensions", 146 | setPrototypeOf: "reflect/set-prototype-of", 147 | set: "reflect/set", 148 | defineMetadata: "reflect/define-metadata", 149 | deleteMetadata: "reflect/delete-metadata", 150 | getMetadata: "reflect/get-metadata", 151 | getMetadataKeys: "reflect/get-metadata-keys", 152 | getOwnMetadata: "reflect/get-own-metadata", 153 | getOwnMetadataKeys: "reflect/get-own-metadata-keys", 154 | hasMetadata: "reflect/has-metadata", 155 | hasOwnMetadata: "reflect/has-own-metadata", 156 | metadata: "reflect/metadata" 157 | }, 158 | System: { 159 | global: "system/global" 160 | }, 161 | Date: {}, 162 | Function: {} 163 | } 164 | }; -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | exports.__esModule = true; 4 | exports.definitions = undefined; 5 | 6 | exports.default = function (_ref) { 7 | var t = _ref.types; 8 | 9 | function getRuntimeModuleName(opts) { 10 | return opts.moduleName || "babel-runtime"; 11 | } 12 | 13 | function has(obj, key) { 14 | return Object.prototype.hasOwnProperty.call(obj, key); 15 | } 16 | 17 | var HEADER_HELPERS = ["interopRequireWildcard", "interopRequireDefault"]; 18 | return { 19 | pre: function pre(file) { 20 | var _this = this; 21 | 22 | var moduleName = getRuntimeModuleName(this.opts); 23 | 24 | if (this.opts.helpers !== false) { 25 | var baseHelpersDir = this.opts.useBuiltIns ? "helpers/builtin" : "helpers"; 26 | var helpersDir = this.opts.useESModules ? baseHelpersDir + "/es6" : baseHelpersDir; 27 | file.set("helperGenerator", function (name) { 28 | var isInteropHelper = HEADER_HELPERS.indexOf(name) !== -1; 29 | var blockHoist = isInteropHelper && !(0, _babelHelperModuleImports.isModule)(file.path) ? 4 : undefined; 30 | return _this.addDefaultImport(moduleName + "/" + helpersDir + "/" + name, name, blockHoist); 31 | }); 32 | } 33 | 34 | if (this.opts.polyfill && this.opts.useBuiltIns) { 35 | throw new Error("The polyfill option conflicts with useBuiltIns; use one or the other"); 36 | } 37 | 38 | this.moduleName = moduleName; 39 | var cache = new Map(); 40 | 41 | this.addDefaultImport = function (source, nameHint, blockHoist) { 42 | var cacheKey = (0, _babelHelperModuleImports.isModule)(file.path); 43 | var key = source + ":" + nameHint + ":" + (cacheKey || ""); 44 | var cached = cache.get(key); 45 | 46 | if (cached) { 47 | cached = t.cloneDeep(cached); 48 | } else { 49 | cached = (0, _babelHelperModuleImports.addDefault)(file.path, source, { 50 | importedInterop: "uncompiled", 51 | nameHint: nameHint, 52 | blockHoist: blockHoist 53 | }); 54 | cache.set(key, cached); 55 | } 56 | 57 | return cached; 58 | }; 59 | }, 60 | visitor: { 61 | ReferencedIdentifier: function ReferencedIdentifier(path, state) { 62 | var node = path.node, 63 | parent = path.parent, 64 | scope = path.scope; 65 | 66 | if (node.name === "regeneratorRuntime" && state.opts.regenerator !== false) { 67 | path.replaceWith(this.addDefaultImport(this.moduleName + "/regenerator", "regeneratorRuntime")); 68 | return; 69 | } 70 | 71 | if (state.opts.polyfill === false || state.opts.useBuiltIns) return; 72 | if (t.isMemberExpression(parent)) return; 73 | if (!has(_definitions2.default.builtins, node.name)) return; 74 | if (scope.getBindingIdentifier(node.name)) return; 75 | var moduleName = getRuntimeModuleName(state.opts); 76 | path.replaceWith(this.addDefaultImport(moduleName + "/core-js/" + _definitions2.default.builtins[node.name], node.name)); 77 | }, 78 | CallExpression: function CallExpression(path, state) { 79 | if (state.opts.polyfill === false || state.opts.useBuiltIns) return; 80 | if (path.node.arguments.length) return; 81 | var callee = path.node.callee; 82 | if (!t.isMemberExpression(callee)) return; 83 | if (!callee.computed) return; 84 | 85 | if (!path.get("callee.property").matchesPattern("Symbol.iterator")) { 86 | return; 87 | } 88 | 89 | var moduleName = getRuntimeModuleName(state.opts); 90 | path.replaceWith(t.callExpression(this.addDefaultImport(moduleName + "/core-js/get-iterator", "getIterator"), [callee.object])); 91 | }, 92 | BinaryExpression: function BinaryExpression(path, state) { 93 | if (state.opts.polyfill === false || state.opts.useBuiltIns) return; 94 | if (path.node.operator !== "in") return; 95 | if (!path.get("left").matchesPattern("Symbol.iterator")) return; 96 | var moduleName = getRuntimeModuleName(state.opts); 97 | path.replaceWith(t.callExpression(this.addDefaultImport(moduleName + "/core-js/is-iterable", "isIterable"), [path.node.right])); 98 | }, 99 | MemberExpression: { 100 | enter: function enter(path, state) { 101 | if (state.opts.polyfill === false || state.opts.useBuiltIns) return; 102 | if (!path.isReferenced()) return; 103 | var node = path.node; 104 | var obj = node.object; 105 | var prop = node.property; 106 | if (!t.isReferenced(obj, node)) return; 107 | if (node.computed) return; 108 | if (!has(_definitions2.default.methods, obj.name)) return; 109 | var methods = _definitions2.default.methods[obj.name]; 110 | if (!has(methods, prop.name)) return; 111 | if (path.scope.getBindingIdentifier(obj.name)) return; 112 | 113 | if (obj.name === "Object" && prop.name === "defineProperty" && path.parentPath.isCallExpression()) { 114 | var call = path.parentPath.node; 115 | 116 | if (call.arguments.length === 3 && t.isLiteral(call.arguments[1])) { 117 | return; 118 | } 119 | } 120 | 121 | var moduleName = getRuntimeModuleName(state.opts); 122 | path.replaceWith(this.addDefaultImport(moduleName + "/core-js/" + methods[prop.name], obj.name + "$" + prop.name)); 123 | }, 124 | exit: function exit(path, state) { 125 | if (state.opts.polyfill === false || state.opts.useBuiltIns) return; 126 | if (!path.isReferenced()) return; 127 | var node = path.node; 128 | var obj = node.object; 129 | if (!has(_definitions2.default.builtins, obj.name)) return; 130 | if (path.scope.getBindingIdentifier(obj.name)) return; 131 | var moduleName = getRuntimeModuleName(state.opts); 132 | path.replaceWith(t.memberExpression(this.addDefaultImport(moduleName + "/core-js/" + _definitions2.default.builtins[obj.name], obj.name), node.property, node.computed)); 133 | } 134 | } 135 | } 136 | }; 137 | }; 138 | 139 | var _babelHelperModuleImports = require("../babel-helper-module-imports"); 140 | 141 | var _definitions = require("./definitions"); 142 | 143 | var _definitions2 = _interopRequireDefault(_definitions); 144 | 145 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 146 | 147 | exports.definitions = _definitions2.default; 148 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-plugin-transform-runtime", 3 | "version": "7.0.0-beta.2", 4 | "description": "Externalise references to helpers and builtins, automatically polyfilling your code without polluting globals", 5 | "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-runtime", 6 | "license": "MIT", 7 | "main": "lib/index.js", 8 | "keywords": [ 9 | "babel-plugin" 10 | ], 11 | "dependencies": { 12 | }, 13 | "devDependencies": { 14 | "babel-helper-plugin-test-runner": "7.0.0-beta.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/definitions.js: -------------------------------------------------------------------------------- 1 | export default { 2 | builtins: { 3 | Symbol: "symbol", 4 | Promise: "promise", 5 | Map: "map", 6 | WeakMap: "weak-map", 7 | Set: "set", 8 | WeakSet: "weak-set", 9 | Observable: "observable", 10 | setImmediate: "set-immediate", 11 | clearImmediate: "clear-immediate", 12 | asap: "asap", 13 | //parseFloat: "parse-float", // temporary disabled 14 | //parseInt: "parse-int" // temporary disabled 15 | }, 16 | 17 | methods: { 18 | Array: { 19 | copyWithin: "array/copy-within", 20 | entries: "array/entries", 21 | every: "array/every", 22 | fill: "array/fill", 23 | filter: "array/filter", 24 | findIndex: "array/find-index", 25 | find: "array/find", 26 | forEach: "array/for-each", 27 | from: "array/from", 28 | includes: "array/includes", 29 | indexOf: "array/index-of", 30 | //isArray: "array/is-array", // temporary disabled 31 | join: "array/join", 32 | keys: "array/keys", 33 | lastIndexOf: "array/last-index-of", 34 | map: "array/map", 35 | of: "array/of", 36 | reduceRight: "array/reduce-right", 37 | reduce: "array/reduce", 38 | some: "array/some", 39 | sort: "array/sort", 40 | splice: "array/splice", 41 | values: "array/values", 42 | }, 43 | 44 | JSON: { 45 | stringify: "json/stringify", 46 | }, 47 | 48 | Object: { 49 | assign: "object/assign", 50 | create: "object/create", 51 | defineProperties: "object/define-properties", 52 | defineProperty: "object/define-property", 53 | entries: "object/entries", 54 | freeze: "object/freeze", 55 | getOwnPropertyDescriptor: "object/get-own-property-descriptor", 56 | getOwnPropertyDescriptors: "object/get-own-property-descriptors", 57 | getOwnPropertyNames: "object/get-own-property-names", 58 | getOwnPropertySymbols: "object/get-own-property-symbols", 59 | getPrototypeOf: "object/get-prototype-of", 60 | isExtensible: "object/is-extensible", 61 | isFrozen: "object/is-frozen", 62 | isSealed: "object/is-sealed", 63 | is: "object/is", 64 | keys: "object/keys", 65 | preventExtensions: "object/prevent-extensions", 66 | seal: "object/seal", 67 | setPrototypeOf: "object/set-prototype-of", 68 | values: "object/values", 69 | }, 70 | 71 | Math: { 72 | acosh: "math/acosh", 73 | asinh: "math/asinh", 74 | atanh: "math/atanh", 75 | cbrt: "math/cbrt", 76 | clz32: "math/clz32", 77 | cosh: "math/cosh", 78 | expm1: "math/expm1", 79 | fround: "math/fround", 80 | hypot: "math/hypot", 81 | imul: "math/imul", 82 | log10: "math/log10", 83 | log1p: "math/log1p", 84 | log2: "math/log2", 85 | sign: "math/sign", 86 | sinh: "math/sinh", 87 | tanh: "math/tanh", 88 | trunc: "math/trunc", 89 | iaddh: "math/iaddh", 90 | isubh: "math/isubh", 91 | imulh: "math/imulh", 92 | umulh: "math/umulh", 93 | }, 94 | 95 | Symbol: { 96 | for: "symbol/for", 97 | hasInstance: "symbol/has-instance", 98 | isConcatSpreadable: "symbol/is-concat-spreadable", 99 | iterator: "symbol/iterator", 100 | keyFor: "symbol/key-for", 101 | match: "symbol/match", 102 | replace: "symbol/replace", 103 | search: "symbol/search", 104 | species: "symbol/species", 105 | split: "symbol/split", 106 | toPrimitive: "symbol/to-primitive", 107 | toStringTag: "symbol/to-string-tag", 108 | unscopables: "symbol/unscopables", 109 | }, 110 | 111 | String: { 112 | at: "string/at", 113 | codePointAt: "string/code-point-at", 114 | endsWith: "string/ends-with", 115 | fromCodePoint: "string/from-code-point", 116 | includes: "string/includes", 117 | matchAll: "string/match-all", 118 | padStart: "string/pad-start", 119 | padEnd: "string/pad-end", 120 | raw: "string/raw", 121 | repeat: "string/repeat", 122 | startsWith: "string/starts-with", 123 | trim: "string/trim", 124 | trimLeft: "string/trim-left", 125 | trimRight: "string/trim-right", 126 | trimStart: "string/trim-start", 127 | trimEnd: "string/trim-end", 128 | }, 129 | 130 | Number: { 131 | EPSILON: "number/epsilon", 132 | isFinite: "number/is-finite", 133 | isInteger: "number/is-integer", 134 | isNaN: "number/is-nan", 135 | isSafeInteger: "number/is-safe-integer", 136 | MAX_SAFE_INTEGER: "number/max-safe-integer", 137 | MIN_SAFE_INTEGER: "number/min-safe-integer", 138 | parseFloat: "number/parse-float", 139 | parseInt: "number/parse-int", 140 | }, 141 | 142 | Reflect: { 143 | apply: "reflect/apply", 144 | construct: "reflect/construct", 145 | defineProperty: "reflect/define-property", 146 | deleteProperty: "reflect/delete-property", 147 | getOwnPropertyDescriptor: "reflect/get-own-property-descriptor", 148 | getPrototypeOf: "reflect/get-prototype-of", 149 | get: "reflect/get", 150 | has: "reflect/has", 151 | isExtensible: "reflect/is-extensible", 152 | ownKeys: "reflect/own-keys", 153 | preventExtensions: "reflect/prevent-extensions", 154 | setPrototypeOf: "reflect/set-prototype-of", 155 | set: "reflect/set", 156 | defineMetadata: "reflect/define-metadata", 157 | deleteMetadata: "reflect/delete-metadata", 158 | getMetadata: "reflect/get-metadata", 159 | getMetadataKeys: "reflect/get-metadata-keys", 160 | getOwnMetadata: "reflect/get-own-metadata", 161 | getOwnMetadataKeys: "reflect/get-own-metadata-keys", 162 | hasMetadata: "reflect/has-metadata", 163 | hasOwnMetadata: "reflect/has-own-metadata", 164 | metadata: "reflect/metadata", 165 | }, 166 | 167 | System: { 168 | global: "system/global", 169 | }, 170 | 171 | Date: { 172 | //now: "date/now" // temporary disabled 173 | }, 174 | 175 | Function: { 176 | // Warning: /virtual/ method - prototype, not static, version 177 | //bind: "function/virtual/bind" // temporary disabled 178 | }, 179 | }, 180 | }; 181 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { addDefault, isModule } from "../babel-helper-module-imports"; 2 | 3 | import definitions from "./definitions"; 4 | 5 | export default function({ types: t }) { 6 | function getRuntimeModuleName(opts) { 7 | return opts.moduleName || "babel-runtime"; 8 | } 9 | 10 | function has(obj, key) { 11 | return Object.prototype.hasOwnProperty.call(obj, key); 12 | } 13 | 14 | const HEADER_HELPERS = ["interopRequireWildcard", "interopRequireDefault"]; 15 | 16 | return { 17 | pre(file) { 18 | const moduleName = getRuntimeModuleName(this.opts); 19 | 20 | if (this.opts.helpers !== false) { 21 | const baseHelpersDir = this.opts.useBuiltIns 22 | ? "helpers/builtin" 23 | : "helpers"; 24 | const helpersDir = this.opts.useESModules 25 | ? `${baseHelpersDir}/es6` 26 | : baseHelpersDir; 27 | file.set("helperGenerator", name => { 28 | const isInteropHelper = HEADER_HELPERS.indexOf(name) !== -1; 29 | 30 | // Explicitly set the CommonJS interop helpers to their reserve 31 | // blockHoist of 4 so they are guaranteed to exist 32 | // when other things used them to import. 33 | const blockHoist = 34 | isInteropHelper && !isModule(file.path) ? 4 : undefined; 35 | 36 | return this.addDefaultImport( 37 | `${moduleName}/${helpersDir}/${name}`, 38 | name, 39 | blockHoist, 40 | ); 41 | }); 42 | } 43 | 44 | if (this.opts.polyfill && this.opts.useBuiltIns) { 45 | throw new Error( 46 | "The polyfill option conflicts with useBuiltIns; use one or the other", 47 | ); 48 | } 49 | 50 | this.moduleName = moduleName; 51 | 52 | const cache = new Map(); 53 | 54 | this.addDefaultImport = (source, nameHint, blockHoist) => { 55 | // If something on the page adds a helper when the file is an ES6 56 | // file, we can't reused the cached helper name after things have been 57 | // transformed because it has almost certainly been renamed. 58 | const cacheKey = isModule(file.path); 59 | const key = `${source}:${nameHint}:${cacheKey || ""}`; 60 | 61 | let cached = cache.get(key); 62 | if (cached) { 63 | cached = t.cloneDeep(cached); 64 | } else { 65 | cached = addDefault(file.path, source, { 66 | importedInterop: "uncompiled", 67 | nameHint, 68 | blockHoist, 69 | }); 70 | 71 | cache.set(key, cached); 72 | } 73 | return cached; 74 | }; 75 | }, 76 | 77 | visitor: { 78 | ReferencedIdentifier(path, state) { 79 | const { node, parent, scope } = path; 80 | if ( 81 | node.name === "regeneratorRuntime" && 82 | state.opts.regenerator !== false 83 | ) { 84 | path.replaceWith( 85 | this.addDefaultImport( 86 | `${this.moduleName}/regenerator`, 87 | "regeneratorRuntime", 88 | ), 89 | ); 90 | return; 91 | } 92 | 93 | if (state.opts.polyfill === false || state.opts.useBuiltIns) return; 94 | 95 | if (t.isMemberExpression(parent)) return; 96 | if (!has(definitions.builtins, node.name)) return; 97 | if (scope.getBindingIdentifier(node.name)) return; 98 | 99 | // Symbol() -> _core.Symbol(); new Promise -> new _core.Promise 100 | const moduleName = getRuntimeModuleName(state.opts); 101 | path.replaceWith( 102 | this.addDefaultImport( 103 | `${moduleName}/core-js/${definitions.builtins[node.name]}`, 104 | node.name, 105 | ), 106 | ); 107 | }, 108 | 109 | // arr[Symbol.iterator]() -> _core.$for.getIterator(arr) 110 | CallExpression(path, state) { 111 | if (state.opts.polyfill === false || state.opts.useBuiltIns) return; 112 | 113 | // we can't compile this 114 | if (path.node.arguments.length) return; 115 | 116 | const callee = path.node.callee; 117 | if (!t.isMemberExpression(callee)) return; 118 | if (!callee.computed) return; 119 | if (!path.get("callee.property").matchesPattern("Symbol.iterator")) { 120 | return; 121 | } 122 | 123 | const moduleName = getRuntimeModuleName(state.opts); 124 | path.replaceWith( 125 | t.callExpression( 126 | this.addDefaultImport( 127 | `${moduleName}/core-js/get-iterator`, 128 | "getIterator", 129 | ), 130 | [callee.object], 131 | ), 132 | ); 133 | }, 134 | 135 | // Symbol.iterator in arr -> core.$for.isIterable(arr) 136 | BinaryExpression(path, state) { 137 | if (state.opts.polyfill === false || state.opts.useBuiltIns) return; 138 | 139 | if (path.node.operator !== "in") return; 140 | if (!path.get("left").matchesPattern("Symbol.iterator")) return; 141 | 142 | const moduleName = getRuntimeModuleName(state.opts); 143 | path.replaceWith( 144 | t.callExpression( 145 | this.addDefaultImport( 146 | `${moduleName}/core-js/is-iterable`, 147 | "isIterable", 148 | ), 149 | [path.node.right], 150 | ), 151 | ); 152 | }, 153 | 154 | // Array.from -> _core.Array.from 155 | MemberExpression: { 156 | enter(path, state) { 157 | if (state.opts.polyfill === false || state.opts.useBuiltIns) return; 158 | if (!path.isReferenced()) return; 159 | 160 | const { node } = path; 161 | const obj = node.object; 162 | const prop = node.property; 163 | 164 | if (!t.isReferenced(obj, node)) return; 165 | if (node.computed) return; 166 | if (!has(definitions.methods, obj.name)) return; 167 | 168 | const methods = definitions.methods[obj.name]; 169 | if (!has(methods, prop.name)) return; 170 | 171 | // doesn't reference the global 172 | if (path.scope.getBindingIdentifier(obj.name)) return; 173 | 174 | // special case Object.defineProperty to not use core-js when using string keys 175 | if ( 176 | obj.name === "Object" && 177 | prop.name === "defineProperty" && 178 | path.parentPath.isCallExpression() 179 | ) { 180 | const call = path.parentPath.node; 181 | if (call.arguments.length === 3 && t.isLiteral(call.arguments[1])) { 182 | return; 183 | } 184 | } 185 | 186 | const moduleName = getRuntimeModuleName(state.opts); 187 | path.replaceWith( 188 | this.addDefaultImport( 189 | `${moduleName}/core-js/${methods[prop.name]}`, 190 | `${obj.name}$${prop.name}`, 191 | ), 192 | ); 193 | }, 194 | 195 | exit(path, state) { 196 | if (state.opts.polyfill === false || state.opts.useBuiltIns) return; 197 | if (!path.isReferenced()) return; 198 | 199 | const { node } = path; 200 | const obj = node.object; 201 | 202 | if (!has(definitions.builtins, obj.name)) return; 203 | if (path.scope.getBindingIdentifier(obj.name)) return; 204 | 205 | const moduleName = getRuntimeModuleName(state.opts); 206 | path.replaceWith( 207 | t.memberExpression( 208 | this.addDefaultImport( 209 | `${moduleName}/core-js/${definitions.builtins[obj.name]}`, 210 | obj.name, 211 | ), 212 | node.property, 213 | node.computed, 214 | ), 215 | ); 216 | }, 217 | }, 218 | }, 219 | }; 220 | } 221 | 222 | export { definitions }; 223 | -------------------------------------------------------------------------------- /src/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-runtime", "transform-regenerator"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/aliased-constructors/actual.js: -------------------------------------------------------------------------------- 1 | obj.constructor === Object; 2 | obj.constructor === Promise; 3 | 4 | Symbol(); 5 | Symbol("test"); 6 | 7 | new Map(); 8 | -------------------------------------------------------------------------------- /test/fixtures/runtime/aliased-constructors/expected.js: -------------------------------------------------------------------------------- 1 | var _Map = require("babel-runtime/core-js/map"); 2 | 3 | var _Symbol = require("babel-runtime/core-js/symbol"); 4 | 5 | var _Promise = require("babel-runtime/core-js/promise"); 6 | 7 | obj.constructor === Object; 8 | obj.constructor === _Promise; 9 | 10 | _Symbol(); 11 | 12 | _Symbol("test"); 13 | 14 | new _Map(); 15 | -------------------------------------------------------------------------------- /test/fixtures/runtime/aliased-constructors/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-runtime", "transform-regenerator"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/catch-all/actual.js: -------------------------------------------------------------------------------- 1 | Promise.resolve; 2 | -------------------------------------------------------------------------------- /test/fixtures/runtime/catch-all/expected.js: -------------------------------------------------------------------------------- 1 | var _Promise = require("babel-runtime/core-js/promise"); 2 | 3 | _Promise.resolve; 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/catch-all/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-runtime", "transform-regenerator"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/class/actual.js: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | -------------------------------------------------------------------------------- /test/fixtures/runtime/class/expected.js: -------------------------------------------------------------------------------- 1 | var _classCallCheck = require("babel-runtime/helpers/classCallCheck"); 2 | 3 | let Foo = function Foo() { 4 | _classCallCheck(this, Foo); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/runtime/class/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-runtime", "transform-es2015-classes"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/custom-runtime/actual.js: -------------------------------------------------------------------------------- 1 | import foo, * as bar from "someModule"; 2 | 3 | export const myWord = Symbol("abc"); 4 | export function* giveWord () { 5 | yield myWord; 6 | } 7 | 8 | foo; 9 | bar; 10 | -------------------------------------------------------------------------------- /test/fixtures/runtime/custom-runtime/expected.js: -------------------------------------------------------------------------------- 1 | import _regeneratorRuntime from "foo/regenerator"; 2 | import _Symbol from "foo/core-js/symbol"; 3 | 4 | var _marked = 5 | /*#__PURE__*/ 6 | _regeneratorRuntime.mark(giveWord); 7 | 8 | import foo, * as bar from "someModule"; 9 | export const myWord = _Symbol("abc"); 10 | export function giveWord() { 11 | return _regeneratorRuntime.wrap(function giveWord$(_context) { 12 | while (1) switch (_context.prev = _context.next) { 13 | case 0: 14 | _context.next = 2; 15 | return myWord; 16 | 17 | case 2: 18 | case "end": 19 | return _context.stop(); 20 | } 21 | }, _marked, this); 22 | } 23 | foo; 24 | bar; 25 | -------------------------------------------------------------------------------- /test/fixtures/runtime/custom-runtime/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [["transform-runtime", { "moduleName": "foo" }], "transform-regenerator"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/es6-for-of/actual.js: -------------------------------------------------------------------------------- 1 | for (var i of arr) { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/es6-for-of/expected.js: -------------------------------------------------------------------------------- 1 | var _getIterator = require("babel-runtime/core-js/get-iterator"); 2 | 3 | var _iteratorNormalCompletion = true; 4 | var _didIteratorError = false; 5 | var _iteratorError = undefined; 6 | 7 | try { 8 | for (var _iterator = _getIterator(arr), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { 9 | var i = _step.value; 10 | } 11 | } catch (err) { 12 | _didIteratorError = true; 13 | _iteratorError = err; 14 | } finally { 15 | try { 16 | if (!_iteratorNormalCompletion && _iterator.return != null) { 17 | _iterator.return(); 18 | } 19 | } finally { 20 | if (_didIteratorError) { 21 | throw _iteratorError; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/runtime/es6-for-of/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-es2015-for-of", "transform-runtime"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/full/actual.js: -------------------------------------------------------------------------------- 1 | import foo, * as bar from "someModule"; 2 | 3 | export const myWord = Symbol("abc"); 4 | export function* giveWord () { 5 | yield myWord; 6 | } 7 | 8 | foo; 9 | bar; 10 | -------------------------------------------------------------------------------- /test/fixtures/runtime/full/expected.js: -------------------------------------------------------------------------------- 1 | import _regeneratorRuntime from "babel-runtime/regenerator"; 2 | import _Symbol from "babel-runtime/core-js/symbol"; 3 | 4 | var _marked = 5 | /*#__PURE__*/ 6 | _regeneratorRuntime.mark(giveWord); 7 | 8 | import foo, * as bar from "someModule"; 9 | export const myWord = _Symbol("abc"); 10 | export function giveWord() { 11 | return _regeneratorRuntime.wrap(function giveWord$(_context) { 12 | while (1) switch (_context.prev = _context.next) { 13 | case 0: 14 | _context.next = 2; 15 | return myWord; 16 | 17 | case 2: 18 | case "end": 19 | return _context.stop(); 20 | } 21 | }, _marked, this); 22 | } 23 | foo; 24 | bar; 25 | -------------------------------------------------------------------------------- /test/fixtures/runtime/full/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-runtime", "transform-regenerator"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/modules-helpers/actual.mjs: -------------------------------------------------------------------------------- 1 | import foo from "foo"; 2 | 3 | class Example { 4 | method() {} 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/runtime/modules-helpers/expected.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var _interopRequireDefault = require("babel-runtime/helpers/interopRequireDefault"); 4 | 5 | var _classCallCheck2 = _interopRequireDefault(require("babel-runtime/helpers/classCallCheck")); 6 | 7 | var _createClass2 = _interopRequireDefault(require("babel-runtime/helpers/createClass")); 8 | 9 | var _foo = _interopRequireDefault(require("foo")); 10 | 11 | let Example = 12 | /*#__PURE__*/ 13 | function () { 14 | function Example() { 15 | (0, _classCallCheck2.default)(this, Example); 16 | } 17 | 18 | (0, _createClass2.default)(Example, [{ 19 | key: "method", 20 | value: function method() {} 21 | }]); 22 | return Example; 23 | }(); 24 | -------------------------------------------------------------------------------- /test/fixtures/runtime/modules-helpers/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "transform-runtime", 4 | "transform-es2015-modules-commonjs", 5 | "transform-es2015-classes" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/runtime/modules/actual.js: -------------------------------------------------------------------------------- 1 | import foo from "bar"; 2 | foo; 3 | 4 | export * from "mod"; 5 | -------------------------------------------------------------------------------- /test/fixtures/runtime/modules/expected.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var _interopRequireDefault = require("babel-runtime/helpers/interopRequireDefault"); 4 | 5 | var _Object$defineProperty = require("babel-runtime/core-js/object/define-property"); 6 | 7 | var _Object$keys = require("babel-runtime/core-js/object/keys"); 8 | 9 | Object.defineProperty(exports, "__esModule", { 10 | value: true 11 | }); 12 | 13 | var _bar = _interopRequireDefault(require("bar")); 14 | 15 | var _mod = require("mod"); 16 | 17 | _Object$keys(_mod).forEach(function (key) { 18 | if (key === "default" || key === "__esModule") return; 19 | 20 | _Object$defineProperty(exports, key, { 21 | enumerable: true, 22 | get: function () { 23 | return _mod[key]; 24 | } 25 | }); 26 | }); 27 | 28 | _bar.default; 29 | -------------------------------------------------------------------------------- /test/fixtures/runtime/modules/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-runtime", "transform-es2015-modules-commonjs"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/no-helpers/actual.js: -------------------------------------------------------------------------------- 1 | class Foo {} 2 | -------------------------------------------------------------------------------- /test/fixtures/runtime/no-helpers/expected.js: -------------------------------------------------------------------------------- 1 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 2 | 3 | let Foo = function Foo() { 4 | _classCallCheck(this, Foo); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/runtime/no-helpers/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [["transform-runtime", { "helpers": false }], "transform-es2015-classes"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/regenerator-runtime/actual.js: -------------------------------------------------------------------------------- 1 | void function* () { 2 | }; 3 | -------------------------------------------------------------------------------- /test/fixtures/runtime/regenerator-runtime/expected.js: -------------------------------------------------------------------------------- 1 | var _regeneratorRuntime = require("babel-runtime/regenerator"); 2 | 3 | void 4 | /*#__PURE__*/ 5 | _regeneratorRuntime.mark(function _callee() { 6 | return _regeneratorRuntime.wrap(function _callee$(_context) { 7 | while (1) switch (_context.prev = _context.next) { 8 | case 0: 9 | case "end": 10 | return _context.stop(); 11 | } 12 | }, _callee, this); 13 | }); 14 | -------------------------------------------------------------------------------- /test/fixtures/runtime/regenerator-runtime/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-runtime", "transform-regenerator"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/symbol-iterator-in/actual.js: -------------------------------------------------------------------------------- 1 | Symbol.iterator in Object(arr); 2 | -------------------------------------------------------------------------------- /test/fixtures/runtime/symbol-iterator-in/expected.js: -------------------------------------------------------------------------------- 1 | var _isIterable = require("babel-runtime/core-js/is-iterable"); 2 | 3 | _isIterable(Object(arr)); 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/symbol-iterator-in/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-runtime", "transform-regenerator"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/symbol-iterator/actual.js: -------------------------------------------------------------------------------- 1 | Symbol.iterator; 2 | -------------------------------------------------------------------------------- /test/fixtures/runtime/symbol-iterator/expected.js: -------------------------------------------------------------------------------- 1 | var _Symbol$iterator = require("babel-runtime/core-js/symbol/iterator"); 2 | 3 | _Symbol$iterator; 4 | -------------------------------------------------------------------------------- /test/fixtures/runtime/symbol-iterator/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-runtime", "transform-regenerator"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/use-options/useBuiltIns-useESModules/actual.js: -------------------------------------------------------------------------------- 1 | class Foo extends Bar {} 2 | -------------------------------------------------------------------------------- /test/fixtures/use-options/useBuiltIns-useESModules/expected.js: -------------------------------------------------------------------------------- 1 | var _classCallCheck = require("babel-runtime/helpers/builtin/es6/classCallCheck"); 2 | 3 | var _possibleConstructorReturn = require("babel-runtime/helpers/builtin/es6/possibleConstructorReturn"); 4 | 5 | var _inherits = require("babel-runtime/helpers/builtin/es6/inherits"); 6 | 7 | let Foo = 8 | /*#__PURE__*/ 9 | function (_Bar) { 10 | _inherits(Foo, _Bar); 11 | 12 | function Foo() { 13 | _classCallCheck(this, Foo); 14 | 15 | return _possibleConstructorReturn(this, (Foo.__proto__ || Object.getPrototypeOf(Foo)).apply(this, arguments)); 16 | } 17 | 18 | return Foo; 19 | }(Bar); 20 | -------------------------------------------------------------------------------- /test/fixtures/use-options/useBuiltIns-useESModules/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [["transform-runtime", { "useBuiltIns": true, "useESModules": true }], "transform-es2015-classes"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/use-options/useBuiltIns/actual.js: -------------------------------------------------------------------------------- 1 | class Foo extends Bar {} 2 | -------------------------------------------------------------------------------- /test/fixtures/use-options/useBuiltIns/expected.js: -------------------------------------------------------------------------------- 1 | var _classCallCheck = require("babel-runtime/helpers/builtin/classCallCheck"); 2 | 3 | var _possibleConstructorReturn = require("babel-runtime/helpers/builtin/possibleConstructorReturn"); 4 | 5 | var _inherits = require("babel-runtime/helpers/builtin/inherits"); 6 | 7 | let Foo = 8 | /*#__PURE__*/ 9 | function (_Bar) { 10 | _inherits(Foo, _Bar); 11 | 12 | function Foo() { 13 | _classCallCheck(this, Foo); 14 | 15 | return _possibleConstructorReturn(this, (Foo.__proto__ || Object.getPrototypeOf(Foo)).apply(this, arguments)); 16 | } 17 | 18 | return Foo; 19 | }(Bar); 20 | -------------------------------------------------------------------------------- /test/fixtures/use-options/useBuiltIns/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [["transform-runtime", { "useBuiltIns": true }], "transform-es2015-classes"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/use-options/useESModules/actual.js: -------------------------------------------------------------------------------- 1 | class Foo extends Bar {} 2 | -------------------------------------------------------------------------------- /test/fixtures/use-options/useESModules/expected.js: -------------------------------------------------------------------------------- 1 | var _Object$getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of"); 2 | 3 | var _classCallCheck = require("babel-runtime/helpers/es6/classCallCheck"); 4 | 5 | var _possibleConstructorReturn = require("babel-runtime/helpers/es6/possibleConstructorReturn"); 6 | 7 | var _inherits = require("babel-runtime/helpers/es6/inherits"); 8 | 9 | let Foo = 10 | /*#__PURE__*/ 11 | function (_Bar) { 12 | _inherits(Foo, _Bar); 13 | 14 | function Foo() { 15 | _classCallCheck(this, Foo); 16 | 17 | return _possibleConstructorReturn(this, (Foo.__proto__ || _Object$getPrototypeOf(Foo)).apply(this, arguments)); 18 | } 19 | 20 | return Foo; 21 | }(Bar); 22 | -------------------------------------------------------------------------------- /test/fixtures/use-options/useESModules/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [["transform-runtime", { "useESModules": true }], "transform-es2015-classes"] 3 | } 4 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | import runner from "babel-helper-plugin-test-runner"; 2 | 3 | runner(__dirname); 4 | --------------------------------------------------------------------------------