From f81d7496b146c5b6c674012206d785bafa6f6003 Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Wed, 15 Mar 2017 15:35:45 +0200 Subject: [PATCH 01/13] Fix exports while destructuring. --- .../src/index.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index 2afc2d6fbbf2..5574550a90bb 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -306,6 +306,15 @@ export default function () { addTo(exports, id.node.name, id.node); init.replaceWith(buildExportsAssignment(id.node, init.node).expression); nonHoistedExportNames[id.node.name] = true; + } else if (id.isObjectPattern()) { + for (let i = 0; i < id.node.properties.length; i++) { + const prop = id.node.properties[i]; + if (!t.isRestProperty(prop)) { + addTo(exports, prop.value.name, prop.value); + path.insertAfter(buildExportsAssignment(prop.value, prop.value)); + nonHoistedExportNames[prop.value.name] = true; + } + } } else { // todo } From 9b410be61c7d4e4e52cbfe5d31e7456d1ba19705 Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Wed, 15 Mar 2017 15:37:17 +0200 Subject: [PATCH 02/13] Add test for exports destructuring. --- .../fixtures/strict/export-const-destructuring/actual.js | 1 + .../strict/export-const-destructuring/expected.js | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/actual.js create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/expected.js diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/actual.js new file mode 100644 index 000000000000..f57149360490 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/actual.js @@ -0,0 +1 @@ +export const { foo: bar, baz } = {}; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/expected.js new file mode 100644 index 000000000000..b1bd9369327f --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/expected.js @@ -0,0 +1,8 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +const { foo: bar, baz } = {}; +exports.baz = baz; +exports.bar = bar; From 0c2e3b1045df669aa2de70f77c492c11b821d82b Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Wed, 15 Mar 2017 16:02:21 +0200 Subject: [PATCH 03/13] Remove exports definition. --- .../fixtures/strict/export-const-destructuring/expected.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/expected.js index b1bd9369327f..ff1a912e331a 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/expected.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/expected.js @@ -1,8 +1,5 @@ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); const { foo: bar, baz } = {}; exports.baz = baz; exports.bar = bar; From b5bb89b30a43db219de22d82eff8cf4b2727efc4 Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Sat, 18 Mar 2017 15:12:46 +0200 Subject: [PATCH 04/13] Add array pattern to exports destructuring. --- .../src/index.js | 22 ++++++++++++++----- .../actual.js | 1 + .../expected.js | 5 +++++ .../actual.js | 0 .../expected.js | 0 5 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js rename packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/{export-const-destructuring => export-const-destructuring-object}/actual.js (100%) rename packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/{export-const-destructuring => export-const-destructuring-object}/expected.js (100%) diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index 5574550a90bb..1ae00f1c3c65 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -300,6 +300,7 @@ export default function () { const id = decl.get("id"); const init = decl.get("init"); + const exportsToInsert = []; if (!init.node) init.replaceWith(t.identifier("undefined")); if (id.isIdentifier()) { @@ -310,14 +311,25 @@ export default function () { for (let i = 0; i < id.node.properties.length; i++) { const prop = id.node.properties[i]; if (!t.isRestProperty(prop)) { - addTo(exports, prop.value.name, prop.value); - path.insertAfter(buildExportsAssignment(prop.value, prop.value)); - nonHoistedExportNames[prop.value.name] = true; + const propValue = prop.value; + addTo(exports, propValue.name, propValue); + exportsToInsert.push(buildExportsAssignment(propValue, propValue)); + nonHoistedExportNames[propValue.name] = true; + } + } + } else if (id.isArrayPattern() && id.node.elements) { + for (let i = 0; i < id.node.elements.length; i++) { + const elem = id.node.elements[i]; + if (!elem) continue; + if (!t.isRestElement(elem)) { + const name = elem.name; + addTo(exports, name, elem); + exportsToInsert.push(buildExportsAssignment(elem, elem)); + nonHoistedExportNames[name] = true; } } - } else { - // todo } + path.insertAfter(exportsToInsert); } path.replaceWith(declaration.node); } diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js new file mode 100644 index 000000000000..1b7752d6c53a --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js @@ -0,0 +1 @@ +export const [ foo, bar ] = []; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js new file mode 100644 index 000000000000..e2fafbd5ca85 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js @@ -0,0 +1,5 @@ +"use strict"; + +const [foo, bar] = []; +exports.foo = foo; +exports.bar = bar; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object/actual.js similarity index 100% rename from packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/actual.js rename to packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object/actual.js diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object/expected.js similarity index 100% rename from packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring/expected.js rename to packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object/expected.js From 06f67e1ad3eda952690d67eebc2cc0c3c827f683 Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Sat, 18 Mar 2017 15:42:39 +0200 Subject: [PATCH 05/13] Consider default parameters for array pattern. --- .../src/index.js | 5 ++++- .../strict/export-const-destructuring-array/actual.js | 2 +- .../strict/export-const-destructuring-array/expected.js | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index 1ae00f1c3c65..8fd67773c6ae 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -319,9 +319,12 @@ export default function () { } } else if (id.isArrayPattern() && id.node.elements) { for (let i = 0; i < id.node.elements.length; i++) { - const elem = id.node.elements[i]; + let elem = id.node.elements[i]; if (!elem) continue; if (!t.isRestElement(elem)) { + if (t.isAssignmentPattern(elem)) { + elem = elem.left; + } const name = elem.name; addTo(exports, name, elem); exportsToInsert.push(buildExportsAssignment(elem, elem)); diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js index 1b7752d6c53a..ae9b52c16826 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js @@ -1 +1 @@ -export const [ foo, bar ] = []; +export const [foo, bar = 2] = [1]; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js index e2fafbd5ca85..62eda5c15045 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js @@ -1,5 +1,5 @@ "use strict"; -const [foo, bar] = []; +const [foo, bar = 2] = [1]; exports.foo = foo; exports.bar = bar; From b608e28aa7978b9c97e0e5cffeefe4441eda5d0b Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Sat, 18 Mar 2017 16:02:06 +0200 Subject: [PATCH 06/13] Consider rest params for array pattern in exports. --- .../src/index.js | 16 ++++++++-------- .../actual.js | 1 + .../expected.js | 5 +++++ .../actual.js | 1 + .../expected.js | 6 ++++++ .../export-const-destructuring-array/actual.js | 2 +- .../export-const-destructuring-array/expected.js | 2 +- 7 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-default-params/actual.js create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-default-params/expected.js create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/actual.js create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/expected.js diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index 8fd67773c6ae..58ee8e97e425 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -321,15 +321,15 @@ export default function () { for (let i = 0; i < id.node.elements.length; i++) { let elem = id.node.elements[i]; if (!elem) continue; - if (!t.isRestElement(elem)) { - if (t.isAssignmentPattern(elem)) { - elem = elem.left; - } - const name = elem.name; - addTo(exports, name, elem); - exportsToInsert.push(buildExportsAssignment(elem, elem)); - nonHoistedExportNames[name] = true; + if (t.isAssignmentPattern(elem)) { + elem = elem.left; + } else if (t.isRestElement(elem)) { + elem = elem.argument; } + const name = elem.name; + addTo(exports, name, elem); + exportsToInsert.push(buildExportsAssignment(elem, elem)); + nonHoistedExportNames[name] = true; } } path.insertAfter(exportsToInsert); diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-default-params/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-default-params/actual.js new file mode 100644 index 000000000000..15f05d97e482 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-default-params/actual.js @@ -0,0 +1 @@ +export const [foo, bar = 2] = []; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-default-params/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-default-params/expected.js new file mode 100644 index 000000000000..124bbfcc78ed --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-default-params/expected.js @@ -0,0 +1,5 @@ +"use strict"; + +const [foo, bar = 2] = []; +exports.foo = foo; +exports.bar = bar; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/actual.js new file mode 100644 index 000000000000..0a9d393da866 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/actual.js @@ -0,0 +1 @@ +export const [foo, bar, ...baz] = []; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/expected.js new file mode 100644 index 000000000000..7f0d3ab179a7 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/expected.js @@ -0,0 +1,6 @@ +"use strict"; + +const [foo, bar, ...baz] = []; +exports.foo = foo; +exports.bar = bar; +exports.bar = baz; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js index ae9b52c16826..17971b0e1171 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/actual.js @@ -1 +1 @@ -export const [foo, bar = 2] = [1]; +export const [foo, bar] = []; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js index 62eda5c15045..e2fafbd5ca85 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array/expected.js @@ -1,5 +1,5 @@ "use strict"; -const [foo, bar = 2] = [1]; +const [foo, bar] = []; exports.foo = foo; exports.bar = bar; From 45b41740d851ccfc2189f987f55fd2bff776a5b4 Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Sat, 18 Mar 2017 16:26:22 +0200 Subject: [PATCH 07/13] Consider default params for object pattern. --- .../src/index.js | 5 ++++- .../actual.js | 1 + .../expected.js | 5 +++++ .../strict/export-const-destructuring-object/expected.js | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-default-params/actual.js create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-default-params/expected.js diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index 58ee8e97e425..4344f2cc7126 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -310,8 +310,11 @@ export default function () { } else if (id.isObjectPattern()) { for (let i = 0; i < id.node.properties.length; i++) { const prop = id.node.properties[i]; + let propValue = prop.value; if (!t.isRestProperty(prop)) { - const propValue = prop.value; + if (t.isAssignmentPattern(propValue)) { + propValue = propValue.left; + } addTo(exports, propValue.name, propValue); exportsToInsert.push(buildExportsAssignment(propValue, propValue)); nonHoistedExportNames[propValue.name] = true; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-default-params/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-default-params/actual.js new file mode 100644 index 000000000000..03958a070943 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-default-params/actual.js @@ -0,0 +1 @@ +export const { foo, bar = 1 } = {}; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-default-params/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-default-params/expected.js new file mode 100644 index 000000000000..2f72b34fb643 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-default-params/expected.js @@ -0,0 +1,5 @@ +"use strict"; + +const { foo, bar = 1 } = {}; +exports.foo = foo; +exports.bar = bar; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object/expected.js index ff1a912e331a..83cc6e03df6b 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object/expected.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object/expected.js @@ -1,5 +1,5 @@ "use strict"; const { foo: bar, baz } = {}; -exports.baz = baz; exports.bar = bar; +exports.baz = baz; From c82b084927c5c15372a51e54158216052a3eddc0 Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Sun, 19 Mar 2017 00:32:27 +0200 Subject: [PATCH 08/13] Fix object rest params for exports. --- .../src/index.js | 18 +++++++++++------- .../actual.js | 1 + .../expected.js | 5 +++++ 3 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index 4344f2cc7126..f780fe72bf0f 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -129,6 +129,10 @@ export default function () { return { inherits: require("babel-plugin-transform-strict-mode"), + manipulateOptions(opts, parserOpts) { + parserOpts.plugins.push("objectRestSpread"); + }, + visitor: { ThisExpression(path, state) { // If other plugins run after this plugin's Program#exit handler, we allow them to @@ -311,14 +315,14 @@ export default function () { for (let i = 0; i < id.node.properties.length; i++) { const prop = id.node.properties[i]; let propValue = prop.value; - if (!t.isRestProperty(prop)) { - if (t.isAssignmentPattern(propValue)) { - propValue = propValue.left; - } - addTo(exports, propValue.name, propValue); - exportsToInsert.push(buildExportsAssignment(propValue, propValue)); - nonHoistedExportNames[propValue.name] = true; + if (t.isAssignmentPattern(propValue)) { + propValue = propValue.left; + } else if (t.isRestProperty(prop)) { + propValue = prop.argument; } + addTo(exports, propValue.name, propValue); + exportsToInsert.push(buildExportsAssignment(propValue, propValue)); + nonHoistedExportNames[propValue.name] = true; } } else if (id.isArrayPattern() && id.node.elements) { for (let i = 0; i < id.node.elements.length; i++) { diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js new file mode 100644 index 000000000000..d4d52568cebd --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js @@ -0,0 +1 @@ +export const { foo, ...bar } = {}; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js new file mode 100644 index 000000000000..4e27e3401413 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js @@ -0,0 +1,5 @@ +"use strict"; + +const { foo, ...bar } = {}; +exports.foo = foo; +exports.bar = bar; From 18d6ba99475665d2a2417ae01ed5055c2ed26f3f Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Sun, 19 Mar 2017 01:18:22 +0200 Subject: [PATCH 09/13] Fix export array rest expected output. --- .../strict/export-const-destructuring-array-rest/expected.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/expected.js index 7f0d3ab179a7..c975988eb976 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/expected.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-array-rest/expected.js @@ -3,4 +3,4 @@ const [foo, bar, ...baz] = []; exports.foo = foo; exports.bar = bar; -exports.bar = baz; +exports.baz = baz; From c42e027602eb7065087fcf7b375c0b5ca4c244e9 Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Sun, 19 Mar 2017 14:02:01 +0200 Subject: [PATCH 10/13] Add object rest spread syntax using plugin. --- .../package.json | 4 +- .../src/index.js | 615 +++++++++--------- 2 files changed, 311 insertions(+), 308 deletions(-) diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/package.json b/packages/babel-plugin-transform-es2015-modules-commonjs/package.json index 148504224f91..cfad0ef5ef43 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/package.json +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/package.json @@ -9,12 +9,14 @@ "babel-types": "^6.23.0", "babel-runtime": "^6.22.0", "babel-template": "^6.23.0", - "babel-plugin-transform-strict-mode": "^6.22.0" + "babel-plugin-transform-strict-mode": "^6.22.0", + "babel-plugin-syntax-object-rest-spread": "^6.13.0" }, "keywords": [ "babel-plugin" ], "devDependencies": { + "babel-plugin-transform-object-assign": "6.22.0", "babel-helper-plugin-test-runner": "^6.24.0" } } diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index f780fe72bf0f..daf10a43575f 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -1,5 +1,8 @@ import { basename, extname } from "path"; import template from "babel-template"; +import babelPluginSyntaxObjectRestSpread from "babel-plugin-syntax-object-rest-spread"; +import babelPluginTransformStrictMode from "babel-plugin-transform-strict-mode"; + import * as t from "babel-types"; const buildRequire = template(` @@ -126,320 +129,287 @@ export default function () { } }; - return { - inherits: require("babel-plugin-transform-strict-mode"), + return Object.assign( + babelPluginSyntaxObjectRestSpread(), + babelPluginTransformStrictMode(), + { + visitor: { + ThisExpression(path, state) { + // If other plugins run after this plugin's Program#exit handler, we allow them to + // insert top-level `this` values. This allows the AMD and UMD plugins to + // function properly. + if (this.ranCommonJS) return; + + if ( + state.opts.allowTopLevelThis !== true && + !path.findParent((path) => !path.is("shadow") && + THIS_BREAK_KEYS.indexOf(path.type) >= 0) + ) { + path.replaceWith(t.identifier("undefined")); + } + }, - manipulateOptions(opts, parserOpts) { - parserOpts.plugins.push("objectRestSpread"); - }, + Program: { + exit(path) { + this.ranCommonJS = true; - visitor: { - ThisExpression(path, state) { - // If other plugins run after this plugin's Program#exit handler, we allow them to - // insert top-level `this` values. This allows the AMD and UMD plugins to - // function properly. - if (this.ranCommonJS) return; - - if ( - state.opts.allowTopLevelThis !== true && - !path.findParent((path) => !path.is("shadow") && - THIS_BREAK_KEYS.indexOf(path.type) >= 0) - ) { - path.replaceWith(t.identifier("undefined")); - } - }, + const strict = !!this.opts.strict; + const noInterop = !!this.opts.noInterop; - Program: { - exit(path) { - this.ranCommonJS = true; + const { scope } = path; - const strict = !!this.opts.strict; - const noInterop = !!this.opts.noInterop; + // rename these commonjs variables if they're declared in the file + scope.rename("module"); + scope.rename("exports"); + scope.rename("require"); - const { scope } = path; + let hasExports = false; + let hasImports = false; - // rename these commonjs variables if they're declared in the file - scope.rename("module"); - scope.rename("exports"); - scope.rename("require"); + const body: Array = path.get("body"); + const imports = Object.create(null); + const exports = Object.create(null); - let hasExports = false; - let hasImports = false; + const nonHoistedExportNames = Object.create(null); - const body: Array = path.get("body"); - const imports = Object.create(null); - const exports = Object.create(null); + const topNodes = []; + const remaps = Object.create(null); - const nonHoistedExportNames = Object.create(null); + const requires = Object.create(null); - const topNodes = []; - const remaps = Object.create(null); + function addRequire(source, blockHoist) { + const cached = requires[source]; + if (cached) return cached; - const requires = Object.create(null); + const ref = path.scope.generateUidIdentifier(basename(source, extname(source))); - function addRequire(source, blockHoist) { - const cached = requires[source]; - if (cached) return cached; + const varDecl = t.variableDeclaration("var", [ + t.variableDeclarator(ref, buildRequire( + t.stringLiteral(source) + ).expression) + ]); - const ref = path.scope.generateUidIdentifier(basename(source, extname(source))); + // Copy location from the original import statement for sourcemap + // generation. + if (imports[source]) { + varDecl.loc = imports[source].loc; + } - const varDecl = t.variableDeclaration("var", [ - t.variableDeclarator(ref, buildRequire( - t.stringLiteral(source) - ).expression) - ]); + if (typeof blockHoist === "number" && blockHoist > 0) { + varDecl._blockHoist = blockHoist; + } - // Copy location from the original import statement for sourcemap - // generation. - if (imports[source]) { - varDecl.loc = imports[source].loc; - } + topNodes.push(varDecl); - if (typeof blockHoist === "number" && blockHoist > 0) { - varDecl._blockHoist = blockHoist; + return requires[source] = ref; } - topNodes.push(varDecl); - - return requires[source] = ref; - } - - function addTo(obj, key, arr) { - const existing = obj[key] || []; - obj[key] = existing.concat(arr); - } + function addTo(obj, key, arr) { + const existing = obj[key] || []; + obj[key] = existing.concat(arr); + } - for (const path of body) { - if (path.isExportDeclaration()) { - hasExports = true; + for (const path of body) { + if (path.isExportDeclaration()) { + hasExports = true; - const specifiers = [].concat(path.get("declaration"), path.get("specifiers")); - for (const specifier of specifiers) { - const ids = specifier.getBindingIdentifiers(); - if (ids.__esModule) { - throw specifier.buildCodeFrameError("Illegal export \"__esModule\""); + const specifiers = [].concat(path.get("declaration"), path.get("specifiers")); + for (const specifier of specifiers) { + const ids = specifier.getBindingIdentifiers(); + if (ids.__esModule) { + throw specifier.buildCodeFrameError("Illegal export \"__esModule\""); + } } } - } - - if (path.isImportDeclaration()) { - hasImports = true; - const key = path.node.source.value; - const importsEntry = imports[key] || { - specifiers: [], - maxBlockHoist: 0, - loc: path.node.loc, - }; + if (path.isImportDeclaration()) { + hasImports = true; - importsEntry.specifiers.push(...path.node.specifiers); + const key = path.node.source.value; + const importsEntry = imports[key] || { + specifiers: [], + maxBlockHoist: 0, + loc: path.node.loc, + }; - if (typeof path.node._blockHoist === "number") { - importsEntry.maxBlockHoist = Math.max( - path.node._blockHoist, - importsEntry.maxBlockHoist - ); - } + importsEntry.specifiers.push(...path.node.specifiers); - imports[key] = importsEntry; - - path.remove(); - } else if (path.isExportDefaultDeclaration()) { - const declaration = path.get("declaration"); - if (declaration.isFunctionDeclaration()) { - const id = declaration.node.id; - const defNode = t.identifier("default"); - if (id) { - addTo(exports, id.name, defNode); - topNodes.push(buildExportsAssignment(defNode, id)); - path.replaceWith(declaration.node); - } else { - topNodes.push(buildExportsAssignment(defNode, t.toExpression(declaration.node))); - path.remove(); + if (typeof path.node._blockHoist === "number") { + importsEntry.maxBlockHoist = Math.max( + path.node._blockHoist, + importsEntry.maxBlockHoist + ); } - } else if (declaration.isClassDeclaration()) { - const id = declaration.node.id; - const defNode = t.identifier("default"); - if (id) { - addTo(exports, id.name, defNode); - path.replaceWithMultiple([ - declaration.node, - buildExportsAssignment(defNode, id) - ]); - } else { - path.replaceWith(buildExportsAssignment(defNode, t.toExpression(declaration.node))); - // Manualy re-queue `export default class {}` expressions so that the ES3 transform - // has an opportunity to convert them. Ideally this would happen automatically from the - // replaceWith above. See #4140 for more info. - path.parentPath.requeue(path.get("expression.left")); - } - } else { - path.replaceWith(buildExportsAssignment(t.identifier("default"), declaration.node)); + imports[key] = importsEntry; - // Manualy re-queue `export default foo;` expressions so that the ES3 transform - // has an opportunity to convert them. Ideally this would happen automatically from the - // replaceWith above. See #4140 for more info. - path.parentPath.requeue(path.get("expression.left")); - } - } else if (path.isExportNamedDeclaration()) { - const declaration = path.get("declaration"); - if (declaration.node) { + path.remove(); + } else if (path.isExportDefaultDeclaration()) { + const declaration = path.get("declaration"); if (declaration.isFunctionDeclaration()) { const id = declaration.node.id; - addTo(exports, id.name, id); - topNodes.push(buildExportsAssignment(id, id)); - path.replaceWith(declaration.node); + const defNode = t.identifier("default"); + if (id) { + addTo(exports, id.name, defNode); + topNodes.push(buildExportsAssignment(defNode, id)); + path.replaceWith(declaration.node); + } else { + topNodes.push(buildExportsAssignment(defNode, t.toExpression(declaration.node))); + path.remove(); + } } else if (declaration.isClassDeclaration()) { const id = declaration.node.id; - addTo(exports, id.name, id); - path.replaceWithMultiple([ - declaration.node, - buildExportsAssignment(id, id) - ]); - nonHoistedExportNames[id.name] = true; - } else if (declaration.isVariableDeclaration()) { - const declarators = declaration.get("declarations"); - for (const decl of declarators) { - const id = decl.get("id"); - - const init = decl.get("init"); - const exportsToInsert = []; - if (!init.node) init.replaceWith(t.identifier("undefined")); - - if (id.isIdentifier()) { - addTo(exports, id.node.name, id.node); - init.replaceWith(buildExportsAssignment(id.node, init.node).expression); - nonHoistedExportNames[id.node.name] = true; - } else if (id.isObjectPattern()) { - for (let i = 0; i < id.node.properties.length; i++) { - const prop = id.node.properties[i]; - let propValue = prop.value; - if (t.isAssignmentPattern(propValue)) { - propValue = propValue.left; - } else if (t.isRestProperty(prop)) { - propValue = prop.argument; + const defNode = t.identifier("default"); + if (id) { + addTo(exports, id.name, defNode); + path.replaceWithMultiple([ + declaration.node, + buildExportsAssignment(defNode, id) + ]); + } else { + path.replaceWith(buildExportsAssignment(defNode, t.toExpression(declaration.node))); + + // Manualy re-queue `export default class {}` expressions so that the ES3 transform + // has an opportunity to convert them. Ideally this would happen automatically from the + // replaceWith above. See #4140 for more info. + path.parentPath.requeue(path.get("expression.left")); + } + } else { + path.replaceWith(buildExportsAssignment(t.identifier("default"), declaration.node)); + + // Manualy re-queue `export default foo;` expressions so that the ES3 transform + // has an opportunity to convert them. Ideally this would happen automatically from the + // replaceWith above. See #4140 for more info. + path.parentPath.requeue(path.get("expression.left")); + } + } else if (path.isExportNamedDeclaration()) { + const declaration = path.get("declaration"); + if (declaration.node) { + if (declaration.isFunctionDeclaration()) { + const id = declaration.node.id; + addTo(exports, id.name, id); + topNodes.push(buildExportsAssignment(id, id)); + path.replaceWith(declaration.node); + } else if (declaration.isClassDeclaration()) { + const id = declaration.node.id; + addTo(exports, id.name, id); + path.replaceWithMultiple([ + declaration.node, + buildExportsAssignment(id, id) + ]); + nonHoistedExportNames[id.name] = true; + } else if (declaration.isVariableDeclaration()) { + const declarators = declaration.get("declarations"); + for (const decl of declarators) { + const id = decl.get("id"); + + const init = decl.get("init"); + const exportsToInsert = []; + if (!init.node) init.replaceWith(t.identifier("undefined")); + + if (id.isIdentifier()) { + addTo(exports, id.node.name, id.node); + init.replaceWith(buildExportsAssignment(id.node, init.node).expression); + nonHoistedExportNames[id.node.name] = true; + } else if (id.isObjectPattern()) { + for (let i = 0; i < id.node.properties.length; i++) { + const prop = id.node.properties[i]; + let propValue = prop.value; + if (t.isAssignmentPattern(propValue)) { + propValue = propValue.left; + } else if (t.isRestProperty(prop)) { + propValue = prop.argument; + } + addTo(exports, propValue.name, propValue); + exportsToInsert.push(buildExportsAssignment(propValue, propValue)); + nonHoistedExportNames[propValue.name] = true; } - addTo(exports, propValue.name, propValue); - exportsToInsert.push(buildExportsAssignment(propValue, propValue)); - nonHoistedExportNames[propValue.name] = true; - } - } else if (id.isArrayPattern() && id.node.elements) { - for (let i = 0; i < id.node.elements.length; i++) { - let elem = id.node.elements[i]; - if (!elem) continue; - if (t.isAssignmentPattern(elem)) { - elem = elem.left; - } else if (t.isRestElement(elem)) { - elem = elem.argument; + } else if (id.isArrayPattern() && id.node.elements) { + for (let i = 0; i < id.node.elements.length; i++) { + let elem = id.node.elements[i]; + if (!elem) continue; + if (t.isAssignmentPattern(elem)) { + elem = elem.left; + } else if (t.isRestElement(elem)) { + elem = elem.argument; + } + const name = elem.name; + addTo(exports, name, elem); + exportsToInsert.push(buildExportsAssignment(elem, elem)); + nonHoistedExportNames[name] = true; } - const name = elem.name; - addTo(exports, name, elem); - exportsToInsert.push(buildExportsAssignment(elem, elem)); - nonHoistedExportNames[name] = true; } + path.insertAfter(exportsToInsert); } - path.insertAfter(exportsToInsert); + path.replaceWith(declaration.node); } - path.replaceWith(declaration.node); + continue; } - continue; - } - - const specifiers = path.get("specifiers"); - const nodes = []; - const source = path.node.source; - if (source) { - const ref = addRequire(source.value, path.node._blockHoist); - for (const specifier of specifiers) { - if (specifier.isExportNamespaceSpecifier()) { - // todo - } else if (specifier.isExportDefaultSpecifier()) { - // todo - } else if (specifier.isExportSpecifier()) { - if (!noInterop && specifier.node.local.name === "default") { - topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), - t.memberExpression( - t.callExpression(this.addHelper("interopRequireDefault"), [ref]), - specifier.node.local - ) - )); - } else { - topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), - t.memberExpression(ref, specifier.node.local))); + const specifiers = path.get("specifiers"); + const nodes = []; + const source = path.node.source; + if (source) { + const ref = addRequire(source.value, path.node._blockHoist); + + for (const specifier of specifiers) { + if (specifier.isExportNamespaceSpecifier()) { + // todo + } else if (specifier.isExportDefaultSpecifier()) { + // todo + } else if (specifier.isExportSpecifier()) { + if (!noInterop && specifier.node.local.name === "default") { + topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), + t.memberExpression( + t.callExpression(this.addHelper("interopRequireDefault"), [ref]), + specifier.node.local + ) + )); + } else { + topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), + t.memberExpression(ref, specifier.node.local))); + } + nonHoistedExportNames[specifier.node.exported.name] = true; } - nonHoistedExportNames[specifier.node.exported.name] = true; } - } - } else { - for (const specifier of specifiers) { - if (specifier.isExportSpecifier()) { - addTo(exports, specifier.node.local.name, specifier.node.exported); - nonHoistedExportNames[specifier.node.exported.name] = true; - nodes.push(buildExportsAssignment(specifier.node.exported, specifier.node.local)); + } else { + for (const specifier of specifiers) { + if (specifier.isExportSpecifier()) { + addTo(exports, specifier.node.local.name, specifier.node.exported); + nonHoistedExportNames[specifier.node.exported.name] = true; + nodes.push(buildExportsAssignment(specifier.node.exported, specifier.node.local)); + } } } + path.replaceWithMultiple(nodes); + } else if (path.isExportAllDeclaration()) { + const exportNode = buildExportAll({ + OBJECT: addRequire(path.node.source.value, path.node._blockHoist) + }); + exportNode.loc = path.node.loc; + topNodes.push(exportNode); + path.remove(); } - path.replaceWithMultiple(nodes); - } else if (path.isExportAllDeclaration()) { - const exportNode = buildExportAll({ - OBJECT: addRequire(path.node.source.value, path.node._blockHoist) - }); - exportNode.loc = path.node.loc; - topNodes.push(exportNode); - path.remove(); } - } - - for (const source in imports) { - const { specifiers, maxBlockHoist } = imports[source]; - if (specifiers.length) { - const uid = addRequire(source, maxBlockHoist); - - let wildcard; - - for (let i = 0; i < specifiers.length; i++) { - const specifier = specifiers[i]; - if (t.isImportNamespaceSpecifier(specifier)) { - if (strict || noInterop) { - remaps[specifier.local.name] = uid; - } else { - const varDecl = t.variableDeclaration("var", [ - t.variableDeclarator( - specifier.local, - t.callExpression( - this.addHelper("interopRequireWildcard"), - [uid] - ) - ) - ]); - if (maxBlockHoist > 0) { - varDecl._blockHoist = maxBlockHoist; - } + for (const source in imports) { + const { specifiers, maxBlockHoist } = imports[source]; + if (specifiers.length) { + const uid = addRequire(source, maxBlockHoist); - topNodes.push(varDecl); - } - wildcard = specifier.local; - } else if (t.isImportDefaultSpecifier(specifier)) { - specifiers[i] = t.importSpecifier(specifier.local, t.identifier("default")); - } - } + let wildcard; - for (const specifier of specifiers) { - if (t.isImportSpecifier(specifier)) { - let target = uid; - if (specifier.imported.name === "default") { - if (wildcard) { - target = wildcard; - } else if (!noInterop) { - target = wildcard = path.scope.generateUidIdentifier(uid.name); + for (let i = 0; i < specifiers.length; i++) { + const specifier = specifiers[i]; + if (t.isImportNamespaceSpecifier(specifier)) { + if (strict || noInterop) { + remaps[specifier.local.name] = uid; + } else { const varDecl = t.variableDeclaration("var", [ t.variableDeclarator( - target, + specifier.local, t.callExpression( - this.addHelper("interopRequireDefault"), + this.addHelper("interopRequireWildcard"), [uid] ) ) @@ -451,68 +421,99 @@ export default function () { topNodes.push(varDecl); } + wildcard = specifier.local; + } else if (t.isImportDefaultSpecifier(specifier)) { + specifiers[i] = t.importSpecifier(specifier.local, t.identifier("default")); + } + } + + for (const specifier of specifiers) { + if (t.isImportSpecifier(specifier)) { + let target = uid; + if (specifier.imported.name === "default") { + if (wildcard) { + target = wildcard; + } else if (!noInterop) { + target = wildcard = path.scope.generateUidIdentifier(uid.name); + const varDecl = t.variableDeclaration("var", [ + t.variableDeclarator( + target, + t.callExpression( + this.addHelper("interopRequireDefault"), + [uid] + ) + ) + ]); + + if (maxBlockHoist > 0) { + varDecl._blockHoist = maxBlockHoist; + } + + topNodes.push(varDecl); + } + } + remaps[specifier.local.name] = t.memberExpression(target, + t.cloneWithoutLoc(specifier.imported)); } - remaps[specifier.local.name] = t.memberExpression(target, - t.cloneWithoutLoc(specifier.imported)); } + } else { + // bare import + const requireNode = buildRequire(t.stringLiteral(source)); + requireNode.loc = imports[source].loc; + topNodes.push(requireNode); } - } else { - // bare import - const requireNode = buildRequire(t.stringLiteral(source)); - requireNode.loc = imports[source].loc; - topNodes.push(requireNode); } - } - if (hasImports && Object.keys(nonHoistedExportNames).length) { + if (hasImports && Object.keys(nonHoistedExportNames).length) { - // avoid creating too long of export assignment to prevent stack overflow - const maxHoistedExportsNodeAssignmentLength = 100; - const nonHoistedExportNamesArr = Object.keys(nonHoistedExportNames); + // avoid creating too long of export assignment to prevent stack overflow + const maxHoistedExportsNodeAssignmentLength = 100; + const nonHoistedExportNamesArr = Object.keys(nonHoistedExportNames); - for ( - let currentExportsNodeAssignmentLength = 0; - currentExportsNodeAssignmentLength < nonHoistedExportNamesArr.length; - currentExportsNodeAssignmentLength += maxHoistedExportsNodeAssignmentLength - ) { - const nonHoistedExportNamesChunk = nonHoistedExportNamesArr.slice( - currentExportsNodeAssignmentLength, - currentExportsNodeAssignmentLength + maxHoistedExportsNodeAssignmentLength); + for ( + let currentExportsNodeAssignmentLength = 0; + currentExportsNodeAssignmentLength < nonHoistedExportNamesArr.length; + currentExportsNodeAssignmentLength += maxHoistedExportsNodeAssignmentLength + ) { + const nonHoistedExportNamesChunk = nonHoistedExportNamesArr.slice( + currentExportsNodeAssignmentLength, + currentExportsNodeAssignmentLength + maxHoistedExportsNodeAssignmentLength); - let hoistedExportsNode = t.identifier("undefined"); + let hoistedExportsNode = t.identifier("undefined"); - nonHoistedExportNamesChunk.forEach(function (name) { - hoistedExportsNode = buildExportsAssignment(t.identifier(name), hoistedExportsNode) - .expression; - }); + nonHoistedExportNamesChunk.forEach(function (name) { + hoistedExportsNode = buildExportsAssignment(t.identifier(name), hoistedExportsNode) + .expression; + }); - const node = t.expressionStatement(hoistedExportsNode); - node._blockHoist = 3; + const node = t.expressionStatement(hoistedExportsNode); + node._blockHoist = 3; - topNodes.unshift(node); + topNodes.unshift(node); + } } - } - // add __esModule declaration if this file has any exports - if (hasExports && !strict) { - let buildTemplate = buildExportsModuleDeclaration; - if (this.opts.loose) buildTemplate = buildLooseExportsModuleDeclaration; + // add __esModule declaration if this file has any exports + if (hasExports && !strict) { + let buildTemplate = buildExportsModuleDeclaration; + if (this.opts.loose) buildTemplate = buildLooseExportsModuleDeclaration; - const declar = buildTemplate(); - declar._blockHoist = 3; + const declar = buildTemplate(); + declar._blockHoist = 3; - topNodes.unshift(declar); - } + topNodes.unshift(declar); + } - path.unshiftContainer("body", topNodes); - path.traverse(reassignmentVisitor, { - remaps, - scope, - exports, - requeueInParent: (newPath) => path.requeue(newPath), - }); + path.unshiftContainer("body", topNodes); + path.traverse(reassignmentVisitor, { + remaps, + scope, + exports, + requeueInParent: (newPath) => path.requeue(newPath), + }); + } } } } - }; + ); } From 70354013f15d3afc52f66af6a5cfb113b9c9447d Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Sun, 19 Mar 2017 14:46:59 +0200 Subject: [PATCH 11/13] Fix visitor inheritance. --- .../src/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index daf10a43575f..0f2c19e52e19 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -130,9 +130,9 @@ export default function () { }; return Object.assign( - babelPluginSyntaxObjectRestSpread(), - babelPluginTransformStrictMode(), { + inherits: babelPluginTransformStrictMode, + visitor: { ThisExpression(path, state) { // If other plugins run after this plugin's Program#exit handler, we allow them to @@ -514,6 +514,7 @@ export default function () { } } } - } + }, + babelPluginSyntaxObjectRestSpread() ); } From ddfb6f2c447ef0dca89a161e8ceb98a32808b41a Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Thu, 23 Mar 2017 00:33:03 +0200 Subject: [PATCH 12/13] Remove object-rest-spread syntax. --- .../package.json | 4 +- .../src/index.js | 614 +++++++++--------- .../actual.js | 1 - .../expected.js | 5 - 4 files changed, 306 insertions(+), 318 deletions(-) delete mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js delete mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/package.json b/packages/babel-plugin-transform-es2015-modules-commonjs/package.json index cfad0ef5ef43..148504224f91 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/package.json +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/package.json @@ -9,14 +9,12 @@ "babel-types": "^6.23.0", "babel-runtime": "^6.22.0", "babel-template": "^6.23.0", - "babel-plugin-transform-strict-mode": "^6.22.0", - "babel-plugin-syntax-object-rest-spread": "^6.13.0" + "babel-plugin-transform-strict-mode": "^6.22.0" }, "keywords": [ "babel-plugin" ], "devDependencies": { - "babel-plugin-transform-object-assign": "6.22.0", "babel-helper-plugin-test-runner": "^6.24.0" } } diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index 0f2c19e52e19..5011bc10ed9b 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -1,6 +1,5 @@ import { basename, extname } from "path"; import template from "babel-template"; -import babelPluginSyntaxObjectRestSpread from "babel-plugin-syntax-object-rest-spread"; import babelPluginTransformStrictMode from "babel-plugin-transform-strict-mode"; import * as t from "babel-types"; @@ -129,287 +128,316 @@ export default function () { } }; - return Object.assign( - { - inherits: babelPluginTransformStrictMode, - - visitor: { - ThisExpression(path, state) { - // If other plugins run after this plugin's Program#exit handler, we allow them to - // insert top-level `this` values. This allows the AMD and UMD plugins to - // function properly. - if (this.ranCommonJS) return; - - if ( - state.opts.allowTopLevelThis !== true && - !path.findParent((path) => !path.is("shadow") && - THIS_BREAK_KEYS.indexOf(path.type) >= 0) - ) { - path.replaceWith(t.identifier("undefined")); - } - }, + return { + inherits: babelPluginTransformStrictMode, + + visitor: { + ThisExpression(path, state) { + // If other plugins run after this plugin's Program#exit handler, we allow them to + // insert top-level `this` values. This allows the AMD and UMD plugins to + // function properly. + if (this.ranCommonJS) return; + + if ( + state.opts.allowTopLevelThis !== true && + !path.findParent((path) => !path.is("shadow") && + THIS_BREAK_KEYS.indexOf(path.type) >= 0) + ) { + path.replaceWith(t.identifier("undefined")); + } + }, - Program: { - exit(path) { - this.ranCommonJS = true; + Program: { + exit(path) { + this.ranCommonJS = true; - const strict = !!this.opts.strict; - const noInterop = !!this.opts.noInterop; + const strict = !!this.opts.strict; + const noInterop = !!this.opts.noInterop; - const { scope } = path; + const { scope } = path; - // rename these commonjs variables if they're declared in the file - scope.rename("module"); - scope.rename("exports"); - scope.rename("require"); + // rename these commonjs variables if they're declared in the file + scope.rename("module"); + scope.rename("exports"); + scope.rename("require"); - let hasExports = false; - let hasImports = false; + let hasExports = false; + let hasImports = false; - const body: Array = path.get("body"); - const imports = Object.create(null); - const exports = Object.create(null); + const body: Array = path.get("body"); + const imports = Object.create(null); + const exports = Object.create(null); - const nonHoistedExportNames = Object.create(null); + const nonHoistedExportNames = Object.create(null); - const topNodes = []; - const remaps = Object.create(null); + const topNodes = []; + const remaps = Object.create(null); - const requires = Object.create(null); + const requires = Object.create(null); - function addRequire(source, blockHoist) { - const cached = requires[source]; - if (cached) return cached; + function addRequire(source, blockHoist) { + const cached = requires[source]; + if (cached) return cached; - const ref = path.scope.generateUidIdentifier(basename(source, extname(source))); + const ref = path.scope.generateUidIdentifier(basename(source, extname(source))); - const varDecl = t.variableDeclaration("var", [ - t.variableDeclarator(ref, buildRequire( - t.stringLiteral(source) - ).expression) - ]); + const varDecl = t.variableDeclaration("var", [ + t.variableDeclarator(ref, buildRequire( + t.stringLiteral(source) + ).expression) + ]); - // Copy location from the original import statement for sourcemap - // generation. - if (imports[source]) { - varDecl.loc = imports[source].loc; - } + // Copy location from the original import statement for sourcemap + // generation. + if (imports[source]) { + varDecl.loc = imports[source].loc; + } - if (typeof blockHoist === "number" && blockHoist > 0) { - varDecl._blockHoist = blockHoist; - } + if (typeof blockHoist === "number" && blockHoist > 0) { + varDecl._blockHoist = blockHoist; + } - topNodes.push(varDecl); + topNodes.push(varDecl); - return requires[source] = ref; - } + return requires[source] = ref; + } - function addTo(obj, key, arr) { - const existing = obj[key] || []; - obj[key] = existing.concat(arr); - } + function addTo(obj, key, arr) { + const existing = obj[key] || []; + obj[key] = existing.concat(arr); + } - for (const path of body) { - if (path.isExportDeclaration()) { - hasExports = true; + for (const path of body) { + if (path.isExportDeclaration()) { + hasExports = true; - const specifiers = [].concat(path.get("declaration"), path.get("specifiers")); - for (const specifier of specifiers) { - const ids = specifier.getBindingIdentifiers(); - if (ids.__esModule) { - throw specifier.buildCodeFrameError("Illegal export \"__esModule\""); - } + const specifiers = [].concat(path.get("declaration"), path.get("specifiers")); + for (const specifier of specifiers) { + const ids = specifier.getBindingIdentifiers(); + if (ids.__esModule) { + throw specifier.buildCodeFrameError("Illegal export \"__esModule\""); } } + } - if (path.isImportDeclaration()) { - hasImports = true; - - const key = path.node.source.value; - const importsEntry = imports[key] || { - specifiers: [], - maxBlockHoist: 0, - loc: path.node.loc, - }; - - importsEntry.specifiers.push(...path.node.specifiers); + if (path.isImportDeclaration()) { + hasImports = true; - if (typeof path.node._blockHoist === "number") { - importsEntry.maxBlockHoist = Math.max( - path.node._blockHoist, - importsEntry.maxBlockHoist - ); - } + const key = path.node.source.value; + const importsEntry = imports[key] || { + specifiers: [], + maxBlockHoist: 0, + loc: path.node.loc, + }; - imports[key] = importsEntry; + importsEntry.specifiers.push(...path.node.specifiers); - path.remove(); - } else if (path.isExportDefaultDeclaration()) { - const declaration = path.get("declaration"); - if (declaration.isFunctionDeclaration()) { - const id = declaration.node.id; - const defNode = t.identifier("default"); - if (id) { - addTo(exports, id.name, defNode); - topNodes.push(buildExportsAssignment(defNode, id)); - path.replaceWith(declaration.node); - } else { - topNodes.push(buildExportsAssignment(defNode, t.toExpression(declaration.node))); - path.remove(); - } - } else if (declaration.isClassDeclaration()) { - const id = declaration.node.id; - const defNode = t.identifier("default"); - if (id) { - addTo(exports, id.name, defNode); - path.replaceWithMultiple([ - declaration.node, - buildExportsAssignment(defNode, id) - ]); - } else { - path.replaceWith(buildExportsAssignment(defNode, t.toExpression(declaration.node))); + if (typeof path.node._blockHoist === "number") { + importsEntry.maxBlockHoist = Math.max( + path.node._blockHoist, + importsEntry.maxBlockHoist + ); + } - // Manualy re-queue `export default class {}` expressions so that the ES3 transform - // has an opportunity to convert them. Ideally this would happen automatically from the - // replaceWith above. See #4140 for more info. - path.parentPath.requeue(path.get("expression.left")); - } + imports[key] = importsEntry; + + path.remove(); + } else if (path.isExportDefaultDeclaration()) { + const declaration = path.get("declaration"); + if (declaration.isFunctionDeclaration()) { + const id = declaration.node.id; + const defNode = t.identifier("default"); + if (id) { + addTo(exports, id.name, defNode); + topNodes.push(buildExportsAssignment(defNode, id)); + path.replaceWith(declaration.node); } else { - path.replaceWith(buildExportsAssignment(t.identifier("default"), declaration.node)); + topNodes.push(buildExportsAssignment(defNode, t.toExpression(declaration.node))); + path.remove(); + } + } else if (declaration.isClassDeclaration()) { + const id = declaration.node.id; + const defNode = t.identifier("default"); + if (id) { + addTo(exports, id.name, defNode); + path.replaceWithMultiple([ + declaration.node, + buildExportsAssignment(defNode, id) + ]); + } else { + path.replaceWith(buildExportsAssignment(defNode, t.toExpression(declaration.node))); - // Manualy re-queue `export default foo;` expressions so that the ES3 transform + // Manualy re-queue `export default class {}` expressions so that the ES3 transform // has an opportunity to convert them. Ideally this would happen automatically from the // replaceWith above. See #4140 for more info. path.parentPath.requeue(path.get("expression.left")); } - } else if (path.isExportNamedDeclaration()) { - const declaration = path.get("declaration"); - if (declaration.node) { - if (declaration.isFunctionDeclaration()) { - const id = declaration.node.id; - addTo(exports, id.name, id); - topNodes.push(buildExportsAssignment(id, id)); - path.replaceWith(declaration.node); - } else if (declaration.isClassDeclaration()) { - const id = declaration.node.id; - addTo(exports, id.name, id); - path.replaceWithMultiple([ - declaration.node, - buildExportsAssignment(id, id) - ]); - nonHoistedExportNames[id.name] = true; - } else if (declaration.isVariableDeclaration()) { - const declarators = declaration.get("declarations"); - for (const decl of declarators) { - const id = decl.get("id"); - - const init = decl.get("init"); - const exportsToInsert = []; - if (!init.node) init.replaceWith(t.identifier("undefined")); - - if (id.isIdentifier()) { - addTo(exports, id.node.name, id.node); - init.replaceWith(buildExportsAssignment(id.node, init.node).expression); - nonHoistedExportNames[id.node.name] = true; - } else if (id.isObjectPattern()) { - for (let i = 0; i < id.node.properties.length; i++) { - const prop = id.node.properties[i]; - let propValue = prop.value; - if (t.isAssignmentPattern(propValue)) { - propValue = propValue.left; - } else if (t.isRestProperty(prop)) { - propValue = prop.argument; - } - addTo(exports, propValue.name, propValue); - exportsToInsert.push(buildExportsAssignment(propValue, propValue)); - nonHoistedExportNames[propValue.name] = true; + } else { + path.replaceWith(buildExportsAssignment(t.identifier("default"), declaration.node)); + + // Manualy re-queue `export default foo;` expressions so that the ES3 transform + // has an opportunity to convert them. Ideally this would happen automatically from the + // replaceWith above. See #4140 for more info. + path.parentPath.requeue(path.get("expression.left")); + } + } else if (path.isExportNamedDeclaration()) { + const declaration = path.get("declaration"); + if (declaration.node) { + if (declaration.isFunctionDeclaration()) { + const id = declaration.node.id; + addTo(exports, id.name, id); + topNodes.push(buildExportsAssignment(id, id)); + path.replaceWith(declaration.node); + } else if (declaration.isClassDeclaration()) { + const id = declaration.node.id; + addTo(exports, id.name, id); + path.replaceWithMultiple([ + declaration.node, + buildExportsAssignment(id, id) + ]); + nonHoistedExportNames[id.name] = true; + } else if (declaration.isVariableDeclaration()) { + const declarators = declaration.get("declarations"); + for (const decl of declarators) { + const id = decl.get("id"); + + const init = decl.get("init"); + const exportsToInsert = []; + if (!init.node) init.replaceWith(t.identifier("undefined")); + + if (id.isIdentifier()) { + addTo(exports, id.node.name, id.node); + init.replaceWith(buildExportsAssignment(id.node, init.node).expression); + nonHoistedExportNames[id.node.name] = true; + } else if (id.isObjectPattern()) { + for (let i = 0; i < id.node.properties.length; i++) { + const prop = id.node.properties[i]; + let propValue = prop.value; + if (t.isAssignmentPattern(propValue)) { + propValue = propValue.left; + } else if (t.isRestProperty(prop)) { + propValue = prop.argument; } - } else if (id.isArrayPattern() && id.node.elements) { - for (let i = 0; i < id.node.elements.length; i++) { - let elem = id.node.elements[i]; - if (!elem) continue; - if (t.isAssignmentPattern(elem)) { - elem = elem.left; - } else if (t.isRestElement(elem)) { - elem = elem.argument; - } - const name = elem.name; - addTo(exports, name, elem); - exportsToInsert.push(buildExportsAssignment(elem, elem)); - nonHoistedExportNames[name] = true; + addTo(exports, propValue.name, propValue); + exportsToInsert.push(buildExportsAssignment(propValue, propValue)); + nonHoistedExportNames[propValue.name] = true; + } + } else if (id.isArrayPattern() && id.node.elements) { + for (let i = 0; i < id.node.elements.length; i++) { + let elem = id.node.elements[i]; + if (!elem) continue; + if (t.isAssignmentPattern(elem)) { + elem = elem.left; + } else if (t.isRestElement(elem)) { + elem = elem.argument; } + const name = elem.name; + addTo(exports, name, elem); + exportsToInsert.push(buildExportsAssignment(elem, elem)); + nonHoistedExportNames[name] = true; } - path.insertAfter(exportsToInsert); } - path.replaceWith(declaration.node); + path.insertAfter(exportsToInsert); } - continue; + path.replaceWith(declaration.node); } + continue; + } - const specifiers = path.get("specifiers"); - const nodes = []; - const source = path.node.source; - if (source) { - const ref = addRequire(source.value, path.node._blockHoist); - - for (const specifier of specifiers) { - if (specifier.isExportNamespaceSpecifier()) { - // todo - } else if (specifier.isExportDefaultSpecifier()) { - // todo - } else if (specifier.isExportSpecifier()) { - if (!noInterop && specifier.node.local.name === "default") { - topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), - t.memberExpression( - t.callExpression(this.addHelper("interopRequireDefault"), [ref]), - specifier.node.local - ) - )); - } else { - topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), - t.memberExpression(ref, specifier.node.local))); - } - nonHoistedExportNames[specifier.node.exported.name] = true; + const specifiers = path.get("specifiers"); + const nodes = []; + const source = path.node.source; + if (source) { + const ref = addRequire(source.value, path.node._blockHoist); + + for (const specifier of specifiers) { + if (specifier.isExportNamespaceSpecifier()) { + // todo + } else if (specifier.isExportDefaultSpecifier()) { + // todo + } else if (specifier.isExportSpecifier()) { + if (!noInterop && specifier.node.local.name === "default") { + topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), + t.memberExpression( + t.callExpression(this.addHelper("interopRequireDefault"), [ref]), + specifier.node.local + ) + )); + } else { + topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), + t.memberExpression(ref, specifier.node.local))); } + nonHoistedExportNames[specifier.node.exported.name] = true; } - } else { - for (const specifier of specifiers) { - if (specifier.isExportSpecifier()) { - addTo(exports, specifier.node.local.name, specifier.node.exported); - nonHoistedExportNames[specifier.node.exported.name] = true; - nodes.push(buildExportsAssignment(specifier.node.exported, specifier.node.local)); - } + } + } else { + for (const specifier of specifiers) { + if (specifier.isExportSpecifier()) { + addTo(exports, specifier.node.local.name, specifier.node.exported); + nonHoistedExportNames[specifier.node.exported.name] = true; + nodes.push(buildExportsAssignment(specifier.node.exported, specifier.node.local)); } } - path.replaceWithMultiple(nodes); - } else if (path.isExportAllDeclaration()) { - const exportNode = buildExportAll({ - OBJECT: addRequire(path.node.source.value, path.node._blockHoist) - }); - exportNode.loc = path.node.loc; - topNodes.push(exportNode); - path.remove(); } + path.replaceWithMultiple(nodes); + } else if (path.isExportAllDeclaration()) { + const exportNode = buildExportAll({ + OBJECT: addRequire(path.node.source.value, path.node._blockHoist) + }); + exportNode.loc = path.node.loc; + topNodes.push(exportNode); + path.remove(); } + } - for (const source in imports) { - const { specifiers, maxBlockHoist } = imports[source]; - if (specifiers.length) { - const uid = addRequire(source, maxBlockHoist); + for (const source in imports) { + const { specifiers, maxBlockHoist } = imports[source]; + if (specifiers.length) { + const uid = addRequire(source, maxBlockHoist); - let wildcard; + let wildcard; - for (let i = 0; i < specifiers.length; i++) { - const specifier = specifiers[i]; - if (t.isImportNamespaceSpecifier(specifier)) { - if (strict || noInterop) { - remaps[specifier.local.name] = uid; - } else { + for (let i = 0; i < specifiers.length; i++) { + const specifier = specifiers[i]; + if (t.isImportNamespaceSpecifier(specifier)) { + if (strict || noInterop) { + remaps[specifier.local.name] = uid; + } else { + const varDecl = t.variableDeclaration("var", [ + t.variableDeclarator( + specifier.local, + t.callExpression( + this.addHelper("interopRequireWildcard"), + [uid] + ) + ) + ]); + + if (maxBlockHoist > 0) { + varDecl._blockHoist = maxBlockHoist; + } + + topNodes.push(varDecl); + } + wildcard = specifier.local; + } else if (t.isImportDefaultSpecifier(specifier)) { + specifiers[i] = t.importSpecifier(specifier.local, t.identifier("default")); + } + } + + for (const specifier of specifiers) { + if (t.isImportSpecifier(specifier)) { + let target = uid; + if (specifier.imported.name === "default") { + if (wildcard) { + target = wildcard; + } else if (!noInterop) { + target = wildcard = path.scope.generateUidIdentifier(uid.name); const varDecl = t.variableDeclaration("var", [ t.variableDeclarator( - specifier.local, + target, t.callExpression( - this.addHelper("interopRequireWildcard"), + this.addHelper("interopRequireDefault"), [uid] ) ) @@ -421,100 +449,68 @@ export default function () { topNodes.push(varDecl); } - wildcard = specifier.local; - } else if (t.isImportDefaultSpecifier(specifier)) { - specifiers[i] = t.importSpecifier(specifier.local, t.identifier("default")); } + remaps[specifier.local.name] = t.memberExpression(target, + t.cloneWithoutLoc(specifier.imported)); } - - for (const specifier of specifiers) { - if (t.isImportSpecifier(specifier)) { - let target = uid; - if (specifier.imported.name === "default") { - if (wildcard) { - target = wildcard; - } else if (!noInterop) { - target = wildcard = path.scope.generateUidIdentifier(uid.name); - const varDecl = t.variableDeclaration("var", [ - t.variableDeclarator( - target, - t.callExpression( - this.addHelper("interopRequireDefault"), - [uid] - ) - ) - ]); - - if (maxBlockHoist > 0) { - varDecl._blockHoist = maxBlockHoist; - } - - topNodes.push(varDecl); - } - } - remaps[specifier.local.name] = t.memberExpression(target, - t.cloneWithoutLoc(specifier.imported)); - } - } - } else { - // bare import - const requireNode = buildRequire(t.stringLiteral(source)); - requireNode.loc = imports[source].loc; - topNodes.push(requireNode); } + } else { + // bare import + const requireNode = buildRequire(t.stringLiteral(source)); + requireNode.loc = imports[source].loc; + topNodes.push(requireNode); } + } - if (hasImports && Object.keys(nonHoistedExportNames).length) { + if (hasImports && Object.keys(nonHoistedExportNames).length) { - // avoid creating too long of export assignment to prevent stack overflow - const maxHoistedExportsNodeAssignmentLength = 100; - const nonHoistedExportNamesArr = Object.keys(nonHoistedExportNames); + // avoid creating too long of export assignment to prevent stack overflow + const maxHoistedExportsNodeAssignmentLength = 100; + const nonHoistedExportNamesArr = Object.keys(nonHoistedExportNames); - for ( - let currentExportsNodeAssignmentLength = 0; - currentExportsNodeAssignmentLength < nonHoistedExportNamesArr.length; - currentExportsNodeAssignmentLength += maxHoistedExportsNodeAssignmentLength - ) { - const nonHoistedExportNamesChunk = nonHoistedExportNamesArr.slice( - currentExportsNodeAssignmentLength, - currentExportsNodeAssignmentLength + maxHoistedExportsNodeAssignmentLength); + for ( + let currentExportsNodeAssignmentLength = 0; + currentExportsNodeAssignmentLength < nonHoistedExportNamesArr.length; + currentExportsNodeAssignmentLength += maxHoistedExportsNodeAssignmentLength + ) { + const nonHoistedExportNamesChunk = nonHoistedExportNamesArr.slice( + currentExportsNodeAssignmentLength, + currentExportsNodeAssignmentLength + maxHoistedExportsNodeAssignmentLength); - let hoistedExportsNode = t.identifier("undefined"); + let hoistedExportsNode = t.identifier("undefined"); - nonHoistedExportNamesChunk.forEach(function (name) { - hoistedExportsNode = buildExportsAssignment(t.identifier(name), hoistedExportsNode) - .expression; - }); + nonHoistedExportNamesChunk.forEach(function (name) { + hoistedExportsNode = buildExportsAssignment(t.identifier(name), hoistedExportsNode) + .expression; + }); - const node = t.expressionStatement(hoistedExportsNode); - node._blockHoist = 3; + const node = t.expressionStatement(hoistedExportsNode); + node._blockHoist = 3; - topNodes.unshift(node); - } + topNodes.unshift(node); } + } - // add __esModule declaration if this file has any exports - if (hasExports && !strict) { - let buildTemplate = buildExportsModuleDeclaration; - if (this.opts.loose) buildTemplate = buildLooseExportsModuleDeclaration; - - const declar = buildTemplate(); - declar._blockHoist = 3; + // add __esModule declaration if this file has any exports + if (hasExports && !strict) { + let buildTemplate = buildExportsModuleDeclaration; + if (this.opts.loose) buildTemplate = buildLooseExportsModuleDeclaration; - topNodes.unshift(declar); - } + const declar = buildTemplate(); + declar._blockHoist = 3; - path.unshiftContainer("body", topNodes); - path.traverse(reassignmentVisitor, { - remaps, - scope, - exports, - requeueInParent: (newPath) => path.requeue(newPath), - }); + topNodes.unshift(declar); } + + path.unshiftContainer("body", topNodes); + path.traverse(reassignmentVisitor, { + remaps, + scope, + exports, + requeueInParent: (newPath) => path.requeue(newPath), + }); } } - }, - babelPluginSyntaxObjectRestSpread() - ); + } + }; } diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js deleted file mode 100644 index d4d52568cebd..000000000000 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js +++ /dev/null @@ -1 +0,0 @@ -export const { foo, ...bar } = {}; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js deleted file mode 100644 index 4e27e3401413..000000000000 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js +++ /dev/null @@ -1,5 +0,0 @@ -"use strict"; - -const { foo, ...bar } = {}; -exports.foo = foo; -exports.bar = bar; From f2f226b4f22b3e0afc66c56d251cbdb1c35b865e Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Thu, 23 Mar 2017 00:52:10 +0200 Subject: [PATCH 13/13] Add syntax-object-rest-spread as devDep for tests. --- .../package.json | 3 ++- .../strict/export-const-destructuring-object-rest/actual.js | 1 + .../export-const-destructuring-object-rest/expected.js | 5 +++++ .../test/fixtures/strict/options.json | 5 ++++- 4 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js create mode 100644 packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/package.json b/packages/babel-plugin-transform-es2015-modules-commonjs/package.json index 148504224f91..416648c85c74 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/package.json +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/package.json @@ -15,6 +15,7 @@ "babel-plugin" ], "devDependencies": { - "babel-helper-plugin-test-runner": "^6.24.0" + "babel-helper-plugin-test-runner": "^6.24.0", + "babel-plugin-syntax-object-rest-spread": "^6.13.0" } } diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js new file mode 100644 index 000000000000..d4d52568cebd --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/actual.js @@ -0,0 +1 @@ +export const { foo, ...bar } = {}; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js new file mode 100644 index 000000000000..4e27e3401413 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/export-const-destructuring-object-rest/expected.js @@ -0,0 +1,5 @@ +"use strict"; + +const { foo, ...bar } = {}; +exports.foo = foo; +exports.bar = bar; diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/options.json b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/options.json index b2db9b920547..064550a7c229 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/options.json +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/strict/options.json @@ -1,3 +1,6 @@ { - "plugins": ["external-helpers", ["transform-es2015-modules-commonjs", { "strict": true }]] + "plugins": [ + "external-helpers", + "syntax-object-rest-spread", + ["transform-es2015-modules-commonjs", { "strict": true }]] }