Skip to content

Commit 5d4776a

Browse files
committed
Update docs
1 parent c472455 commit 5d4776a

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

docs/problems/CJSOnlyExportsDefault.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@ CommonJS module simulates a default export with `exports.default` and `exports._
66

77
This problem does not indicate that the types are wrong, but rather that the API exposed may have compatibility problems between Node and bundlers, and will need to be consumed in Node ES modules in a way that the author likely did not intend. It occurs when both of the following conditions are true:
88

9-
* A JavaScript file assigns `exports.default = ...` and has an `exports.__esModule = true` or similar method of setting the `__esModule` flag. (This pattern indicates that the CommonJS module has been transpiled from an ES module that used a default export.)
10-
* There is not an additional assignment to `module.exports = ...`, indicating that a compatibility pattern like `module.exports.default = module.exports = ...` was not used.
9+
- A JavaScript file assigns `exports.default = ...` and has an `exports.__esModule = true` or similar method of setting the `__esModule` flag. (This pattern indicates that the CommonJS module has been transpiled from an ES module that used a default export.)
10+
- There is not an additional assignment to `module.exports = ...`, indicating that a compatibility pattern like `module.exports.default = module.exports = ...` was not used.
1111

12-
When these are true, imports in Node will behave differently from imports in most bundlers. Node always synthesizes a default export for CommonJS modules that points to their `module.exports` objects, whereas most bundlers use the `__esModule` property as an indicator that the default export of the CommonJS module should be the value found at `exports.default`. So for a CommonJS module like:
12+
When these are true, imports in Node, and imports in Webpack and esbuild under certain conditions, will behave differently from imports in other bundlers and imports that have been transpiled to CJS. Node always synthesizes a default export for CommonJS modules that points to their `module.exports` objects, whereas most bundlers use the `__esModule` property as an indicator that the default export of the CommonJS module should be the value found at `exports.default`. So for a CommonJS module like:
1313

1414
```js
1515
Object.defineProperty(exports, "__esModule", { value: true });
16-
exports.default = function f() { /* ... */ };
16+
exports.default = function f() {
17+
/* ... */
18+
};
1719
```
1820

1921
a program with a default import like:
@@ -25,11 +27,15 @@ console.log(mod);
2527

2628
will result in `{ default: [Function: f] }` in Node, but `[Function: f]` in most bundlers. ([This table](https://andrewbranch.github.io/interop-test/#synthesizing-default-exports-for-cjs-modules) shows the behavior of several bundlers and the Bun runtime under different conditions.)
2729

30+
This problem is only reported in `node16-esm` and `bundler` resolutions, since those are the modes representing module systems that may not respect the `__esModule` marker and require an unexpected extra `.default` property access. In other words, a dual package that includes CommonJS files that use this pattern will not trigger this problem as long as its package.json `"exports"` direct the `"import"` condition away from such files.
31+
2832
The divergence in behavior between various runtimes and bundlers can be mitigated by assigning the value intended to be the default export to `module.exports`, then additionally assigning a circular `default` property on that object back to itself:
2933

3034
```js
3135
Object.defineProperty(exports, "__esModule", { value: true });
32-
function f() { /* ... */ };
36+
function f() {
37+
/* ... */
38+
}
3339
module.exports = f;
3440
module.exports.default = f;
3541
```
@@ -38,8 +44,8 @@ This compatibility pattern has an odd effect where `f.default.default.default...
3844

3945
## Consequences
4046

41-
* Consumers in Node will need to access the module’s intended export with `mod.default` where `mod` is already a default import, which is likely not the author’s intention.
42-
* It may be impossible or inconvenient for consumers to write code that works both in Node and in bundlers.
47+
- Consumers in Node will need to access the module’s intended export with `mod.default` where `mod` is already a default import, which is likely not the author’s intention.
48+
- It may be impossible or inconvenient for consumers to write code that works both in Node and in bundlers.
4349

4450
## Common causes
4551

0 commit comments

Comments
 (0)