From 03a3055c0f8b0e60fc8f5d0d8319cdf372f30304 Mon Sep 17 00:00:00 2001 From: ed eustace Date: Fri, 21 Feb 2020 20:45:25 +0000 Subject: [PATCH 1/3] feat: support Object.defineProperty(exports, ..) --- packages/commonjs/src/transform.js | 23 +++++++++++++++++++ .../fixtures/samples/define-property/foo.js | 6 +++++ .../fixtures/samples/define-property/main.js | 1 + packages/commonjs/test/test.js | 9 ++++++++ 4 files changed, 39 insertions(+) create mode 100644 packages/commonjs/test/fixtures/samples/define-property/foo.js create mode 100644 packages/commonjs/test/fixtures/samples/define-property/main.js diff --git a/packages/commonjs/src/transform.js b/packages/commonjs/src/transform.js index 1bd6e8fcf..3c48d9667 100644 --- a/packages/commonjs/src/transform.js +++ b/packages/commonjs/src/transform.js @@ -67,6 +67,25 @@ export function checkEsModule(parse, code, id) { return { isEsModule, hasDefaultExport: false, ast }; } +function defineProperty(node, targetName) { + if (node.type !== 'CallExpression') return; + + const { + callee: { object, property } + } = node; + + if (!object || object.type !== 'Identifier' || object.name !== 'Object') return; + + if (!property || property.type !== 'Identifier' || property.name !== 'defineProperty') return; + + if (node.arguments.length !== 3) return; + + const [target, val] = node.arguments; + if (target.type !== 'Identifier' || target.name !== targetName) return; + // eslint-disable-next-line consistent-return + return val.value; +} + export function transformCommonjs( parse, code, @@ -299,6 +318,10 @@ export function transformCommonjs( return; } + // Is this a call to Object.defineProperty(exports, ...)? + const def = defineProperty(node, 'exports'); + if (def && def === makeLegalIdentifier(def)) namedExports[def] = true; + // if this is `var x = require('x')`, we can do `import x from 'x'` if ( node.type === 'VariableDeclarator' && diff --git a/packages/commonjs/test/fixtures/samples/define-property/foo.js b/packages/commonjs/test/fixtures/samples/define-property/foo.js new file mode 100644 index 000000000..39ae035df --- /dev/null +++ b/packages/commonjs/test/fixtures/samples/define-property/foo.js @@ -0,0 +1,6 @@ +Object.defineProperty(exports, "foo", { + enumerable: true, + get: function get() { + return "bar"; + } +}); diff --git a/packages/commonjs/test/fixtures/samples/define-property/main.js b/packages/commonjs/test/fixtures/samples/define-property/main.js new file mode 100644 index 000000000..f5b64e142 --- /dev/null +++ b/packages/commonjs/test/fixtures/samples/define-property/main.js @@ -0,0 +1 @@ +export { foo } from "./foo"; diff --git a/packages/commonjs/test/test.js b/packages/commonjs/test/test.js index 5748c8018..d3e09297b 100644 --- a/packages/commonjs/test/test.js +++ b/packages/commonjs/test/test.js @@ -407,6 +407,15 @@ test('does not reexport named contents', async (t) => { } }); +test(`exports props defined by 'Object.defineProperty'`, async (t) => { + const bundle = await rollup({ + input: 'fixtures/samples/define-property/main.js', + plugins: [commonjs()] + }); + const m = await executeBundle(bundle, t); + t.is(m.exports.foo, 'bar'); +}); + test('respects other plugins', async (t) => { const bundle = await rollup({ input: 'fixtures/samples/other-transforms/main.js', From 74ab8b1033f9ac4ec38f47ad1d676544c6814159 Mon Sep 17 00:00:00 2001 From: ed eustace Date: Fri, 28 Feb 2020 22:01:39 +0000 Subject: [PATCH 2/3] chore: rename defineProperty -> isDefinePropertyCall --- packages/commonjs/src/transform.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/commonjs/src/transform.js b/packages/commonjs/src/transform.js index 3c48d9667..2aad8ef38 100644 --- a/packages/commonjs/src/transform.js +++ b/packages/commonjs/src/transform.js @@ -67,7 +67,7 @@ export function checkEsModule(parse, code, id) { return { isEsModule, hasDefaultExport: false, ast }; } -function defineProperty(node, targetName) { +function isDefinePropertyCall(node, targetName) { if (node.type !== 'CallExpression') return; const { @@ -318,8 +318,7 @@ export function transformCommonjs( return; } - // Is this a call to Object.defineProperty(exports, ...)? - const def = defineProperty(node, 'exports'); + const def = isDefinePropertyCall(node, 'exports'); if (def && def === makeLegalIdentifier(def)) namedExports[def] = true; // if this is `var x = require('x')`, we can do `import x from 'x'` From d54b03082e881739e35e7f27d09069407ca89875 Mon Sep 17 00:00:00 2001 From: ed eustace Date: Fri, 28 Feb 2020 22:06:36 +0000 Subject: [PATCH 3/3] chore: rename isDefinePropertyCall -> getDefinePropertyCallName --- packages/commonjs/src/transform.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/commonjs/src/transform.js b/packages/commonjs/src/transform.js index 2aad8ef38..792cf6c1b 100644 --- a/packages/commonjs/src/transform.js +++ b/packages/commonjs/src/transform.js @@ -67,7 +67,7 @@ export function checkEsModule(parse, code, id) { return { isEsModule, hasDefaultExport: false, ast }; } -function isDefinePropertyCall(node, targetName) { +function getDefinePropertyCallName(node, targetName) { if (node.type !== 'CallExpression') return; const { @@ -318,8 +318,8 @@ export function transformCommonjs( return; } - const def = isDefinePropertyCall(node, 'exports'); - if (def && def === makeLegalIdentifier(def)) namedExports[def] = true; + const name = getDefinePropertyCallName(node, 'exports'); + if (name && name === makeLegalIdentifier(name)) namedExports[name] = true; // if this is `var x = require('x')`, we can do `import x from 'x'` if (