diff --git a/packages/commonjs/README.md b/packages/commonjs/README.md
index 6aff1ee2e..66432e503 100644
--- a/packages/commonjs/README.md
+++ b/packages/commonjs/README.md
@@ -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"`
+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")`
diff --git a/packages/commonjs/src/generate-exports.js b/packages/commonjs/src/generate-exports.js
index 2818c65ed..4a30cb5ff 100644
--- a/packages/commonjs/src/generate-exports.js
+++ b/packages/commonjs/src/generate-exports.js
@@ -20,7 +20,8 @@ export function rewriteExportsAndGetExportsBlock(
isRestorableCompiledEsm,
code,
uses,
- HELPERS_NAME
+ HELPERS_NAME,
+ defaultIsModuleExports
) {
const namedExportDeclarations = [`export { ${moduleName} as __moduleExports };`];
const moduleExportsPropertyAssignments = [];
@@ -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
diff --git a/packages/commonjs/src/index.js b/packages/commonjs/src/index.js
index 79015294b..bdb92bcdc 100644
--- a/packages/commonjs/src/index.js
+++ b/packages/commonjs/src/index.js
@@ -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
@@ -145,7 +147,8 @@ export default function commonjs(options = {}) {
dynamicRequireModuleSet,
disableWrap,
commonDir,
- ast
+ ast,
+ defaultIsModuleExports
);
}
diff --git a/packages/commonjs/src/transform-commonjs.js b/packages/commonjs/src/transform-commonjs.js
index ccb32a565..e37271a8e 100644
--- a/packages/commonjs/src/transform-commonjs.js
+++ b/packages/commonjs/src/transform-commonjs.js
@@ -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);
@@ -470,7 +471,8 @@ export default function transformCommonjs(
isRestorableCompiledEsm,
code,
uses,
- HELPERS_NAME
+ HELPERS_NAME,
+ defaultIsModuleExports
);
const importBlock = rewriteRequireExpressionsAndGetImportBlock(
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-__esModule/_config.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-__esModule/_config.js
new file mode 100755
index 000000000..466f62535
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-__esModule/_config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ options: {
+ defaultIsModuleExports: 'auto'
+ }
+};
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-__esModule/input.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-__esModule/input.js
new file mode 100755
index 000000000..d4efb165b
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-__esModule/input.js
@@ -0,0 +1,3 @@
+exports.__esModule = true;
+exports.default = 2;
+exports.named = 3;
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-__esModule/output.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-__esModule/output.js
new file mode 100755
index 000000000..29b4b47c3
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-__esModule/output.js
@@ -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 };
\ No newline at end of file
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-no-__esModule/_config.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-no-__esModule/_config.js
new file mode 100755
index 000000000..466f62535
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-no-__esModule/_config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ options: {
+ defaultIsModuleExports: 'auto'
+ }
+};
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-no-__esModule/input.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-no-__esModule/input.js
new file mode 100755
index 000000000..562cc1abe
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-no-__esModule/input.js
@@ -0,0 +1,2 @@
+exports.default = 2;
+exports.named = 3;
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-no-__esModule/output.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-no-__esModule/output.js
new file mode 100755
index 000000000..9e4a115e8
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-auto-no-__esModule/output.js
@@ -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 };
\ No newline at end of file
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-__esModule/_config.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-__esModule/_config.js
new file mode 100755
index 000000000..d4402a7ee
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-__esModule/_config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ options: {
+ defaultIsModuleExports: false
+ }
+};
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-__esModule/input.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-__esModule/input.js
new file mode 100755
index 000000000..d4efb165b
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-__esModule/input.js
@@ -0,0 +1,3 @@
+exports.__esModule = true;
+exports.default = 2;
+exports.named = 3;
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-__esModule/output.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-__esModule/output.js
new file mode 100755
index 000000000..29b4b47c3
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-__esModule/output.js
@@ -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 };
\ No newline at end of file
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-__esModule/_config.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-__esModule/_config.js
new file mode 100755
index 000000000..d4402a7ee
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-__esModule/_config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ options: {
+ defaultIsModuleExports: false
+ }
+};
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-__esModule/input.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-__esModule/input.js
new file mode 100755
index 000000000..562cc1abe
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-__esModule/input.js
@@ -0,0 +1,2 @@
+exports.default = 2;
+exports.named = 3;
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-__esModule/output.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-__esModule/output.js
new file mode 100755
index 000000000..de8e0862a
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-__esModule/output.js
@@ -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 };
\ No newline at end of file
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-default/_config.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-default/_config.js
new file mode 100755
index 000000000..d4402a7ee
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-default/_config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ options: {
+ defaultIsModuleExports: false
+ }
+};
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-default/input.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-default/input.js
new file mode 100755
index 000000000..fd2304246
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-default/input.js
@@ -0,0 +1 @@
+exports.named = 3;
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-default/output.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-default/output.js
new file mode 100755
index 000000000..81484f1e4
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-false-no-default/output.js
@@ -0,0 +1,9 @@
+var named = 3;
+
+var input = {
+ named: named
+};
+
+export default input.default;
+export { input as __moduleExports };
+export { named };
\ No newline at end of file
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-__esModule/_config.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-__esModule/_config.js
new file mode 100755
index 000000000..a57f02831
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-__esModule/_config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ options: {
+ defaultIsModuleExports: true
+ }
+};
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-__esModule/input.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-__esModule/input.js
new file mode 100755
index 000000000..d4efb165b
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-__esModule/input.js
@@ -0,0 +1,3 @@
+exports.__esModule = true;
+exports.default = 2;
+exports.named = 3;
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-__esModule/output.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-__esModule/output.js
new file mode 100755
index 000000000..f997b9eaf
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-__esModule/output.js
@@ -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 };
\ No newline at end of file
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-no-__esModule/_config.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-no-__esModule/_config.js
new file mode 100755
index 000000000..a57f02831
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-no-__esModule/_config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ options: {
+ defaultIsModuleExports: true
+ }
+};
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-no-__esModule/input.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-no-__esModule/input.js
new file mode 100755
index 000000000..562cc1abe
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-no-__esModule/input.js
@@ -0,0 +1,2 @@
+exports.default = 2;
+exports.named = 3;
diff --git a/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-no-__esModule/output.js b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-no-__esModule/output.js
new file mode 100755
index 000000000..9e4a115e8
--- /dev/null
+++ b/packages/commonjs/test/fixtures/form/defaultIsModuleExports-true-no-__esModule/output.js
@@ -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 };
\ No newline at end of file