Skip to content

Commit

Permalink
Document the importInterop option
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Apr 6, 2021
1 parent 338ac32 commit e68093b
Showing 1 changed file with 92 additions and 22 deletions.
114 changes: 92 additions & 22 deletions docs/plugin-transform-modules-commonjs.md
Expand Up @@ -66,6 +66,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`.
Expand Down Expand Up @@ -108,28 +192,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<string>`, or `(string) => boolean`, defaults to `false`
Expand Down Expand Up @@ -165,3 +227,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"`.

0 comments on commit e68093b

Please sign in to comment.