Skip to content

Commit

Permalink
[commonjs] Add defaultIsModuleExports option to match Node.js behav…
Browse files Browse the repository at this point in the history
…ior (#838)

* [commonjs] Add `nodeDefaultImport` option to match Node.js behavior

* Undo unrelated changes

* Undo editor autoformatter

* Change option
  • Loading branch information
nicolo-ribaudo committed Apr 3, 2021
1 parent c328e2c commit 53776ee
Show file tree
Hide file tree
Showing 25 changed files with 201 additions and 16 deletions.
43 changes: 43 additions & 0 deletions packages/commonjs/README.md
Expand Up @@ -174,6 +174,49 @@ If you set `esmExternals` to `true`, this plugins assumes that all external depe

You can also supply an array of ids to be treated as ES modules, or a function that will be passed each external id to determine if it is an ES module.

### `defaultIsModuleExports`

Type: `boolean | "auto"`<br>
Default: `"auto"`

Controls what is the default export when importing a CommonJS file from an ES module.

- `true`: The value of the default export is `module.exports`. This currently matches the behavior of Node.js when importing a CommonJS file.
```js
// mod.cjs
exports.default = 3;
```
```js
import foo from './mod.cjs';
console.log(foo); // { default: 3 }
```
- `false`: The value of the default export is `exports.default`.
```js
// mod.cjs
exports.default = 3;
```
```js
import foo from './mod.cjs';
console.log(foo); // 3
```
- `"auto"`: The value of the default export is `exports.default` if the CommonJS file has an `exports.__esModule === true` property; otherwise it's `module.exports`. This makes it possible to import
the default export of ES modules compiled to CommonJS as if they were not compiled.
```js
// mod.cjs
exports.default = 3;
```
```js
// mod-compiled.cjs
exports.__esModule = true;
exports.default = 3;
```
```js
import foo from './mod.cjs';
import bar from './mod-compiled.cjs';
console.log(foo); // { default: 3 }
console.log(bar); // 3
```

### `requireReturnsDefault`

Type: `boolean | "namespace" | "auto" | "preferred" | ((id: string) => boolean | "auto" | "preferred")`<br>
Expand Down
37 changes: 24 additions & 13 deletions packages/commonjs/src/generate-exports.js
Expand Up @@ -20,7 +20,8 @@ export function rewriteExportsAndGetExportsBlock(
isRestorableCompiledEsm,
code,
uses,
HELPERS_NAME
HELPERS_NAME,
defaultIsModuleExports
) {
const namedExportDeclarations = [`export { ${moduleName} as __moduleExports };`];
const moduleExportsPropertyAssignments = [];
Expand Down Expand Up @@ -75,19 +76,29 @@ export function rewriteExportsAndGetExportsBlock(

// Generate default export
const defaultExport = [];
if (isRestorableCompiledEsm) {
defaultExport.push(`export default ${deconflictedDefaultExportName || moduleName};`);
} else if (
(wrapped || deconflictedDefaultExportName) &&
(defineCompiledEsmExpressions.length > 0 || code.indexOf('__esModule') >= 0)
) {
// eslint-disable-next-line no-param-reassign
uses.commonjsHelpers = true;
defaultExport.push(
`export default /*@__PURE__*/${HELPERS_NAME}.getDefaultExportFromCjs(${moduleName});`
);
} else {
if (defaultIsModuleExports === 'auto') {
if (isRestorableCompiledEsm) {
defaultExport.push(`export default ${deconflictedDefaultExportName || moduleName};`);
} else if (
(wrapped || deconflictedDefaultExportName) &&
(defineCompiledEsmExpressions.length > 0 || code.includes('__esModule'))
) {
// eslint-disable-next-line no-param-reassign
uses.commonjsHelpers = true;
defaultExport.push(
`export default /*@__PURE__*/${HELPERS_NAME}.getDefaultExportFromCjs(${moduleName});`
);
} else {
defaultExport.push(`export default ${moduleName};`);
}
} else if (defaultIsModuleExports === true) {
defaultExport.push(`export default ${moduleName};`);
} else if (defaultIsModuleExports === false) {
if (deconflictedDefaultExportName) {
defaultExport.push(`export default ${deconflictedDefaultExportName};`);
} else {
defaultExport.push(`export default ${moduleName}.default;`);
}
}

return `\n\n${defaultExport
Expand Down
5 changes: 4 additions & 1 deletion packages/commonjs/src/index.js
Expand Up @@ -59,6 +59,8 @@ export default function commonjs(options = {}) {
: Array.isArray(esmExternals)
? ((esmExternalIds = new Set(esmExternals)), (id) => esmExternalIds.has(id))
: () => esmExternals;
const defaultIsModuleExports =
typeof options.defaultIsModuleExports === 'boolean' ? options.defaultIsModuleExports : 'auto';

const { dynamicRequireModuleSet, dynamicRequireModuleDirPaths } = getDynamicRequirePaths(
options.dynamicRequireTargets
Expand Down Expand Up @@ -145,7 +147,8 @@ export default function commonjs(options = {}) {
dynamicRequireModuleSet,
disableWrap,
commonDir,
ast
ast,
defaultIsModuleExports
);
}

Expand Down
6 changes: 4 additions & 2 deletions packages/commonjs/src/transform-commonjs.js
Expand Up @@ -53,7 +53,8 @@ export default function transformCommonjs(
dynamicRequireModuleSet,
disableWrap,
commonDir,
astCache
astCache,
defaultIsModuleExports
) {
const ast = astCache || tryParse(parse, code, id);
const magicString = new MagicString(code);
Expand Down Expand Up @@ -470,7 +471,8 @@ export default function transformCommonjs(
isRestorableCompiledEsm,
code,
uses,
HELPERS_NAME
HELPERS_NAME,
defaultIsModuleExports
);

const importBlock = rewriteRequireExpressionsAndGetImportBlock(
Expand Down
@@ -0,0 +1,5 @@
module.exports = {
options: {
defaultIsModuleExports: 'auto'
}
};
@@ -0,0 +1,3 @@
exports.__esModule = true;
exports.default = 2;
exports.named = 3;
@@ -0,0 +1,11 @@
var _default = 2;
var named = 3;

var input = /*#__PURE__*/Object.defineProperty({
default: _default,
named: named
}, '__esModule', {value: true});

export default _default;
export { input as __moduleExports };
export { named };
@@ -0,0 +1,5 @@
module.exports = {
options: {
defaultIsModuleExports: 'auto'
}
};
@@ -0,0 +1,2 @@
exports.default = 2;
exports.named = 3;
@@ -0,0 +1,11 @@
var _default = 2;
var named = 3;

var input = {
default: _default,
named: named
};

export default input;
export { input as __moduleExports };
export { named };
@@ -0,0 +1,5 @@
module.exports = {
options: {
defaultIsModuleExports: false
}
};
@@ -0,0 +1,3 @@
exports.__esModule = true;
exports.default = 2;
exports.named = 3;
@@ -0,0 +1,11 @@
var _default = 2;
var named = 3;

var input = /*#__PURE__*/Object.defineProperty({
default: _default,
named: named
}, '__esModule', {value: true});

export default _default;
export { input as __moduleExports };
export { named };
@@ -0,0 +1,5 @@
module.exports = {
options: {
defaultIsModuleExports: false
}
};
@@ -0,0 +1,2 @@
exports.default = 2;
exports.named = 3;
@@ -0,0 +1,11 @@
var _default = 2;
var named = 3;

var input = {
default: _default,
named: named
};

export default _default;
export { input as __moduleExports };
export { named };
@@ -0,0 +1,5 @@
module.exports = {
options: {
defaultIsModuleExports: false
}
};
@@ -0,0 +1 @@
exports.named = 3;
@@ -0,0 +1,9 @@
var named = 3;

var input = {
named: named
};

export default input.default;
export { input as __moduleExports };
export { named };
@@ -0,0 +1,5 @@
module.exports = {
options: {
defaultIsModuleExports: true
}
};
@@ -0,0 +1,3 @@
exports.__esModule = true;
exports.default = 2;
exports.named = 3;
@@ -0,0 +1,11 @@
var _default = 2;
var named = 3;

var input = /*#__PURE__*/Object.defineProperty({
default: _default,
named: named
}, '__esModule', {value: true});

export default input;
export { input as __moduleExports };
export { named };
@@ -0,0 +1,5 @@
module.exports = {
options: {
defaultIsModuleExports: true
}
};
@@ -0,0 +1,2 @@
exports.default = 2;
exports.named = 3;
@@ -0,0 +1,11 @@
var _default = 2;
var named = 3;

var input = {
default: _default,
named: named
};

export default input;
export { input as __moduleExports };
export { named };

0 comments on commit 53776ee

Please sign in to comment.