Skip to content

Commit

Permalink
feat(commonjs): add esmExternals option
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Jul 26, 2020
1 parent 61c1fc7 commit e4dc686
Show file tree
Hide file tree
Showing 20 changed files with 330 additions and 17 deletions.
20 changes: 17 additions & 3 deletions packages/commonjs/src/index.js
Expand Up @@ -36,12 +36,23 @@ import {
export default function commonjs(options = {}) {
const extensions = options.extensions || ['.js'];
const filter = createFilter(options.include, options.exclude);
// TODO Lukas document values: true, 'preferred', 'auto', false
const { ignoreGlobal, requireReturnsDefault: requireReturnsDefaultOption } = options;
// TODO Lukas document esmExternals
const {
ignoreGlobal,
requireReturnsDefault: requireReturnsDefaultOption,
esmExternals
} = options;
const getRequireReturnsDefault =
typeof requireReturnsDefaultOption === 'function'
? requireReturnsDefaultOption
: () => requireReturnsDefaultOption;
let esmExternalIds;
const isEsmExternal =
typeof esmExternals === 'function'
? esmExternals
: Array.isArray(esmExternals)
? ((esmExternalIds = new Set(esmExternals)), (id) => esmExternalIds.has(id))
: () => esmExternals;

const { dynamicRequireModuleSet, dynamicRequireModuleDirPaths } = getDynamicRequirePaths(
options.dynamicRequireTargets
Expand Down Expand Up @@ -137,7 +148,10 @@ export default function commonjs(options = {}) {

if (id.endsWith(EXTERNAL_SUFFIX)) {
const actualId = getIdFromExternalProxyId(id);
return getUnknownRequireProxy(actualId, getRequireReturnsDefault(actualId));
return getUnknownRequireProxy(
actualId,
isEsmExternal(actualId) ? getRequireReturnsDefault(actualId) : true
);
}

if (id === DYNAMIC_PACKAGES_ID) {
Expand Down
@@ -0,0 +1,15 @@
module.exports = {
description: 'always uses the default export when esmExternals is not used',
options: {
external: [
'external-cjs-exports',
'external-cjs-module-exports',
'external-esm-named',
'external-esm-mixed',
'external-esm-default'
]
},
pluginOptions: {
esmExternals: false
}
};
@@ -0,0 +1,11 @@
const externalExports = require('external-cjs-exports');
const externalModuleExports = require('external-cjs-module-exports');
const externalNamed = require('external-esm-named');
const externalMixed = require('external-esm-mixed');
const externalDefault = require('external-esm-default');

t.deepEqual(externalExports, { foo: 'foo' }, 'external exports');
t.deepEqual(externalModuleExports, 'bar', 'external module exports');
t.deepEqual(externalNamed, { foo: 'foo' }, 'external named');
t.deepEqual(externalMixed, 'bar', 'external mixed');
t.deepEqual(externalDefault, 'bar', 'external default');
@@ -0,0 +1,36 @@
const assert = require('assert');

const called = {};

module.exports = {
description: 'always uses the default export when esmExternals is not used',
options: {
external: [
'external-cjs-exports',
'external-cjs-module-exports',
'external-esm-named',
'external-esm-mixed',
'external-esm-default'
],
plugins: [
{
name: 'test-plugin',
buildEnd() {
assert.deepStrictEqual(called, {
'external-cjs-exports': 1,
'external-cjs-module-exports': 1,
'external-esm-named': 1,
'external-esm-mixed': 1,
'external-esm-default': 1
});
}
}
]
},
pluginOptions: {
esmExternals: (id) => {
called[id] = (called[id] || 0) + 1;
return id === 'external-esm-default';
}
}
};
@@ -0,0 +1,11 @@
const externalExports = require('external-cjs-exports');
const externalModuleExports = require('external-cjs-module-exports');
const externalNamed = require('external-esm-named');
const externalMixed = require('external-esm-mixed');
const externalDefault = require('external-esm-default');

t.deepEqual(externalExports, { foo: 'foo' }, 'external exports');
t.deepEqual(externalModuleExports, 'bar', 'external module exports');
t.deepEqual(externalNamed, { foo: 'foo' }, 'external named');
t.deepEqual(externalMixed, 'bar', 'external mixed');
t.deepEqual(externalDefault, { default: 'bar' }, 'external default');
@@ -0,0 +1,15 @@
module.exports = {
description: 'always uses the default export when esmExternals is not used',
options: {
external: [
'external-cjs-exports',
'external-cjs-module-exports',
'external-esm-named',
'external-esm-mixed',
'external-esm-default'
]
},
pluginOptions: {
esmExternals: ['external-esm-default']
}
};
@@ -0,0 +1,11 @@
const externalExports = require('external-cjs-exports');
const externalModuleExports = require('external-cjs-module-exports');
const externalNamed = require('external-esm-named');
const externalMixed = require('external-esm-mixed');
const externalDefault = require('external-esm-default');

t.deepEqual(externalExports, { foo: 'foo' }, 'external exports');
t.deepEqual(externalModuleExports, 'bar', 'external module exports');
t.deepEqual(externalNamed, { foo: 'foo' }, 'external named');
t.deepEqual(externalMixed, 'bar', 'external mixed');
t.deepEqual(externalDefault, { default: 'bar' }, 'external default');
@@ -0,0 +1,15 @@
module.exports = {
description: 'always uses the default export when esmExternals is not used',
options: {
external: [
'external-cjs-exports',
'external-cjs-module-exports',
'external-esm-named',
'external-esm-mixed',
'external-esm-default'
]
},
pluginOptions: {
esmExternals: true
}
};
@@ -0,0 +1,11 @@
const externalExports = require('external-cjs-exports');
const externalModuleExports = require('external-cjs-module-exports');
const externalNamed = require('external-esm-named');
const externalMixed = require('external-esm-mixed');
const externalDefault = require('external-esm-default');

t.deepEqual(externalExports, { foo: 'foo' }, 'external exports');
t.deepEqual(externalModuleExports, 'bar', 'external module exports');
t.deepEqual(externalNamed, { foo: 'foo' }, 'external named');
t.deepEqual(externalMixed, { default: 'bar', foo: 'foo' }, 'external mixed');
t.deepEqual(externalDefault, { default: 'bar' }, 'external default');
@@ -0,0 +1,12 @@
module.exports = {
description: 'always uses the default export when esmExternals is not used',
options: {
external: [
'external-cjs-exports',
'external-cjs-module-exports',
'external-esm-named',
'external-esm-mixed',
'external-esm-default'
]
}
};
@@ -0,0 +1,11 @@
const externalExports = require('external-cjs-exports');
const externalModuleExports = require('external-cjs-module-exports');
const externalNamed = require('external-esm-named');
const externalMixed = require('external-esm-mixed');
const externalDefault = require('external-esm-default');

t.deepEqual(externalExports, { foo: 'foo' }, 'external exports');
t.deepEqual(externalModuleExports, 'bar', 'external module exports');
t.deepEqual(externalNamed, { foo: 'foo' }, 'external named');
t.deepEqual(externalMixed, 'bar', 'external mixed');
t.deepEqual(externalDefault, 'bar', 'external default');
Expand Up @@ -5,6 +5,7 @@ module.exports = {
external: ['external-esm-named', 'external-esm-mixed', 'external-esm-default']
},
pluginOptions: {
requireReturnsDefault: 'auto'
requireReturnsDefault: 'auto',
esmExternals: true
}
};
Expand Up @@ -5,6 +5,7 @@ module.exports = {
external: ['external-esm-named', 'external-esm-mixed', 'external-esm-default']
},
pluginOptions: {
requireReturnsDefault: false
requireReturnsDefault: false,
esmExternals: true
}
};
@@ -1,10 +1,6 @@
const assert = require('assert');

const called = {
'main.js': 0,
'both.js': 0,
'other.js': 0
};
const called = {};

module.exports = {
description: 'only calls a requireReturnsDefault function once per id',
Expand Down Expand Up @@ -37,7 +33,7 @@ module.exports = {
requireReturnsDefault: (id) => {
const [prefix, name] = id.split('_');
if (prefix === 'dep') {
called[name] += 1;
called[name] = (called[name] || 0) + 1;
return 'preferred';
}
return false;
Expand Down
Expand Up @@ -8,6 +8,7 @@ module.exports = {
if (id === 'external-esm-mixed') return true;
if (id === 'external-esm-default') return false;
return 'auto';
}
},
esmExternals: true
}
};
Expand Up @@ -5,6 +5,7 @@ module.exports = {
external: ['external-esm-named', 'external-esm-mixed', 'external-esm-default']
},
pluginOptions: {
requireReturnsDefault: 'preferred'
requireReturnsDefault: 'preferred',
esmExternals: true
}
};
Expand Up @@ -5,6 +5,7 @@ module.exports = {
external: ['external-esm-named', 'external-esm-mixed', 'external-esm-default']
},
pluginOptions: {
requireReturnsDefault: true
requireReturnsDefault: true,
esmExternals: true
}
};
Expand Up @@ -3,5 +3,8 @@ module.exports = {
'returns the namespace when requiring an ES module and requireReturnsDefault is missing',
options: {
external: ['external-esm-named', 'external-esm-mixed', 'external-esm-default']
},
pluginOptions: {
esmExternals: true
}
};

0 comments on commit e4dc686

Please sign in to comment.