From 10dfcf72eac57200595abc5529b231d5ffcad12e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Tue, 6 Apr 2021 12:36:22 +0200 Subject: [PATCH 1/2] Document the `importInterop` option --- docs/plugin-transform-modules-commonjs.md | 114 +++++++++++++++++----- 1 file changed, 92 insertions(+), 22 deletions(-) diff --git a/docs/plugin-transform-modules-commonjs.md b/docs/plugin-transform-modules-commonjs.md index f9fa68c43c..deefbee7ba 100644 --- a/docs/plugin-transform-modules-commonjs.md +++ b/docs/plugin-transform-modules-commonjs.md @@ -68,6 +68,90 @@ require("@babel/core").transformSync("code", { ## Options +### `importInterop` + +`"babel" | "node" | "none"`, or `(specifier: string) => "babel" | "node" | "none"`. Defaults to `"babel"`. + +CommonJS modules and ECMAScript modules are not fully compatible. However, compilers, bundlers and JavaScript +runtimes developed different strategies to make them work together as well as possible. + +This option specify which interop strategy Babel should use. When it's a function, Babel calls this function +passing the import specifier (for example, `@babel/core` in `import { transform } from "@babel/core"`), and the +function should return the interop to use for that specific import. + +#### `"babel"` + +When using exports with babel a non-enumerable `__esModule` property is exported. This property is then used to determine if the import _is_ the default export or if it _contains_ the default export. + +```javascript +import foo from "foo"; +import { bar } from "bar"; +foo; +bar; + +// Is compiled to ... + +"use strict"; + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; +} + +var _foo = _interopRequireDefault(require("foo")); +var _bar = require("bar"); + +_foo.default; +_bar.bar; +``` + +When this import interop is used, if both the imported and the importer module are compiled with Babel they behave as if none of them was copiled. + +This is the default behavior. + +#### `"node"` + +When importing CommonJS files (either directly written in CommonJS, or generated with a compiler) Node.js always binds the `default` export to the value of `module.exports`. + +```javascript +import foo from "foo"; +import { bar } from "bar"; +foo; +bar; + +// Is compiled to ... + +"use strict"; + +var _foo = require("foo"); +var _bar = require("bar"); + +_foo; +_bar.bar; +``` + +This is not exactly the same as what Node.js does since Babel allows accessing any property of `module.exports` as a named export, while Node.js only allows importing _statically analyzable_ properties of `module.exports`. However, any import working in Node.js will also work when compiled with Babel using `importInterop: "node"`. + +#### `"none"` + +If you know that the imported file has been transformed with a compiler that stores the `default` export on `exports.default` (such as Babel), you can safely omit the `_interopRequireDefault` helper. + +```javascript +import foo from "foo"; +import { bar } from "bar"; +foo; +bar; + +// Is compiled to ... + +"use strict"; + +var _foo = require("foo"); +var _bar = require("bar"); + +_foo.default; +_bar.bar; +``` + ### `loose` `boolean`, defaults to `false`. @@ -110,28 +194,6 @@ Object.defineProperty(exports, "__esModule", { In order to prevent the `__esModule` property from being exported, you can set the `strict` option to `true`. -### `noInterop` - -`boolean`, defaults to `false` - -By default, when using exports with babel a non-enumerable `__esModule` property -is exported. This property is then used to determine if the import _is_ the default -export or if it _contains_ the default export. - -```javascript -"use strict"; - -var _foo = _interopRequireDefault(require("foo")); - -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj }; -} -``` - -In cases where the auto-unwrapping of `default` is not needed, you can set the -`noInterop` option to `true` to avoid the usage of the `interopRequireDefault` -helper (shown in inline form above). - ### `lazy` `boolean`, `Array`, or `(string) => boolean`, defaults to `false` @@ -167,3 +229,11 @@ The two cases where imports can never be lazy are: way to know what names need to be exported. > You can read more about configuring plugin options [here](https://babeljs.io/docs/en/plugins#plugin-options) + +### `noInterop` + +`boolean`, defaults to `false` + +> ⚠️ **Deptecated**: Use the `importInterop` option instead. + +When set to `true`, this option has the same behavior as setting `importInterop: "none"`. From 69488f422b7f15e5306b60f403472585b6a42532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Tue, 6 Apr 2021 12:38:27 +0200 Subject: [PATCH 2/2] History --- docs/plugin-transform-modules-commonjs.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/plugin-transform-modules-commonjs.md b/docs/plugin-transform-modules-commonjs.md index deefbee7ba..97a2b2c45e 100644 --- a/docs/plugin-transform-modules-commonjs.md +++ b/docs/plugin-transform-modules-commonjs.md @@ -4,6 +4,13 @@ title: @babel/plugin-transform-modules-commonjs sidebar_label: Common JS --- +
+ History +| Version | Changes | +| --- | --- | +| `v7.14.0` | Implemented the `importInterop` option | +
+ > **NOTE**: This plugin is included in `@babel/preset-env` under the `modules` option This plugin transforms ECMAScript modules to [CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1). Note that only the _syntax_ of import/export statements (`import "./mod.js"`) and import expressions (`import('./mod.js')`) is transformed, as Babel is unaware of different resolution algorithms between implementations of ECMAScript modules and CommonJS.