From bcd5dc789c25cec25fa1f2941206781785e63f19 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 28 Apr 2016 10:17:13 -0400 Subject: [PATCH 001/331] ensure import paths are case-sensitive (#590) --- src/utils/defaults.js | 11 ++++++----- test/function/paths-are-case-sensitive/Foo.js | 3 +++ test/function/paths-are-case-sensitive/_config.js | 8 ++++++++ test/function/paths-are-case-sensitive/main.js | 3 +++ 4 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 test/function/paths-are-case-sensitive/Foo.js create mode 100644 test/function/paths-are-case-sensitive/_config.js create mode 100644 test/function/paths-are-case-sensitive/main.js diff --git a/src/utils/defaults.js b/src/utils/defaults.js index 70c36fe..449e320 100644 --- a/src/utils/defaults.js +++ b/src/utils/defaults.js @@ -1,5 +1,5 @@ -import { isFile, readFileSync } from './fs.js'; -import { dirname, isAbsolute, resolve } from './path.js'; +import { isFile, readdirSync, readFileSync } from './fs.js'; +import { basename, dirname, isAbsolute, resolve } from './path.js'; import { blank } from './object.js'; export function load ( id ) { @@ -7,10 +7,11 @@ export function load ( id ) { } function addJsExtensionIfNecessary ( file ) { - if ( isFile( file ) ) return file; + const name = basename( file ); + const files = readdirSync( dirname( file ) ); - file += '.js'; - if ( isFile( file ) ) return file; + if ( ~files.indexOf( name ) && isFile( file ) ) return file; + if ( ~files.indexOf( `${name}.js` ) && isFile( `${file}.js` ) ) return `${file}.js`; return null; } diff --git a/test/function/paths-are-case-sensitive/Foo.js b/test/function/paths-are-case-sensitive/Foo.js new file mode 100644 index 0000000..81baecb --- /dev/null +++ b/test/function/paths-are-case-sensitive/Foo.js @@ -0,0 +1,3 @@ +export default function () { + assert.ok( false ); +} diff --git a/test/function/paths-are-case-sensitive/_config.js b/test/function/paths-are-case-sensitive/_config.js new file mode 100644 index 0000000..3f81b80 --- /dev/null +++ b/test/function/paths-are-case-sensitive/_config.js @@ -0,0 +1,8 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'insists on correct casing for imports', + error: function ( err ) { + assert.ok( /Could not resolve/.test( err.message ) ); + } +}; diff --git a/test/function/paths-are-case-sensitive/main.js b/test/function/paths-are-case-sensitive/main.js new file mode 100644 index 0000000..e1fb5c4 --- /dev/null +++ b/test/function/paths-are-case-sensitive/main.js @@ -0,0 +1,3 @@ +import foo from './foo.js'; + +foo(); From d8844e7078e293001fa66aff2f8c1b19d198faf0 Mon Sep 17 00:00:00 2001 From: Cameron Martin Date: Sat, 14 May 2016 13:38:03 +0100 Subject: [PATCH 002/331] Added the __esModule export, with value true, when the format is cjs or umd, and the exports option is named. --- src/finalisers/cjs.js | 4 ++++ src/finalisers/umd.js | 4 ++++ .../assignment-to-exports-class-declaration/_expected/cjs.js | 2 ++ .../assignment-to-exports-class-declaration/_expected/umd.js | 2 ++ test/form/computed-properties/_expected/cjs.js | 4 +++- test/form/computed-properties/_expected/umd.js | 4 +++- test/form/dedupes-external-imports/_expected/cjs.js | 2 ++ test/form/dedupes-external-imports/_expected/umd.js | 4 +++- test/form/export-all-from-internal/_expected/cjs.js | 2 ++ test/form/export-all-from-internal/_expected/umd.js | 4 +++- test/form/export-default-import/_expected/cjs.js | 4 +++- test/form/export-default-import/_expected/umd.js | 4 +++- test/form/exports-at-end-if-possible/_expected/cjs.js | 2 ++ test/form/exports-at-end-if-possible/_expected/umd.js | 4 +++- test/form/multiple-exports/_expected/cjs.js | 2 ++ test/form/multiple-exports/_expected/umd.js | 4 +++- test/form/namespaced-named-exports/_expected/cjs.js | 4 +++- test/form/namespaced-named-exports/_expected/umd.js | 4 +++- test/form/no-treeshake/_expected/cjs.js | 2 ++ test/form/no-treeshake/_expected/umd.js | 2 ++ test/form/preserves-comments-after-imports/_expected/cjs.js | 2 ++ test/form/preserves-comments-after-imports/_expected/umd.js | 4 +++- test/form/umd-noconflict/_expected/cjs.js | 4 +++- test/form/umd-noconflict/_expected/umd.js | 2 ++ test/function/deconflicts-exports/_config.js | 2 +- test/function/export-destruction/_config.js | 2 +- 26 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index 07adf72..5b4145a 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -34,5 +34,9 @@ export default function cjs ( bundle, magicString, { exportMode }, options ) { const exportBlock = getExportBlock( bundle.entryModule, exportMode, 'module.exports =' ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); + if (exportMode === 'named') { + magicString.append('\n\nexports.__esModule = true;\n\n'); + } + return magicString; } diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index 0ec344e..4db72da 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -69,6 +69,10 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); + if (exportMode === 'named') { + magicString.append('\n\nexports.__esModule = true;\n\n'); + } + return magicString .trim() .indent( indentString ) diff --git a/test/form/assignment-to-exports-class-declaration/_expected/cjs.js b/test/form/assignment-to-exports-class-declaration/_expected/cjs.js index b062474..09efe46 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/cjs.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/cjs.js @@ -2,3 +2,5 @@ exports.Foo = class Foo {} exports.Foo = lol( exports.Foo ); + +exports.__esModule = true; diff --git a/test/form/assignment-to-exports-class-declaration/_expected/umd.js b/test/form/assignment-to-exports-class-declaration/_expected/umd.js index bbefc87..2432b64 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/umd.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/umd.js @@ -7,4 +7,6 @@ exports.Foo = class Foo {} exports.Foo = lol( exports.Foo ); + exports.__esModule = true; + })); diff --git a/test/form/computed-properties/_expected/cjs.js b/test/form/computed-properties/_expected/cjs.js index 443bab3..8220c15 100644 --- a/test/form/computed-properties/_expected/cjs.js +++ b/test/form/computed-properties/_expected/cjs.js @@ -14,4 +14,6 @@ class X { } exports.x = x; -exports.X = X; \ No newline at end of file +exports.X = X; + +exports.__esModule = true; diff --git a/test/form/computed-properties/_expected/umd.js b/test/form/computed-properties/_expected/umd.js index ae57683..3c68104 100644 --- a/test/form/computed-properties/_expected/umd.js +++ b/test/form/computed-properties/_expected/umd.js @@ -20,4 +20,6 @@ exports.x = x; exports.X = X; -})); \ No newline at end of file + exports.__esModule = true; + +})); diff --git a/test/form/dedupes-external-imports/_expected/cjs.js b/test/form/dedupes-external-imports/_expected/cjs.js index fd4138b..c12daee 100644 --- a/test/form/dedupes-external-imports/_expected/cjs.js +++ b/test/form/dedupes-external-imports/_expected/cjs.js @@ -30,3 +30,5 @@ const baz = new Baz(); exports.foo = foo; exports.bar = bar; exports.baz = baz; + +exports.__esModule = true; diff --git a/test/form/dedupes-external-imports/_expected/umd.js b/test/form/dedupes-external-imports/_expected/umd.js index 06be0e7..bcd5d74 100644 --- a/test/form/dedupes-external-imports/_expected/umd.js +++ b/test/form/dedupes-external-imports/_expected/umd.js @@ -33,4 +33,6 @@ exports.bar = bar; exports.baz = baz; -})); \ No newline at end of file + exports.__esModule = true; + +})); diff --git a/test/form/export-all-from-internal/_expected/cjs.js b/test/form/export-all-from-internal/_expected/cjs.js index 869bba0..207acbd 100644 --- a/test/form/export-all-from-internal/_expected/cjs.js +++ b/test/form/export-all-from-internal/_expected/cjs.js @@ -5,3 +5,5 @@ const b = 2; exports.a = a; exports.b = b; + +exports.__esModule = true; diff --git a/test/form/export-all-from-internal/_expected/umd.js b/test/form/export-all-from-internal/_expected/umd.js index b249cc6..ae889e3 100644 --- a/test/form/export-all-from-internal/_expected/umd.js +++ b/test/form/export-all-from-internal/_expected/umd.js @@ -10,4 +10,6 @@ exports.a = a; exports.b = b; -})); \ No newline at end of file + exports.__esModule = true; + +})); diff --git a/test/form/export-default-import/_expected/cjs.js b/test/form/export-default-import/_expected/cjs.js index 60037db..28e34b0 100644 --- a/test/form/export-default-import/_expected/cjs.js +++ b/test/form/export-default-import/_expected/cjs.js @@ -6,4 +6,6 @@ var x = _interopDefault(require('x')); -exports.x = x; \ No newline at end of file +exports.x = x; + +exports.__esModule = true; diff --git a/test/form/export-default-import/_expected/umd.js b/test/form/export-default-import/_expected/umd.js index 872c0d8..39040e6 100644 --- a/test/form/export-default-import/_expected/umd.js +++ b/test/form/export-default-import/_expected/umd.js @@ -10,4 +10,6 @@ exports.x = x; -})); \ No newline at end of file + exports.__esModule = true; + +})); diff --git a/test/form/exports-at-end-if-possible/_expected/cjs.js b/test/form/exports-at-end-if-possible/_expected/cjs.js index 57d55d3..f966613 100644 --- a/test/form/exports-at-end-if-possible/_expected/cjs.js +++ b/test/form/exports-at-end-if-possible/_expected/cjs.js @@ -7,3 +7,5 @@ console.log( FOO ); console.log( FOO ); exports.FOO = FOO; + +exports.__esModule = true; diff --git a/test/form/exports-at-end-if-possible/_expected/umd.js b/test/form/exports-at-end-if-possible/_expected/umd.js index e9cbc8d..a2c13f8 100644 --- a/test/form/exports-at-end-if-possible/_expected/umd.js +++ b/test/form/exports-at-end-if-possible/_expected/umd.js @@ -12,4 +12,6 @@ exports.FOO = FOO; -})); \ No newline at end of file + exports.__esModule = true; + +})); diff --git a/test/form/multiple-exports/_expected/cjs.js b/test/form/multiple-exports/_expected/cjs.js index 1968b8b..9d7081c 100644 --- a/test/form/multiple-exports/_expected/cjs.js +++ b/test/form/multiple-exports/_expected/cjs.js @@ -5,3 +5,5 @@ var bar = 2; exports.foo = foo; exports.bar = bar; + +exports.__esModule = true; diff --git a/test/form/multiple-exports/_expected/umd.js b/test/form/multiple-exports/_expected/umd.js index 30a54d6..9d9b112f7 100644 --- a/test/form/multiple-exports/_expected/umd.js +++ b/test/form/multiple-exports/_expected/umd.js @@ -10,4 +10,6 @@ exports.foo = foo; exports.bar = bar; -})); \ No newline at end of file + exports.__esModule = true; + +})); diff --git a/test/form/namespaced-named-exports/_expected/cjs.js b/test/form/namespaced-named-exports/_expected/cjs.js index 4b8935f..87e3bde 100644 --- a/test/form/namespaced-named-exports/_expected/cjs.js +++ b/test/form/namespaced-named-exports/_expected/cjs.js @@ -2,4 +2,6 @@ var answer = 42; -exports.answer = answer; \ No newline at end of file +exports.answer = answer; + +exports.__esModule = true; diff --git a/test/form/namespaced-named-exports/_expected/umd.js b/test/form/namespaced-named-exports/_expected/umd.js index 9a0f47d..f0e64a6 100644 --- a/test/form/namespaced-named-exports/_expected/umd.js +++ b/test/form/namespaced-named-exports/_expected/umd.js @@ -8,4 +8,6 @@ exports.answer = answer; -})); \ No newline at end of file + exports.__esModule = true; + +})); diff --git a/test/form/no-treeshake/_expected/cjs.js b/test/form/no-treeshake/_expected/cjs.js index c188f06..d8fdece 100644 --- a/test/form/no-treeshake/_expected/cjs.js +++ b/test/form/no-treeshake/_expected/cjs.js @@ -23,3 +23,5 @@ exports.baz = baz; exports.create = create; exports.getPrototypeOf = getPrototypeOf; exports.strange = quux; + +exports.__esModule = true; diff --git a/test/form/no-treeshake/_expected/umd.js b/test/form/no-treeshake/_expected/umd.js index 2136453..ce07d58 100644 --- a/test/form/no-treeshake/_expected/umd.js +++ b/test/form/no-treeshake/_expected/umd.js @@ -26,4 +26,6 @@ exports.getPrototypeOf = getPrototypeOf; exports.strange = quux; + exports.__esModule = true; + })); diff --git a/test/form/preserves-comments-after-imports/_expected/cjs.js b/test/form/preserves-comments-after-imports/_expected/cjs.js index 8b15cd1..8b4421f 100644 --- a/test/form/preserves-comments-after-imports/_expected/cjs.js +++ b/test/form/preserves-comments-after-imports/_expected/cjs.js @@ -7,3 +7,5 @@ var number = 5; var obj = { number }; exports.obj = obj; + +exports.__esModule = true; diff --git a/test/form/preserves-comments-after-imports/_expected/umd.js b/test/form/preserves-comments-after-imports/_expected/umd.js index 13a54bf..29b316b 100644 --- a/test/form/preserves-comments-after-imports/_expected/umd.js +++ b/test/form/preserves-comments-after-imports/_expected/umd.js @@ -12,4 +12,6 @@ exports.obj = obj; -})); \ No newline at end of file + exports.__esModule = true; + +})); diff --git a/test/form/umd-noconflict/_expected/cjs.js b/test/form/umd-noconflict/_expected/cjs.js index 4379f50..df41ba1 100644 --- a/test/form/umd-noconflict/_expected/cjs.js +++ b/test/form/umd-noconflict/_expected/cjs.js @@ -10,4 +10,6 @@ var setting = 'no'; exports.doThings = doThings; exports.number = number; -exports.setting = setting; \ No newline at end of file +exports.setting = setting; + +exports.__esModule = true; diff --git a/test/form/umd-noconflict/_expected/umd.js b/test/form/umd-noconflict/_expected/umd.js index 5578ce9..3a7d1d1 100644 --- a/test/form/umd-noconflict/_expected/umd.js +++ b/test/form/umd-noconflict/_expected/umd.js @@ -21,4 +21,6 @@ exports.number = number; exports.setting = setting; + exports.__esModule = true; + })); diff --git a/test/function/deconflicts-exports/_config.js b/test/function/deconflicts-exports/_config.js index 8724967..a564b5c 100644 --- a/test/function/deconflicts-exports/_config.js +++ b/test/function/deconflicts-exports/_config.js @@ -3,7 +3,7 @@ var assert = require( 'assert' ); module.exports = { description: 'renames variables named `exports` if necessary', exports: function ( exports ) { - assert.deepEqual( Object.keys( exports ), [ 'a', 'b' ] ); + assert.deepEqual( Object.keys( exports ), [ 'a', 'b', '__esModule' ] ); assert.equal( exports.a, 'A' ); assert.equal( exports.b, 42 ); } diff --git a/test/function/export-destruction/_config.js b/test/function/export-destruction/_config.js index 263c8d1..740e33a 100644 --- a/test/function/export-destruction/_config.js +++ b/test/function/export-destruction/_config.js @@ -5,7 +5,7 @@ module.exports = { babel: true, exports: function ( exports ) { - assert.deepEqual( Object.keys( exports ), [ 'baz', 'quux' ] ); + assert.deepEqual( Object.keys( exports ), [ 'baz', 'quux', '__esModule' ] ); assert.equal( exports.baz, 5 ); assert.equal( exports.quux, 17 ); } From a660b896dcbca62bbc0ee950aa4a9ebeef9460b9 Mon Sep 17 00:00:00 2001 From: Cameron Martin Date: Sun, 15 May 2016 11:35:27 +0100 Subject: [PATCH 003/331] Made __esModule a non-enumerable property of exports. This is the same as how babel does it. See https://goo.gl/KTGKyH. --- src/finalisers/cjs.js | 3 ++- src/finalisers/shared/esModuleExport.js | 4 ++++ src/finalisers/umd.js | 3 ++- .../assignment-to-exports-class-declaration/_expected/cjs.js | 4 +++- .../assignment-to-exports-class-declaration/_expected/umd.js | 4 +++- test/form/computed-properties/_expected/cjs.js | 4 +++- test/form/computed-properties/_expected/umd.js | 4 +++- test/form/dedupes-external-imports/_expected/cjs.js | 4 +++- test/form/dedupes-external-imports/_expected/umd.js | 4 +++- test/form/export-all-from-internal/_expected/cjs.js | 4 +++- test/form/export-all-from-internal/_expected/umd.js | 4 +++- test/form/export-default-import/_expected/cjs.js | 4 +++- test/form/export-default-import/_expected/umd.js | 4 +++- test/form/exports-at-end-if-possible/_expected/cjs.js | 4 +++- test/form/exports-at-end-if-possible/_expected/umd.js | 4 +++- test/form/multiple-exports/_expected/cjs.js | 4 +++- test/form/multiple-exports/_expected/umd.js | 4 +++- test/form/namespaced-named-exports/_expected/cjs.js | 4 +++- test/form/namespaced-named-exports/_expected/umd.js | 4 +++- test/form/no-treeshake/_expected/cjs.js | 4 +++- test/form/no-treeshake/_expected/umd.js | 4 +++- test/form/preserves-comments-after-imports/_expected/cjs.js | 4 +++- test/form/preserves-comments-after-imports/_expected/umd.js | 4 +++- test/form/umd-noconflict/_expected/cjs.js | 4 +++- test/form/umd-noconflict/_expected/umd.js | 4 +++- test/function/deconflicts-exports/_config.js | 2 +- test/function/export-destruction/_config.js | 2 +- 27 files changed, 76 insertions(+), 26 deletions(-) create mode 100644 src/finalisers/shared/esModuleExport.js diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index 5b4145a..d147e6c 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -1,4 +1,5 @@ import getExportBlock from './shared/getExportBlock.js'; +import esModuleExport from './shared/esModuleExport.js'; export default function cjs ( bundle, magicString, { exportMode }, options ) { let intro = options.useStrict === false ? `` : `'use strict';\n\n`; @@ -35,7 +36,7 @@ export default function cjs ( bundle, magicString, { exportMode }, options ) { if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); if (exportMode === 'named') { - magicString.append('\n\nexports.__esModule = true;\n\n'); + magicString.append(esModuleExport); } return magicString; diff --git a/src/finalisers/shared/esModuleExport.js b/src/finalisers/shared/esModuleExport.js new file mode 100644 index 0000000..058aa09 --- /dev/null +++ b/src/finalisers/shared/esModuleExport.js @@ -0,0 +1,4 @@ +export default '\n\n' + + 'Object.defineProperty(exports, "__esModule", {\n' + + ' value: true\n' + + '});\n\n'; diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index 4db72da..7e00e8e 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -3,6 +3,7 @@ import { getName, quoteId, req } from '../utils/map-helpers.js'; import getInteropBlock from './shared/getInteropBlock.js'; import getExportBlock from './shared/getExportBlock.js'; import getGlobalNameMaker from './shared/getGlobalNameMaker.js'; +import esModuleExport from './shared/esModuleExport.js'; function setupNamespace ( name ) { const parts = name.split( '.' ); @@ -70,7 +71,7 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); if (exportMode === 'named') { - magicString.append('\n\nexports.__esModule = true;\n\n'); + magicString.append(esModuleExport); } return magicString diff --git a/test/form/assignment-to-exports-class-declaration/_expected/cjs.js b/test/form/assignment-to-exports-class-declaration/_expected/cjs.js index 09efe46..21765bb 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/cjs.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/cjs.js @@ -3,4 +3,6 @@ exports.Foo = class Foo {} exports.Foo = lol( exports.Foo ); -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { + value: true +}); diff --git a/test/form/assignment-to-exports-class-declaration/_expected/umd.js b/test/form/assignment-to-exports-class-declaration/_expected/umd.js index 2432b64..c2d9d5f 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/umd.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/umd.js @@ -7,6 +7,8 @@ exports.Foo = class Foo {} exports.Foo = lol( exports.Foo ); - exports.__esModule = true; + Object.defineProperty(exports, "__esModule", { + value: true + }); })); diff --git a/test/form/computed-properties/_expected/cjs.js b/test/form/computed-properties/_expected/cjs.js index 8220c15..5f5f759 100644 --- a/test/form/computed-properties/_expected/cjs.js +++ b/test/form/computed-properties/_expected/cjs.js @@ -16,4 +16,6 @@ class X { exports.x = x; exports.X = X; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { + value: true +}); diff --git a/test/form/computed-properties/_expected/umd.js b/test/form/computed-properties/_expected/umd.js index 3c68104..47c13dd 100644 --- a/test/form/computed-properties/_expected/umd.js +++ b/test/form/computed-properties/_expected/umd.js @@ -20,6 +20,8 @@ exports.x = x; exports.X = X; - exports.__esModule = true; + Object.defineProperty(exports, "__esModule", { + value: true + }); })); diff --git a/test/form/dedupes-external-imports/_expected/cjs.js b/test/form/dedupes-external-imports/_expected/cjs.js index c12daee..7c47196 100644 --- a/test/form/dedupes-external-imports/_expected/cjs.js +++ b/test/form/dedupes-external-imports/_expected/cjs.js @@ -31,4 +31,6 @@ exports.foo = foo; exports.bar = bar; exports.baz = baz; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { + value: true +}); diff --git a/test/form/dedupes-external-imports/_expected/umd.js b/test/form/dedupes-external-imports/_expected/umd.js index bcd5d74..86d2d54 100644 --- a/test/form/dedupes-external-imports/_expected/umd.js +++ b/test/form/dedupes-external-imports/_expected/umd.js @@ -33,6 +33,8 @@ exports.bar = bar; exports.baz = baz; - exports.__esModule = true; + Object.defineProperty(exports, "__esModule", { + value: true + }); })); diff --git a/test/form/export-all-from-internal/_expected/cjs.js b/test/form/export-all-from-internal/_expected/cjs.js index 207acbd..e2755a7 100644 --- a/test/form/export-all-from-internal/_expected/cjs.js +++ b/test/form/export-all-from-internal/_expected/cjs.js @@ -6,4 +6,6 @@ const b = 2; exports.a = a; exports.b = b; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { + value: true +}); diff --git a/test/form/export-all-from-internal/_expected/umd.js b/test/form/export-all-from-internal/_expected/umd.js index ae889e3..802d77e 100644 --- a/test/form/export-all-from-internal/_expected/umd.js +++ b/test/form/export-all-from-internal/_expected/umd.js @@ -10,6 +10,8 @@ exports.a = a; exports.b = b; - exports.__esModule = true; + Object.defineProperty(exports, "__esModule", { + value: true + }); })); diff --git a/test/form/export-default-import/_expected/cjs.js b/test/form/export-default-import/_expected/cjs.js index 28e34b0..313caa2 100644 --- a/test/form/export-default-import/_expected/cjs.js +++ b/test/form/export-default-import/_expected/cjs.js @@ -8,4 +8,6 @@ var x = _interopDefault(require('x')); exports.x = x; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { + value: true +}); diff --git a/test/form/export-default-import/_expected/umd.js b/test/form/export-default-import/_expected/umd.js index 39040e6..2d1f6d0 100644 --- a/test/form/export-default-import/_expected/umd.js +++ b/test/form/export-default-import/_expected/umd.js @@ -10,6 +10,8 @@ exports.x = x; - exports.__esModule = true; + Object.defineProperty(exports, "__esModule", { + value: true + }); })); diff --git a/test/form/exports-at-end-if-possible/_expected/cjs.js b/test/form/exports-at-end-if-possible/_expected/cjs.js index f966613..0d6ed44 100644 --- a/test/form/exports-at-end-if-possible/_expected/cjs.js +++ b/test/form/exports-at-end-if-possible/_expected/cjs.js @@ -8,4 +8,6 @@ console.log( FOO ); exports.FOO = FOO; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { + value: true +}); diff --git a/test/form/exports-at-end-if-possible/_expected/umd.js b/test/form/exports-at-end-if-possible/_expected/umd.js index a2c13f8..bd3dc71 100644 --- a/test/form/exports-at-end-if-possible/_expected/umd.js +++ b/test/form/exports-at-end-if-possible/_expected/umd.js @@ -12,6 +12,8 @@ exports.FOO = FOO; - exports.__esModule = true; + Object.defineProperty(exports, "__esModule", { + value: true + }); })); diff --git a/test/form/multiple-exports/_expected/cjs.js b/test/form/multiple-exports/_expected/cjs.js index 9d7081c..8a0f713 100644 --- a/test/form/multiple-exports/_expected/cjs.js +++ b/test/form/multiple-exports/_expected/cjs.js @@ -6,4 +6,6 @@ var bar = 2; exports.foo = foo; exports.bar = bar; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { + value: true +}); diff --git a/test/form/multiple-exports/_expected/umd.js b/test/form/multiple-exports/_expected/umd.js index 9d9b112f7..7fd1b6b 100644 --- a/test/form/multiple-exports/_expected/umd.js +++ b/test/form/multiple-exports/_expected/umd.js @@ -10,6 +10,8 @@ exports.foo = foo; exports.bar = bar; - exports.__esModule = true; + Object.defineProperty(exports, "__esModule", { + value: true + }); })); diff --git a/test/form/namespaced-named-exports/_expected/cjs.js b/test/form/namespaced-named-exports/_expected/cjs.js index 87e3bde..a367d02 100644 --- a/test/form/namespaced-named-exports/_expected/cjs.js +++ b/test/form/namespaced-named-exports/_expected/cjs.js @@ -4,4 +4,6 @@ var answer = 42; exports.answer = answer; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { + value: true +}); diff --git a/test/form/namespaced-named-exports/_expected/umd.js b/test/form/namespaced-named-exports/_expected/umd.js index f0e64a6..54733bf 100644 --- a/test/form/namespaced-named-exports/_expected/umd.js +++ b/test/form/namespaced-named-exports/_expected/umd.js @@ -8,6 +8,8 @@ exports.answer = answer; - exports.__esModule = true; + Object.defineProperty(exports, "__esModule", { + value: true + }); })); diff --git a/test/form/no-treeshake/_expected/cjs.js b/test/form/no-treeshake/_expected/cjs.js index d8fdece..447ad76 100644 --- a/test/form/no-treeshake/_expected/cjs.js +++ b/test/form/no-treeshake/_expected/cjs.js @@ -24,4 +24,6 @@ exports.create = create; exports.getPrototypeOf = getPrototypeOf; exports.strange = quux; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { + value: true +}); diff --git a/test/form/no-treeshake/_expected/umd.js b/test/form/no-treeshake/_expected/umd.js index ce07d58..711654a 100644 --- a/test/form/no-treeshake/_expected/umd.js +++ b/test/form/no-treeshake/_expected/umd.js @@ -26,6 +26,8 @@ exports.getPrototypeOf = getPrototypeOf; exports.strange = quux; - exports.__esModule = true; + Object.defineProperty(exports, "__esModule", { + value: true + }); })); diff --git a/test/form/preserves-comments-after-imports/_expected/cjs.js b/test/form/preserves-comments-after-imports/_expected/cjs.js index 8b4421f..f92d54d 100644 --- a/test/form/preserves-comments-after-imports/_expected/cjs.js +++ b/test/form/preserves-comments-after-imports/_expected/cjs.js @@ -8,4 +8,6 @@ var obj = { number }; exports.obj = obj; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { + value: true +}); diff --git a/test/form/preserves-comments-after-imports/_expected/umd.js b/test/form/preserves-comments-after-imports/_expected/umd.js index 29b316b..a2f5fbf 100644 --- a/test/form/preserves-comments-after-imports/_expected/umd.js +++ b/test/form/preserves-comments-after-imports/_expected/umd.js @@ -12,6 +12,8 @@ exports.obj = obj; - exports.__esModule = true; + Object.defineProperty(exports, "__esModule", { + value: true + }); })); diff --git a/test/form/umd-noconflict/_expected/cjs.js b/test/form/umd-noconflict/_expected/cjs.js index df41ba1..1e80273 100644 --- a/test/form/umd-noconflict/_expected/cjs.js +++ b/test/form/umd-noconflict/_expected/cjs.js @@ -12,4 +12,6 @@ exports.doThings = doThings; exports.number = number; exports.setting = setting; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { + value: true +}); diff --git a/test/form/umd-noconflict/_expected/umd.js b/test/form/umd-noconflict/_expected/umd.js index 3a7d1d1..50b58d4 100644 --- a/test/form/umd-noconflict/_expected/umd.js +++ b/test/form/umd-noconflict/_expected/umd.js @@ -21,6 +21,8 @@ exports.number = number; exports.setting = setting; - exports.__esModule = true; + Object.defineProperty(exports, "__esModule", { + value: true + }); })); diff --git a/test/function/deconflicts-exports/_config.js b/test/function/deconflicts-exports/_config.js index a564b5c..8724967 100644 --- a/test/function/deconflicts-exports/_config.js +++ b/test/function/deconflicts-exports/_config.js @@ -3,7 +3,7 @@ var assert = require( 'assert' ); module.exports = { description: 'renames variables named `exports` if necessary', exports: function ( exports ) { - assert.deepEqual( Object.keys( exports ), [ 'a', 'b', '__esModule' ] ); + assert.deepEqual( Object.keys( exports ), [ 'a', 'b' ] ); assert.equal( exports.a, 'A' ); assert.equal( exports.b, 42 ); } diff --git a/test/function/export-destruction/_config.js b/test/function/export-destruction/_config.js index 740e33a..263c8d1 100644 --- a/test/function/export-destruction/_config.js +++ b/test/function/export-destruction/_config.js @@ -5,7 +5,7 @@ module.exports = { babel: true, exports: function ( exports ) { - assert.deepEqual( Object.keys( exports ), [ 'baz', 'quux', '__esModule' ] ); + assert.deepEqual( Object.keys( exports ), [ 'baz', 'quux' ] ); assert.equal( exports.baz, 5 ); assert.equal( exports.quux, 17 ); } From ad44c4ba5b624c711787c01f9e86aedfd35135b1 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 21 May 2016 22:52:50 +0300 Subject: [PATCH 004/331] Add incremental support build by passing previous bundle --- src/Bundle.js | 18 +++++++++++++++++- src/rollup.js | 7 +++---- test/incremental/expected.js | 5 +++++ test/incremental/foo.js | 3 +++ test/incremental/main.js | 3 +++ test/test.js | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 test/incremental/expected.js create mode 100644 test/incremental/foo.js create mode 100644 test/incremental/main.js diff --git a/src/Bundle.js b/src/Bundle.js index a050de2..0a56180 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -19,6 +19,13 @@ import { dirname, isRelative, relative, resolve } from './utils/path.js'; export default class Bundle { constructor ( options ) { + if ( typeof options.bundle === 'object' ) { + this.cachedModules = options.bundle.modules.reduce((modules, module) => { + modules[module.id] = module; + return modules; + }, {}); + } + this.plugins = ensureArray( options.plugins ); this.plugins.forEach( plugin => { @@ -173,7 +180,16 @@ export default class Bundle { throw new Error( `Error loading ${id}: load hook should return a string, a { code, map } object, or nothing/null` ); }) - .then( source => transform( source, id, this.transformers ) ) + .then( source => { + if (this.cachedModules && this.cachedModules[id]) { + const { code, originalCode } = this.cachedModules[id]; + return { + code, + originalCode + }; + } + return transform( source, id, this.transformers ); + }) .then( source => { const { code, originalCode, ast, sourceMapChain } = source; diff --git a/src/rollup.js b/src/rollup.js index 490fe72..448c2aa 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -27,7 +27,8 @@ const ALLOWED_KEYS = [ 'plugins', 'sourceMap', 'treeshake', - 'useStrict' + 'useStrict', + 'bundle' ]; export function rollup ( options ) { @@ -51,9 +52,7 @@ export function rollup ( options ) { return { imports: bundle.externalModules.map( module => module.id ), exports: keys( bundle.entryModule.exports ), - modules: bundle.orderedModules.map( module => { - return { id: module.id }; - }), + modules: bundle.orderedModules.map( ( { id, code, originalCode } ) => ( { id, code, originalCode } ) ), generate: options => bundle.render( options ), write: options => { diff --git a/test/incremental/expected.js b/test/incremental/expected.js new file mode 100644 index 0000000..7063df5 --- /dev/null +++ b/test/incremental/expected.js @@ -0,0 +1,5 @@ +function foo () { + console.log('foo'); +}; + +foo(); \ No newline at end of file diff --git a/test/incremental/foo.js b/test/incremental/foo.js new file mode 100644 index 0000000..3bdfb02 --- /dev/null +++ b/test/incremental/foo.js @@ -0,0 +1,3 @@ +export default function () { + console.log('foo'); +}; diff --git a/test/incremental/main.js b/test/incremental/main.js new file mode 100644 index 0000000..e1fb5c4 --- /dev/null +++ b/test/incremental/main.js @@ -0,0 +1,3 @@ +import foo from './foo.js'; + +foo(); diff --git a/test/test.js b/test/test.js index 22d4bce..2d8d54c 100644 --- a/test/test.js +++ b/test/test.js @@ -13,6 +13,7 @@ var FUNCTION = path.resolve( __dirname, 'function' ); var FORM = path.resolve( __dirname, 'form' ); var SOURCEMAPS = path.resolve( __dirname, 'sourcemaps' ); var CLI = path.resolve( __dirname, 'cli' ); +var INCREMENTAL = path.resolve( __dirname, 'incremental' ); var PROFILES = [ { format: 'amd' }, @@ -423,4 +424,35 @@ describe( 'rollup', function () { }); }); }); + + describe.only('incremental', function () { + it('uses previous bundle object to prevent unnecessary transformations', function () { + var calls = 0; + var counter = { + transform: function ( code ) { + calls += 1; + return code; + } + }; + return rollup.rollup({ + entry: path.join( INCREMENTAL, 'main.js' ), + plugins: [counter] + }).then( function ( bundle ) { + assert.equal( calls, 2 ); + return rollup.rollup({ + entry: path.join( INCREMENTAL, 'main.js' ), + plugins: [counter], + bundle + }); + }).then( function ( bundle ) { + assert.equal( calls, 2 ); + var result = bundle.generate({ + format: 'es6' + }); + return sander.readFile( path.join( INCREMENTAL, 'expected.js' ) ).then( function (expected) { + assert.equal(expected.toString().replace( /(\r\n)/g, '\n'), result.code); + }); + }); + }); + }); }); From 157b7c151f49097b6aa4e4b68958287a13b01ba1 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 21 May 2016 23:58:51 +0300 Subject: [PATCH 005/331] Invalidate module when file content is changed --- src/Bundle.js | 8 ++- src/utils/transform.js | 7 --- .../{ => not-transform-twice}/expected.js | 0 .../{ => not-transform-twice}/foo.js | 0 .../{ => not-transform-twice}/main.js | 0 .../incremental/transform-changed/expected.js | 5 ++ .../transform-changed/foo-changed.js | 3 ++ test/incremental/transform-changed/foo.js | 3 ++ test/incremental/transform-changed/main.js | 3 ++ test/test.js | 54 +++++++++++++++++-- 10 files changed, 70 insertions(+), 13 deletions(-) rename test/incremental/{ => not-transform-twice}/expected.js (100%) rename test/incremental/{ => not-transform-twice}/foo.js (100%) rename test/incremental/{ => not-transform-twice}/main.js (100%) create mode 100644 test/incremental/transform-changed/expected.js create mode 100644 test/incremental/transform-changed/foo-changed.js create mode 100644 test/incremental/transform-changed/foo.js create mode 100644 test/incremental/transform-changed/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 0a56180..0f34a0f 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -181,7 +181,13 @@ export default class Bundle { throw new Error( `Error loading ${id}: load hook should return a string, a { code, map } object, or nothing/null` ); }) .then( source => { - if (this.cachedModules && this.cachedModules[id]) { + if ( typeof source === 'string' ) { + source = { + code: source, + ast: null + }; + } + if (this.cachedModules && this.cachedModules[id] && this.cachedModules[id].originalCode === source.code) { const { code, originalCode } = this.cachedModules[id]; return { code, diff --git a/src/utils/transform.js b/src/utils/transform.js index b401370..c2ffe43 100644 --- a/src/utils/transform.js +++ b/src/utils/transform.js @@ -3,13 +3,6 @@ import Promise from 'es6-promise/lib/es6-promise/promise.js'; export default function transform ( source, id, transformers ) { let sourceMapChain = []; - if ( typeof source === 'string' ) { - source = { - code: source, - ast: null - }; - } - let originalCode = source.code; let ast = source.ast; diff --git a/test/incremental/expected.js b/test/incremental/not-transform-twice/expected.js similarity index 100% rename from test/incremental/expected.js rename to test/incremental/not-transform-twice/expected.js diff --git a/test/incremental/foo.js b/test/incremental/not-transform-twice/foo.js similarity index 100% rename from test/incremental/foo.js rename to test/incremental/not-transform-twice/foo.js diff --git a/test/incremental/main.js b/test/incremental/not-transform-twice/main.js similarity index 100% rename from test/incremental/main.js rename to test/incremental/not-transform-twice/main.js diff --git a/test/incremental/transform-changed/expected.js b/test/incremental/transform-changed/expected.js new file mode 100644 index 0000000..e1c10a1 --- /dev/null +++ b/test/incremental/transform-changed/expected.js @@ -0,0 +1,5 @@ +function foo () { + console.log('foo-changed'); +}; + +foo(); \ No newline at end of file diff --git a/test/incremental/transform-changed/foo-changed.js b/test/incremental/transform-changed/foo-changed.js new file mode 100644 index 0000000..b96789c --- /dev/null +++ b/test/incremental/transform-changed/foo-changed.js @@ -0,0 +1,3 @@ +export default function () { + console.log('foo-changed'); +}; diff --git a/test/incremental/transform-changed/foo.js b/test/incremental/transform-changed/foo.js new file mode 100644 index 0000000..435568b --- /dev/null +++ b/test/incremental/transform-changed/foo.js @@ -0,0 +1,3 @@ +export default function () { + console.log('foo'); +}; \ No newline at end of file diff --git a/test/incremental/transform-changed/main.js b/test/incremental/transform-changed/main.js new file mode 100644 index 0000000..e1fb5c4 --- /dev/null +++ b/test/incremental/transform-changed/main.js @@ -0,0 +1,3 @@ +import foo from './foo.js'; + +foo(); diff --git a/test/test.js b/test/test.js index 2d8d54c..5389346 100644 --- a/test/test.js +++ b/test/test.js @@ -426,7 +426,7 @@ describe( 'rollup', function () { }); describe.only('incremental', function () { - it('uses previous bundle object to prevent unnecessary transformations', function () { + it('does not transforms in the second time', function () { var calls = 0; var counter = { transform: function ( code ) { @@ -435,12 +435,12 @@ describe( 'rollup', function () { } }; return rollup.rollup({ - entry: path.join( INCREMENTAL, 'main.js' ), + entry: path.join( INCREMENTAL, 'not-transform-twice', 'main.js' ), plugins: [counter] }).then( function ( bundle ) { assert.equal( calls, 2 ); return rollup.rollup({ - entry: path.join( INCREMENTAL, 'main.js' ), + entry: path.join( INCREMENTAL, 'not-transform-twice', 'main.js' ), plugins: [counter], bundle }); @@ -449,10 +449,54 @@ describe( 'rollup', function () { var result = bundle.generate({ format: 'es6' }); - return sander.readFile( path.join( INCREMENTAL, 'expected.js' ) ).then( function (expected) { - assert.equal(expected.toString().replace( /(\r\n)/g, '\n'), result.code); + return sander.readFile( path.join( INCREMENTAL, 'not-transform-twice', 'expected.js' ) ).then( function (expected) { + assert.equal( normaliseOutput( expected ), result.code ); }); }); }); + + it('transforms modified sources', function () { + var calls = 0; + var counter = { + transform: function ( code ) { + calls += 1; + return code; + } + }; + var bundle; + var foo; + var changed; + var expected; + return Promise.all([ + rollup.rollup({ + entry: path.join( INCREMENTAL, 'transform-changed', 'main.js' ), + plugins: [counter] + }), + sander.readFile( path.join( INCREMENTAL, 'transform-changed', 'foo.js' ) ), + sander.readFile( path.join( INCREMENTAL, 'transform-changed', 'foo-changed.js' ) ), + sander.readFile( path.join( INCREMENTAL, 'transform-changed', 'expected.js' ) ) + ]).then( function ( [_bundle, _foo, _changed, _expected] ) { + bundle = _bundle; + foo = normaliseOutput( _foo ); + changed = normaliseOutput( _changed ); + expected = normaliseOutput( _expected ); + assert.equal( calls, 2 ); + + return sander.writeFile( INCREMENTAL, 'transform-changed', 'foo.js', changed ); + }).then(function () { + return rollup.rollup({ + entry: path.join( INCREMENTAL, 'transform-changed', 'main.js' ), + plugins: [counter], + bundle + }); + }).then( function ( bundle ) { + assert.equal( calls, 3 ); + var result = bundle.generate({ + format: 'es6' + }); + assert.equal(expected, result.code); + return sander.writeFile( INCREMENTAL, 'transform-changed', 'foo.js', foo ); + }); + }); }); }); From b059d075d53155305152ed43f68904b533c08574 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 5 Jun 2016 12:56:47 -0400 Subject: [PATCH 006/331] add __esModule to AMD, move to top of CJS, consistent style --- src/finalisers/amd.js | 5 +++++ src/finalisers/cjs.js | 7 ++----- src/finalisers/shared/esModuleExport.js | 5 +---- src/finalisers/umd.js | 2 +- .../_expected/amd.js | 2 ++ .../_expected/cjs.js | 6 ++---- .../_expected/umd.js | 4 +--- test/form/computed-properties/_expected/amd.js | 4 +++- test/form/computed-properties/_expected/cjs.js | 6 ++---- test/form/computed-properties/_expected/umd.js | 4 +--- test/form/dedupes-external-imports/_expected/amd.js | 2 ++ test/form/dedupes-external-imports/_expected/cjs.js | 6 ++---- test/form/dedupes-external-imports/_expected/umd.js | 4 +--- test/form/export-all-from-internal/_expected/amd.js | 2 ++ test/form/export-all-from-internal/_expected/cjs.js | 6 ++---- test/form/export-all-from-internal/_expected/umd.js | 4 +--- test/form/export-default-import/_expected/amd.js | 4 +++- test/form/export-default-import/_expected/cjs.js | 6 ++---- test/form/export-default-import/_expected/umd.js | 4 +--- test/form/exports-at-end-if-possible/_expected/amd.js | 2 ++ test/form/exports-at-end-if-possible/_expected/cjs.js | 6 ++---- test/form/exports-at-end-if-possible/_expected/umd.js | 4 +--- test/form/multiple-exports/_expected/amd.js | 2 ++ test/form/multiple-exports/_expected/cjs.js | 6 ++---- test/form/multiple-exports/_expected/umd.js | 4 +--- test/form/namespaced-named-exports/_expected/amd.js | 4 +++- test/form/namespaced-named-exports/_expected/cjs.js | 6 ++---- test/form/namespaced-named-exports/_expected/umd.js | 4 +--- test/form/no-treeshake/_expected/amd.js | 2 ++ test/form/no-treeshake/_expected/cjs.js | 6 ++---- test/form/no-treeshake/_expected/umd.js | 4 +--- .../form/preserves-comments-after-imports/_expected/amd.js | 2 ++ .../form/preserves-comments-after-imports/_expected/cjs.js | 6 ++---- .../form/preserves-comments-after-imports/_expected/umd.js | 4 +--- test/form/umd-noconflict/_expected/amd.js | 4 +++- test/form/umd-noconflict/_expected/cjs.js | 6 ++---- test/form/umd-noconflict/_expected/umd.js | 4 +--- 37 files changed, 68 insertions(+), 91 deletions(-) diff --git a/src/finalisers/amd.js b/src/finalisers/amd.js index 7f63305..2ac7e6d 100644 --- a/src/finalisers/amd.js +++ b/src/finalisers/amd.js @@ -1,6 +1,7 @@ import { getName, quoteId } from '../utils/map-helpers.js'; import getInteropBlock from './shared/getInteropBlock.js'; import getExportBlock from './shared/getExportBlock.js'; +import esModuleExport from './shared/esModuleExport.js'; export default function amd ( bundle, magicString, { exportMode, indentString }, options ) { let deps = bundle.externalModules.map( quoteId ); @@ -25,6 +26,10 @@ export default function amd ( bundle, magicString, { exportMode, indentString }, const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); + if ( exportMode === 'named' ) { + magicString.append( `\n\n${esModuleExport}` ); + } + return magicString .indent( indentString ) .append( '\n\n});' ) diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index d147e6c..f2f30f0 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -2,7 +2,8 @@ import getExportBlock from './shared/getExportBlock.js'; import esModuleExport from './shared/esModuleExport.js'; export default function cjs ( bundle, magicString, { exportMode }, options ) { - let intro = options.useStrict === false ? `` : `'use strict';\n\n`; + let intro = ( options.useStrict === false ? `` : `'use strict';\n\n` ) + + ( exportMode === 'named' ? `${esModuleExport}\n\n` : '' ); const hasDefaultImport = bundle.externalModules.some( mod => mod.declarations.default); @@ -35,9 +36,5 @@ export default function cjs ( bundle, magicString, { exportMode }, options ) { const exportBlock = getExportBlock( bundle.entryModule, exportMode, 'module.exports =' ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); - if (exportMode === 'named') { - magicString.append(esModuleExport); - } - return magicString; } diff --git a/src/finalisers/shared/esModuleExport.js b/src/finalisers/shared/esModuleExport.js index 058aa09..7764bdc 100644 --- a/src/finalisers/shared/esModuleExport.js +++ b/src/finalisers/shared/esModuleExport.js @@ -1,4 +1 @@ -export default '\n\n' + - 'Object.defineProperty(exports, "__esModule", {\n' + - ' value: true\n' + - '});\n\n'; +export default `Object.defineProperty(exports, '__esModule', { value: true });`; diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index 7e00e8e..a31c5c9 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -71,7 +71,7 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); if (exportMode === 'named') { - magicString.append(esModuleExport); + magicString.append( `\n\n${esModuleExport}` ); } return magicString diff --git a/test/form/assignment-to-exports-class-declaration/_expected/amd.js b/test/form/assignment-to-exports-class-declaration/_expected/amd.js index c2d0691..bdbdbe5 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/amd.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/amd.js @@ -3,4 +3,6 @@ define(['exports'], function (exports) { 'use strict'; exports.Foo = class Foo {} exports.Foo = lol( exports.Foo ); + Object.defineProperty(exports, '__esModule', { value: true }); + }); diff --git a/test/form/assignment-to-exports-class-declaration/_expected/cjs.js b/test/form/assignment-to-exports-class-declaration/_expected/cjs.js index 21765bb..03bdfb8 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/cjs.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/cjs.js @@ -1,8 +1,6 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + exports.Foo = class Foo {} exports.Foo = lol( exports.Foo ); - -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/test/form/assignment-to-exports-class-declaration/_expected/umd.js b/test/form/assignment-to-exports-class-declaration/_expected/umd.js index c2d9d5f..503039e 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/umd.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/umd.js @@ -7,8 +7,6 @@ exports.Foo = class Foo {} exports.Foo = lol( exports.Foo ); - Object.defineProperty(exports, "__esModule", { - value: true - }); + Object.defineProperty(exports, '__esModule', { value: true }); })); diff --git a/test/form/computed-properties/_expected/amd.js b/test/form/computed-properties/_expected/amd.js index 0ccd4d8..cafa262 100644 --- a/test/form/computed-properties/_expected/amd.js +++ b/test/form/computed-properties/_expected/amd.js @@ -16,4 +16,6 @@ define(['exports'], function (exports) { 'use strict'; exports.x = x; exports.X = X; -}); \ No newline at end of file + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/form/computed-properties/_expected/cjs.js b/test/form/computed-properties/_expected/cjs.js index 5f5f759..77f714c 100644 --- a/test/form/computed-properties/_expected/cjs.js +++ b/test/form/computed-properties/_expected/cjs.js @@ -1,5 +1,7 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + var foo = 'foo'; var bar = 'bar'; var baz = 'baz'; @@ -15,7 +17,3 @@ class X { exports.x = x; exports.X = X; - -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/test/form/computed-properties/_expected/umd.js b/test/form/computed-properties/_expected/umd.js index 47c13dd..8f247e8 100644 --- a/test/form/computed-properties/_expected/umd.js +++ b/test/form/computed-properties/_expected/umd.js @@ -20,8 +20,6 @@ exports.x = x; exports.X = X; - Object.defineProperty(exports, "__esModule", { - value: true - }); + Object.defineProperty(exports, '__esModule', { value: true }); })); diff --git a/test/form/dedupes-external-imports/_expected/amd.js b/test/form/dedupes-external-imports/_expected/amd.js index 7f52eda..a503cb3 100644 --- a/test/form/dedupes-external-imports/_expected/amd.js +++ b/test/form/dedupes-external-imports/_expected/amd.js @@ -29,4 +29,6 @@ define(['exports', 'external'], function (exports, external) { 'use strict'; exports.bar = bar; exports.baz = baz; + Object.defineProperty(exports, '__esModule', { value: true }); + }); diff --git a/test/form/dedupes-external-imports/_expected/cjs.js b/test/form/dedupes-external-imports/_expected/cjs.js index 7c47196..ede4836 100644 --- a/test/form/dedupes-external-imports/_expected/cjs.js +++ b/test/form/dedupes-external-imports/_expected/cjs.js @@ -1,5 +1,7 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + var external = require('external'); class Foo extends external.Component { @@ -30,7 +32,3 @@ const baz = new Baz(); exports.foo = foo; exports.bar = bar; exports.baz = baz; - -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/test/form/dedupes-external-imports/_expected/umd.js b/test/form/dedupes-external-imports/_expected/umd.js index 86d2d54..af73333 100644 --- a/test/form/dedupes-external-imports/_expected/umd.js +++ b/test/form/dedupes-external-imports/_expected/umd.js @@ -33,8 +33,6 @@ exports.bar = bar; exports.baz = baz; - Object.defineProperty(exports, "__esModule", { - value: true - }); + Object.defineProperty(exports, '__esModule', { value: true }); })); diff --git a/test/form/export-all-from-internal/_expected/amd.js b/test/form/export-all-from-internal/_expected/amd.js index 6b0c47e..c3acbb0 100644 --- a/test/form/export-all-from-internal/_expected/amd.js +++ b/test/form/export-all-from-internal/_expected/amd.js @@ -6,4 +6,6 @@ define(['exports'], function (exports) { 'use strict'; exports.a = a; exports.b = b; + Object.defineProperty(exports, '__esModule', { value: true }); + }); diff --git a/test/form/export-all-from-internal/_expected/cjs.js b/test/form/export-all-from-internal/_expected/cjs.js index e2755a7..e208b74 100644 --- a/test/form/export-all-from-internal/_expected/cjs.js +++ b/test/form/export-all-from-internal/_expected/cjs.js @@ -1,11 +1,9 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + const a = 1; const b = 2; exports.a = a; exports.b = b; - -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/test/form/export-all-from-internal/_expected/umd.js b/test/form/export-all-from-internal/_expected/umd.js index 802d77e..1d0f5ec 100644 --- a/test/form/export-all-from-internal/_expected/umd.js +++ b/test/form/export-all-from-internal/_expected/umd.js @@ -10,8 +10,6 @@ exports.a = a; exports.b = b; - Object.defineProperty(exports, "__esModule", { - value: true - }); + Object.defineProperty(exports, '__esModule', { value: true }); })); diff --git a/test/form/export-default-import/_expected/amd.js b/test/form/export-default-import/_expected/amd.js index 9158c43..c880afb 100644 --- a/test/form/export-default-import/_expected/amd.js +++ b/test/form/export-default-import/_expected/amd.js @@ -6,4 +6,6 @@ define(['exports', 'x'], function (exports, x) { 'use strict'; exports.x = x; -}); \ No newline at end of file + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/form/export-default-import/_expected/cjs.js b/test/form/export-default-import/_expected/cjs.js index 313caa2..9cf5968 100644 --- a/test/form/export-default-import/_expected/cjs.js +++ b/test/form/export-default-import/_expected/cjs.js @@ -1,5 +1,7 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var x = _interopDefault(require('x')); @@ -7,7 +9,3 @@ var x = _interopDefault(require('x')); exports.x = x; - -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/test/form/export-default-import/_expected/umd.js b/test/form/export-default-import/_expected/umd.js index 2d1f6d0..4428aa4 100644 --- a/test/form/export-default-import/_expected/umd.js +++ b/test/form/export-default-import/_expected/umd.js @@ -10,8 +10,6 @@ exports.x = x; - Object.defineProperty(exports, "__esModule", { - value: true - }); + Object.defineProperty(exports, '__esModule', { value: true }); })); diff --git a/test/form/exports-at-end-if-possible/_expected/amd.js b/test/form/exports-at-end-if-possible/_expected/amd.js index 2612901..7138aff 100644 --- a/test/form/exports-at-end-if-possible/_expected/amd.js +++ b/test/form/exports-at-end-if-possible/_expected/amd.js @@ -8,4 +8,6 @@ define(['exports'], function (exports) { 'use strict'; exports.FOO = FOO; + Object.defineProperty(exports, '__esModule', { value: true }); + }); diff --git a/test/form/exports-at-end-if-possible/_expected/cjs.js b/test/form/exports-at-end-if-possible/_expected/cjs.js index 0d6ed44..f62037c 100644 --- a/test/form/exports-at-end-if-possible/_expected/cjs.js +++ b/test/form/exports-at-end-if-possible/_expected/cjs.js @@ -1,5 +1,7 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + var FOO = 'foo'; console.log( FOO ); @@ -7,7 +9,3 @@ console.log( FOO ); console.log( FOO ); exports.FOO = FOO; - -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/test/form/exports-at-end-if-possible/_expected/umd.js b/test/form/exports-at-end-if-possible/_expected/umd.js index bd3dc71..f5557e7 100644 --- a/test/form/exports-at-end-if-possible/_expected/umd.js +++ b/test/form/exports-at-end-if-possible/_expected/umd.js @@ -12,8 +12,6 @@ exports.FOO = FOO; - Object.defineProperty(exports, "__esModule", { - value: true - }); + Object.defineProperty(exports, '__esModule', { value: true }); })); diff --git a/test/form/multiple-exports/_expected/amd.js b/test/form/multiple-exports/_expected/amd.js index 2ebff3b..0d70786 100644 --- a/test/form/multiple-exports/_expected/amd.js +++ b/test/form/multiple-exports/_expected/amd.js @@ -6,4 +6,6 @@ define(['exports'], function (exports) { 'use strict'; exports.foo = foo; exports.bar = bar; + Object.defineProperty(exports, '__esModule', { value: true }); + }); diff --git a/test/form/multiple-exports/_expected/cjs.js b/test/form/multiple-exports/_expected/cjs.js index 8a0f713..a5fbd76 100644 --- a/test/form/multiple-exports/_expected/cjs.js +++ b/test/form/multiple-exports/_expected/cjs.js @@ -1,11 +1,9 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + var foo = 1; var bar = 2; exports.foo = foo; exports.bar = bar; - -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/test/form/multiple-exports/_expected/umd.js b/test/form/multiple-exports/_expected/umd.js index 7fd1b6b..afaecf2 100644 --- a/test/form/multiple-exports/_expected/umd.js +++ b/test/form/multiple-exports/_expected/umd.js @@ -10,8 +10,6 @@ exports.foo = foo; exports.bar = bar; - Object.defineProperty(exports, "__esModule", { - value: true - }); + Object.defineProperty(exports, '__esModule', { value: true }); })); diff --git a/test/form/namespaced-named-exports/_expected/amd.js b/test/form/namespaced-named-exports/_expected/amd.js index 21429fd..cec0f51 100644 --- a/test/form/namespaced-named-exports/_expected/amd.js +++ b/test/form/namespaced-named-exports/_expected/amd.js @@ -4,4 +4,6 @@ define(['exports'], function (exports) { 'use strict'; exports.answer = answer; -}); \ No newline at end of file + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/form/namespaced-named-exports/_expected/cjs.js b/test/form/namespaced-named-exports/_expected/cjs.js index a367d02..f58e06d 100644 --- a/test/form/namespaced-named-exports/_expected/cjs.js +++ b/test/form/namespaced-named-exports/_expected/cjs.js @@ -1,9 +1,7 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + var answer = 42; exports.answer = answer; - -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/test/form/namespaced-named-exports/_expected/umd.js b/test/form/namespaced-named-exports/_expected/umd.js index 54733bf..37a8623 100644 --- a/test/form/namespaced-named-exports/_expected/umd.js +++ b/test/form/namespaced-named-exports/_expected/umd.js @@ -8,8 +8,6 @@ exports.answer = answer; - Object.defineProperty(exports, "__esModule", { - value: true - }); + Object.defineProperty(exports, '__esModule', { value: true }); })); diff --git a/test/form/no-treeshake/_expected/amd.js b/test/form/no-treeshake/_expected/amd.js index 7bbe64b..eb4f6ca 100644 --- a/test/form/no-treeshake/_expected/amd.js +++ b/test/form/no-treeshake/_expected/amd.js @@ -22,4 +22,6 @@ define(['exports', 'external'], function (exports, external) { 'use strict'; exports.getPrototypeOf = getPrototypeOf; exports.strange = quux; + Object.defineProperty(exports, '__esModule', { value: true }); + }); diff --git a/test/form/no-treeshake/_expected/cjs.js b/test/form/no-treeshake/_expected/cjs.js index 447ad76..c65e700 100644 --- a/test/form/no-treeshake/_expected/cjs.js +++ b/test/form/no-treeshake/_expected/cjs.js @@ -1,5 +1,7 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + var external = require('external'); var foo = 'unused'; @@ -23,7 +25,3 @@ exports.baz = baz; exports.create = create; exports.getPrototypeOf = getPrototypeOf; exports.strange = quux; - -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/test/form/no-treeshake/_expected/umd.js b/test/form/no-treeshake/_expected/umd.js index 711654a..757a187 100644 --- a/test/form/no-treeshake/_expected/umd.js +++ b/test/form/no-treeshake/_expected/umd.js @@ -26,8 +26,6 @@ exports.getPrototypeOf = getPrototypeOf; exports.strange = quux; - Object.defineProperty(exports, "__esModule", { - value: true - }); + Object.defineProperty(exports, '__esModule', { value: true }); })); diff --git a/test/form/preserves-comments-after-imports/_expected/amd.js b/test/form/preserves-comments-after-imports/_expected/amd.js index 82a0a52..8271ac9 100644 --- a/test/form/preserves-comments-after-imports/_expected/amd.js +++ b/test/form/preserves-comments-after-imports/_expected/amd.js @@ -8,4 +8,6 @@ define(['exports'], function (exports) { 'use strict'; exports.obj = obj; + Object.defineProperty(exports, '__esModule', { value: true }); + }); diff --git a/test/form/preserves-comments-after-imports/_expected/cjs.js b/test/form/preserves-comments-after-imports/_expected/cjs.js index f92d54d..723b1cb 100644 --- a/test/form/preserves-comments-after-imports/_expected/cjs.js +++ b/test/form/preserves-comments-after-imports/_expected/cjs.js @@ -1,5 +1,7 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + /** A comment for a number */ var number = 5; @@ -7,7 +9,3 @@ var number = 5; var obj = { number }; exports.obj = obj; - -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/test/form/preserves-comments-after-imports/_expected/umd.js b/test/form/preserves-comments-after-imports/_expected/umd.js index a2f5fbf..96d6a7e 100644 --- a/test/form/preserves-comments-after-imports/_expected/umd.js +++ b/test/form/preserves-comments-after-imports/_expected/umd.js @@ -12,8 +12,6 @@ exports.obj = obj; - Object.defineProperty(exports, "__esModule", { - value: true - }); + Object.defineProperty(exports, '__esModule', { value: true }); })); diff --git a/test/form/umd-noconflict/_expected/amd.js b/test/form/umd-noconflict/_expected/amd.js index 16ca409..f2fd756 100644 --- a/test/form/umd-noconflict/_expected/amd.js +++ b/test/form/umd-noconflict/_expected/amd.js @@ -12,4 +12,6 @@ define(['exports'], function (exports) { 'use strict'; exports.number = number; exports.setting = setting; -}); \ No newline at end of file + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/form/umd-noconflict/_expected/cjs.js b/test/form/umd-noconflict/_expected/cjs.js index 1e80273..0595288 100644 --- a/test/form/umd-noconflict/_expected/cjs.js +++ b/test/form/umd-noconflict/_expected/cjs.js @@ -1,5 +1,7 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + function doThings() { console.log( 'doing things...' ); } @@ -11,7 +13,3 @@ var setting = 'no'; exports.doThings = doThings; exports.number = number; exports.setting = setting; - -Object.defineProperty(exports, "__esModule", { - value: true -}); diff --git a/test/form/umd-noconflict/_expected/umd.js b/test/form/umd-noconflict/_expected/umd.js index 50b58d4..e249923 100644 --- a/test/form/umd-noconflict/_expected/umd.js +++ b/test/form/umd-noconflict/_expected/umd.js @@ -21,8 +21,6 @@ exports.number = number; exports.setting = setting; - Object.defineProperty(exports, "__esModule", { - value: true - }); + Object.defineProperty(exports, '__esModule', { value: true }); })); From 7f1d9f26914f80afd5395461b18f1d1bd979f4b1 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 5 Jun 2016 17:09:42 -0400 Subject: [PATCH 007/331] -> v0.26.7 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03d0f1a..cc79b92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.27.7 + +* Distinguish between default and namespace imports of external module ([#637](https://github.com/rollup/rollup/issues/637)) +* Add `__esModule` property to named exports in AMD, CJS and UMD modes ([#650](https://github.com/rollup/rollup/issues/650)) + ## 0.26.6 * Deconflict named imports from external modules in ES bundles ([#659](https://github.com/rollup/rollup/issues/659)) diff --git a/package.json b/package.json index be499e9..cb726fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.26.6", + "version": "0.26.7", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "src/rollup.js", From a3f2d17596d8ceff8f4cbd7a66bab56b83b5557b Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Sun, 5 Jun 2016 14:37:12 -0700 Subject: [PATCH 008/331] Allow specifying multiple output targets. Closes #655. --- bin/runRollup.js | 10 +++++++++ src/rollup.js | 1 + test/cli/multiple-targets/_config.js | 4 ++++ test/cli/multiple-targets/_expected/cjs.js | 5 +++++ test/cli/multiple-targets/_expected/es6.js | 3 +++ test/cli/multiple-targets/main.js | 1 + test/cli/multiple-targets/rollup.config.js | 13 +++++++++++ test/test.js | 26 ++++++++++++++++++---- 8 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 test/cli/multiple-targets/_config.js create mode 100644 test/cli/multiple-targets/_expected/cjs.js create mode 100644 test/cli/multiple-targets/_expected/es6.js create mode 100644 test/cli/multiple-targets/main.js create mode 100644 test/cli/multiple-targets/rollup.config.js diff --git a/bin/runRollup.js b/bin/runRollup.js index 220c378..ea8ade9 100644 --- a/bin/runRollup.js +++ b/bin/runRollup.js @@ -143,6 +143,16 @@ function bundle ( options ) { return bundle.write( options ); } + if ( options.targets ) { + var result = null; + + options.targets.forEach( function ( target ) { + result = bundle.write(target); + }); + + return result; + } + if ( options.sourceMap && options.sourceMap !== 'inline' ) { handleError({ code: 'MISSING_OUTPUT_OPTION' }); } diff --git a/src/rollup.js b/src/rollup.js index 77a97bd..8a05ac4 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -27,6 +27,7 @@ const ALLOWED_KEYS = [ 'plugins', 'preferConst', 'sourceMap', + 'targets', 'treeshake', 'useStrict' ]; diff --git a/test/cli/multiple-targets/_config.js b/test/cli/multiple-targets/_config.js new file mode 100644 index 0000000..73d5d28 --- /dev/null +++ b/test/cli/multiple-targets/_config.js @@ -0,0 +1,4 @@ +module.exports = { + description: 'generates multiple output files when multiple targets are specified', + command: 'rollup -c' +}; diff --git a/test/cli/multiple-targets/_expected/cjs.js b/test/cli/multiple-targets/_expected/cjs.js new file mode 100644 index 0000000..98deb0c --- /dev/null +++ b/test/cli/multiple-targets/_expected/cjs.js @@ -0,0 +1,5 @@ +'use strict'; + +var main = 0; + +module.exports = main; diff --git a/test/cli/multiple-targets/_expected/es6.js b/test/cli/multiple-targets/_expected/es6.js new file mode 100644 index 0000000..d326592 --- /dev/null +++ b/test/cli/multiple-targets/_expected/es6.js @@ -0,0 +1,3 @@ +var main = 0; + +export default main; diff --git a/test/cli/multiple-targets/main.js b/test/cli/multiple-targets/main.js new file mode 100644 index 0000000..7f810d3 --- /dev/null +++ b/test/cli/multiple-targets/main.js @@ -0,0 +1 @@ +export default 0; diff --git a/test/cli/multiple-targets/rollup.config.js b/test/cli/multiple-targets/rollup.config.js new file mode 100644 index 0000000..db165db --- /dev/null +++ b/test/cli/multiple-targets/rollup.config.js @@ -0,0 +1,13 @@ +export default { + entry: 'main.js', + targets: [ + { + format: 'cjs', + dest: '_actual/cjs.js' + }, + { + format: 'es6', + dest: '_actual/es6.js' + } + ] +}; diff --git a/test/test.js b/test/test.js index 22239fe..d571f7f 100644 --- a/test/test.js +++ b/test/test.js @@ -76,7 +76,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( function () { throw new Error( 'Missing expected error' ); }, function ( err ) { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: banner, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, treeshake, useStrict' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: banner, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, targets, treeshake, useStrict' ); }); }); }); @@ -353,9 +353,13 @@ describe( 'rollup', function () { PATH: path.resolve( __dirname, '../bin' ) + path.delimiter + process.env.PATH } }, function ( err, code, stderr ) { - if ( err || config.error ) { - config.error( err ); - return done(); + if ( err ) { + if ( config.error ) { + config.error( err ); + return done(); + } else { + throw err; + } } if ( stderr ) console.error( stderr ); @@ -409,6 +413,20 @@ describe( 'rollup', function () { } } + else if ( sander.existsSync( '_expected' ) && sander.statSync( '_expected' ).isDirectory() ) { + var error = null; + sander.readdirSync( '_expected' ).forEach( child => { + var expected = sander.readFileSync( path.join( '_expected', child ) ).toString(); + var actual = sander.readFileSync( path.join( '_actual', child ) ).toString(); + try { + assert.equal( normaliseOutput( actual ), normaliseOutput( expected ) ); + } catch ( err ) { + error = err; + } + }); + done( error ); + } + else { var expected = sander.readFileSync( '_expected.js' ).toString(); try { From 169ae35413a02ce413e7a19c9352d381a7fa7600 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Mon, 6 Jun 2016 20:43:48 -0400 Subject: [PATCH 009/331] allow resolved module IDs to be non-strings --- src/Bundle.js | 84 ++++++++++--------- src/Module.js | 16 ++-- .../custom-resolver-non-string/_config.js | 15 ++++ .../custom-resolver-non-string/main.js | 2 + 4 files changed, 72 insertions(+), 45 deletions(-) create mode 100644 test/function/custom-resolver-non-string/_config.js create mode 100644 test/function/custom-resolver-non-string/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 95c0d10..95248b1 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -54,7 +54,7 @@ export default class Bundle { .map( plugin => plugin.transformBundle ) .filter( Boolean ); - this.moduleById = blank(); + this.moduleById = new Map(); this.modules = []; this.externalModules = []; @@ -164,8 +164,8 @@ export default class Bundle { fetchModule ( id, importer ) { // short-circuit cycles - if ( id in this.moduleById ) return null; - this.moduleById[ id ] = null; + if ( this.moduleById.has( id ) ) return null; + this.moduleById.set( id, null ); return this.load( id ) .catch( err => { @@ -188,7 +188,7 @@ export default class Bundle { const module = new Module({ id, code, originalCode, ast, sourceMapChain, bundle: this }); this.modules.push( module ); - this.moduleById[ id ] = module; + this.moduleById.set( id, module ); return this.fetchAllDependencies( module ).then( () => module ); }); @@ -198,47 +198,53 @@ export default class Bundle { return mapSequence( module.sources, source => { return this.resolveId( source, module.id ) .then( resolvedId => { - let externalName; - if ( resolvedId ) { - // If the `resolvedId` is supposed to be external, make it so. - externalName = resolvedId.replace( /[\/\\]/g, '/' ); - } else if ( isRelative( source ) ) { - // This could be an external, relative dependency, based on the current module's parent dir. - externalName = resolve( module.id, '..', source ); - } - const forcedExternal = externalName && this.isExternal( externalName ); - - if ( !resolvedId || forcedExternal ) { - let normalizedExternal = source; - - if ( !forcedExternal ) { - if ( isRelative( source ) ) throw new Error( `Could not resolve ${source} from ${module.id}` ); - if ( !this.isExternal( source ) ) this.onwarn( `Treating '${source}' as external dependency` ); - } else if ( resolvedId ) { - if ( isRelative(resolvedId) || isAbsolute(resolvedId) ) { - // Try to deduce relative path from entry dir if resolvedId is defined as a relative path. - normalizedExternal = this.getPathRelativeToEntryDirname( resolvedId ); - } else { - normalizedExternal = resolvedId; - } + module.resolvedIds[ source ] = resolvedId; + + if ( !resolvedId || typeof resolvedId === 'string' ) { + let externalName; + if ( resolvedId ) { + // If the `resolvedId` is supposed to be external, make it so. + externalName = resolvedId.replace( /[\/\\]/g, '/' ); + } else if ( isRelative( source ) ) { + // This could be an external, relative dependency, based on the current module's parent dir. + externalName = resolve( module.id, '..', source ); } - module.resolvedIds[ source ] = normalizedExternal; - if ( !this.moduleById[ normalizedExternal ] ) { - const module = new ExternalModule( normalizedExternal ); - this.externalModules.push( module ); - this.moduleById[ normalizedExternal ] = module; - } - } + const forcedExternal = externalName && this.isExternal( externalName ); + + if ( !resolvedId || forcedExternal ) { + let normalizedExternal = source; + + if ( !forcedExternal ) { + if ( isRelative( source ) ) throw new Error( `Could not resolve ${source} from ${module.id}` ); + if ( !this.isExternal( source ) ) this.onwarn( `Treating '${source}' as external dependency` ); + } else if ( resolvedId ) { + if ( isRelative(resolvedId) || isAbsolute(resolvedId) ) { + // Try to deduce relative path from entry dir if resolvedId is defined as a relative path. + normalizedExternal = this.getPathRelativeToEntryDirname( resolvedId ); + } else { + normalizedExternal = resolvedId; + } + } - else { - if ( resolvedId === module.id ) { - throw new Error( `A module cannot import itself (${resolvedId})` ); + // overwrite existing + module.resolvedIds[ source ] = normalizedExternal; + + if ( !this.moduleById.has( normalizedExternal ) ) { + const module = new ExternalModule( normalizedExternal ); + this.externalModules.push( module ); + this.moduleById.set( normalizedExternal, module ); + } + + return null; } + } - module.resolvedIds[ source ] = resolvedId; - return this.fetchModule( resolvedId, module.id ); + if ( resolvedId === module.id ) { + throw new Error( `A module cannot import itself (${resolvedId})` ); } + + return this.fetchModule( resolvedId, module.id ); }); }); } diff --git a/src/Module.js b/src/Module.js index 175ecd5..e222b3a 100644 --- a/src/Module.js +++ b/src/Module.js @@ -191,10 +191,14 @@ export default class Module { } basename () { - const base = basename( this.id ); - const ext = extname( this.id ); + if ( typeof this.id === 'string' ) { + const base = basename( this.id ); + const ext = extname( this.id ); - return makeLegalIdentifier( ext ? base.slice( 0, -ext.length ) : base ); + return makeLegalIdentifier( ext ? base.slice( 0, -ext.length ) : base ); + } + + return 'module'; } bindAliases () { @@ -224,18 +228,18 @@ export default class Module { const specifier = specifiers[ name ]; const id = this.resolvedIds[ specifier.source ]; - specifier.module = this.bundle.moduleById[ id ]; + specifier.module = this.bundle.moduleById.get( id ); }); }); this.exportAllModules = this.exportAllSources.map( source => { const id = this.resolvedIds[ source ]; - return this.bundle.moduleById[ id ]; + return this.bundle.moduleById.get( id ); }); this.sources.forEach( source => { const id = this.resolvedIds[ source ]; - const module = this.bundle.moduleById[ id ]; + const module = this.bundle.moduleById.get( id ); if ( !module.isExternal ) this.dependencies.push( module ); }); diff --git a/test/function/custom-resolver-non-string/_config.js b/test/function/custom-resolver-non-string/_config.js new file mode 100644 index 0000000..5cdcdac --- /dev/null +++ b/test/function/custom-resolver-non-string/_config.js @@ -0,0 +1,15 @@ +const FOO = {}; + +module.exports = { + description: 'allows resolveId to return a non-string', + options: { + plugins: [{ + resolveId: importee => { + if ( importee === 'foo' ) return FOO; + }, + load: id => { + if ( id === FOO ) return 'export default 42'; + } + }] + } +}; diff --git a/test/function/custom-resolver-non-string/main.js b/test/function/custom-resolver-non-string/main.js new file mode 100644 index 0000000..2e13986 --- /dev/null +++ b/test/function/custom-resolver-non-string/main.js @@ -0,0 +1,2 @@ +import foo from 'foo'; +assert.equal( foo, 42 ); From fc648ea46c795c03e06875b99fb96b407a8a88ba Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Mon, 6 Jun 2016 22:45:20 -0400 Subject: [PATCH 010/331] remove es6-promise. closes #689 --- package.json | 1 - src/rollup.js | 1 - src/utils/first.js | 2 -- src/utils/fs.js | 1 - src/utils/promise.js | 2 -- src/utils/transform.js | 2 -- 6 files changed, 9 deletions(-) diff --git a/package.json b/package.json index cb726fa..ff96caf 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "buble": "^0.6.4", "codecov.io": "^0.1.6", "console-group": "^0.2.0", - "es6-promise": "^3.0.2", "eslint": "^2.9.0", "estree-walker": "^0.2.0", "istanbul": "^0.4.0", diff --git a/src/rollup.js b/src/rollup.js index 77a97bd..8efd22d 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -1,4 +1,3 @@ -import Promise from 'es6-promise/lib/es6-promise/promise.js'; import { basename } from './utils/path.js'; import { writeFile } from './utils/fs.js'; import { keys } from './utils/object.js'; diff --git a/src/utils/first.js b/src/utils/first.js index 21d6fe3..7246246 100644 --- a/src/utils/first.js +++ b/src/utils/first.js @@ -1,5 +1,3 @@ -import Promise from 'es6-promise/lib/es6-promise/promise.js'; - // Return the first non-falsy result from an array of // maybe-sync, maybe-promise-returning functions export default function first ( candidates ) { diff --git a/src/utils/fs.js b/src/utils/fs.js index d153099..8a0e3e7 100644 --- a/src/utils/fs.js +++ b/src/utils/fs.js @@ -1,4 +1,3 @@ -import Promise from 'es6-promise/lib/es6-promise/promise.js'; import * as fs from 'fs'; import { dirname } from './path.js'; diff --git a/src/utils/promise.js b/src/utils/promise.js index 1730de8..d18a22d 100644 --- a/src/utils/promise.js +++ b/src/utils/promise.js @@ -1,5 +1,3 @@ -import Promise from 'es6-promise/lib/es6-promise/promise.js'; - export function mapSequence ( array, fn ) { let results = []; let promise = Promise.resolve(); diff --git a/src/utils/transform.js b/src/utils/transform.js index b401370..dfd4d95 100644 --- a/src/utils/transform.js +++ b/src/utils/transform.js @@ -1,5 +1,3 @@ -import Promise from 'es6-promise/lib/es6-promise/promise.js'; - export default function transform ( source, id, transformers ) { let sourceMapChain = []; From 32643783307bdbb91a64ccde6ea7a3d527612041 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Mon, 6 Jun 2016 23:21:32 -0400 Subject: [PATCH 011/331] tidy up tests, squelch nuisance warnings --- .../export-default-anonymous-function/_config.js | 1 - test/function/import-chain-as/main.js | 1 - test/sourcemaps/basic-support/_config.js | 2 +- test/test.js | 12 ++++++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/test/function/export-default-anonymous-function/_config.js b/test/function/export-default-anonymous-function/_config.js index 3cb321f..245bdaf 100644 --- a/test/function/export-default-anonymous-function/_config.js +++ b/test/function/export-default-anonymous-function/_config.js @@ -9,7 +9,6 @@ module.exports = { return path.basename( importee ).replace( /\..+/, '' ); }, load: function ( id ) { - console.log( 'id', id ) return fs.readFileSync( path.join( __dirname, id + '.js' ), 'utf-8' ); } }] diff --git a/test/function/import-chain-as/main.js b/test/function/import-chain-as/main.js index d1dc2b9..3672452 100644 --- a/test/function/import-chain-as/main.js +++ b/test/function/import-chain-as/main.js @@ -1,5 +1,4 @@ import * as second from './second'; assert.equal( second.first.value, 42 ); -console.log( 'second', second ) assert.deepEqual( second, { first: { value: 42 } }); diff --git a/test/sourcemaps/basic-support/_config.js b/test/sourcemaps/basic-support/_config.js index d2910f7..9c8d790 100644 --- a/test/sourcemaps/basic-support/_config.js +++ b/test/sourcemaps/basic-support/_config.js @@ -7,7 +7,7 @@ module.exports = { description: 'basic sourcemap support', test: function ( code, map ) { assert.equal( map.version, 3 ); - assert.equal( map.file, 'bundle.js' ); + assert.ok( /^bundle\.(\w+)\.js/.test( map.file ) ); var smc = new SourceMapConsumer( map ); var generatedLoc, originalLoc; diff --git a/test/test.js b/test/test.js index 22239fe..e8fc1cd 100644 --- a/test/test.js +++ b/test/test.js @@ -153,7 +153,6 @@ describe( 'rollup', function () { // try to generate output try { - if(config.bundleOptions) { console.log(config.bundleOptions); } var result = bundle.generate( extend( {}, config.bundleOptions, { format: 'cjs' })); @@ -252,7 +251,12 @@ describe( 'rollup', function () { if ( config.skipIfWindows && process.platform === 'win32' ) return; var options = extend( {}, config.options, { - entry: FORM + '/' + dir + '/main.js' + entry: FORM + '/' + dir + '/main.js', + onwarn: msg => { + if ( /No name was provided for/.test( msg ) ) return; + if ( /as external dependency/.test( msg ) ) return; + console.error( msg ); + } }); ( config.skip ? describe.skip : config.solo ? describe.only : describe)( dir, function () { @@ -308,7 +312,7 @@ describe( 'rollup', function () { var config = loadConfig( SOURCEMAPS + '/' + dir + '/_config.js' ); var entry = path.resolve( SOURCEMAPS, dir, 'main.js' ); - var dest = path.resolve( SOURCEMAPS, dir, '_actual/bundle.js' ); + var dest = path.resolve( SOURCEMAPS, dir, '_actual/bundle' ); var options = extend( {}, config.options, { entry: entry @@ -320,7 +324,7 @@ describe( 'rollup', function () { var options = extend( {}, { format: profile.format, sourceMap: true, - dest: dest + dest: `${dest}.${profile.format}.js` }, config.options ); bundle.write( options ); From 200eb1325906854babdefd9f7e7242f5829031e9 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Mon, 6 Jun 2016 23:21:57 -0400 Subject: [PATCH 012/331] update to latest magic-string --- package.json | 1 + src/Bundle.js | 4 ++-- src/Module.js | 9 +++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index cb726fa..2d13811 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ }, "dependencies": { "chalk": "^1.1.1", + "magic-string": "^0.15.0", "minimist": "^1.2.0", "source-map-support": "^0.4.0" }, diff --git a/src/Bundle.js b/src/Bundle.js index 95248b1..65bf133 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -1,4 +1,4 @@ -import MagicString from 'magic-string'; +import { Bundle as MagicStringBundle } from 'magic-string'; import first from './utils/first.js'; import { blank, forOwn, keys } from './utils/object.js'; import Module from './Module.js'; @@ -268,7 +268,7 @@ export default class Bundle { // Determine export mode - 'default', 'named', 'none' const exportMode = getExportMode( this, options.exports, options.moduleName ); - let magicString = new MagicString.Bundle({ separator: '\n\n' }); + let magicString = new MagicStringBundle({ separator: '\n\n' }); let usedModules = []; this.orderedModules.forEach( module => { diff --git a/src/Module.js b/src/Module.js index e222b3a..e05f04c 100644 --- a/src/Module.js +++ b/src/Module.js @@ -491,15 +491,16 @@ export default class Module { const declaration = this.declarations[ name ]; if ( declaration.exportName && declaration.isReassigned ) { - magicString.insert( statement.end, `;\nexports.${name} = ${declaration.render( es6 )}` ); + magicString.insertLeft( statement.end, `;\nexports.${name} = ${declaration.render( es6 )}` ); } }); } if ( statement.node.isSynthetic ) { // insert `var/let/const` if necessary - magicString.insert( statement.start, `${statement.node.kind} ` ); - magicString.overwrite( statement.end, statement.next, ';\n' ); // TODO account for trailing newlines + magicString.insertRight( statement.start, `${statement.node.kind} ` ); + magicString.insertLeft( statement.end, ';' ); + magicString.overwrite( statement.end, statement.next, '\n' ); // TODO account for trailing newlines } } @@ -530,7 +531,7 @@ export default class Module { } if ( reference.isShorthandProperty ) { - magicString.insert( end, `: ${name}` ); + magicString.insertLeft( end, `: ${name}` ); } else { magicString.overwrite( start, end, name, true ); } From 834d5fbd8047d2c187f1a1f4057f838cf5441c90 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Mon, 6 Jun 2016 23:25:21 -0400 Subject: [PATCH 013/331] magic-string should be devDependency, because it gets bundled --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 2d13811..b15b244 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "eslint": "^2.9.0", "estree-walker": "^0.2.0", "istanbul": "^0.4.0", - "magic-string": "^0.10.1", + "magic-string": "^0.15.0", "mocha": "^2.3.3", "remap-istanbul": "^0.5.1", "rollup": "^0.26.2", @@ -63,7 +63,6 @@ }, "dependencies": { "chalk": "^1.1.1", - "magic-string": "^0.15.0", "minimist": "^1.2.0", "source-map-support": "^0.4.0" }, From e21d8a33eed6e4bfc9ce98d87042a01e8b1b06f2 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Mon, 6 Jun 2016 23:30:18 -0400 Subject: [PATCH 014/331] oops --- test/function/transformer-async/_config.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/function/transformer-async/_config.js b/test/function/transformer-async/_config.js index 960eb69..cd9afd0 100644 --- a/test/function/transformer-async/_config.js +++ b/test/function/transformer-async/_config.js @@ -1,5 +1,3 @@ -var Promise = require( 'es6-promise' ).Promise; - module.exports = { description: 'transformers can be asynchronous', options: { From b12db919407f902d458b6c5c05e644cc80c09004 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Mon, 6 Jun 2016 23:37:18 -0400 Subject: [PATCH 015/331] -> v0.27.0 --- CHANGELOG.md | 8 +++++++- package.json | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc79b92..24a3743 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # rollup changelog -## 0.27.7 +## 0.27.0 + +* Use native promises instead of `es6-promise` ([#689](https://github.com/rollup/rollup/issues/689)) +* Support multiple targets in config files ([#655](https://github.com/rollup/rollup/issues/655)) +* Allow `resolveId` plugin functions to return non-strings ([#692](https://github.com/rollup/rollup/pull/692)) + +## 0.26.7 * Distinguish between default and namespace imports of external module ([#637](https://github.com/rollup/rollup/issues/637)) * Add `__esModule` property to named exports in AMD, CJS and UMD modes ([#650](https://github.com/rollup/rollup/issues/650)) diff --git a/package.json b/package.json index ff96caf..7eeb4c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.26.7", + "version": "0.27.0", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "src/rollup.js", From 001901a6956a7d225ee37d6b7d3287c0e60c530b Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Mon, 6 Jun 2016 23:51:34 -0400 Subject: [PATCH 016/331] undo non-string ID change (#692) --- src/Bundle.js | 76 +++++++++---------- src/Module.js | 10 +-- .../custom-resolver-non-string/_config.js | 15 ---- .../custom-resolver-non-string/main.js | 2 - 4 files changed, 38 insertions(+), 65 deletions(-) delete mode 100644 test/function/custom-resolver-non-string/_config.js delete mode 100644 test/function/custom-resolver-non-string/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 95248b1..0253c33 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -198,53 +198,47 @@ export default class Bundle { return mapSequence( module.sources, source => { return this.resolveId( source, module.id ) .then( resolvedId => { - module.resolvedIds[ source ] = resolvedId; - - if ( !resolvedId || typeof resolvedId === 'string' ) { - let externalName; - if ( resolvedId ) { - // If the `resolvedId` is supposed to be external, make it so. - externalName = resolvedId.replace( /[\/\\]/g, '/' ); - } else if ( isRelative( source ) ) { - // This could be an external, relative dependency, based on the current module's parent dir. - externalName = resolve( module.id, '..', source ); - } - - const forcedExternal = externalName && this.isExternal( externalName ); - - if ( !resolvedId || forcedExternal ) { - let normalizedExternal = source; - - if ( !forcedExternal ) { - if ( isRelative( source ) ) throw new Error( `Could not resolve ${source} from ${module.id}` ); - if ( !this.isExternal( source ) ) this.onwarn( `Treating '${source}' as external dependency` ); - } else if ( resolvedId ) { - if ( isRelative(resolvedId) || isAbsolute(resolvedId) ) { - // Try to deduce relative path from entry dir if resolvedId is defined as a relative path. - normalizedExternal = this.getPathRelativeToEntryDirname( resolvedId ); - } else { - normalizedExternal = resolvedId; - } - } - - // overwrite existing - module.resolvedIds[ source ] = normalizedExternal; - - if ( !this.moduleById.has( normalizedExternal ) ) { - const module = new ExternalModule( normalizedExternal ); - this.externalModules.push( module ); - this.moduleById.set( normalizedExternal, module ); + let externalName; + if ( resolvedId ) { + // If the `resolvedId` is supposed to be external, make it so. + externalName = resolvedId.replace( /[\/\\]/g, '/' ); + } else if ( isRelative( source ) ) { + // This could be an external, relative dependency, based on the current module's parent dir. + externalName = resolve( module.id, '..', source ); + } + const forcedExternal = externalName && this.isExternal( externalName ); + + if ( !resolvedId || forcedExternal ) { + let normalizedExternal = source; + + if ( !forcedExternal ) { + if ( isRelative( source ) ) throw new Error( `Could not resolve ${source} from ${module.id}` ); + if ( !this.isExternal( source ) ) this.onwarn( `Treating '${source}' as external dependency` ); + } else if ( resolvedId ) { + if ( isRelative(resolvedId) || isAbsolute(resolvedId) ) { + // Try to deduce relative path from entry dir if resolvedId is defined as a relative path. + normalizedExternal = this.getPathRelativeToEntryDirname( resolvedId ); + } else { + normalizedExternal = resolvedId; } + } + module.resolvedIds[ source ] = normalizedExternal; - return null; + if ( !this.moduleById.has( normalizedExternal ) ) { + const module = new ExternalModule( normalizedExternal ); + this.externalModules.push( module ); + this.moduleById.set( normalizedExternal, module ); } } - if ( resolvedId === module.id ) { - throw new Error( `A module cannot import itself (${resolvedId})` ); - } + else { + if ( resolvedId === module.id ) { + throw new Error( `A module cannot import itself (${resolvedId})` ); + } - return this.fetchModule( resolvedId, module.id ); + module.resolvedIds[ source ] = resolvedId; + return this.fetchModule( resolvedId, module.id ); + } }); }); } diff --git a/src/Module.js b/src/Module.js index e222b3a..9f6ae45 100644 --- a/src/Module.js +++ b/src/Module.js @@ -191,14 +191,10 @@ export default class Module { } basename () { - if ( typeof this.id === 'string' ) { - const base = basename( this.id ); - const ext = extname( this.id ); + const base = basename( this.id ); + const ext = extname( this.id ); - return makeLegalIdentifier( ext ? base.slice( 0, -ext.length ) : base ); - } - - return 'module'; + return makeLegalIdentifier( ext ? base.slice( 0, -ext.length ) : base ); } bindAliases () { diff --git a/test/function/custom-resolver-non-string/_config.js b/test/function/custom-resolver-non-string/_config.js deleted file mode 100644 index 5cdcdac..0000000 --- a/test/function/custom-resolver-non-string/_config.js +++ /dev/null @@ -1,15 +0,0 @@ -const FOO = {}; - -module.exports = { - description: 'allows resolveId to return a non-string', - options: { - plugins: [{ - resolveId: importee => { - if ( importee === 'foo' ) return FOO; - }, - load: id => { - if ( id === FOO ) return 'export default 42'; - } - }] - } -}; diff --git a/test/function/custom-resolver-non-string/main.js b/test/function/custom-resolver-non-string/main.js deleted file mode 100644 index 2e13986..0000000 --- a/test/function/custom-resolver-non-string/main.js +++ /dev/null @@ -1,2 +0,0 @@ -import foo from 'foo'; -assert.equal( foo, 42 ); From 528b692a38ce06ba753632381ed1b8b647b1936b Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 7 Jun 2016 11:03:14 -0400 Subject: [PATCH 017/331] ensure name suggestions are legal identifiers --- src/Declaration.js | 8 ++++++-- test/function/legal-suggested-names/_config.js | 3 +++ test/function/legal-suggested-names/bar.js | 5 +++++ test/function/legal-suggested-names/foo.js | 5 +++++ test/function/legal-suggested-names/helpers.js | 5 +++++ test/function/legal-suggested-names/main.js | 8 ++++++++ 6 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 test/function/legal-suggested-names/_config.js create mode 100644 test/function/legal-suggested-names/bar.js create mode 100644 test/function/legal-suggested-names/foo.js create mode 100644 test/function/legal-suggested-names/helpers.js create mode 100644 test/function/legal-suggested-names/main.js diff --git a/src/Declaration.js b/src/Declaration.js index 0601606..7bf906a 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -1,4 +1,5 @@ import { blank, forOwn, keys } from './utils/object.js'; +import makeLegalIdentifier from './utils/makeLegalIdentifier.js'; import run from './utils/run.js'; import { SyntheticReference } from './Reference.js'; @@ -17,7 +18,7 @@ export default class Declaration { } this.statement = statement; - this.name = null; + this.name = node.id ? node.id.name : node.name; this.exportName = null; this.isParam = isParam; @@ -33,7 +34,10 @@ export default class Declaration { addReference ( reference ) { reference.declaration = this; - this.name = reference.name; // TODO handle differences of opinion + + if ( reference.name !== this.name ) { + this.name = makeLegalIdentifier( reference.name ); // TODO handle differences of opinion + } if ( reference.isReassignment ) this.isReassigned = true; } diff --git a/test/function/legal-suggested-names/_config.js b/test/function/legal-suggested-names/_config.js new file mode 100644 index 0000000..d68f4e7 --- /dev/null +++ b/test/function/legal-suggested-names/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'illegal name suggestions are ignored' +}; diff --git a/test/function/legal-suggested-names/bar.js b/test/function/legal-suggested-names/bar.js new file mode 100644 index 0000000..a6071df --- /dev/null +++ b/test/function/legal-suggested-names/bar.js @@ -0,0 +1,5 @@ +import * as helpers from './helpers.js'; + +export default function bar ( a ) { + return helpers.typeof( a ); +} diff --git a/test/function/legal-suggested-names/foo.js b/test/function/legal-suggested-names/foo.js new file mode 100644 index 0000000..91a1fb7 --- /dev/null +++ b/test/function/legal-suggested-names/foo.js @@ -0,0 +1,5 @@ +import * as helpers from './helpers.js'; + +export default function foo ( a ) { + return helpers.typeof( a ); +} diff --git a/test/function/legal-suggested-names/helpers.js b/test/function/legal-suggested-names/helpers.js new file mode 100644 index 0000000..1938dee --- /dev/null +++ b/test/function/legal-suggested-names/helpers.js @@ -0,0 +1,5 @@ +var _typeof = function ( thing ) { + return typeof thing; +}; + +export { _typeof as typeof }; diff --git a/test/function/legal-suggested-names/main.js b/test/function/legal-suggested-names/main.js new file mode 100644 index 0000000..7c47804 --- /dev/null +++ b/test/function/legal-suggested-names/main.js @@ -0,0 +1,8 @@ +import * as helpers from './helpers.js'; +import foo from './foo.js'; +import bar from './bar.js'; + +assert.equal( helpers.typeof( foo ), 'function' ); +assert.equal( helpers.typeof( bar ), 'function' ); +assert.equal( foo( 1 ), 'number' ); +assert.equal( bar( 2 ), 'number' ); From 1a4c45ac8983b6e6dd27d057459d083763ab0398 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 7 Jun 2016 11:27:30 -0400 Subject: [PATCH 018/331] -> v0.27.1 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24a3743..8ee47c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.27.1 + +* Ensure names exported from a module are not replaced with reserved words ([#696](https://github.com/rollup/rollup/pull/696)) +* Revert ([#692](https://github.com/rollup/rollup/pull/692)) – resolved IDs must be strings + ## 0.27.0 * Use native promises instead of `es6-promise` ([#689](https://github.com/rollup/rollup/issues/689)) diff --git a/package.json b/package.json index 7eeb4c0..b947be7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.27.0", + "version": "0.27.1", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "src/rollup.js", From fc7e0f1ce2f33cada6f431419ab51e8bda389ca4 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 7 Jun 2016 17:32:15 -0400 Subject: [PATCH 019/331] change option from bundle to cache --- src/Bundle.js | 4 ++-- src/rollup.js | 4 ++-- test/test.js | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 9ffb0dd..1d9f8d3 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -19,8 +19,8 @@ import { dirname, isRelative, isAbsolute, relative, resolve } from './utils/path export default class Bundle { constructor ( options ) { - if ( typeof options.bundle === 'object' ) { - this.cachedModules = options.bundle.modules.reduce((modules, module) => { + if ( typeof options.cache === 'object' ) { + this.cachedModules = options.cache.modules.reduce((modules, module) => { modules[module.id] = module; return modules; }, {}); diff --git a/src/rollup.js b/src/rollup.js index dc59f1d..4667fae 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -9,6 +9,7 @@ export const VERSION = '<@VERSION@>'; const ALLOWED_KEYS = [ 'banner', + 'cache', 'dest', 'entry', 'exports', @@ -28,8 +29,7 @@ const ALLOWED_KEYS = [ 'sourceMap', 'targets', 'treeshake', - 'useStrict', - 'bundle' + 'useStrict' ]; export function rollup ( options ) { diff --git a/test/test.js b/test/test.js index d171c45..1191267 100644 --- a/test/test.js +++ b/test/test.js @@ -431,7 +431,7 @@ describe( 'rollup', function () { }); done( error ); } - + else { var expected = sander.readFileSync( '_expected.js' ).toString(); try { @@ -464,7 +464,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: path.join( INCREMENTAL, 'not-transform-twice', 'main.js' ), plugins: [counter], - bundle + cache: bundle }); }).then( function ( bundle ) { assert.equal( calls, 2 ); @@ -509,7 +509,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: path.join( INCREMENTAL, 'transform-changed', 'main.js' ), plugins: [counter], - bundle + cache: bundle }); }).then( function ( bundle ) { assert.equal( calls, 3 ); From 84d408f9adcd30d265b01c1ec2840af8d49fd73c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 7 Jun 2016 17:53:43 -0400 Subject: [PATCH 020/331] make tests more robust (fs was getting out of sync) --- src/Bundle.js | 20 ++-- .../not-transform-twice/expected.js | 5 - test/incremental/not-transform-twice/foo.js | 3 - test/incremental/not-transform-twice/main.js | 3 - .../incremental/transform-changed/expected.js | 5 - .../transform-changed/foo-changed.js | 3 - test/incremental/transform-changed/foo.js | 3 - test/incremental/transform-changed/main.js | 3 - test/test.js | 111 +++++++++--------- 9 files changed, 66 insertions(+), 90 deletions(-) delete mode 100644 test/incremental/not-transform-twice/expected.js delete mode 100644 test/incremental/not-transform-twice/foo.js delete mode 100644 test/incremental/not-transform-twice/main.js delete mode 100644 test/incremental/transform-changed/expected.js delete mode 100644 test/incremental/transform-changed/foo-changed.js delete mode 100644 test/incremental/transform-changed/foo.js delete mode 100644 test/incremental/transform-changed/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 1d9f8d3..f16d105 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -19,11 +19,11 @@ import { dirname, isRelative, isAbsolute, relative, resolve } from './utils/path export default class Bundle { constructor ( options ) { - if ( typeof options.cache === 'object' ) { - this.cachedModules = options.cache.modules.reduce((modules, module) => { - modules[module.id] = module; - return modules; - }, {}); + this.cachedModules = new Map(); + if ( options.cache ) { + options.cache.modules.forEach( module => { + this.cachedModules.set( module.id, module ); + }); } this.plugins = ensureArray( options.plugins ); @@ -195,13 +195,11 @@ export default class Bundle { ast: null }; } - if (this.cachedModules && this.cachedModules[id] && this.cachedModules[id].originalCode === source.code) { - const { code, originalCode } = this.cachedModules[id]; - return { - code, - originalCode - }; + + if ( this.cachedModules.has( id ) && this.cachedModules.get( id ).originalCode === source.code ) { + return this.cachedModules.get( id ); } + return transform( source, id, this.transformers ); }) .then( source => { diff --git a/test/incremental/not-transform-twice/expected.js b/test/incremental/not-transform-twice/expected.js deleted file mode 100644 index 7063df5..0000000 --- a/test/incremental/not-transform-twice/expected.js +++ /dev/null @@ -1,5 +0,0 @@ -function foo () { - console.log('foo'); -}; - -foo(); \ No newline at end of file diff --git a/test/incremental/not-transform-twice/foo.js b/test/incremental/not-transform-twice/foo.js deleted file mode 100644 index 3bdfb02..0000000 --- a/test/incremental/not-transform-twice/foo.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function () { - console.log('foo'); -}; diff --git a/test/incremental/not-transform-twice/main.js b/test/incremental/not-transform-twice/main.js deleted file mode 100644 index e1fb5c4..0000000 --- a/test/incremental/not-transform-twice/main.js +++ /dev/null @@ -1,3 +0,0 @@ -import foo from './foo.js'; - -foo(); diff --git a/test/incremental/transform-changed/expected.js b/test/incremental/transform-changed/expected.js deleted file mode 100644 index e1c10a1..0000000 --- a/test/incremental/transform-changed/expected.js +++ /dev/null @@ -1,5 +0,0 @@ -function foo () { - console.log('foo-changed'); -}; - -foo(); \ No newline at end of file diff --git a/test/incremental/transform-changed/foo-changed.js b/test/incremental/transform-changed/foo-changed.js deleted file mode 100644 index b96789c..0000000 --- a/test/incremental/transform-changed/foo-changed.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function () { - console.log('foo-changed'); -}; diff --git a/test/incremental/transform-changed/foo.js b/test/incremental/transform-changed/foo.js deleted file mode 100644 index 435568b..0000000 --- a/test/incremental/transform-changed/foo.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function () { - console.log('foo'); -}; \ No newline at end of file diff --git a/test/incremental/transform-changed/main.js b/test/incremental/transform-changed/main.js deleted file mode 100644 index e1fb5c4..0000000 --- a/test/incremental/transform-changed/main.js +++ /dev/null @@ -1,3 +0,0 @@ -import foo from './foo.js'; - -foo(); diff --git a/test/test.js b/test/test.js index 1191267..d4cebb4 100644 --- a/test/test.js +++ b/test/test.js @@ -448,76 +448,79 @@ describe( 'rollup', function () { }); describe.only('incremental', function () { - it('does not transforms in the second time', function () { - var calls = 0; - var counter = { - transform: function ( code ) { - calls += 1; - return code; - } + function executeBundle ( bundle ) { + const cjs = bundle.generate({ format: 'cjs' }); + const m = new Function( 'module', 'exports', cjs.code ); + + let module = { exports: {} }; + m( module, module.exports ); + + return module.exports; + } + + var calls; + var modules; + + var plugin = { + resolveId: id => id, + + load: id => { + return modules[ id ]; + }, + + transform: function ( code ) { + calls += 1; + return code; + } + }; + + beforeEach( () => { + calls = 0; + + modules = { + entry: `import foo from 'foo'; export default foo;`, + foo: `export default 42` }; + }); + + it('does not transforms in the second time', function () { return rollup.rollup({ - entry: path.join( INCREMENTAL, 'not-transform-twice', 'main.js' ), - plugins: [counter] - }).then( function ( bundle ) { + entry: 'entry', + plugins: [ plugin ] + }).then( bundle => { assert.equal( calls, 2 ); return rollup.rollup({ - entry: path.join( INCREMENTAL, 'not-transform-twice', 'main.js' ), - plugins: [counter], + entry: 'entry', + plugins: [ plugin ], cache: bundle }); - }).then( function ( bundle ) { + }).then( bundle => { assert.equal( calls, 2 ); - var result = bundle.generate({ - format: 'es6' - }); - return sander.readFile( path.join( INCREMENTAL, 'not-transform-twice', 'expected.js' ) ).then( function (expected) { - assert.equal( normaliseOutput( expected ), result.code ); - }); + assert.equal( executeBundle( bundle ), 42 ); }); }); it('transforms modified sources', function () { - var calls = 0; - var counter = { - transform: function ( code ) { - calls += 1; - return code; - } - }; - var bundle; - var foo; - var changed; - var expected; - return Promise.all([ - rollup.rollup({ - entry: path.join( INCREMENTAL, 'transform-changed', 'main.js' ), - plugins: [counter] - }), - sander.readFile( path.join( INCREMENTAL, 'transform-changed', 'foo.js' ) ), - sander.readFile( path.join( INCREMENTAL, 'transform-changed', 'foo-changed.js' ) ), - sander.readFile( path.join( INCREMENTAL, 'transform-changed', 'expected.js' ) ) - ]).then( function ( [_bundle, _foo, _changed, _expected] ) { - bundle = _bundle; - foo = normaliseOutput( _foo ); - changed = normaliseOutput( _changed ); - expected = normaliseOutput( _expected ); + let cache; + + return rollup.rollup({ + entry: 'entry', + plugins: [ plugin ] + }).then( bundle => { assert.equal( calls, 2 ); + assert.equal( executeBundle( bundle ), 42 ); - return sander.writeFile( INCREMENTAL, 'transform-changed', 'foo.js', changed ); - }).then(function () { + modules.foo = `export default 43`; + cache = bundle; + }).then( () => { return rollup.rollup({ - entry: path.join( INCREMENTAL, 'transform-changed', 'main.js' ), - plugins: [counter], - cache: bundle + entry: 'entry', + plugins: [ plugin ], + cache }); - }).then( function ( bundle ) { + }).then( bundle => { assert.equal( calls, 3 ); - var result = bundle.generate({ - format: 'es6' - }); - assert.equal(expected, result.code); - return sander.writeFile( INCREMENTAL, 'transform-changed', 'foo.js', foo ); + assert.equal( executeBundle( bundle ), 43 ); }); }); }); From 0a7a391c049861bd68811958a074723616a449c0 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 7 Jun 2016 18:01:33 -0400 Subject: [PATCH 021/331] preserve ast to avoid re-parsing --- src/Module.js | 22 ++++++++++++++++------ src/rollup.js | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/Module.js b/src/Module.js index 9f6ae45..33e50a5 100644 --- a/src/Module.js +++ b/src/Module.js @@ -53,7 +53,8 @@ export default class Module { } this.comments = []; - this.statements = this.parse( ast ); + this.ast = ast; + this.statements = this.parse(); this.declarations = blank(); this.analyse(); @@ -298,13 +299,13 @@ export default class Module { return this.declarations['*']; } - parse ( ast ) { + parse () { // The ast can be supplied programmatically (but usually won't be) - if ( !ast ) { + if ( !this.ast ) { // Try to extract a list of top-level statements/declarations. If // the parse fails, attach file info and abort try { - ast = parse( this.code, { + this.ast = parse( this.code, { ecmaVersion: 6, sourceType: 'module', onComment: ( block, text, start, end ) => this.comments.push({ block, text, start, end }), @@ -318,7 +319,7 @@ export default class Module { } } - walk( ast, { + walk( this.ast, { enter: node => { // eliminate dead branches early if ( node.type === 'IfStatement' ) { @@ -354,7 +355,7 @@ export default class Module { let lastChar = 0; let commentIndex = 0; - ast.body.forEach( node => { + this.ast.body.forEach( node => { if ( node.type === 'EmptyStatement' ) return; if ( @@ -637,6 +638,15 @@ export default class Module { return marked; } + toJSON () { + return { + id: this.id, + code: this.code, + originalCode: this.originalCode, + ast: this.ast + }; + } + trace ( name ) { if ( name in this.declarations ) return this.declarations[ name ]; if ( name in this.imports ) { diff --git a/src/rollup.js b/src/rollup.js index 4667fae..29a6fa1 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -53,7 +53,7 @@ export function rollup ( options ) { return { imports: bundle.externalModules.map( module => module.id ), exports: keys( bundle.entryModule.exports ), - modules: bundle.orderedModules.map( ( { id, code, originalCode } ) => ( { id, code, originalCode } ) ), + modules: bundle.orderedModules.map( module => module.toJSON() ), generate: options => bundle.render( options ), write: options => { From e11b1f2d682b0cd86cd52197c7af9234121ae165 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 7 Jun 2016 18:03:15 -0400 Subject: [PATCH 022/331] preserve sourcemap chain --- src/Module.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Module.js b/src/Module.js index 33e50a5..cde624c 100644 --- a/src/Module.js +++ b/src/Module.js @@ -643,7 +643,8 @@ export default class Module { id: this.id, code: this.code, originalCode: this.originalCode, - ast: this.ast + ast: this.ast, + sourceMapChain: this.sourceMapChain }; } From 53fdae7173ae79e36ae5140c268f753eea020dba Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 7 Jun 2016 23:48:32 -0400 Subject: [PATCH 023/331] -> v0.28.0 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ee47c7..69cc4c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.28.0 + +* Experimental support for incremental rebuilds ([#658](https://github.com/rollup/rollup/pull/658)) + ## 0.27.1 * Ensure names exported from a module are not replaced with reserved words ([#696](https://github.com/rollup/rollup/pull/696)) diff --git a/package.json b/package.json index b947be7..e6d87b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.27.1", + "version": "0.28.0", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "src/rollup.js", From 9cfedd55d4ed3f5ef21e6c1b15d484c3546bae7b Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 7 Jun 2016 23:49:56 -0400 Subject: [PATCH 024/331] reinstate all tests --- test/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test.js b/test/test.js index d4cebb4..af44baa 100644 --- a/test/test.js +++ b/test/test.js @@ -77,7 +77,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( function () { throw new Error( 'Missing expected error' ); }, function ( err ) { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: banner, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, targets, treeshake, useStrict' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, targets, treeshake, useStrict' ); }); }); }); @@ -447,7 +447,7 @@ describe( 'rollup', function () { }); }); - describe.only('incremental', function () { + describe('incremental', function () { function executeBundle ( bundle ) { const cjs = bundle.generate({ format: 'cjs' }); const m = new Function( 'module', 'exports', cjs.code ); From 7485b60d45f3a7a82e9bffc644450024ee07e74a Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 8 Jun 2016 01:07:40 -0400 Subject: [PATCH 025/331] implement rollup --watch --- bin/help.md | 1 + bin/rollup | 3 ++- bin/runRollup.js | 16 +++++++++++++++- package.json | 1 + 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/bin/help.md b/bin/help.md index 46886c7..7b02ed1 100644 --- a/bin/help.md +++ b/bin/help.md @@ -9,6 +9,7 @@ Basic options: -h, --help Show this help message -c, --config Use this config file (if argument is used but value is unspecified, defaults to rollup.config.js) +-w, --watch Watch files in bundle and rebuild on changes -i, --input Input (alternative to ) -o, --output Output (if absent, prints to stdout) -f, --format [es6] Type of output (amd, cjs, es6, iife, umd) diff --git a/bin/rollup b/bin/rollup index 200c4bb..123f388 100755 --- a/bin/rollup +++ b/bin/rollup @@ -20,7 +20,8 @@ command = minimist( process.argv.slice( 2 ), { n: 'name', o: 'output', u: 'id', - v: 'version' + v: 'version', + w: 'watch' } }); diff --git a/bin/runRollup.js b/bin/runRollup.js index ea8ade9..27629b2 100644 --- a/bin/runRollup.js +++ b/bin/runRollup.js @@ -1,6 +1,7 @@ require( 'source-map-support' ).install(); var path = require( 'path' ); +var relative = require( 'require-relative' ); var handleError = require( './handleError' ); var rollup = require( '../' ); @@ -127,7 +128,20 @@ function execute ( options, command ) { }); try { - bundle( options ).catch( handleError ); + if ( command.watch ) { + let watch; + + try { + watch = relative( 'rollup-watch', process.cwd() ); + } catch ( err ) { + // TODO offer to install rollup-watch + throw err; + } + + watch( options ); + } else { + bundle( options ).catch( handleError ); + } } catch ( err ) { handleError( err ); } diff --git a/package.json b/package.json index e6d87b9..dba86ad 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "dependencies": { "chalk": "^1.1.1", "minimist": "^1.2.0", + "require-relative": "^0.8.7", "source-map-support": "^0.4.0" }, "files": [ From fa93c5fe37abef5242641ce1b40895cf186fda55 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 8 Jun 2016 08:58:19 -0400 Subject: [PATCH 026/331] var not let --- bin/runRollup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/runRollup.js b/bin/runRollup.js index 27629b2..46ac35c 100644 --- a/bin/runRollup.js +++ b/bin/runRollup.js @@ -129,7 +129,7 @@ function execute ( options, command ) { try { if ( command.watch ) { - let watch; + var watch; try { watch = relative( 'rollup-watch', process.cwd() ); From d61df97d8d7ce4e6e522fd506a12390dd81f34ef Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 8 Jun 2016 10:56:49 -0400 Subject: [PATCH 027/331] auto-install rollup-watch if requested --- bin/getRollupWatch.js | 43 +++++++++++++++++++++++++++++++++++++++++++ bin/handleError.js | 8 ++++++++ bin/runRollup.js | 37 ++++++++++++++++++++++++++++--------- 3 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 bin/getRollupWatch.js diff --git a/bin/getRollupWatch.js b/bin/getRollupWatch.js new file mode 100644 index 0000000..d830023 --- /dev/null +++ b/bin/getRollupWatch.js @@ -0,0 +1,43 @@ +var chalk = require( 'chalk' ); +var relative = require( 'require-relative' ); + +module.exports = function getRollupWatch () { + try { + watch = relative( 'rollup-watch', process.cwd() ); + return Promise.resolve( watch ); + } catch ( err ) { + if ( err.code === 'MODULE_NOT_FOUND' ) { + return installRollupWatch().then( () => { + return relative( 'rollup-watch', process.cwd() ); + }); + } else { + return Promise.reject( err ); + } + } +}; + +function installRollupWatch () { + console.error( 'rollup --watch depends on the rollup-watch package, which could not be found. You can install it globally with ' + chalk.cyan( 'npm install -g rollup-watch' ) + '. Do this now? ' + chalk.green.bold( '[y/n]' ) ); + + process.stdin.setEncoding( 'utf8' ); + + return new Promise( ( fulfil, reject ) => { + process.stdin.on( 'readable', function () { + var chunk = process.stdin.read(); + if ( !chunk ) return; + + if ( /^y(?:es)?$/i.test( chunk ) ) { + console.error( 'installing rollup-watch...' ); + child = require( 'child_process' ).exec( 'npm install --global rollup-watch', err => { + if ( err ) { + reject( err ); + } else { + fulfil(); + } + }); + } else { + reject( new Error( 'aborted' ) ); + } + }); + }); +} diff --git a/bin/handleError.js b/bin/handleError.js index b7cd224..33ee847 100644 --- a/bin/handleError.js +++ b/bin/handleError.js @@ -27,6 +27,14 @@ var handlers = { DUPLICATE_IMPORT_OPTIONS: function ( err ) { console.error( chalk.red( 'use --input, or pass input path as argument' ) ); + }, + + ROLLUP_WATCH_NOT_INSTALLED: function ( err ) { + console.error( chalk.red( 'failed to find or install rollup-watch' ) ); + }, + + WATCHER_MISSING_INPUT_OR_OUTPUT: function ( err ) { + console.error( chalk.red( 'must specify --input and --output when using rollup --watch' ) ); } }; diff --git a/bin/runRollup.js b/bin/runRollup.js index 46ac35c..91a3df4 100644 --- a/bin/runRollup.js +++ b/bin/runRollup.js @@ -1,8 +1,9 @@ require( 'source-map-support' ).install(); var path = require( 'path' ); -var relative = require( 'require-relative' ); var handleError = require( './handleError' ); +var getRollupWatch = require( './getRollupWatch' ); +var chalk = require( 'chalk' ); var rollup = require( '../' ); // log to stderr to keep `rollup main.js > bundle.js` from breaking @@ -129,16 +130,34 @@ function execute ( options, command ) { try { if ( command.watch ) { - var watch; - - try { - watch = relative( 'rollup-watch', process.cwd() ); - } catch ( err ) { - // TODO offer to install rollup-watch - throw err; + if ( !options.entry || !options.dest ) { + handleError({ code: 'WATCHER_MISSING_INPUT_OR_OUTPUT' }); } - watch( options ); + getRollupWatch() + .then( watch => { + const watcher = watch( rollup, options ); + + watcher.on( 'event', event => { + switch ( event.code ) { + case 'STARTING': + console.error( 'checking rollup-watch version...' ); + break; + + case 'BUILD_START': + console.error( 'bundling...' ); + break; + + case 'BUILD_END': + console.error( 'bundled in ' + event.duration + 'ms. Watching for changes...' ); + break; + + default: + console.error( 'unknown event', event ); + } + }); + }) + .catch( handleError ); } else { bundle( options ).catch( handleError ); } From 138d255af45209716b2c11ca549125a76219227e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 8 Jun 2016 11:49:50 -0400 Subject: [PATCH 028/331] on second thoughts, dont auto-install. will cause problems in many cases --- bin/getRollupWatch.js | 43 --------------------------------- bin/handleError.js | 2 +- bin/runRollup.js | 55 +++++++++++++++++++++++-------------------- 3 files changed, 31 insertions(+), 69 deletions(-) delete mode 100644 bin/getRollupWatch.js diff --git a/bin/getRollupWatch.js b/bin/getRollupWatch.js deleted file mode 100644 index d830023..0000000 --- a/bin/getRollupWatch.js +++ /dev/null @@ -1,43 +0,0 @@ -var chalk = require( 'chalk' ); -var relative = require( 'require-relative' ); - -module.exports = function getRollupWatch () { - try { - watch = relative( 'rollup-watch', process.cwd() ); - return Promise.resolve( watch ); - } catch ( err ) { - if ( err.code === 'MODULE_NOT_FOUND' ) { - return installRollupWatch().then( () => { - return relative( 'rollup-watch', process.cwd() ); - }); - } else { - return Promise.reject( err ); - } - } -}; - -function installRollupWatch () { - console.error( 'rollup --watch depends on the rollup-watch package, which could not be found. You can install it globally with ' + chalk.cyan( 'npm install -g rollup-watch' ) + '. Do this now? ' + chalk.green.bold( '[y/n]' ) ); - - process.stdin.setEncoding( 'utf8' ); - - return new Promise( ( fulfil, reject ) => { - process.stdin.on( 'readable', function () { - var chunk = process.stdin.read(); - if ( !chunk ) return; - - if ( /^y(?:es)?$/i.test( chunk ) ) { - console.error( 'installing rollup-watch...' ); - child = require( 'child_process' ).exec( 'npm install --global rollup-watch', err => { - if ( err ) { - reject( err ); - } else { - fulfil(); - } - }); - } else { - reject( new Error( 'aborted' ) ); - } - }); - }); -} diff --git a/bin/handleError.js b/bin/handleError.js index 33ee847..21a100d 100644 --- a/bin/handleError.js +++ b/bin/handleError.js @@ -30,7 +30,7 @@ var handlers = { }, ROLLUP_WATCH_NOT_INSTALLED: function ( err ) { - console.error( chalk.red( 'failed to find or install rollup-watch' ) ); + console.error( chalk.red( 'rollup --watch depends on the rollup-watch package, which could not be found. You can install it globally (recommended) with ' ) + chalk.cyan( 'npm install -g rollup-watch' ) ); }, WATCHER_MISSING_INPUT_OR_OUTPUT: function ( err ) { diff --git a/bin/runRollup.js b/bin/runRollup.js index 91a3df4..20b6264 100644 --- a/bin/runRollup.js +++ b/bin/runRollup.js @@ -1,8 +1,8 @@ require( 'source-map-support' ).install(); var path = require( 'path' ); +var relative = require( 'require-relative' ); var handleError = require( './handleError' ); -var getRollupWatch = require( './getRollupWatch' ); var chalk = require( 'chalk' ); var rollup = require( '../' ); @@ -134,30 +134,35 @@ function execute ( options, command ) { handleError({ code: 'WATCHER_MISSING_INPUT_OR_OUTPUT' }); } - getRollupWatch() - .then( watch => { - const watcher = watch( rollup, options ); - - watcher.on( 'event', event => { - switch ( event.code ) { - case 'STARTING': - console.error( 'checking rollup-watch version...' ); - break; - - case 'BUILD_START': - console.error( 'bundling...' ); - break; - - case 'BUILD_END': - console.error( 'bundled in ' + event.duration + 'ms. Watching for changes...' ); - break; - - default: - console.error( 'unknown event', event ); - } - }); - }) - .catch( handleError ); + try { + var watch = relative( 'rollup-watch', process.cwd() ); + var watcher = watch( rollup, options ); + + watcher.on( 'event', event => { + switch ( event.code ) { + case 'STARTING': + console.error( 'checking rollup-watch version...' ); + break; + + case 'BUILD_START': + console.error( 'bundling...' ); + break; + + case 'BUILD_END': + console.error( 'bundled in ' + event.duration + 'ms. Watching for changes...' ); + break; + + default: + console.error( 'unknown event', event ); + } + }); + } catch ( err ) { + if ( err.code === 'MODULE_NOT_FOUND' ) { + err.code = 'ROLLUP_WATCH_NOT_INSTALLED'; + } + + handleError( err ); + } } else { bundle( options ).catch( handleError ); } From f2671c0519817bc42b8915215b175cdecffb0e30 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 8 Jun 2016 11:55:04 -0400 Subject: [PATCH 029/331] oops i did it again --- bin/runRollup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/runRollup.js b/bin/runRollup.js index 20b6264..38d5339 100644 --- a/bin/runRollup.js +++ b/bin/runRollup.js @@ -138,7 +138,7 @@ function execute ( options, command ) { var watch = relative( 'rollup-watch', process.cwd() ); var watcher = watch( rollup, options ); - watcher.on( 'event', event => { + watcher.on( 'event', function ( event ) { switch ( event.code ) { case 'STARTING': console.error( 'checking rollup-watch version...' ); From 5f7c2f68cbc7952a81f2b77d4723ce594c1562b5 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 8 Jun 2016 12:00:10 -0400 Subject: [PATCH 030/331] -> v0.29.0 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69cc4c2..9689ba3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.29.0 + +* `rollup --watch` ([#284](https://github.com/rollup/rollup/issues/284)) + ## 0.28.0 * Experimental support for incremental rebuilds ([#658](https://github.com/rollup/rollup/pull/658)) diff --git a/package.json b/package.json index dba86ad..5b10eed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.28.0", + "version": "0.29.0", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "src/rollup.js", From fca02171facbd2821a35d73ee65a0a70c74a693f Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Thu, 9 Jun 2016 07:00:45 -0700 Subject: [PATCH 031/331] Merge target options with main options. Fixes #701. --- bin/runRollup.js | 13 ++++++++++++- test/cli/multiple-targets-shared-config/_config.js | 4 ++++ .../_expected/cjs.js | 6 ++++++ .../_expected/cjs.js.map | 1 + .../_expected/es6.js | 4 ++++ .../_expected/es6.js.map | 1 + test/cli/multiple-targets-shared-config/main.js | 1 + .../rollup.config.js | 14 ++++++++++++++ 8 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/cli/multiple-targets-shared-config/_config.js create mode 100644 test/cli/multiple-targets-shared-config/_expected/cjs.js create mode 100644 test/cli/multiple-targets-shared-config/_expected/cjs.js.map create mode 100644 test/cli/multiple-targets-shared-config/_expected/es6.js create mode 100644 test/cli/multiple-targets-shared-config/_expected/es6.js.map create mode 100644 test/cli/multiple-targets-shared-config/main.js create mode 100644 test/cli/multiple-targets-shared-config/rollup.config.js diff --git a/bin/runRollup.js b/bin/runRollup.js index 38d5339..ed88549 100644 --- a/bin/runRollup.js +++ b/bin/runRollup.js @@ -171,6 +171,17 @@ function execute ( options, command ) { } } +function clone ( object ) { + return assign( {}, object ); +} + +function assign ( target, source ) { + Object.keys( source ).forEach( function ( key ) { + target[ key ] = source[ key ]; + }); + return target; +} + function bundle ( options ) { if ( !options.entry ) { handleError({ code: 'MISSING_INPUT_OPTION' }); @@ -185,7 +196,7 @@ function bundle ( options ) { var result = null; options.targets.forEach( function ( target ) { - result = bundle.write(target); + result = bundle.write( assign( clone( options ), target ) ); }); return result; diff --git a/test/cli/multiple-targets-shared-config/_config.js b/test/cli/multiple-targets-shared-config/_config.js new file mode 100644 index 0000000..6d7125c --- /dev/null +++ b/test/cli/multiple-targets-shared-config/_config.js @@ -0,0 +1,4 @@ +module.exports = { + description: 'uses shared config for each target', + command: 'rollup -c' +}; diff --git a/test/cli/multiple-targets-shared-config/_expected/cjs.js b/test/cli/multiple-targets-shared-config/_expected/cjs.js new file mode 100644 index 0000000..d3b3eb0 --- /dev/null +++ b/test/cli/multiple-targets-shared-config/_expected/cjs.js @@ -0,0 +1,6 @@ +'use strict'; + +var main = 0; + +module.exports = main; +//# sourceMappingURL=cjs.js.map \ No newline at end of file diff --git a/test/cli/multiple-targets-shared-config/_expected/cjs.js.map b/test/cli/multiple-targets-shared-config/_expected/cjs.js.map new file mode 100644 index 0000000..7010396 --- /dev/null +++ b/test/cli/multiple-targets-shared-config/_expected/cjs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"cjs.js","sources":["../main.js"],"sourcesContent":["export default 0;\n"],"names":[],"mappings":";;WAAe,CAAC,CAAC,;;"} \ No newline at end of file diff --git a/test/cli/multiple-targets-shared-config/_expected/es6.js b/test/cli/multiple-targets-shared-config/_expected/es6.js new file mode 100644 index 0000000..e24bdc9 --- /dev/null +++ b/test/cli/multiple-targets-shared-config/_expected/es6.js @@ -0,0 +1,4 @@ +var main = 0; + +export default main; +//# sourceMappingURL=es6.js.map \ No newline at end of file diff --git a/test/cli/multiple-targets-shared-config/_expected/es6.js.map b/test/cli/multiple-targets-shared-config/_expected/es6.js.map new file mode 100644 index 0000000..ba7fc9c --- /dev/null +++ b/test/cli/multiple-targets-shared-config/_expected/es6.js.map @@ -0,0 +1 @@ +{"version":3,"file":"es6.js","sources":["../main.js"],"sourcesContent":["export default 0;\n"],"names":[],"mappings":"WAAe,CAAC,CAAC,;;"} \ No newline at end of file diff --git a/test/cli/multiple-targets-shared-config/main.js b/test/cli/multiple-targets-shared-config/main.js new file mode 100644 index 0000000..7f810d3 --- /dev/null +++ b/test/cli/multiple-targets-shared-config/main.js @@ -0,0 +1 @@ +export default 0; diff --git a/test/cli/multiple-targets-shared-config/rollup.config.js b/test/cli/multiple-targets-shared-config/rollup.config.js new file mode 100644 index 0000000..e99ab56 --- /dev/null +++ b/test/cli/multiple-targets-shared-config/rollup.config.js @@ -0,0 +1,14 @@ +export default { + entry: 'main.js', + sourceMap: true, + targets: [ + { + format: 'cjs', + dest: '_actual/cjs.js' + }, + { + format: 'es6', + dest: '_actual/es6.js' + } + ] +}; From c2afe7d9bd13bd8d276a6f113940276c5881dfd8 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 13:17:02 -0400 Subject: [PATCH 032/331] rename test to workaround mochas confusion --- test/form/{sourcemaps => sourcemaps-external}/_config.js | 0 test/form/{sourcemaps => sourcemaps-external}/_expected/amd.js | 0 .../form/{sourcemaps => sourcemaps-external}/_expected/amd.js.map | 0 test/form/{sourcemaps => sourcemaps-external}/_expected/cjs.js | 0 .../form/{sourcemaps => sourcemaps-external}/_expected/cjs.js.map | 0 test/form/{sourcemaps => sourcemaps-external}/_expected/es6.js | 0 .../form/{sourcemaps => sourcemaps-external}/_expected/es6.js.map | 0 test/form/{sourcemaps => sourcemaps-external}/_expected/iife.js | 0 .../{sourcemaps => sourcemaps-external}/_expected/iife.js.map | 0 test/form/{sourcemaps => sourcemaps-external}/_expected/umd.js | 0 .../form/{sourcemaps => sourcemaps-external}/_expected/umd.js.map | 0 test/form/{sourcemaps => sourcemaps-external}/bar.js | 0 test/form/{sourcemaps => sourcemaps-external}/foo.js | 0 test/form/{sourcemaps => sourcemaps-external}/main.js | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename test/form/{sourcemaps => sourcemaps-external}/_config.js (100%) rename test/form/{sourcemaps => sourcemaps-external}/_expected/amd.js (100%) rename test/form/{sourcemaps => sourcemaps-external}/_expected/amd.js.map (100%) rename test/form/{sourcemaps => sourcemaps-external}/_expected/cjs.js (100%) rename test/form/{sourcemaps => sourcemaps-external}/_expected/cjs.js.map (100%) rename test/form/{sourcemaps => sourcemaps-external}/_expected/es6.js (100%) rename test/form/{sourcemaps => sourcemaps-external}/_expected/es6.js.map (100%) rename test/form/{sourcemaps => sourcemaps-external}/_expected/iife.js (100%) rename test/form/{sourcemaps => sourcemaps-external}/_expected/iife.js.map (100%) rename test/form/{sourcemaps => sourcemaps-external}/_expected/umd.js (100%) rename test/form/{sourcemaps => sourcemaps-external}/_expected/umd.js.map (100%) rename test/form/{sourcemaps => sourcemaps-external}/bar.js (100%) rename test/form/{sourcemaps => sourcemaps-external}/foo.js (100%) rename test/form/{sourcemaps => sourcemaps-external}/main.js (100%) diff --git a/test/form/sourcemaps/_config.js b/test/form/sourcemaps-external/_config.js similarity index 100% rename from test/form/sourcemaps/_config.js rename to test/form/sourcemaps-external/_config.js diff --git a/test/form/sourcemaps/_expected/amd.js b/test/form/sourcemaps-external/_expected/amd.js similarity index 100% rename from test/form/sourcemaps/_expected/amd.js rename to test/form/sourcemaps-external/_expected/amd.js diff --git a/test/form/sourcemaps/_expected/amd.js.map b/test/form/sourcemaps-external/_expected/amd.js.map similarity index 100% rename from test/form/sourcemaps/_expected/amd.js.map rename to test/form/sourcemaps-external/_expected/amd.js.map diff --git a/test/form/sourcemaps/_expected/cjs.js b/test/form/sourcemaps-external/_expected/cjs.js similarity index 100% rename from test/form/sourcemaps/_expected/cjs.js rename to test/form/sourcemaps-external/_expected/cjs.js diff --git a/test/form/sourcemaps/_expected/cjs.js.map b/test/form/sourcemaps-external/_expected/cjs.js.map similarity index 100% rename from test/form/sourcemaps/_expected/cjs.js.map rename to test/form/sourcemaps-external/_expected/cjs.js.map diff --git a/test/form/sourcemaps/_expected/es6.js b/test/form/sourcemaps-external/_expected/es6.js similarity index 100% rename from test/form/sourcemaps/_expected/es6.js rename to test/form/sourcemaps-external/_expected/es6.js diff --git a/test/form/sourcemaps/_expected/es6.js.map b/test/form/sourcemaps-external/_expected/es6.js.map similarity index 100% rename from test/form/sourcemaps/_expected/es6.js.map rename to test/form/sourcemaps-external/_expected/es6.js.map diff --git a/test/form/sourcemaps/_expected/iife.js b/test/form/sourcemaps-external/_expected/iife.js similarity index 100% rename from test/form/sourcemaps/_expected/iife.js rename to test/form/sourcemaps-external/_expected/iife.js diff --git a/test/form/sourcemaps/_expected/iife.js.map b/test/form/sourcemaps-external/_expected/iife.js.map similarity index 100% rename from test/form/sourcemaps/_expected/iife.js.map rename to test/form/sourcemaps-external/_expected/iife.js.map diff --git a/test/form/sourcemaps/_expected/umd.js b/test/form/sourcemaps-external/_expected/umd.js similarity index 100% rename from test/form/sourcemaps/_expected/umd.js rename to test/form/sourcemaps-external/_expected/umd.js diff --git a/test/form/sourcemaps/_expected/umd.js.map b/test/form/sourcemaps-external/_expected/umd.js.map similarity index 100% rename from test/form/sourcemaps/_expected/umd.js.map rename to test/form/sourcemaps-external/_expected/umd.js.map diff --git a/test/form/sourcemaps/bar.js b/test/form/sourcemaps-external/bar.js similarity index 100% rename from test/form/sourcemaps/bar.js rename to test/form/sourcemaps-external/bar.js diff --git a/test/form/sourcemaps/foo.js b/test/form/sourcemaps-external/foo.js similarity index 100% rename from test/form/sourcemaps/foo.js rename to test/form/sourcemaps-external/foo.js diff --git a/test/form/sourcemaps/main.js b/test/form/sourcemaps-external/main.js similarity index 100% rename from test/form/sourcemaps/main.js rename to test/form/sourcemaps-external/main.js From f171048be03d2c50fb21cbc436c7ce05319c018a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 13:52:56 -0400 Subject: [PATCH 033/331] remove unused variable --- test/test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test.js b/test/test.js index af44baa..1df5666 100644 --- a/test/test.js +++ b/test/test.js @@ -13,7 +13,6 @@ var FUNCTION = path.resolve( __dirname, 'function' ); var FORM = path.resolve( __dirname, 'form' ); var SOURCEMAPS = path.resolve( __dirname, 'sourcemaps' ); var CLI = path.resolve( __dirname, 'cli' ); -var INCREMENTAL = path.resolve( __dirname, 'incremental' ); var PROFILES = [ { format: 'amd' }, From 887d22683c175ef165f181905f76028d3310e64a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 13:53:30 -0400 Subject: [PATCH 034/331] update magic-string --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0d05b9c..38c4d2a 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "eslint": "^2.9.0", "estree-walker": "^0.2.0", "istanbul": "^0.4.0", - "magic-string": "^0.15.0", + "magic-string": "^0.15.1", "mocha": "^2.3.3", "remap-istanbul": "^0.5.1", "rollup": "^0.26.2", From 9575b680ee9180dfe5c8d336c0cbd5de8a33947c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 14:01:14 -0400 Subject: [PATCH 035/331] update test --- test/cli/multiple-targets-shared-config/_expected/cjs.js.map | 2 +- test/cli/multiple-targets-shared-config/_expected/es6.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cli/multiple-targets-shared-config/_expected/cjs.js.map b/test/cli/multiple-targets-shared-config/_expected/cjs.js.map index 7010396..d88316a 100644 --- a/test/cli/multiple-targets-shared-config/_expected/cjs.js.map +++ b/test/cli/multiple-targets-shared-config/_expected/cjs.js.map @@ -1 +1 @@ -{"version":3,"file":"cjs.js","sources":["../main.js"],"sourcesContent":["export default 0;\n"],"names":[],"mappings":";;WAAe,CAAC,CAAC,;;"} \ No newline at end of file +{"version":3,"file":"cjs.js","sources":["../main.js"],"sourcesContent":["export default 0;\n"],"names":[],"mappings":";;AAAA,WAAe,CAAC,CAAC,;;"} diff --git a/test/cli/multiple-targets-shared-config/_expected/es6.js.map b/test/cli/multiple-targets-shared-config/_expected/es6.js.map index ba7fc9c..8b3e60e 100644 --- a/test/cli/multiple-targets-shared-config/_expected/es6.js.map +++ b/test/cli/multiple-targets-shared-config/_expected/es6.js.map @@ -1 +1 @@ -{"version":3,"file":"es6.js","sources":["../main.js"],"sourcesContent":["export default 0;\n"],"names":[],"mappings":"WAAe,CAAC,CAAC,;;"} \ No newline at end of file +{"version":3,"file":"es6.js","sources":["../main.js"],"sourcesContent":["export default 0;\n"],"names":[],"mappings":"AAAA,WAAe,CAAC,CAAC,;;"} From 1e0a27f59ae92201fb71c9ec9c0d198b157e2555 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 14:19:43 -0400 Subject: [PATCH 036/331] -> v0.29.1 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9689ba3..64427d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.29.1 + +* Merge `target` options with main options ([#701](https://github.com/rollup/rollup/issues/701)) +* Update magic-string ([#690](https://github.com/rollup/rollup/issues/690)) + ## 0.29.0 * `rollup --watch` ([#284](https://github.com/rollup/rollup/issues/284)) diff --git a/package.json b/package.json index 38c4d2a..67b23b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.29.0", + "version": "0.29.1", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "src/rollup.js", From ef20502229923f29d1fcea0a81fcd07d66f9581b Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 15:07:30 -0400 Subject: [PATCH 037/331] allow rollup --watch with targets --- bin/runRollup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/runRollup.js b/bin/runRollup.js index ed88549..2009ff4 100644 --- a/bin/runRollup.js +++ b/bin/runRollup.js @@ -130,7 +130,7 @@ function execute ( options, command ) { try { if ( command.watch ) { - if ( !options.entry || !options.dest ) { + if ( !options.entry || ( !options.dest && !options.targets ) ) { handleError({ code: 'WATCHER_MISSING_INPUT_OR_OUTPUT' }); } From 2b13d59ee4dccd63c0ff9df27799e75e96efb416 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Thu, 9 Jun 2016 22:13:45 +0300 Subject: [PATCH 038/331] Add normalize-absolute test --- test/form/absolute-path-resolver/_config.js | 15 +++++++++++++++ test/form/absolute-path-resolver/_expected/amd.js | 10 ++++++++++ test/form/absolute-path-resolver/_expected/cjs.js | 8 ++++++++ test/form/absolute-path-resolver/_expected/es6.js | 6 ++++++ .../form/absolute-path-resolver/_expected/iife.js | 11 +++++++++++ test/form/absolute-path-resolver/_expected/umd.js | 14 ++++++++++++++ test/form/absolute-path-resolver/a.js | 3 +++ test/form/absolute-path-resolver/main.js | 4 ++++ 8 files changed, 71 insertions(+) create mode 100644 test/form/absolute-path-resolver/_config.js create mode 100644 test/form/absolute-path-resolver/_expected/amd.js create mode 100644 test/form/absolute-path-resolver/_expected/cjs.js create mode 100644 test/form/absolute-path-resolver/_expected/es6.js create mode 100644 test/form/absolute-path-resolver/_expected/iife.js create mode 100644 test/form/absolute-path-resolver/_expected/umd.js create mode 100644 test/form/absolute-path-resolver/a.js create mode 100644 test/form/absolute-path-resolver/main.js diff --git a/test/form/absolute-path-resolver/_config.js b/test/form/absolute-path-resolver/_config.js new file mode 100644 index 0000000..9e88960 --- /dev/null +++ b/test/form/absolute-path-resolver/_config.js @@ -0,0 +1,15 @@ +var path = require('path'); + +module.exports = { + solo: true, + description: 'normalizes absolute ids', + options: { + plugins: [{ + transform: function (code, id) { + if (/main/.test(id)) { + return code.replace('"./a.js"', JSON.stringify(path.resolve(__dirname, 'a.js'))); + } + } + }] + } +}; diff --git a/test/form/absolute-path-resolver/_expected/amd.js b/test/form/absolute-path-resolver/_expected/amd.js new file mode 100644 index 0000000..4718f2e --- /dev/null +++ b/test/form/absolute-path-resolver/_expected/amd.js @@ -0,0 +1,10 @@ +define(function () { 'use strict'; + + var a = () => { + console.log('props'); + }; + + a(); + a(); + +}); \ No newline at end of file diff --git a/test/form/absolute-path-resolver/_expected/cjs.js b/test/form/absolute-path-resolver/_expected/cjs.js new file mode 100644 index 0000000..473b57e --- /dev/null +++ b/test/form/absolute-path-resolver/_expected/cjs.js @@ -0,0 +1,8 @@ +'use strict'; + +var a = () => { + console.log('props'); +}; + +a(); +a(); \ No newline at end of file diff --git a/test/form/absolute-path-resolver/_expected/es6.js b/test/form/absolute-path-resolver/_expected/es6.js new file mode 100644 index 0000000..0415d2c --- /dev/null +++ b/test/form/absolute-path-resolver/_expected/es6.js @@ -0,0 +1,6 @@ +var a = () => { + console.log('props'); +}; + +a(); +a(); \ No newline at end of file diff --git a/test/form/absolute-path-resolver/_expected/iife.js b/test/form/absolute-path-resolver/_expected/iife.js new file mode 100644 index 0000000..cb9df4a --- /dev/null +++ b/test/form/absolute-path-resolver/_expected/iife.js @@ -0,0 +1,11 @@ +(function () { + 'use strict'; + + var a = () => { + console.log('props'); + }; + + a(); + a(); + +}()); \ No newline at end of file diff --git a/test/form/absolute-path-resolver/_expected/umd.js b/test/form/absolute-path-resolver/_expected/umd.js new file mode 100644 index 0000000..02345b3 --- /dev/null +++ b/test/form/absolute-path-resolver/_expected/umd.js @@ -0,0 +1,14 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, function () { 'use strict'; + + var a = () => { + console.log('props'); + }; + + a(); + a(); + +})); \ No newline at end of file diff --git a/test/form/absolute-path-resolver/a.js b/test/form/absolute-path-resolver/a.js new file mode 100644 index 0000000..3223031 --- /dev/null +++ b/test/form/absolute-path-resolver/a.js @@ -0,0 +1,3 @@ +export var a = () => { + console.log('props'); +}; \ No newline at end of file diff --git a/test/form/absolute-path-resolver/main.js b/test/form/absolute-path-resolver/main.js new file mode 100644 index 0000000..f0b4f66 --- /dev/null +++ b/test/form/absolute-path-resolver/main.js @@ -0,0 +1,4 @@ +import { a } from "./a.js"; +import { a as b } from "./a.js"; +a(); +b(); \ No newline at end of file From ccbc11cce196bdc88c1b0bf55a8bcb40837f5269 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Thu, 9 Jun 2016 22:28:15 +0300 Subject: [PATCH 039/331] Normalize absolute paths in default resolver --- src/utils/defaults.js | 2 +- test/form/absolute-path-resolver/_config.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils/defaults.js b/src/utils/defaults.js index 70c36fe..e275f69 100644 --- a/src/utils/defaults.js +++ b/src/utils/defaults.js @@ -19,7 +19,7 @@ export function resolveId ( importee, importer ) { if ( typeof process === 'undefined' ) throw new Error( `It looks like you're using Rollup in a non-Node.js environment. This means you must supply a plugin with custom resolveId and load functions. See https://github.com/rollup/rollup/wiki/Plugins for more information` ); // absolute paths are left untouched - if ( isAbsolute( importee ) ) return addJsExtensionIfNecessary( importee ); + if ( isAbsolute( importee ) ) return addJsExtensionIfNecessary( resolve( importee ) ); // if this is the entry point, resolve against cwd if ( importer === undefined ) return addJsExtensionIfNecessary( resolve( process.cwd(), importee ) ); diff --git a/test/form/absolute-path-resolver/_config.js b/test/form/absolute-path-resolver/_config.js index 9e88960..a2f129c 100644 --- a/test/form/absolute-path-resolver/_config.js +++ b/test/form/absolute-path-resolver/_config.js @@ -1,7 +1,6 @@ var path = require('path'); module.exports = { - solo: true, description: 'normalizes absolute ids', options: { plugins: [{ From b62aa070bf696405f79fe5da595bb26236e6b4d7 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 16:04:01 -0400 Subject: [PATCH 040/331] build/bundle CLI --- bin/handleError.js | 57 --- bin/rollup | 873 +++++++++++++++++++++++++++++++++++- bin/showHelp.js | 13 - bin/src/handleError.js | 61 +++ bin/{ => src}/help.md | 2 +- bin/src/index.js | 38 ++ bin/{ => src}/runRollup.js | 95 ++-- bin/src/sourceMappingUrl.js | 4 + package.json | 8 +- rollup.config.cli.js | 29 ++ rollup.config.js | 4 +- test/mocha.opts | 1 + 12 files changed, 1053 insertions(+), 132 deletions(-) delete mode 100644 bin/handleError.js delete mode 100644 bin/showHelp.js create mode 100644 bin/src/handleError.js rename bin/{ => src}/help.md (98%) create mode 100644 bin/src/index.js rename bin/{ => src}/runRollup.js (61%) create mode 100644 bin/src/sourceMappingUrl.js create mode 100644 rollup.config.cli.js create mode 100644 test/mocha.opts diff --git a/bin/handleError.js b/bin/handleError.js deleted file mode 100644 index 21a100d..0000000 --- a/bin/handleError.js +++ /dev/null @@ -1,57 +0,0 @@ -var chalk = require( 'chalk' ); - -var handlers = { - MISSING_CONFIG: function () { - console.error( chalk.red( 'Config file must export an options object. See https://github.com/rollup/rollup/wiki/Command-Line-Interface#using-a-config-file' ) ); - }, - - MISSING_INPUT_OPTION: function () { - console.error( chalk.red( 'You must specify an --input (-i) option' ) ); - }, - - MISSING_OUTPUT_OPTION: function () { - console.error( chalk.red( 'You must specify an --output (-o) option when creating a file with a sourcemap' ) ); - }, - - MISSING_NAME: function ( err ) { - console.error( chalk.red( 'You must supply a name for UMD exports (e.g. `--name myModule`)' ) ); - }, - - PARSE_ERROR: function ( err ) { - console.error( chalk.red( 'Error parsing ' + err.file + ': ' + err.message ) ); - }, - - ONE_AT_A_TIME: function ( err ) { - console.error( chalk.red( 'rollup can only bundle one file at a time' ) ); - }, - - DUPLICATE_IMPORT_OPTIONS: function ( err ) { - console.error( chalk.red( 'use --input, or pass input path as argument' ) ); - }, - - ROLLUP_WATCH_NOT_INSTALLED: function ( err ) { - console.error( chalk.red( 'rollup --watch depends on the rollup-watch package, which could not be found. You can install it globally (recommended) with ' ) + chalk.cyan( 'npm install -g rollup-watch' ) ); - }, - - WATCHER_MISSING_INPUT_OR_OUTPUT: function ( err ) { - console.error( chalk.red( 'must specify --input and --output when using rollup --watch' ) ); - } -}; - -module.exports = function handleError ( err ) { - var handler; - - if ( handler = handlers[ err && err.code ] ) { - handler( err ); - } else { - console.error( chalk.red( err.message || err ) ); - - if ( err.stack ) { - console.error( chalk.grey( err.stack ) ); - } - } - - console.error( 'Type ' + chalk.cyan( 'rollup --help' ) + ' for help, or visit https://github.com/rollup/rollup/wiki' ); - - process.exit( 1 ); -}; diff --git a/bin/rollup b/bin/rollup index 123f388..2e1b2a6 100755 --- a/bin/rollup +++ b/bin/rollup @@ -1,9 +1,868 @@ #!/usr/bin/env node +'use strict'; -var minimist = require( 'minimist' ), - command; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -command = minimist( process.argv.slice( 2 ), { +var require$$1 = require('path'); +var require$$1__default = _interopDefault(require$$1); +var require$$0 = _interopDefault(require('module')); +var sourceMapSupport = require('source-map-support'); + +function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; +} + +var index = createCommonjsModule(function (module) { +module.exports = function (args, opts) { + if (!opts) opts = {}; + + var flags = { bools : {}, strings : {}, unknownFn: null }; + + if (typeof opts['unknown'] === 'function') { + flags.unknownFn = opts['unknown']; + } + + if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { + flags.allBools = true; + } else { + [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { + flags.bools[key] = true; + }); + } + + var aliases = {}; + Object.keys(opts.alias || {}).forEach(function (key) { + aliases[key] = [].concat(opts.alias[key]); + aliases[key].forEach(function (x) { + aliases[x] = [key].concat(aliases[key].filter(function (y) { + return x !== y; + })); + }); + }); + + [].concat(opts.string).filter(Boolean).forEach(function (key) { + flags.strings[key] = true; + if (aliases[key]) { + flags.strings[aliases[key]] = true; + } + }); + + var defaults = opts['default'] || {}; + + var argv = { _ : [] }; + Object.keys(flags.bools).forEach(function (key) { + setArg(key, defaults[key] === undefined ? false : defaults[key]); + }); + + var notFlags = []; + + if (args.indexOf('--') !== -1) { + notFlags = args.slice(args.indexOf('--')+1); + args = args.slice(0, args.indexOf('--')); + } + + function argDefined(key, arg) { + return (flags.allBools && /^--[^=]+$/.test(arg)) || + flags.strings[key] || flags.bools[key] || aliases[key]; + } + + function setArg (key, val, arg) { + if (arg && flags.unknownFn && !argDefined(key, arg)) { + if (flags.unknownFn(arg) === false) return; + } + + var value = !flags.strings[key] && isNumber(val) + ? Number(val) : val + ; + setKey(argv, key.split('.'), value); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), value); + }); + } + + function setKey (obj, keys, value) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + if (o[key] === undefined) o[key] = {}; + o = o[key]; + }); + + var key = keys[keys.length - 1]; + if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { + o[key] = value; + } + else if (Array.isArray(o[key])) { + o[key].push(value); + } + else { + o[key] = [ o[key], value ]; + } + } + + function aliasIsBoolean(key) { + return aliases[key].some(function (x) { + return flags.bools[x]; + }); + } + + for (var i = 0; i < args.length; i++) { + var arg = args[i]; + + if (/^--.+=/.test(arg)) { + // Using [\s\S] instead of . because js doesn't support the + // 'dotall' regex modifier. See: + // http://stackoverflow.com/a/1068308/13216 + var m = arg.match(/^--([^=]+)=([\s\S]*)$/); + var key = m[1]; + var value = m[2]; + if (flags.bools[key]) { + value = value !== 'false'; + } + setArg(key, value, arg); + } + else if (/^--no-.+/.test(arg)) { + var key = arg.match(/^--no-(.+)/)[1]; + setArg(key, false, arg); + } + else if (/^--.+/.test(arg)) { + var key = arg.match(/^--(.+)/)[1]; + var next = args[i + 1]; + if (next !== undefined && !/^-/.test(next) + && !flags.bools[key] + && !flags.allBools + && (aliases[key] ? !aliasIsBoolean(key) : true)) { + setArg(key, next, arg); + i++; + } + else if (/^(true|false)$/.test(next)) { + setArg(key, next === 'true', arg); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true, arg); + } + } + else if (/^-[^-]+/.test(arg)) { + var letters = arg.slice(1,-1).split(''); + + var broken = false; + for (var j = 0; j < letters.length; j++) { + var next = arg.slice(j+2); + + if (next === '-') { + setArg(letters[j], next, arg) + continue; + } + + if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { + setArg(letters[j], next.split('=')[1], arg); + broken = true; + break; + } + + if (/[A-Za-z]/.test(letters[j]) + && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { + setArg(letters[j], next, arg); + broken = true; + break; + } + + if (letters[j+1] && letters[j+1].match(/\W/)) { + setArg(letters[j], arg.slice(j+2), arg); + broken = true; + break; + } + else { + setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); + } + } + + var key = arg.slice(-1)[0]; + if (!broken && key !== '-') { + if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) + && !flags.bools[key] + && (aliases[key] ? !aliasIsBoolean(key) : true)) { + setArg(key, args[i+1], arg); + i++; + } + else if (args[i+1] && /true|false/.test(args[i+1])) { + setArg(key, args[i+1] === 'true', arg); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true, arg); + } + } + } + else { + if (!flags.unknownFn || flags.unknownFn(arg) !== false) { + argv._.push( + flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) + ); + } + if (opts.stopEarly) { + argv._.push.apply(argv._, args.slice(i + 1)); + break; + } + } + } + + Object.keys(defaults).forEach(function (key) { + if (!hasKey(argv, key.split('.'))) { + setKey(argv, key.split('.'), defaults[key]); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), defaults[key]); + }); + } + }); + + if (opts['--']) { + argv['--'] = new Array(); + notFlags.forEach(function(key) { + argv['--'].push(key); + }); + } + else { + notFlags.forEach(function(key) { + argv._.push(key); + }); + } + + return argv; +}; + +function hasKey (obj, keys) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + o = (o[key] || {}); + }); + + var key = keys[keys.length - 1]; + return key in o; +} + +function isNumber (x) { + if (typeof x === 'number') return true; + if (/^0x[0-9a-f]+$/i.test(x)) return true; + return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); +} +}); + +var minimist = (index && typeof index === 'object' && 'default' in index ? index['default'] : index); + +var help = "rollup version __VERSION__\n=====================================\n\nUsage: rollup [options] \n\nBasic options:\n\n-v, --version Show version number\n-h, --help Show this help message\n-c, --config Use this config file (if argument is used but value\n is unspecified, defaults to rollup.config.js)\n-w, --watch Watch files in bundle and rebuild on changes\n-i, --input Input (alternative to )\n-o, --output Output (if absent, prints to stdout)\n-f, --format [es6] Type of output (amd, cjs, es6, iife, umd)\n-e, --external Comma-separate list of module IDs to exclude\n-g, --globals Comma-separate list of `module ID:Global` pairs\n Any module IDs defined here are added to external\n-n, --name Name for UMD export\n-u, --id ID for AMD module (default is anonymous)\n-m, --sourcemap Generate sourcemap (`-m inline` for inline map)\n--no-strict Don't emit a `\"use strict\";` in the generated modules.\n--no-indent Don't indent result\n--environment Settings passed to config file (see example)\n--no-conflict Generate a noConflict method for UMD globals\n--intro Content to insert at top of bundle (inside wrapper)\n--outro Content to insert at end of bundle (inside wrapper)\n--banner Content to insert at top of bundle (outside wrapper)\n--footer Content to insert at end of bundle (outside wrapper)\n\nExamples:\n\n# use settings in config file\nrollup -c\n\n# in config file, process.env.INCLUDE_DEPS === 'true'\n# and process.env.BUILD === 'production'\nrollup -c --environment INCLUDE_DEPS,BUILD:production\n\n# create CommonJS bundle.js from src/main.js\nrollup --format=cjs --output=bundle.js -- src/main.js\n\n# create self-executing IIFE using `window.jQuery`\n# and `window._` as external globals\nrollup -f iife --globals jquery:jQuery,lodash:_ \\\n -i src/app.js -o build/app.js -m build/app.js.map\n\nNotes:\n\n* When piping to stdout, only inline sourcemaps are permitted\n\nFor more information visit https://github.com/rollup/rollup/wiki\n"; + +var version = "0.29.1"; + +var index$1 = createCommonjsModule(function (module) { +/* +relative require +*/'use strict'; + +var path = require$$1__default; +var Module = require$$0; + +var modules = {}; + +var getModule = function(dir) { + var rootPath = dir ? path.resolve(dir) : process.cwd(); + var rootName = path.join(rootPath, '@root'); + var root = modules[rootName]; + if (!root) { + root = new Module(rootName); + root.filename = rootName; + root.paths = Module._nodeModulePaths(rootPath); + modules[rootName] = root; + } + return root; +}; + +var requireRelative = function(requested, relativeTo) { + var root = getModule(relativeTo); + return root.require(requested); +}; + +requireRelative.resolve = function(requested, relativeTo) { + var root = getModule(relativeTo); + return Module._resolveFilename(requested, root); +}; + +module.exports = requireRelative; +}); + +var relative = (index$1 && typeof index$1 === 'object' && 'default' in index$1 ? index$1['default'] : index$1); + +var index$4 = createCommonjsModule(function (module) { +'use strict'; +var argv = process.argv; + +var terminator = argv.indexOf('--'); +var hasFlag = function (flag) { + flag = '--' + flag; + var pos = argv.indexOf(flag); + return pos !== -1 && (terminator !== -1 ? pos < terminator : true); +}; + +module.exports = (function () { + if ('FORCE_COLOR' in process.env) { + return true; + } + + if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + return false; + } + + if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + return true; + } + + if (process.stdout && !process.stdout.isTTY) { + return false; + } + + if (process.platform === 'win32') { + return true; + } + + if ('COLORTERM' in process.env) { + return true; + } + + if (process.env.TERM === 'dumb') { + return false; + } + + if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { + return true; + } + + return false; +})(); +}); + +var require$$0$1 = (index$4 && typeof index$4 === 'object' && 'default' in index$4 ? index$4['default'] : index$4); + +var index$6 = createCommonjsModule(function (module) { +'use strict'; +module.exports = function () { + return /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; +}; +}); + +var require$$0$2 = (index$6 && typeof index$6 === 'object' && 'default' in index$6 ? index$6['default'] : index$6); + +var index$5 = createCommonjsModule(function (module) { +'use strict'; +var ansiRegex = require$$0$2; +var re = new RegExp(ansiRegex().source); // remove the `g` flag +module.exports = re.test.bind(re); +}); + +var require$$1$1 = (index$5 && typeof index$5 === 'object' && 'default' in index$5 ? index$5['default'] : index$5); + +var index$7 = createCommonjsModule(function (module) { +'use strict'; +var ansiRegex = require$$0$2(); + +module.exports = function (str) { + return typeof str === 'string' ? str.replace(ansiRegex, '') : str; +}; +}); + +var require$$2 = (index$7 && typeof index$7 === 'object' && 'default' in index$7 ? index$7['default'] : index$7); + +var index$8 = createCommonjsModule(function (module) { +'use strict'; + +function assembleStyles () { + var styles = { + modifiers: { + reset: [0, 0], + bold: [1, 22], // 21 isn't widely supported and 22 does the same thing + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29] + }, + colors: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + gray: [90, 39] + }, + bgColors: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49] + } + }; + + // fix humans + styles.colors.grey = styles.colors.gray; + + Object.keys(styles).forEach(function (groupName) { + var group = styles[groupName]; + + Object.keys(group).forEach(function (styleName) { + var style = group[styleName]; + + styles[styleName] = group[styleName] = { + open: '\u001b[' + style[0] + 'm', + close: '\u001b[' + style[1] + 'm' + }; + }); + + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false + }); + }); + + return styles; +} + +Object.defineProperty(module, 'exports', { + enumerable: true, + get: assembleStyles +}); +}); + +var require$$3 = (index$8 && typeof index$8 === 'object' && 'default' in index$8 ? index$8['default'] : index$8); + +var index$9 = createCommonjsModule(function (module) { +'use strict'; + +var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; + +module.exports = function (str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + + return str.replace(matchOperatorsRe, '\\$&'); +}; +}); + +var require$$4 = (index$9 && typeof index$9 === 'object' && 'default' in index$9 ? index$9['default'] : index$9); + +var index$2 = createCommonjsModule(function (module) { +'use strict'; +var escapeStringRegexp = require$$4; +var ansiStyles = require$$3; +var stripAnsi = require$$2; +var hasAnsi = require$$1$1; +var supportsColor = require$$0$1; +var defineProps = Object.defineProperties; +var isSimpleWindowsTerm = process.platform === 'win32' && !/^xterm/i.test(process.env.TERM); + +function Chalk(options) { + // detect mode if not set manually + this.enabled = !options || options.enabled === undefined ? supportsColor : options.enabled; +} + +// use bright blue on Windows as the normal blue color is illegible +if (isSimpleWindowsTerm) { + ansiStyles.blue.open = '\u001b[94m'; +} + +var styles = (function () { + var ret = {}; + + Object.keys(ansiStyles).forEach(function (key) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); + + ret[key] = { + get: function () { + return build.call(this, this._styles.concat(key)); + } + }; + }); + + return ret; +})(); + +var proto = defineProps(function chalk() {}, styles); + +function build(_styles) { + var builder = function () { + return applyStyle.apply(builder, arguments); + }; + + builder._styles = _styles; + builder.enabled = this.enabled; + // __proto__ is used because we must return a function, but there is + // no way to create a function with a different prototype. + /* eslint-disable no-proto */ + builder.__proto__ = proto; + + return builder; +} + +function applyStyle() { + // support varags, but simply cast to string in case there's only one arg + var args = arguments; + var argsLen = args.length; + var str = argsLen !== 0 && String(arguments[0]); + + if (argsLen > 1) { + // don't slice `arguments`, it prevents v8 optimizations + for (var a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } + + if (!this.enabled || !str) { + return str; + } + + var nestedStyles = this._styles; + var i = nestedStyles.length; + + // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, + // see https://github.com/chalk/chalk/issues/58 + // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. + var originalDim = ansiStyles.dim.open; + if (isSimpleWindowsTerm && (nestedStyles.indexOf('gray') !== -1 || nestedStyles.indexOf('grey') !== -1)) { + ansiStyles.dim.open = ''; + } + + while (i--) { + var code = ansiStyles[nestedStyles[i]]; + + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + str = code.open + str.replace(code.closeRe, code.open) + code.close; + } + + // Reset the original 'dim' if we changed it to work around the Windows dimmed gray issue. + ansiStyles.dim.open = originalDim; + + return str; +} + +function init() { + var ret = {}; + + Object.keys(styles).forEach(function (name) { + ret[name] = { + get: function () { + return build.call(this, [name]); + } + }; + }); + + return ret; +} + +defineProps(Chalk.prototype, init()); + +module.exports = new Chalk(); +module.exports.styles = ansiStyles; +module.exports.hasColor = hasAnsi; +module.exports.stripColor = stripAnsi; +module.exports.supportsColor = supportsColor; +}); + +var red = index$2.red; +var cyan = index$2.cyan; +var grey = index$2.grey; + +function stderr$1 ( msg ) { + console.error( msg ); // eslint-disable-line no-console +} + +var handlers = { + MISSING_CONFIG: function () { + stderr$1( red( 'Config file must export an options object. See https://github.com/rollup/rollup/wiki/Command-Line-Interface#using-a-config-file' ) ); + }, + + MISSING_INPUT_OPTION: function () { + stderr$1( red( 'You must specify an --input (-i) option' ) ); + }, + + MISSING_OUTPUT_OPTION: function () { + stderr$1( red( 'You must specify an --output (-o) option when creating a file with a sourcemap' ) ); + }, + + MISSING_NAME: function () { + stderr$1( red( 'You must supply a name for UMD exports (e.g. `--name myModule`)' ) ); + }, + + PARSE_ERROR: function ( err ) { + stderr$1( red( ("Error parsing " + (err.file) + ": " + (err.message)) ) ); + }, + + ONE_AT_A_TIME: function () { + stderr$1( red( 'rollup can only bundle one file at a time' ) ); + }, + + DUPLICATE_IMPORT_OPTIONS: function () { + stderr$1( red( 'use --input, or pass input path as argument' ) ); + }, + + ROLLUP_WATCH_NOT_INSTALLED: function () { + stderr$1( red( 'rollup --watch depends on the rollup-watch package, which could not be found. You can install it globally (recommended) with ' ) + cyan( 'npm install -g rollup-watch' ) ); + }, + + WATCHER_MISSING_INPUT_OR_OUTPUT: function () { + stderr$1( red( 'must specify --input and --output when using rollup --watch' ) ); + } +}; + +function handleError ( err ) { + var handler = handlers[ err && err.code ]; + + if ( handler ) { + handler( err ); + } else { + stderr$1( red( err.message || err ) ); + + if ( err.stack ) { + stderr$1( grey( err.stack ) ); + } + } + + stderr$1( ("Type " + (cyan( 'rollup --help' )) + " for help, or visit https://github.com/rollup/rollup/wiki") ); + + process.exit( 1 ); +} + +var SOURCEMAPPING_URL = 'sourceMa'; +SOURCEMAPPING_URL += 'ppingURL'; + +var SOURCEMAPPING_URL$1 = SOURCEMAPPING_URL; + +var rollup = require( '../dist/rollup.js' ); sourceMapSupport.install(); + +// stderr to stderr to keep `rollup main.js > bundle.js` from breaking +var stderr = console.error.bind( console ); // eslint-disable-line no-console + +function runRollup ( command ) { + if ( command._.length > 1 ) { + handleError({ code: 'ONE_AT_A_TIME' }); + } + + if ( command._.length === 1 ) { + if ( command.input ) { + handleError({ code: 'DUPLICATE_IMPORT_OPTIONS' }); + } + + command.input = command._[0]; + } + + if ( command.environment ) { + command.environment.split( ',' ).forEach( function ( pair ) { + var index = pair.indexOf( ':' ); + if ( ~index ) { + process.env[ pair.slice( 0, index ) ] = pair.slice( index + 1 ); + } else { + process.env[ pair ] = true; + } + }); + } + + var config = command.config === true ? 'rollup.config.js' : command.config; + + if ( config ) { + config = require$$1.resolve( config ); + + rollup.rollup({ + entry: config, + onwarn: function ( message ) { + if ( /Treating .+ as external dependency/.test( message ) ) return; + stderr( message ); + } + }).then( function ( bundle ) { + var ref = bundle.generate({ + format: 'cjs' + }), code = ref.code; + + // temporarily override require + var defaultLoader = require.extensions[ '.js' ]; + require.extensions[ '.js' ] = function ( m, filename ) { + if ( filename === config ) { + m._compile( code, filename ); + } else { + defaultLoader( m, filename ); + } + }; + + try { + var options = require( require$$1.resolve( config ) ); + if ( Object.keys( options ).length === 0 ) { + handleError({ code: 'MISSING_CONFIG' }); + } + execute( options, command ); + require.extensions[ '.js' ] = defaultLoader; + } catch ( err ) { + handleError( err ); + } + }) + .catch( stderr ); + } else { + execute( {}, command ); + } +} + +var equivalents = { + banner: 'banner', + footer: 'footer', + format: 'format', + globals: 'globals', + id: 'moduleId', + indent: 'indent', + input: 'entry', + intro: 'intro', + name: 'moduleName', + output: 'dest', + outro: 'outro', + sourcemap: 'sourceMap', + treeshake: 'treeshake' +}; + +function execute ( options, command ) { + var external = ( options.external || [] ) + .concat( command.external ? command.external.split( ',' ) : [] ); + + if ( command.globals ) { + var globals = Object.create( null ); + + command.globals.split( ',' ).forEach( function ( str ) { + var names = str.split( ':' ); + globals[ names[0] ] = names[1]; + + // Add missing Module IDs to external. + if ( external.indexOf( names[0] ) === -1 ) { + external.push( names[0] ); + } + }); + + command.globals = globals; + } + + options.onwarn = options.onwarn || stderr; + + options.external = external; + + options.noConflict = command.conflict === false; + delete command.conflict; + + // Use any options passed through the CLI as overrides. + Object.keys( equivalents ).forEach( function ( cliOption ) { + if ( command.hasOwnProperty( cliOption ) ) { + options[ equivalents[ cliOption ] ] = command[ cliOption ]; + } + }); + + try { + if ( command.watch ) { + if ( !options.entry || ( !options.dest && !options.targets ) ) { + handleError({ code: 'WATCHER_MISSING_INPUT_OR_OUTPUT' }); + } + + try { + var watch = relative( 'rollup-watch', process.cwd() ); + var watcher = watch( rollup, options ); + + watcher.on( 'event', function ( event ) { + switch ( event.code ) { + case 'STARTING': + stderr( 'checking rollup-watch version...' ); + break; + + case 'BUILD_START': + stderr( 'bundling...' ); + break; + + case 'BUILD_END': + stderr( 'bundled in ' + event.duration + 'ms. Watching for changes...' ); + break; + + default: + stderr( 'unknown event', event ); + } + }); + } catch ( err ) { + if ( err.code === 'MODULE_NOT_FOUND' ) { + err.code = 'ROLLUP_WATCH_NOT_INSTALLED'; + } + + handleError( err ); + } + } else { + bundle( options ).catch( handleError ); + } + } catch ( err ) { + handleError( err ); + } +} + +function clone ( object ) { + return assign( {}, object ); +} + +function assign ( target, source ) { + Object.keys( source ).forEach( function ( key ) { + target[ key ] = source[ key ]; + }); + return target; +} + +function bundle ( options ) { + if ( !options.entry ) { + handleError({ code: 'MISSING_INPUT_OPTION' }); + } + + return rollup.rollup( options ).then( function ( bundle ) { + if ( options.dest ) { + return bundle.write( options ); + } + + if ( options.targets ) { + var result = null; + + options.targets.forEach( function ( target ) { + result = bundle.write( assign( clone( options ), target ) ); + }); + + return result; + } + + if ( options.sourceMap && options.sourceMap !== 'inline' ) { + handleError({ code: 'MISSING_OUTPUT_OPTION' }); + } + + var ref = bundle.generate( options ), code = ref.code, map = ref.map; + + if ( options.sourceMap === 'inline' ) { + code += "\n//# " + SOURCEMAPPING_URL$1 + "=" + (map.toUrl()); + } + + process.stdout.write( code ); + }); +} + +var command = minimist( process.argv.slice( 2 ), { alias: { // Aliases strict: 'useStrict', @@ -26,13 +885,13 @@ command = minimist( process.argv.slice( 2 ), { }); if ( command.help || ( process.argv.length <= 2 && process.stdin.isTTY ) ) { - require( './showHelp' )(); + console.log( ("\n" + (help.replace('__VERSION__', version)) + "\n") ); // eslint-disable-line no-console } else if ( command.version ) { - console.log( 'rollup version ' + require( '../package.json' ).version ); + console.log( ("rollup version " + version) ); // eslint-disable-line no-console } else { - require( './runRollup' )( command ); -} + runRollup( command ); +} \ No newline at end of file diff --git a/bin/showHelp.js b/bin/showHelp.js deleted file mode 100644 index 1cc19b6..0000000 --- a/bin/showHelp.js +++ /dev/null @@ -1,13 +0,0 @@ -var fs = require( 'fs' ); -var path = require( 'path' ); - -module.exports = function () { - fs.readFile( path.join( __dirname, 'help.md' ), function ( err, result ) { - var help; - - if ( err ) throw err; - - help = result.toString().replace( '<%= version %>', require( '../package.json' ).version ); - console.log( '\n' + help + '\n' ); - }); -}; diff --git a/bin/src/handleError.js b/bin/src/handleError.js new file mode 100644 index 0000000..ba17d0c --- /dev/null +++ b/bin/src/handleError.js @@ -0,0 +1,61 @@ +import * as chalk from 'chalk'; + +function stderr ( msg ) { + console.error( msg ); // eslint-disable-line no-console +} + +const handlers = { + MISSING_CONFIG: () => { + stderr( chalk.red( 'Config file must export an options object. See https://github.com/rollup/rollup/wiki/Command-Line-Interface#using-a-config-file' ) ); + }, + + MISSING_INPUT_OPTION: () => { + stderr( chalk.red( 'You must specify an --input (-i) option' ) ); + }, + + MISSING_OUTPUT_OPTION: () => { + stderr( chalk.red( 'You must specify an --output (-o) option when creating a file with a sourcemap' ) ); + }, + + MISSING_NAME: () => { + stderr( chalk.red( 'You must supply a name for UMD exports (e.g. `--name myModule`)' ) ); + }, + + PARSE_ERROR: err => { + stderr( chalk.red( `Error parsing ${err.file}: ${err.message}` ) ); + }, + + ONE_AT_A_TIME: () => { + stderr( chalk.red( 'rollup can only bundle one file at a time' ) ); + }, + + DUPLICATE_IMPORT_OPTIONS: () => { + stderr( chalk.red( 'use --input, or pass input path as argument' ) ); + }, + + ROLLUP_WATCH_NOT_INSTALLED: () => { + stderr( chalk.red( 'rollup --watch depends on the rollup-watch package, which could not be found. You can install it globally (recommended) with ' ) + chalk.cyan( 'npm install -g rollup-watch' ) ); + }, + + WATCHER_MISSING_INPUT_OR_OUTPUT: () => { + stderr( chalk.red( 'must specify --input and --output when using rollup --watch' ) ); + } +}; + +export default function handleError ( err ) { + const handler = handlers[ err && err.code ]; + + if ( handler ) { + handler( err ); + } else { + stderr( chalk.red( err.message || err ) ); + + if ( err.stack ) { + stderr( chalk.grey( err.stack ) ); + } + } + + stderr( `Type ${chalk.cyan( 'rollup --help' )} for help, or visit https://github.com/rollup/rollup/wiki` ); + + process.exit( 1 ); +} diff --git a/bin/help.md b/bin/src/help.md similarity index 98% rename from bin/help.md rename to bin/src/help.md index 7b02ed1..cf2ef8b 100644 --- a/bin/help.md +++ b/bin/src/help.md @@ -1,4 +1,4 @@ -rollup version <%= version %> +rollup version __VERSION__ ===================================== Usage: rollup [options] diff --git a/bin/src/index.js b/bin/src/index.js new file mode 100644 index 0000000..1b8f1e6 --- /dev/null +++ b/bin/src/index.js @@ -0,0 +1,38 @@ +import minimist from 'minimist'; +import help from './help.md'; +import { version } from '../../package.json'; +import runRollup from './runRollup'; + +const command = minimist( process.argv.slice( 2 ), { + alias: { + // Aliases + strict: 'useStrict', + + // Short options + c: 'config', + d: 'indent', + e: 'external', + f: 'format', + g: 'globals', + h: 'help', + i: 'input', + m: 'sourcemap', + n: 'name', + o: 'output', + u: 'id', + v: 'version', + w: 'watch' + } +}); + +if ( command.help || ( process.argv.length <= 2 && process.stdin.isTTY ) ) { + console.log( `\n${help.replace('__VERSION__', version)}\n` ); // eslint-disable-line no-console +} + +else if ( command.version ) { + console.log( `rollup version ${version}` ); // eslint-disable-line no-console +} + +else { + runRollup( command ); +} diff --git a/bin/runRollup.js b/bin/src/runRollup.js similarity index 61% rename from bin/runRollup.js rename to bin/src/runRollup.js index 2009ff4..aeff331 100644 --- a/bin/runRollup.js +++ b/bin/src/runRollup.js @@ -1,15 +1,17 @@ -require( 'source-map-support' ).install(); +import { resolve } from 'path'; +import relative from 'require-relative'; +import handleError from './handleError'; +import SOURCEMAPPING_URL from './sourceMappingURL.js'; -var path = require( 'path' ); -var relative = require( 'require-relative' ); -var handleError = require( './handleError' ); -var chalk = require( 'chalk' ); -var rollup = require( '../' ); +const rollup = require( '../dist/rollup.js' ); // TODO make this an import, somehow -// log to stderr to keep `rollup main.js > bundle.js` from breaking -var log = console.error.bind(console); +import { install as installSourcemapSupport } from 'source-map-support'; +installSourcemapSupport(); -module.exports = function ( command ) { +// stderr to stderr to keep `rollup main.js > bundle.js` from breaking +const stderr = console.error.bind( console ); // eslint-disable-line no-console + +export default function runRollup ( command ) { if ( command._.length > 1 ) { handleError({ code: 'ONE_AT_A_TIME' }); } @@ -23,8 +25,8 @@ module.exports = function ( command ) { } if ( command.environment ) { - command.environment.split( ',' ).forEach( function ( pair ) { - var index = pair.indexOf( ':' ); + command.environment.split( ',' ).forEach( pair => { + const index = pair.indexOf( ':' ); if ( ~index ) { process.env[ pair.slice( 0, index ) ] = pair.slice( index + 1 ); } else { @@ -33,25 +35,25 @@ module.exports = function ( command ) { }); } - var config = command.config === true ? 'rollup.config.js' : command.config; + let config = command.config === true ? 'rollup.config.js' : command.config; if ( config ) { - config = path.resolve( config ); + config = resolve( config ); rollup.rollup({ entry: config, - onwarn: function ( message ) { + onwarn: message => { if ( /Treating .+ as external dependency/.test( message ) ) return; - log( message ); + stderr( message ); } - }).then( function ( bundle ) { - var code = bundle.generate({ + }).then( bundle => { + const { code } = bundle.generate({ format: 'cjs' - }).code; + }); // temporarily override require var defaultLoader = require.extensions[ '.js' ]; - require.extensions[ '.js' ] = function ( m, filename ) { + require.extensions[ '.js' ] = ( m, filename ) => { if ( filename === config ) { m._compile( code, filename ); } else { @@ -60,25 +62,23 @@ module.exports = function ( command ) { }; try { - var options = require( path.resolve( config ) ); + const options = require( resolve( config ) ); if ( Object.keys( options ).length === 0 ) { handleError({ code: 'MISSING_CONFIG' }); } + execute( options, command ); + require.extensions[ '.js' ] = defaultLoader; } catch ( err ) { handleError( err ); } - - execute( options, command ); - - require.extensions[ '.js' ] = defaultLoader; }) - .catch(log); + .catch( stderr ); } else { execute( {}, command ); } -}; +} -var equivalents = { +const equivalents = { banner: 'banner', footer: 'footer', format: 'format', @@ -95,14 +95,14 @@ var equivalents = { }; function execute ( options, command ) { - var external = ( options.external || [] ) + let external = ( options.external || [] ) .concat( command.external ? command.external.split( ',' ) : [] ); if ( command.globals ) { - var globals = Object.create( null ); + let globals = Object.create( null ); - command.globals.split( ',' ).forEach(function ( str ) { - var names = str.split( ':' ); + command.globals.split( ',' ).forEach( str => { + const names = str.split( ':' ); globals[ names[0] ] = names[1]; // Add missing Module IDs to external. @@ -114,7 +114,7 @@ function execute ( options, command ) { command.globals = globals; } - options.onwarn = options.onwarn || log; + options.onwarn = options.onwarn || stderr; options.external = external; @@ -122,7 +122,7 @@ function execute ( options, command ) { delete command.conflict; // Use any options passed through the CLI as overrides. - Object.keys( equivalents ).forEach( function ( cliOption ) { + Object.keys( equivalents ).forEach( cliOption => { if ( command.hasOwnProperty( cliOption ) ) { options[ equivalents[ cliOption ] ] = command[ cliOption ]; } @@ -135,25 +135,25 @@ function execute ( options, command ) { } try { - var watch = relative( 'rollup-watch', process.cwd() ); - var watcher = watch( rollup, options ); + const watch = relative( 'rollup-watch', process.cwd() ); + const watcher = watch( rollup, options ); - watcher.on( 'event', function ( event ) { + watcher.on( 'event', event => { switch ( event.code ) { case 'STARTING': - console.error( 'checking rollup-watch version...' ); + stderr( 'checking rollup-watch version...' ); break; case 'BUILD_START': - console.error( 'bundling...' ); + stderr( 'bundling...' ); break; case 'BUILD_END': - console.error( 'bundled in ' + event.duration + 'ms. Watching for changes...' ); + stderr( 'bundled in ' + event.duration + 'ms. Watching for changes...' ); break; default: - console.error( 'unknown event', event ); + stderr( 'unknown event', event ); } }); } catch ( err ) { @@ -176,7 +176,7 @@ function clone ( object ) { } function assign ( target, source ) { - Object.keys( source ).forEach( function ( key ) { + Object.keys( source ).forEach( key => { target[ key ] = source[ key ]; }); return target; @@ -187,15 +187,15 @@ function bundle ( options ) { handleError({ code: 'MISSING_INPUT_OPTION' }); } - return rollup.rollup( options ).then( function ( bundle ) { + return rollup.rollup( options ).then( bundle => { if ( options.dest ) { return bundle.write( options ); } if ( options.targets ) { - var result = null; + let result = null; - options.targets.forEach( function ( target ) { + options.targets.forEach( target => { result = bundle.write( assign( clone( options ), target ) ); }); @@ -206,13 +206,10 @@ function bundle ( options ) { handleError({ code: 'MISSING_OUTPUT_OPTION' }); } - var result = bundle.generate( options ); - - var code = result.code, - map = result.map; + let { code, map } = bundle.generate( options ); if ( options.sourceMap === 'inline' ) { - code += '\n//# sourceMappingURL=' + map.toUrl(); + code += `\n//# ${SOURCEMAPPING_URL}=${map.toUrl()}`; } process.stdout.write( code ); diff --git a/bin/src/sourceMappingUrl.js b/bin/src/sourceMappingUrl.js new file mode 100644 index 0000000..e7c4265 --- /dev/null +++ b/bin/src/sourceMappingUrl.js @@ -0,0 +1,4 @@ +let SOURCEMAPPING_URL = 'sourceMa'; +SOURCEMAPPING_URL += 'ppingURL'; + +export default SOURCEMAPPING_URL; diff --git a/package.json b/package.json index 67b23b4..6e2f61d 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,14 @@ "rollup": "./bin/rollup" }, "scripts": { - "pretest": "npm run build", - "test": "mocha --compilers js:buble/register", + "pretest": "npm run build && npm run build:cli", + "test": "mocha", "pretest-coverage": "npm run build", "test-coverage": "rm -rf coverage/* && istanbul cover --report json node_modules/.bin/_mocha -- -u exports -R spec test/test.js", "posttest-coverage": "remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.json -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.lcov -t lcovonly -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped -t html -b dist", "ci": "npm run test-coverage && codecov < coverage/coverage-remapped.lcov", "build": "git rev-parse HEAD > .commithash && rollup -c -o dist/rollup.js", + "build:cli": "rollup -c rollup.config.cli.js", "build:browser": "git rev-parse HEAD > .commithash && rollup -c rollup.config.browser.js -o dist/rollup.browser.js", "prepublish": "npm run lint && npm test && npm run build:browser", "lint": "eslint src browser" @@ -51,8 +52,9 @@ "magic-string": "^0.15.1", "mocha": "^2.3.3", "remap-istanbul": "^0.5.1", - "rollup": "^0.26.2", + "rollup": "^0.29.1", "rollup-plugin-buble": "^0.6.0", + "rollup-plugin-commonjs": "^3.0.0", "rollup-plugin-node-resolve": "^1.5.0", "rollup-plugin-replace": "^1.0.1", "sander": "^0.5.0", diff --git a/rollup.config.cli.js b/rollup.config.cli.js new file mode 100644 index 0000000..4ae9f11 --- /dev/null +++ b/rollup.config.cli.js @@ -0,0 +1,29 @@ +import buble from 'rollup-plugin-buble'; +import json from 'rollup-plugin-json'; +import string from 'rollup-plugin-string'; +import nodeResolve from 'rollup-plugin-node-resolve'; +import commonjs from 'rollup-plugin-commonjs'; + +export default { + entry: 'bin/src/index.js', + dest: 'bin/rollup', + format: 'cjs', + banner: '#!/usr/bin/env node', + plugins: [ + string({ extensions: [ '.md' ] }), + json(), + buble(), + commonjs({ + include: 'node_modules/**', + namedExports: { 'chalk': [ 'red', 'cyan', 'grey' ] } + }), + nodeResolve({ + main: true + }) + ], + external: [ + 'path', + 'fs', + 'source-map-support' + ] +}; diff --git a/rollup.config.js b/rollup.config.js index 521d614..e7996f4 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,6 +1,6 @@ import { readFileSync } from 'fs'; import buble from 'rollup-plugin-buble'; -import npm from 'rollup-plugin-node-resolve'; +import nodeResolve from 'rollup-plugin-node-resolve'; import replace from 'rollup-plugin-replace'; var pkg = JSON.parse( readFileSync( 'package.json', 'utf-8' ) ); @@ -26,7 +26,7 @@ export default { include: [ 'src/**', 'node_modules/acorn/**' ] }), - npm({ + nodeResolve({ jsnext: true }), diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 0000000..078771e --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1 @@ +--compilers js:buble/register From c0d45930581f4999b2d0bbf7107e3d508ade5825 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 16:06:45 -0400 Subject: [PATCH 041/331] move bundled CLI dependencies to devDependencies --- package.json | 6 +++--- rollup.config.cli.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 6e2f61d..33a2609 100644 --- a/package.json +++ b/package.json @@ -44,14 +44,17 @@ "acorn": "^3.1.0", "babel-core": "^5.8.32", "buble": "^0.6.4", + "chalk": "^1.1.1", "codecov.io": "^0.1.6", "console-group": "^0.2.0", "eslint": "^2.9.0", "estree-walker": "^0.2.0", "istanbul": "^0.4.0", "magic-string": "^0.15.1", + "minimist": "^1.2.0", "mocha": "^2.3.3", "remap-istanbul": "^0.5.1", + "require-relative": "^0.8.7", "rollup": "^0.29.1", "rollup-plugin-buble": "^0.6.0", "rollup-plugin-commonjs": "^3.0.0", @@ -63,9 +66,6 @@ "uglify-js": "^2.6.1" }, "dependencies": { - "chalk": "^1.1.1", - "minimist": "^1.2.0", - "require-relative": "^0.8.7", "source-map-support": "^0.4.0" }, "files": [ diff --git a/rollup.config.cli.js b/rollup.config.cli.js index 4ae9f11..cd8def2 100644 --- a/rollup.config.cli.js +++ b/rollup.config.cli.js @@ -23,7 +23,7 @@ export default { ], external: [ 'path', - 'fs', + 'module', 'source-map-support' ] }; From 1f97f4e4e228b22f962f2ad04220273673bbbcf5 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 16:10:30 -0400 Subject: [PATCH 042/331] only include dist files in npm package --- .gitignore | 1 + package.json | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 55804cb..c461514 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ _actual coverage .commithash .idea +bin/rollup diff --git a/package.json b/package.json index 33a2609..0d407ae 100644 --- a/package.json +++ b/package.json @@ -69,9 +69,8 @@ "source-map-support": "^0.4.0" }, "files": [ - "src", "dist", - "bin", + "bin/rollup", "README.md" ] } From 17886820295021a3041e68615630f7dfd48445e0 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 16:28:50 -0400 Subject: [PATCH 043/331] untrack bin/rollup --- bin/rollup | 897 ----------------------------------------------------- 1 file changed, 897 deletions(-) delete mode 100755 bin/rollup diff --git a/bin/rollup b/bin/rollup deleted file mode 100755 index 2e1b2a6..0000000 --- a/bin/rollup +++ /dev/null @@ -1,897 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var require$$1 = require('path'); -var require$$1__default = _interopDefault(require$$1); -var require$$0 = _interopDefault(require('module')); -var sourceMapSupport = require('source-map-support'); - -function createCommonjsModule(fn, module) { - return module = { exports: {} }, fn(module, module.exports), module.exports; -} - -var index = createCommonjsModule(function (module) { -module.exports = function (args, opts) { - if (!opts) opts = {}; - - var flags = { bools : {}, strings : {}, unknownFn: null }; - - if (typeof opts['unknown'] === 'function') { - flags.unknownFn = opts['unknown']; - } - - if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { - flags.allBools = true; - } else { - [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { - flags.bools[key] = true; - }); - } - - var aliases = {}; - Object.keys(opts.alias || {}).forEach(function (key) { - aliases[key] = [].concat(opts.alias[key]); - aliases[key].forEach(function (x) { - aliases[x] = [key].concat(aliases[key].filter(function (y) { - return x !== y; - })); - }); - }); - - [].concat(opts.string).filter(Boolean).forEach(function (key) { - flags.strings[key] = true; - if (aliases[key]) { - flags.strings[aliases[key]] = true; - } - }); - - var defaults = opts['default'] || {}; - - var argv = { _ : [] }; - Object.keys(flags.bools).forEach(function (key) { - setArg(key, defaults[key] === undefined ? false : defaults[key]); - }); - - var notFlags = []; - - if (args.indexOf('--') !== -1) { - notFlags = args.slice(args.indexOf('--')+1); - args = args.slice(0, args.indexOf('--')); - } - - function argDefined(key, arg) { - return (flags.allBools && /^--[^=]+$/.test(arg)) || - flags.strings[key] || flags.bools[key] || aliases[key]; - } - - function setArg (key, val, arg) { - if (arg && flags.unknownFn && !argDefined(key, arg)) { - if (flags.unknownFn(arg) === false) return; - } - - var value = !flags.strings[key] && isNumber(val) - ? Number(val) : val - ; - setKey(argv, key.split('.'), value); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), value); - }); - } - - function setKey (obj, keys, value) { - var o = obj; - keys.slice(0,-1).forEach(function (key) { - if (o[key] === undefined) o[key] = {}; - o = o[key]; - }); - - var key = keys[keys.length - 1]; - if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { - o[key] = value; - } - else if (Array.isArray(o[key])) { - o[key].push(value); - } - else { - o[key] = [ o[key], value ]; - } - } - - function aliasIsBoolean(key) { - return aliases[key].some(function (x) { - return flags.bools[x]; - }); - } - - for (var i = 0; i < args.length; i++) { - var arg = args[i]; - - if (/^--.+=/.test(arg)) { - // Using [\s\S] instead of . because js doesn't support the - // 'dotall' regex modifier. See: - // http://stackoverflow.com/a/1068308/13216 - var m = arg.match(/^--([^=]+)=([\s\S]*)$/); - var key = m[1]; - var value = m[2]; - if (flags.bools[key]) { - value = value !== 'false'; - } - setArg(key, value, arg); - } - else if (/^--no-.+/.test(arg)) { - var key = arg.match(/^--no-(.+)/)[1]; - setArg(key, false, arg); - } - else if (/^--.+/.test(arg)) { - var key = arg.match(/^--(.+)/)[1]; - var next = args[i + 1]; - if (next !== undefined && !/^-/.test(next) - && !flags.bools[key] - && !flags.allBools - && (aliases[key] ? !aliasIsBoolean(key) : true)) { - setArg(key, next, arg); - i++; - } - else if (/^(true|false)$/.test(next)) { - setArg(key, next === 'true', arg); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true, arg); - } - } - else if (/^-[^-]+/.test(arg)) { - var letters = arg.slice(1,-1).split(''); - - var broken = false; - for (var j = 0; j < letters.length; j++) { - var next = arg.slice(j+2); - - if (next === '-') { - setArg(letters[j], next, arg) - continue; - } - - if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { - setArg(letters[j], next.split('=')[1], arg); - broken = true; - break; - } - - if (/[A-Za-z]/.test(letters[j]) - && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { - setArg(letters[j], next, arg); - broken = true; - break; - } - - if (letters[j+1] && letters[j+1].match(/\W/)) { - setArg(letters[j], arg.slice(j+2), arg); - broken = true; - break; - } - else { - setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); - } - } - - var key = arg.slice(-1)[0]; - if (!broken && key !== '-') { - if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) - && !flags.bools[key] - && (aliases[key] ? !aliasIsBoolean(key) : true)) { - setArg(key, args[i+1], arg); - i++; - } - else if (args[i+1] && /true|false/.test(args[i+1])) { - setArg(key, args[i+1] === 'true', arg); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true, arg); - } - } - } - else { - if (!flags.unknownFn || flags.unknownFn(arg) !== false) { - argv._.push( - flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) - ); - } - if (opts.stopEarly) { - argv._.push.apply(argv._, args.slice(i + 1)); - break; - } - } - } - - Object.keys(defaults).forEach(function (key) { - if (!hasKey(argv, key.split('.'))) { - setKey(argv, key.split('.'), defaults[key]); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), defaults[key]); - }); - } - }); - - if (opts['--']) { - argv['--'] = new Array(); - notFlags.forEach(function(key) { - argv['--'].push(key); - }); - } - else { - notFlags.forEach(function(key) { - argv._.push(key); - }); - } - - return argv; -}; - -function hasKey (obj, keys) { - var o = obj; - keys.slice(0,-1).forEach(function (key) { - o = (o[key] || {}); - }); - - var key = keys[keys.length - 1]; - return key in o; -} - -function isNumber (x) { - if (typeof x === 'number') return true; - if (/^0x[0-9a-f]+$/i.test(x)) return true; - return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); -} -}); - -var minimist = (index && typeof index === 'object' && 'default' in index ? index['default'] : index); - -var help = "rollup version __VERSION__\n=====================================\n\nUsage: rollup [options] \n\nBasic options:\n\n-v, --version Show version number\n-h, --help Show this help message\n-c, --config Use this config file (if argument is used but value\n is unspecified, defaults to rollup.config.js)\n-w, --watch Watch files in bundle and rebuild on changes\n-i, --input Input (alternative to )\n-o, --output Output (if absent, prints to stdout)\n-f, --format [es6] Type of output (amd, cjs, es6, iife, umd)\n-e, --external Comma-separate list of module IDs to exclude\n-g, --globals Comma-separate list of `module ID:Global` pairs\n Any module IDs defined here are added to external\n-n, --name Name for UMD export\n-u, --id ID for AMD module (default is anonymous)\n-m, --sourcemap Generate sourcemap (`-m inline` for inline map)\n--no-strict Don't emit a `\"use strict\";` in the generated modules.\n--no-indent Don't indent result\n--environment Settings passed to config file (see example)\n--no-conflict Generate a noConflict method for UMD globals\n--intro Content to insert at top of bundle (inside wrapper)\n--outro Content to insert at end of bundle (inside wrapper)\n--banner Content to insert at top of bundle (outside wrapper)\n--footer Content to insert at end of bundle (outside wrapper)\n\nExamples:\n\n# use settings in config file\nrollup -c\n\n# in config file, process.env.INCLUDE_DEPS === 'true'\n# and process.env.BUILD === 'production'\nrollup -c --environment INCLUDE_DEPS,BUILD:production\n\n# create CommonJS bundle.js from src/main.js\nrollup --format=cjs --output=bundle.js -- src/main.js\n\n# create self-executing IIFE using `window.jQuery`\n# and `window._` as external globals\nrollup -f iife --globals jquery:jQuery,lodash:_ \\\n -i src/app.js -o build/app.js -m build/app.js.map\n\nNotes:\n\n* When piping to stdout, only inline sourcemaps are permitted\n\nFor more information visit https://github.com/rollup/rollup/wiki\n"; - -var version = "0.29.1"; - -var index$1 = createCommonjsModule(function (module) { -/* -relative require -*/'use strict'; - -var path = require$$1__default; -var Module = require$$0; - -var modules = {}; - -var getModule = function(dir) { - var rootPath = dir ? path.resolve(dir) : process.cwd(); - var rootName = path.join(rootPath, '@root'); - var root = modules[rootName]; - if (!root) { - root = new Module(rootName); - root.filename = rootName; - root.paths = Module._nodeModulePaths(rootPath); - modules[rootName] = root; - } - return root; -}; - -var requireRelative = function(requested, relativeTo) { - var root = getModule(relativeTo); - return root.require(requested); -}; - -requireRelative.resolve = function(requested, relativeTo) { - var root = getModule(relativeTo); - return Module._resolveFilename(requested, root); -}; - -module.exports = requireRelative; -}); - -var relative = (index$1 && typeof index$1 === 'object' && 'default' in index$1 ? index$1['default'] : index$1); - -var index$4 = createCommonjsModule(function (module) { -'use strict'; -var argv = process.argv; - -var terminator = argv.indexOf('--'); -var hasFlag = function (flag) { - flag = '--' + flag; - var pos = argv.indexOf(flag); - return pos !== -1 && (terminator !== -1 ? pos < terminator : true); -}; - -module.exports = (function () { - if ('FORCE_COLOR' in process.env) { - return true; - } - - if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - return false; - } - - if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - return true; - } - - if (process.stdout && !process.stdout.isTTY) { - return false; - } - - if (process.platform === 'win32') { - return true; - } - - if ('COLORTERM' in process.env) { - return true; - } - - if (process.env.TERM === 'dumb') { - return false; - } - - if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { - return true; - } - - return false; -})(); -}); - -var require$$0$1 = (index$4 && typeof index$4 === 'object' && 'default' in index$4 ? index$4['default'] : index$4); - -var index$6 = createCommonjsModule(function (module) { -'use strict'; -module.exports = function () { - return /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; -}; -}); - -var require$$0$2 = (index$6 && typeof index$6 === 'object' && 'default' in index$6 ? index$6['default'] : index$6); - -var index$5 = createCommonjsModule(function (module) { -'use strict'; -var ansiRegex = require$$0$2; -var re = new RegExp(ansiRegex().source); // remove the `g` flag -module.exports = re.test.bind(re); -}); - -var require$$1$1 = (index$5 && typeof index$5 === 'object' && 'default' in index$5 ? index$5['default'] : index$5); - -var index$7 = createCommonjsModule(function (module) { -'use strict'; -var ansiRegex = require$$0$2(); - -module.exports = function (str) { - return typeof str === 'string' ? str.replace(ansiRegex, '') : str; -}; -}); - -var require$$2 = (index$7 && typeof index$7 === 'object' && 'default' in index$7 ? index$7['default'] : index$7); - -var index$8 = createCommonjsModule(function (module) { -'use strict'; - -function assembleStyles () { - var styles = { - modifiers: { - reset: [0, 0], - bold: [1, 22], // 21 isn't widely supported and 22 does the same thing - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - colors: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - gray: [90, 39] - }, - bgColors: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49] - } - }; - - // fix humans - styles.colors.grey = styles.colors.gray; - - Object.keys(styles).forEach(function (groupName) { - var group = styles[groupName]; - - Object.keys(group).forEach(function (styleName) { - var style = group[styleName]; - - styles[styleName] = group[styleName] = { - open: '\u001b[' + style[0] + 'm', - close: '\u001b[' + style[1] + 'm' - }; - }); - - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - }); - - return styles; -} - -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); -}); - -var require$$3 = (index$8 && typeof index$8 === 'object' && 'default' in index$8 ? index$8['default'] : index$8); - -var index$9 = createCommonjsModule(function (module) { -'use strict'; - -var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; - -module.exports = function (str) { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); - } - - return str.replace(matchOperatorsRe, '\\$&'); -}; -}); - -var require$$4 = (index$9 && typeof index$9 === 'object' && 'default' in index$9 ? index$9['default'] : index$9); - -var index$2 = createCommonjsModule(function (module) { -'use strict'; -var escapeStringRegexp = require$$4; -var ansiStyles = require$$3; -var stripAnsi = require$$2; -var hasAnsi = require$$1$1; -var supportsColor = require$$0$1; -var defineProps = Object.defineProperties; -var isSimpleWindowsTerm = process.platform === 'win32' && !/^xterm/i.test(process.env.TERM); - -function Chalk(options) { - // detect mode if not set manually - this.enabled = !options || options.enabled === undefined ? supportsColor : options.enabled; -} - -// use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001b[94m'; -} - -var styles = (function () { - var ret = {}; - - Object.keys(ansiStyles).forEach(function (key) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - - ret[key] = { - get: function () { - return build.call(this, this._styles.concat(key)); - } - }; - }); - - return ret; -})(); - -var proto = defineProps(function chalk() {}, styles); - -function build(_styles) { - var builder = function () { - return applyStyle.apply(builder, arguments); - }; - - builder._styles = _styles; - builder.enabled = this.enabled; - // __proto__ is used because we must return a function, but there is - // no way to create a function with a different prototype. - /* eslint-disable no-proto */ - builder.__proto__ = proto; - - return builder; -} - -function applyStyle() { - // support varags, but simply cast to string in case there's only one arg - var args = arguments; - var argsLen = args.length; - var str = argsLen !== 0 && String(arguments[0]); - - if (argsLen > 1) { - // don't slice `arguments`, it prevents v8 optimizations - for (var a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } - - if (!this.enabled || !str) { - return str; - } - - var nestedStyles = this._styles; - var i = nestedStyles.length; - - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - var originalDim = ansiStyles.dim.open; - if (isSimpleWindowsTerm && (nestedStyles.indexOf('gray') !== -1 || nestedStyles.indexOf('grey') !== -1)) { - ansiStyles.dim.open = ''; - } - - while (i--) { - var code = ansiStyles[nestedStyles[i]]; - - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; - } - - // Reset the original 'dim' if we changed it to work around the Windows dimmed gray issue. - ansiStyles.dim.open = originalDim; - - return str; -} - -function init() { - var ret = {}; - - Object.keys(styles).forEach(function (name) { - ret[name] = { - get: function () { - return build.call(this, [name]); - } - }; - }); - - return ret; -} - -defineProps(Chalk.prototype, init()); - -module.exports = new Chalk(); -module.exports.styles = ansiStyles; -module.exports.hasColor = hasAnsi; -module.exports.stripColor = stripAnsi; -module.exports.supportsColor = supportsColor; -}); - -var red = index$2.red; -var cyan = index$2.cyan; -var grey = index$2.grey; - -function stderr$1 ( msg ) { - console.error( msg ); // eslint-disable-line no-console -} - -var handlers = { - MISSING_CONFIG: function () { - stderr$1( red( 'Config file must export an options object. See https://github.com/rollup/rollup/wiki/Command-Line-Interface#using-a-config-file' ) ); - }, - - MISSING_INPUT_OPTION: function () { - stderr$1( red( 'You must specify an --input (-i) option' ) ); - }, - - MISSING_OUTPUT_OPTION: function () { - stderr$1( red( 'You must specify an --output (-o) option when creating a file with a sourcemap' ) ); - }, - - MISSING_NAME: function () { - stderr$1( red( 'You must supply a name for UMD exports (e.g. `--name myModule`)' ) ); - }, - - PARSE_ERROR: function ( err ) { - stderr$1( red( ("Error parsing " + (err.file) + ": " + (err.message)) ) ); - }, - - ONE_AT_A_TIME: function () { - stderr$1( red( 'rollup can only bundle one file at a time' ) ); - }, - - DUPLICATE_IMPORT_OPTIONS: function () { - stderr$1( red( 'use --input, or pass input path as argument' ) ); - }, - - ROLLUP_WATCH_NOT_INSTALLED: function () { - stderr$1( red( 'rollup --watch depends on the rollup-watch package, which could not be found. You can install it globally (recommended) with ' ) + cyan( 'npm install -g rollup-watch' ) ); - }, - - WATCHER_MISSING_INPUT_OR_OUTPUT: function () { - stderr$1( red( 'must specify --input and --output when using rollup --watch' ) ); - } -}; - -function handleError ( err ) { - var handler = handlers[ err && err.code ]; - - if ( handler ) { - handler( err ); - } else { - stderr$1( red( err.message || err ) ); - - if ( err.stack ) { - stderr$1( grey( err.stack ) ); - } - } - - stderr$1( ("Type " + (cyan( 'rollup --help' )) + " for help, or visit https://github.com/rollup/rollup/wiki") ); - - process.exit( 1 ); -} - -var SOURCEMAPPING_URL = 'sourceMa'; -SOURCEMAPPING_URL += 'ppingURL'; - -var SOURCEMAPPING_URL$1 = SOURCEMAPPING_URL; - -var rollup = require( '../dist/rollup.js' ); sourceMapSupport.install(); - -// stderr to stderr to keep `rollup main.js > bundle.js` from breaking -var stderr = console.error.bind( console ); // eslint-disable-line no-console - -function runRollup ( command ) { - if ( command._.length > 1 ) { - handleError({ code: 'ONE_AT_A_TIME' }); - } - - if ( command._.length === 1 ) { - if ( command.input ) { - handleError({ code: 'DUPLICATE_IMPORT_OPTIONS' }); - } - - command.input = command._[0]; - } - - if ( command.environment ) { - command.environment.split( ',' ).forEach( function ( pair ) { - var index = pair.indexOf( ':' ); - if ( ~index ) { - process.env[ pair.slice( 0, index ) ] = pair.slice( index + 1 ); - } else { - process.env[ pair ] = true; - } - }); - } - - var config = command.config === true ? 'rollup.config.js' : command.config; - - if ( config ) { - config = require$$1.resolve( config ); - - rollup.rollup({ - entry: config, - onwarn: function ( message ) { - if ( /Treating .+ as external dependency/.test( message ) ) return; - stderr( message ); - } - }).then( function ( bundle ) { - var ref = bundle.generate({ - format: 'cjs' - }), code = ref.code; - - // temporarily override require - var defaultLoader = require.extensions[ '.js' ]; - require.extensions[ '.js' ] = function ( m, filename ) { - if ( filename === config ) { - m._compile( code, filename ); - } else { - defaultLoader( m, filename ); - } - }; - - try { - var options = require( require$$1.resolve( config ) ); - if ( Object.keys( options ).length === 0 ) { - handleError({ code: 'MISSING_CONFIG' }); - } - execute( options, command ); - require.extensions[ '.js' ] = defaultLoader; - } catch ( err ) { - handleError( err ); - } - }) - .catch( stderr ); - } else { - execute( {}, command ); - } -} - -var equivalents = { - banner: 'banner', - footer: 'footer', - format: 'format', - globals: 'globals', - id: 'moduleId', - indent: 'indent', - input: 'entry', - intro: 'intro', - name: 'moduleName', - output: 'dest', - outro: 'outro', - sourcemap: 'sourceMap', - treeshake: 'treeshake' -}; - -function execute ( options, command ) { - var external = ( options.external || [] ) - .concat( command.external ? command.external.split( ',' ) : [] ); - - if ( command.globals ) { - var globals = Object.create( null ); - - command.globals.split( ',' ).forEach( function ( str ) { - var names = str.split( ':' ); - globals[ names[0] ] = names[1]; - - // Add missing Module IDs to external. - if ( external.indexOf( names[0] ) === -1 ) { - external.push( names[0] ); - } - }); - - command.globals = globals; - } - - options.onwarn = options.onwarn || stderr; - - options.external = external; - - options.noConflict = command.conflict === false; - delete command.conflict; - - // Use any options passed through the CLI as overrides. - Object.keys( equivalents ).forEach( function ( cliOption ) { - if ( command.hasOwnProperty( cliOption ) ) { - options[ equivalents[ cliOption ] ] = command[ cliOption ]; - } - }); - - try { - if ( command.watch ) { - if ( !options.entry || ( !options.dest && !options.targets ) ) { - handleError({ code: 'WATCHER_MISSING_INPUT_OR_OUTPUT' }); - } - - try { - var watch = relative( 'rollup-watch', process.cwd() ); - var watcher = watch( rollup, options ); - - watcher.on( 'event', function ( event ) { - switch ( event.code ) { - case 'STARTING': - stderr( 'checking rollup-watch version...' ); - break; - - case 'BUILD_START': - stderr( 'bundling...' ); - break; - - case 'BUILD_END': - stderr( 'bundled in ' + event.duration + 'ms. Watching for changes...' ); - break; - - default: - stderr( 'unknown event', event ); - } - }); - } catch ( err ) { - if ( err.code === 'MODULE_NOT_FOUND' ) { - err.code = 'ROLLUP_WATCH_NOT_INSTALLED'; - } - - handleError( err ); - } - } else { - bundle( options ).catch( handleError ); - } - } catch ( err ) { - handleError( err ); - } -} - -function clone ( object ) { - return assign( {}, object ); -} - -function assign ( target, source ) { - Object.keys( source ).forEach( function ( key ) { - target[ key ] = source[ key ]; - }); - return target; -} - -function bundle ( options ) { - if ( !options.entry ) { - handleError({ code: 'MISSING_INPUT_OPTION' }); - } - - return rollup.rollup( options ).then( function ( bundle ) { - if ( options.dest ) { - return bundle.write( options ); - } - - if ( options.targets ) { - var result = null; - - options.targets.forEach( function ( target ) { - result = bundle.write( assign( clone( options ), target ) ); - }); - - return result; - } - - if ( options.sourceMap && options.sourceMap !== 'inline' ) { - handleError({ code: 'MISSING_OUTPUT_OPTION' }); - } - - var ref = bundle.generate( options ), code = ref.code, map = ref.map; - - if ( options.sourceMap === 'inline' ) { - code += "\n//# " + SOURCEMAPPING_URL$1 + "=" + (map.toUrl()); - } - - process.stdout.write( code ); - }); -} - -var command = minimist( process.argv.slice( 2 ), { - alias: { - // Aliases - strict: 'useStrict', - - // Short options - c: 'config', - d: 'indent', - e: 'external', - f: 'format', - g: 'globals', - h: 'help', - i: 'input', - m: 'sourcemap', - n: 'name', - o: 'output', - u: 'id', - v: 'version', - w: 'watch' - } -}); - -if ( command.help || ( process.argv.length <= 2 && process.stdin.isTTY ) ) { - console.log( ("\n" + (help.replace('__VERSION__', version)) + "\n") ); // eslint-disable-line no-console -} - -else if ( command.version ) { - console.log( ("rollup version " + version) ); // eslint-disable-line no-console -} - -else { - runRollup( command ); -} \ No newline at end of file From f7a4a57f806635ec38ecb9c6216dd935e559c70b Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 16:28:56 -0400 Subject: [PATCH 044/331] install deps --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index 0d407ae..c429786 100644 --- a/package.json +++ b/package.json @@ -58,8 +58,10 @@ "rollup": "^0.29.1", "rollup-plugin-buble": "^0.6.0", "rollup-plugin-commonjs": "^3.0.0", + "rollup-plugin-json": "^2.0.0", "rollup-plugin-node-resolve": "^1.5.0", "rollup-plugin-replace": "^1.0.1", + "rollup-plugin-string": "^1.0.1", "sander": "^0.5.0", "source-map": "^0.5.3", "sourcemap-codec": "^1.2.1", From b848413de9859007f22196231cf311969c54e6c7 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 16:45:48 -0400 Subject: [PATCH 045/331] doh --- bin/src/runRollup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index aeff331..c724b55 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -1,7 +1,7 @@ import { resolve } from 'path'; import relative from 'require-relative'; import handleError from './handleError'; -import SOURCEMAPPING_URL from './sourceMappingURL.js'; +import SOURCEMAPPING_URL from './sourceMappingUrl.js'; const rollup = require( '../dist/rollup.js' ); // TODO make this an import, somehow From fb1004524e7c3bff2dc3db83e945000508ef8e89 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 16:59:09 -0400 Subject: [PATCH 046/331] -> v0.30.0 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64427d8..18d7c47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # rollup changelog +## 0.30.0 + +* Bundle CLI ([#700](https://github.com/rollup/rollup/issues/701) +* Ensure absolute paths are normalised ([#704](https://github.com/rollup/rollup/issues/704)) +* Allow `rollup --watch` to work with targets + ## 0.29.1 * Merge `target` options with main options ([#701](https://github.com/rollup/rollup/issues/701)) diff --git a/package.json b/package.json index c429786..81ae178 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.29.1", + "version": "0.30.0", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "src/rollup.js", From 51c3da9a6f969e074f40072c144126b493a9c61e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 17:16:02 -0400 Subject: [PATCH 047/331] rewrite top-level this as undefined --- src/Statement.js | 10 +++++--- test/form/this-is-undefined/_config.js | 3 +++ test/form/this-is-undefined/_expected/amd.js | 21 ++++++++++++++++ test/form/this-is-undefined/_expected/cjs.js | 19 ++++++++++++++ test/form/this-is-undefined/_expected/es6.js | 17 +++++++++++++ test/form/this-is-undefined/_expected/iife.js | 22 ++++++++++++++++ test/form/this-is-undefined/_expected/umd.js | 25 +++++++++++++++++++ .../this-is-undefined/main.js | 2 +- test/function/this-is-undefined/_config.js | 4 --- 9 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 test/form/this-is-undefined/_config.js create mode 100644 test/form/this-is-undefined/_expected/amd.js create mode 100644 test/form/this-is-undefined/_expected/cjs.js create mode 100644 test/form/this-is-undefined/_expected/es6.js create mode 100644 test/form/this-is-undefined/_expected/iife.js create mode 100644 test/form/this-is-undefined/_expected/umd.js rename test/{function => form}/this-is-undefined/main.js (93%) delete mode 100644 test/function/this-is-undefined/_config.js diff --git a/src/Statement.js b/src/Statement.js index 3c00c36..8723ad5 100644 --- a/src/Statement.js +++ b/src/Statement.js @@ -41,7 +41,7 @@ export default class Statement { // find references const statement = this; let { module, references, scope, stringLiteralRanges } = this; - let readDepth = 0; + let contextDepth = 0; walk( this.node, { enter ( node, parent, prop ) { @@ -59,8 +59,12 @@ export default class Statement { stringLiteralRanges.push([ node.start + 1, node.end - 1 ]); } + if ( node.type === 'ThisExpression' && contextDepth === 0 ) { + module.magicString.overwrite( node.start, node.end, 'undefined' ); + } + if ( node._scope ) scope = node._scope; - if ( /Function/.test( node.type ) ) readDepth += 1; + if ( /^Function/.test( node.type ) ) contextDepth += 1; let isReassignment; @@ -121,7 +125,7 @@ export default class Statement { }, leave ( node ) { if ( node._scope ) scope = scope.parent; - if ( /Function/.test( node.type ) ) readDepth -= 1; + if ( /^Function/.test( node.type ) ) contextDepth -= 1; } }); } diff --git a/test/form/this-is-undefined/_config.js b/test/form/this-is-undefined/_config.js new file mode 100644 index 0000000..155461a --- /dev/null +++ b/test/form/this-is-undefined/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'top-level `this` expression is rewritten as `undefined`' +}; diff --git a/test/form/this-is-undefined/_expected/amd.js b/test/form/this-is-undefined/_expected/amd.js new file mode 100644 index 0000000..4452e03 --- /dev/null +++ b/test/form/this-is-undefined/_expected/amd.js @@ -0,0 +1,21 @@ +define(function () { 'use strict'; + + const fooContext = {}; + + function foo () { + // inside a function, `this` should be untouched... + assert.strictEqual( this, fooContext ); + } + + const bar = () => { + // ...unless it's an arrow function + assert.strictEqual( undefined, undefined ); + } + + foo.call( fooContext ); + bar.call( {} ); + + // outside a function, `this` is undefined + assert.strictEqual( undefined, undefined ); + +}); diff --git a/test/form/this-is-undefined/_expected/cjs.js b/test/form/this-is-undefined/_expected/cjs.js new file mode 100644 index 0000000..bfa1110 --- /dev/null +++ b/test/form/this-is-undefined/_expected/cjs.js @@ -0,0 +1,19 @@ +'use strict'; + +const fooContext = {}; + +function foo () { + // inside a function, `this` should be untouched... + assert.strictEqual( this, fooContext ); +} + +const bar = () => { + // ...unless it's an arrow function + assert.strictEqual( undefined, undefined ); +} + +foo.call( fooContext ); +bar.call( {} ); + +// outside a function, `this` is undefined +assert.strictEqual( undefined, undefined ); diff --git a/test/form/this-is-undefined/_expected/es6.js b/test/form/this-is-undefined/_expected/es6.js new file mode 100644 index 0000000..f5bd3ba --- /dev/null +++ b/test/form/this-is-undefined/_expected/es6.js @@ -0,0 +1,17 @@ +const fooContext = {}; + +function foo () { + // inside a function, `this` should be untouched... + assert.strictEqual( this, fooContext ); +} + +const bar = () => { + // ...unless it's an arrow function + assert.strictEqual( undefined, undefined ); +} + +foo.call( fooContext ); +bar.call( {} ); + +// outside a function, `this` is undefined +assert.strictEqual( undefined, undefined ); diff --git a/test/form/this-is-undefined/_expected/iife.js b/test/form/this-is-undefined/_expected/iife.js new file mode 100644 index 0000000..890862c --- /dev/null +++ b/test/form/this-is-undefined/_expected/iife.js @@ -0,0 +1,22 @@ +(function () { + 'use strict'; + + const fooContext = {}; + + function foo () { + // inside a function, `this` should be untouched... + assert.strictEqual( this, fooContext ); + } + + const bar = () => { + // ...unless it's an arrow function + assert.strictEqual( undefined, undefined ); + } + + foo.call( fooContext ); + bar.call( {} ); + + // outside a function, `this` is undefined + assert.strictEqual( undefined, undefined ); + +}()); diff --git a/test/form/this-is-undefined/_expected/umd.js b/test/form/this-is-undefined/_expected/umd.js new file mode 100644 index 0000000..34ce474 --- /dev/null +++ b/test/form/this-is-undefined/_expected/umd.js @@ -0,0 +1,25 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, function () { 'use strict'; + + const fooContext = {}; + + function foo () { + // inside a function, `this` should be untouched... + assert.strictEqual( this, fooContext ); + } + + const bar = () => { + // ...unless it's an arrow function + assert.strictEqual( undefined, undefined ); + } + + foo.call( fooContext ); + bar.call( {} ); + + // outside a function, `this` is undefined + assert.strictEqual( undefined, undefined ); + +})); diff --git a/test/function/this-is-undefined/main.js b/test/form/this-is-undefined/main.js similarity index 93% rename from test/function/this-is-undefined/main.js rename to test/form/this-is-undefined/main.js index 5c82fb4..4fcdf42 100644 --- a/test/function/this-is-undefined/main.js +++ b/test/form/this-is-undefined/main.js @@ -1,4 +1,4 @@ -const fooContext = {} +const fooContext = {}; function foo () { // inside a function, `this` should be untouched... diff --git a/test/function/this-is-undefined/_config.js b/test/function/this-is-undefined/_config.js deleted file mode 100644 index 750d99a..0000000 --- a/test/function/this-is-undefined/_config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - description: 'this at top level is undefined', - babel: true -}; From 1d11282d6e32e4b0e0f4e8d46bd866bf3f292948 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 9 Jun 2016 18:00:18 -0400 Subject: [PATCH 048/331] allow user-specified acorn options (#564) --- src/Bundle.js | 1 + src/Module.js | 6 +++--- src/rollup.js | 1 + src/utils/object.js | 10 ++++++++++ test/function/allow-reserved/_config.js | 9 +++++++++ test/function/allow-reserved/main.js | 2 ++ 6 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 test/function/allow-reserved/_config.js create mode 100644 test/function/allow-reserved/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 9fc7c01..3d4414a 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -82,6 +82,7 @@ export default class Bundle { [ 'module', 'exports', '_interopDefault' ].forEach( global => this.assumedGlobals[ global ] = true ); this.varOrConst = options.preferConst ? 'const' : 'var'; + this.acornOptions = options.acorn || {}; } build () { diff --git a/src/Module.js b/src/Module.js index 9786374..7bc89d3 100644 --- a/src/Module.js +++ b/src/Module.js @@ -2,7 +2,7 @@ import { parse } from 'acorn/src/index.js'; import MagicString from 'magic-string'; import { walk } from 'estree-walker'; import Statement from './Statement.js'; -import { blank, keys } from './utils/object.js'; +import { assign, blank, keys } from './utils/object.js'; import { basename, extname } from './utils/path.js'; import getLocation from './utils/getLocation.js'; import makeLegalIdentifier from './utils/makeLegalIdentifier.js'; @@ -305,12 +305,12 @@ export default class Module { // Try to extract a list of top-level statements/declarations. If // the parse fails, attach file info and abort try { - this.ast = parse( this.code, { + this.ast = parse( this.code, assign({ ecmaVersion: 6, sourceType: 'module', onComment: ( block, text, start, end ) => this.comments.push({ block, text, start, end }), preserveParens: true - }); + }, this.bundle.acornOptions )); } catch ( err ) { err.code = 'PARSE_ERROR'; err.file = this.id; // see above - not necessarily true, but true enough diff --git a/src/rollup.js b/src/rollup.js index 29a6fa1..714a170 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -8,6 +8,7 @@ import Bundle from './Bundle.js'; export const VERSION = '<@VERSION@>'; const ALLOWED_KEYS = [ + 'acorn', 'banner', 'cache', 'dest', diff --git a/src/utils/object.js b/src/utils/object.js index b4e1ff1..688b1ca 100644 --- a/src/utils/object.js +++ b/src/utils/object.js @@ -7,3 +7,13 @@ export function blank () { export function forOwn ( object, func ) { Object.keys( object ).forEach( key => func( object[ key ], key ) ); } + +export function assign ( target, ...sources ) { + sources.forEach( source => { + for ( let key in source ) { + if ( source.hasOwnProperty( key ) ) target[ key ] = source[ key ]; + } + }); + + return target; +} diff --git a/test/function/allow-reserved/_config.js b/test/function/allow-reserved/_config.js new file mode 100644 index 0000000..9fdc00e --- /dev/null +++ b/test/function/allow-reserved/_config.js @@ -0,0 +1,9 @@ +module.exports = { + solo: true, + description: 'allow reserved identifiers via custom acorn options', + options: { + acorn: { + allowReserved: true + } + } +}; diff --git a/test/function/allow-reserved/main.js b/test/function/allow-reserved/main.js new file mode 100644 index 0000000..547a9a5 --- /dev/null +++ b/test/function/allow-reserved/main.js @@ -0,0 +1,2 @@ +var x = function await () {} +assert.equal( x.name, 'await' ); From 4abf336af5270a3459598186d5bd1f826d86785e Mon Sep 17 00:00:00 2001 From: Oleg Orlov Date: Fri, 10 Jun 2016 14:08:27 +0400 Subject: [PATCH 049/331] Update CHANGELOG.md fix the issue link --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18d7c47..3e21528 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 0.30.0 -* Bundle CLI ([#700](https://github.com/rollup/rollup/issues/701) +* Bundle CLI ([#700](https://github.com/rollup/rollup/issues/700)) * Ensure absolute paths are normalised ([#704](https://github.com/rollup/rollup/issues/704)) * Allow `rollup --watch` to work with targets From 4434cf1f5b210d7ac9759b8d1190743107429961 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 10 Jun 2016 17:38:42 -0400 Subject: [PATCH 050/331] -> v0.31.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e21528..0f03ecc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.31.0 + +* Rewrite top-level `this` as `undefined` ([#707](https://github.com/rollup/rollup/pull/707)) +* Pass `options.acorn` to Acorn ([#564](https://github.com/rollup/rollup/issues/564)) + ## 0.30.0 * Bundle CLI ([#700](https://github.com/rollup/rollup/issues/700)) diff --git a/package.json b/package.json index 81ae178..a845ded 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.30.0", + "version": "0.31.0", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "src/rollup.js", From 89327d50b2e3b92cd5c614c8c041097bcdc0d534 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 10 Jun 2016 17:39:58 -0400 Subject: [PATCH 051/331] oops --- test/function/allow-reserved/_config.js | 1 - test/test.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/function/allow-reserved/_config.js b/test/function/allow-reserved/_config.js index 9fdc00e..63f2a11 100644 --- a/test/function/allow-reserved/_config.js +++ b/test/function/allow-reserved/_config.js @@ -1,5 +1,4 @@ module.exports = { - solo: true, description: 'allow reserved identifiers via custom acorn options', options: { acorn: { diff --git a/test/test.js b/test/test.js index 1df5666..639104e 100644 --- a/test/test.js +++ b/test/test.js @@ -76,7 +76,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( function () { throw new Error( 'Missing expected error' ); }, function ( err ) { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, targets, treeshake, useStrict' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, targets, treeshake, useStrict' ); }); }); }); From c6e360d22422f924b0c8e3fc97b6e89491032371 Mon Sep 17 00:00:00 2001 From: Permutator Date: Fri, 10 Jun 2016 21:29:10 -0700 Subject: [PATCH 052/331] const map = map? I think not. --- src/utils/transformBundle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/transformBundle.js b/src/utils/transformBundle.js index f82bfb6..56a4359 100644 --- a/src/utils/transformBundle.js +++ b/src/utils/transformBundle.js @@ -11,7 +11,7 @@ export default function transformBundle ( code, transformers, sourceMapChain ) { }; } - const map = typeof result.map === 'string' ? JSON.parse( result.map ) : map; + const map = typeof result.map === 'string' ? JSON.parse( result.map ) : result.map; sourceMapChain.push( map ); return result.code; From 958ff75dc5aeca46d97c251bda70dcc8dfcded5a Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 11 Jun 2016 17:34:47 +0300 Subject: [PATCH 053/331] Upgrade rollup-plugin-string --- package.json | 2 +- rollup.config.cli.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a845ded..6a9c5fe 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "rollup-plugin-json": "^2.0.0", "rollup-plugin-node-resolve": "^1.5.0", "rollup-plugin-replace": "^1.0.1", - "rollup-plugin-string": "^1.0.1", + "rollup-plugin-string": "^2.0.0", "sander": "^0.5.0", "source-map": "^0.5.3", "sourcemap-codec": "^1.2.1", diff --git a/rollup.config.cli.js b/rollup.config.cli.js index cd8def2..0e0eed6 100644 --- a/rollup.config.cli.js +++ b/rollup.config.cli.js @@ -10,7 +10,7 @@ export default { format: 'cjs', banner: '#!/usr/bin/env node', plugins: [ - string({ extensions: [ '.md' ] }), + string({ include: '**/*.md' }), json(), buble(), commonjs({ From a085bdc93a8e8d7bc4301a1b1fef27221deb00dd Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 11 Jun 2016 12:10:49 -0400 Subject: [PATCH 054/331] handle errors emitted by rollup-watch (#712) --- bin/src/handleError.js | 4 ++-- bin/src/runRollup.js | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bin/src/handleError.js b/bin/src/handleError.js index ba17d0c..243592c 100644 --- a/bin/src/handleError.js +++ b/bin/src/handleError.js @@ -42,7 +42,7 @@ const handlers = { } }; -export default function handleError ( err ) { +export default function handleError ( err, recover ) { const handler = handlers[ err && err.code ]; if ( handler ) { @@ -57,5 +57,5 @@ export default function handleError ( err ) { stderr( `Type ${chalk.cyan( 'rollup --help' )} for help, or visit https://github.com/rollup/rollup/wiki` ); - process.exit( 1 ); + if ( !recover ) process.exit( 1 ); } diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index c724b55..45c305e 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -152,6 +152,10 @@ function execute ( options, command ) { stderr( 'bundled in ' + event.duration + 'ms. Watching for changes...' ); break; + case 'ERROR': + handleError( event.error, true ); + break; + default: stderr( 'unknown event', event ); } From c93debcc2e84f1d259063306cdd999914a88f3c7 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 11 Jun 2016 12:29:46 -0400 Subject: [PATCH 055/331] -> v0.31.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f03ecc..e58b661 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.31.1 + +* Logging for errors emitted by `rollup-watch` ([#712](https://github.com/rollup/rollup/issues/712)) + ## 0.31.0 * Rewrite top-level `this` as `undefined` ([#707](https://github.com/rollup/rollup/pull/707)) diff --git a/package.json b/package.json index 6a9c5fe..20effd7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.31.0", + "version": "0.31.1", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "src/rollup.js", From 22f57c4571b938a9b7d89b4b130c2b61229f4e07 Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 11 Jun 2016 19:12:54 -0700 Subject: [PATCH 056/331] Made it possible for plugin loaders to provide sourcemaps --- src/Bundle.js | 24 +++++----- src/Module.js | 3 +- src/utils/collapseSourcemaps.js | 72 +++++++++++++++++++++++------- src/utils/transform.js | 4 +- test/sourcemaps/loaders/_config.js | 50 +++++++++++++++++++++ test/sourcemaps/loaders/foo.js | 3 ++ test/sourcemaps/loaders/main.js | 1 + 7 files changed, 128 insertions(+), 29 deletions(-) create mode 100644 test/sourcemaps/loaders/_config.js create mode 100644 test/sourcemaps/loaders/foo.js create mode 100644 test/sourcemaps/loaders/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 3d4414a..d0709fa 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -46,12 +46,11 @@ export default class Bundle { .concat( resolveId ) ); - this.load = first( - this.plugins - .map( plugin => plugin.load ) - .filter( Boolean ) - .concat( load ) - ); + const loaders = this.plugins + .map( plugin => plugin.load ) + .filter( Boolean ); + this.hasLoaders = loaders.length !== 0; + this.load = first( loaders.concat( load ) ); this.transformers = this.plugins .map( plugin => plugin.transform ) @@ -204,9 +203,9 @@ export default class Bundle { return transform( source, id, this.transformers ); }) .then( source => { - const { code, originalCode, ast, sourceMapChain } = source; + const { code, originalCode, originalSourceMap, ast, sourceMapChain } = source; - const module = new Module({ id, code, originalCode, ast, sourceMapChain, bundle: this }); + const module = new Module({ id, code, originalCode, originalSourceMap, ast, sourceMapChain, bundle: this }); this.modules.push( module ); this.moduleById.set( id, module ); @@ -337,10 +336,11 @@ export default class Bundle { let file = options.sourceMapFile || options.dest; if ( file ) file = resolve( typeof process !== 'undefined' ? process.cwd() : '', file ); - map = magicString.generateMap({ file, includeContent: true }); - - if ( this.transformers.length || this.bundleTransformers.length ) { - map = collapseSourcemaps( map, usedModules, bundleSourcemapChain ); + if ( this.hasLoaders || this.transformers.length || this.bundleTransformers.length ) { + map = magicString.generateMap( {} ); + map = collapseSourcemaps( file, map, usedModules, bundleSourcemapChain ); + } else { + map = magicString.generateMap({ file, includeContent: true }); } map.sources = map.sources.map( unixizePath ); diff --git a/src/Module.js b/src/Module.js index 7bc89d3..2cb9a61 100644 --- a/src/Module.js +++ b/src/Module.js @@ -17,9 +17,10 @@ import { emptyBlockStatement } from './ast/create.js'; import extractNames from './ast/extractNames.js'; export default class Module { - constructor ({ id, code, originalCode, ast, sourceMapChain, bundle }) { + constructor ({ id, code, originalCode, originalSourceMap, ast, sourceMapChain, bundle }) { this.code = code; this.originalCode = originalCode; + this.originalSourceMap = originalSourceMap; this.sourceMapChain = sourceMapChain; this.bundle = bundle; diff --git a/src/utils/collapseSourcemaps.js b/src/utils/collapseSourcemaps.js index ff86eaf..b2a6a97 100644 --- a/src/utils/collapseSourcemaps.js +++ b/src/utils/collapseSourcemaps.js @@ -1,13 +1,15 @@ import { encode, decode } from 'sourcemap-codec'; +import { dirname, relative, resolve } from './path.js'; class Source { - constructor ( index ) { + constructor ( filename, content ) { this.isOriginal = true; - this.index = index; + this.filename = filename; + this.content = content; } traceSegment ( line, column, name ) { - return { line, column, name, index: this.index }; + return { line, column, name, source: this }; } } @@ -21,7 +23,7 @@ class Link { } traceMappings () { - let names = []; + let sources = [], sourcesContent = [], names = []; const mappings = this.mappings.map( line => { let tracedLine = []; @@ -31,14 +33,28 @@ class Link { const traced = source.traceSegment( segment[2], segment[3], this.names[ segment[4] ] ); if ( traced ) { - let nameIndex = null; + let sourceIndex = null, nameIndex = null; segment = [ segment[0], - traced.index, + null, traced.line, traced.column ]; + // newer sources are more likely to be used, so search backwards. + sourceIndex = sources.lastIndexOf( traced.source.filename ); + if ( sourceIndex === -1 ) { + sourceIndex = sources.length; + sources.push( traced.source.filename ); + sourcesContent[ sourceIndex ] = traced.source.content; + } else if ( sourcesContent[ sourceIndex ] == null ) { + sourcesContent[ sourceIndex ] = traced.source.content; + } else if ( traced.source.content != null && sourcesContent[ sourceIndex ] !== traced.source.content ) { + throw new Error( `Multiple conflicting contents for sourcemap source ${source.filename}` ); + } + + segment[1] = sourceIndex; + if ( traced.name ) { nameIndex = names.indexOf( traced.name ); if ( nameIndex === -1 ) { @@ -56,7 +72,7 @@ class Link { return tracedLine; }); - return { names, mappings }; + return { sources, sourcesContent, names, mappings }; } traceSegment ( line, column, name ) { @@ -81,29 +97,55 @@ class Link { } } -export default function collapseSourcemaps ( map, modules, bundleSourcemapChain ) { - const sources = modules.map( ( module, i ) => { - let source = new Source( i ); +export default function collapseSourcemaps ( file, map, modules, bundleSourcemapChain ) { + const moduleSources = modules.map( module => { + let sourceMapChain = module.sourceMapChain; + + let source; + if ( module.originalSourceMap == null ) { + source = new Source( module.id, module.originalCode ); + } else { + const sources = module.originalSourceMap.sources; + if ( sources == null || ( sources.length <= 1 && sources[0] == null ) ) { + source = new Source( module.id, module.originalCode ); + sourceMapChain = [ module.originalSourceMap ].concat( sourceMapChain ); + } else { + // TODO indiscriminately treating IDs and sources as normal paths is probably bad. + const sourcesContent = module.originalSourceMap.sourcesContent || []; + const directory = dirname( module.id ) || '.'; + const sourceRoot = module.originalSourceMap.sourceRoot || '.'; + const baseSources = sources.map( (source, i) => { + return new Source( resolve( directory, sourceRoot, source ), sourcesContent[i] ); + }); + source = new Link( module.originalSourceMap, baseSources ); + } + } - module.sourceMapChain.forEach( map => { + sourceMapChain.forEach( map => { source = new Link( map, [ source ]); }); return source; }); - let source = new Link( map, sources ); + let source = new Link( map, moduleSources ); bundleSourcemapChain.forEach( map => { source = new Link( map, [ source ] ); }); - const { names, mappings } = source.traceMappings(); + let { sources, sourcesContent, names, mappings } = source.traceMappings(); + + if ( file ) { + const directory = dirname( file ); + sources = sources.map( source => relative( directory, source ) ); + } // we re-use the `map` object because it has convenient toString/toURL methods - map.sourcesContent = modules.map( module => module.originalCode ); - map.mappings = encode( mappings ); + map.sources = sources; + map.sourcesContent = sourcesContent; map.names = names; + map.mappings = encode( mappings ); return map; } diff --git a/src/utils/transform.js b/src/utils/transform.js index 62b47e2..285eea0 100644 --- a/src/utils/transform.js +++ b/src/utils/transform.js @@ -1,6 +1,8 @@ export default function transform ( source, id, transformers ) { let sourceMapChain = []; + const originalSourceMap = typeof source.map === 'string' ? JSON.parse( source.map ) : source.map; + let originalCode = source.code; let ast = source.ast; @@ -30,7 +32,7 @@ export default function transform ( source, id, transformers ) { }, Promise.resolve( source.code ) ) - .then( code => ({ code, originalCode, ast, sourceMapChain }) ) + .then( code => ({ code, originalCode, originalSourceMap, ast, sourceMapChain }) ) .catch( err => { err.id = id; err.message = `Error loading ${id}: ${err.message}`; diff --git a/test/sourcemaps/loaders/_config.js b/test/sourcemaps/loaders/_config.js new file mode 100644 index 0000000..ea8e90e --- /dev/null +++ b/test/sourcemaps/loaders/_config.js @@ -0,0 +1,50 @@ +var babel = require( 'babel-core' ); +var fs = require( 'fs' ); +var assert = require( 'assert' ); +var getLocation = require( '../../utils/getLocation' ); +var SourceMapConsumer = require( 'source-map' ).SourceMapConsumer; + +module.exports = { + description: 'preserves sourcemap chains when transforming', + options: { + plugins: [ + { + load: function ( id ) { + if ( id.endsWith( 'main.js' ) ) { + id = id.replace( /main.js$/, 'foo.js' ); + } else { + id = id.replace( /foo.js$/, 'main.js' ); + } + + var out = babel.transformFileSync( id, { + blacklist: [ 'es6.modules' ], + sourceMap: true + }); + + const sourceRoot = out.map.sources[0].slice( 0, out.map.sources[0].lastIndexOf( '/' ) ); + out.map.sources = out.map.sources.map( source => '../' + source.slice( sourceRoot.length + 1 ) ); + out.map.sourceRoot = 'fake'; + + return { code: out.code, map: out.map }; + } + } + ] + }, + test: function ( code, map ) { + var smc = new SourceMapConsumer( map ); + + var generatedLoc = getLocation( code, code.indexOf( '42' ) ); + var originalLoc = smc.originalPositionFor( generatedLoc ); + + assert.equal( originalLoc.source, '../main.js' ); + assert.equal( originalLoc.line, 1 ); + assert.equal( originalLoc.column, 25 ); + + generatedLoc = getLocation( code, code.indexOf( 'log' ) ); + originalLoc = smc.originalPositionFor( generatedLoc ); + + assert.equal( originalLoc.source, '../foo.js' ); + assert.equal( originalLoc.line, 3 ); + assert.equal( originalLoc.column, 8 ); + } +}; diff --git a/test/sourcemaps/loaders/foo.js b/test/sourcemaps/loaders/foo.js new file mode 100644 index 0000000..c0b4c17 --- /dev/null +++ b/test/sourcemaps/loaders/foo.js @@ -0,0 +1,3 @@ +import { foo } from './foo'; + +console.log( `the answer is ${foo()}` ); diff --git a/test/sourcemaps/loaders/main.js b/test/sourcemaps/loaders/main.js new file mode 100644 index 0000000..0cf01be --- /dev/null +++ b/test/sourcemaps/loaders/main.js @@ -0,0 +1 @@ +export const foo = () => 42; From 3f39f2aec4ea8c83abdd1942a768f8be8fb4fa40 Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 11 Jun 2016 19:19:32 -0700 Subject: [PATCH 057/331] Simplify sourcemaps loaders test --- test/sourcemaps/loaders/_config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/sourcemaps/loaders/_config.js b/test/sourcemaps/loaders/_config.js index ea8e90e..cf13906 100644 --- a/test/sourcemaps/loaders/_config.js +++ b/test/sourcemaps/loaders/_config.js @@ -21,8 +21,8 @@ module.exports = { sourceMap: true }); - const sourceRoot = out.map.sources[0].slice( 0, out.map.sources[0].lastIndexOf( '/' ) ); - out.map.sources = out.map.sources.map( source => '../' + source.slice( sourceRoot.length + 1 ) ); + const slash = out.map.sources[0].lastIndexOf( '/' ) + 1; + out.map.sources = out.map.sources.map( source => '../' + source.slice( slash ) ); out.map.sourceRoot = 'fake'; return { code: out.code, map: out.map }; From 4ebaeecb1514ed9f6f2926c0cf3c4ffc63e638eb Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 11 Jun 2016 19:24:37 -0700 Subject: [PATCH 058/331] Reduce blobbiness of collapseSourcemaps --- src/utils/collapseSourcemaps.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/utils/collapseSourcemaps.js b/src/utils/collapseSourcemaps.js index b2a6a97..763998f 100644 --- a/src/utils/collapseSourcemaps.js +++ b/src/utils/collapseSourcemaps.js @@ -106,17 +106,21 @@ export default function collapseSourcemaps ( file, map, modules, bundleSourcemap source = new Source( module.id, module.originalCode ); } else { const sources = module.originalSourceMap.sources; + if ( sources == null || ( sources.length <= 1 && sources[0] == null ) ) { source = new Source( module.id, module.originalCode ); sourceMapChain = [ module.originalSourceMap ].concat( sourceMapChain ); } else { - // TODO indiscriminately treating IDs and sources as normal paths is probably bad. const sourcesContent = module.originalSourceMap.sourcesContent || []; + + // TODO indiscriminately treating IDs and sources as normal paths is probably bad. const directory = dirname( module.id ) || '.'; const sourceRoot = module.originalSourceMap.sourceRoot || '.'; + const baseSources = sources.map( (source, i) => { return new Source( resolve( directory, sourceRoot, source ), sourcesContent[i] ); }); + source = new Link( module.originalSourceMap, baseSources ); } } From 7535c518ff16c1c93f64ef68e9149058186e831e Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 11 Jun 2016 19:55:49 -0700 Subject: [PATCH 059/331] Fixed loading of source content from loader-provided sourcemaps --- src/utils/collapseSourcemaps.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/utils/collapseSourcemaps.js b/src/utils/collapseSourcemaps.js index 763998f..68a97e0 100644 --- a/src/utils/collapseSourcemaps.js +++ b/src/utils/collapseSourcemaps.js @@ -100,19 +100,18 @@ class Link { export default function collapseSourcemaps ( file, map, modules, bundleSourcemapChain ) { const moduleSources = modules.map( module => { let sourceMapChain = module.sourceMapChain; - + let source; if ( module.originalSourceMap == null ) { source = new Source( module.id, module.originalCode ); } else { const sources = module.originalSourceMap.sources; + const sourcesContent = module.originalSourceMap.sourcesContent || []; if ( sources == null || ( sources.length <= 1 && sources[0] == null ) ) { - source = new Source( module.id, module.originalCode ); + source = new Source( module.id, sourcesContent[0] ); sourceMapChain = [ module.originalSourceMap ].concat( sourceMapChain ); } else { - const sourcesContent = module.originalSourceMap.sourcesContent || []; - // TODO indiscriminately treating IDs and sources as normal paths is probably bad. const directory = dirname( module.id ) || '.'; const sourceRoot = module.originalSourceMap.sourceRoot || '.'; From 2a7a1a70904d10c8ada50df8177f823cfb5fb295 Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 11 Jun 2016 19:56:16 -0700 Subject: [PATCH 060/331] Updated test for loader sourcemaps --- test/sourcemaps/loaders/_config.js | 42 ++++++++++++++++++++---------- test/sourcemaps/loaders/bar.js | 1 + test/sourcemaps/loaders/foo.js | 4 +-- test/sourcemaps/loaders/main.js | 5 +++- 4 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 test/sourcemaps/loaders/bar.js diff --git a/test/sourcemaps/loaders/_config.js b/test/sourcemaps/loaders/_config.js index cf13906..d278904 100644 --- a/test/sourcemaps/loaders/_config.js +++ b/test/sourcemaps/loaders/_config.js @@ -10,20 +10,26 @@ module.exports = { plugins: [ { load: function ( id ) { - if ( id.endsWith( 'main.js' ) ) { - id = id.replace( /main.js$/, 'foo.js' ); - } else { - id = id.replace( /foo.js$/, 'main.js' ); + if ( id.endsWith( 'foo.js' ) ) { + id = id.replace( /foo.js$/, 'bar.js' ); + } else if ( id.endsWith( 'bar.js' ) ) { + id = id.replace( /bar.js$/, 'foo.js' ); } var out = babel.transformFileSync( id, { blacklist: [ 'es6.modules' ], - sourceMap: true + sourceMap: true, + comments: false // misalign the columns }); - const slash = out.map.sources[0].lastIndexOf( '/' ) + 1; - out.map.sources = out.map.sources.map( source => '../' + source.slice( slash ) ); - out.map.sourceRoot = 'fake'; + if ( id.endsWith( 'main.js' ) ) { + delete out.map.sources; + //throw new Error(JSON.stringify(out.code)); + } else { + const slash = out.map.sources[0].lastIndexOf( '/' ) + 1; + out.map.sources = out.map.sources.map( source => '../' + source.slice( slash ) ); + out.map.sourceRoot = 'fake'; + } return { code: out.code, map: out.map }; } @@ -33,18 +39,26 @@ module.exports = { test: function ( code, map ) { var smc = new SourceMapConsumer( map ); - var generatedLoc = getLocation( code, code.indexOf( '42' ) ); + var generatedLoc = getLocation( code, code.indexOf( '22' ) ); var originalLoc = smc.originalPositionFor( generatedLoc ); - assert.equal( originalLoc.source, '../main.js' ); + assert.equal( originalLoc.source, '../foo.js' ); assert.equal( originalLoc.line, 1 ); - assert.equal( originalLoc.column, 25 ); + assert.equal( originalLoc.column, 32 ); + + var generatedLoc = getLocation( code, code.indexOf( '20' ) ); + var originalLoc = smc.originalPositionFor( generatedLoc ); + + assert.equal( originalLoc.source, '../bar.js' ); + assert.equal( originalLoc.line, 1 ); + assert.equal( originalLoc.column, 37 ); generatedLoc = getLocation( code, code.indexOf( 'log' ) ); originalLoc = smc.originalPositionFor( generatedLoc ); - assert.equal( originalLoc.source, '../foo.js' ); - assert.equal( originalLoc.line, 3 ); - assert.equal( originalLoc.column, 8 ); + assert.equal( originalLoc.source, '../main.js' ); + assert.ok( /columns/.test( smc.sourceContentFor( '../main.js' ) ) ); + assert.equal( originalLoc.line, 4 ); + assert.equal( originalLoc.column, 19 ); } }; diff --git a/test/sourcemaps/loaders/bar.js b/test/sourcemaps/loaders/bar.js new file mode 100644 index 0000000..6c3e77f --- /dev/null +++ b/test/sourcemaps/loaders/bar.js @@ -0,0 +1 @@ +/*misalign*/export const foo = () => 20; diff --git a/test/sourcemaps/loaders/foo.js b/test/sourcemaps/loaders/foo.js index c0b4c17..9ce4283 100644 --- a/test/sourcemaps/loaders/foo.js +++ b/test/sourcemaps/loaders/foo.js @@ -1,3 +1 @@ -import { foo } from './foo'; - -console.log( `the answer is ${foo()}` ); +/*the*/export const bar = () => 22; diff --git a/test/sourcemaps/loaders/main.js b/test/sourcemaps/loaders/main.js index 0cf01be..df7e27a 100644 --- a/test/sourcemaps/loaders/main.js +++ b/test/sourcemaps/loaders/main.js @@ -1 +1,4 @@ -export const foo = () => 42; +import { foo } from './foo'; +import { bar } from './bar'; + +/*columns*/console.log( `the answer is ${foo() + bar()}` ); From e256ddb727d4dc4ebb134781e33880cdb62805c0 Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 11 Jun 2016 20:16:15 -0700 Subject: [PATCH 061/331] Removed debugging line in sourcemaps loaders test --- test/sourcemaps/loaders/_config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/sourcemaps/loaders/_config.js b/test/sourcemaps/loaders/_config.js index d278904..2127639 100644 --- a/test/sourcemaps/loaders/_config.js +++ b/test/sourcemaps/loaders/_config.js @@ -24,7 +24,6 @@ module.exports = { if ( id.endsWith( 'main.js' ) ) { delete out.map.sources; - //throw new Error(JSON.stringify(out.code)); } else { const slash = out.map.sources[0].lastIndexOf( '/' ) + 1; out.map.sources = out.map.sources.map( source => '../' + source.slice( slash ) ); From 3a2f9b6e15668837ec6e8306075b6b24da82a53a Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 11 Jun 2016 21:42:15 -0700 Subject: [PATCH 062/331] Don't use endsWith. Will this fix the 0.12 build? --- test/sourcemaps/loaders/_config.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/sourcemaps/loaders/_config.js b/test/sourcemaps/loaders/_config.js index 2127639..8665133 100644 --- a/test/sourcemaps/loaders/_config.js +++ b/test/sourcemaps/loaders/_config.js @@ -10,9 +10,9 @@ module.exports = { plugins: [ { load: function ( id ) { - if ( id.endsWith( 'foo.js' ) ) { + if ( /foo.js$/.test( id ) ) { id = id.replace( /foo.js$/, 'bar.js' ); - } else if ( id.endsWith( 'bar.js' ) ) { + } else if ( /bar.js$/.test( id ) ) { id = id.replace( /bar.js$/, 'foo.js' ); } @@ -22,7 +22,7 @@ module.exports = { comments: false // misalign the columns }); - if ( id.endsWith( 'main.js' ) ) { + if ( /main.js$/.test( id ) ) { delete out.map.sources; } else { const slash = out.map.sources[0].lastIndexOf( '/' ) + 1; From c9d422d52dcb0969d5a05f69c71872d5a1af3b4a Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Sun, 12 Jun 2016 18:22:14 -0700 Subject: [PATCH 063/331] Allow `sourceMapFile` as an option. Fixes #717. --- src/rollup.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rollup.js b/src/rollup.js index 714a170..a9c50fd 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -28,6 +28,7 @@ const ALLOWED_KEYS = [ 'plugins', 'preferConst', 'sourceMap', + 'sourceMapFile', 'targets', 'treeshake', 'useStrict' From 9b13711cf7b2af65df4f0311279b3f9676510d47 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 13 Jun 2016 11:03:28 -0400 Subject: [PATCH 064/331] update allowed options test --- test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index 639104e..ce9fbcf 100644 --- a/test/test.js +++ b/test/test.js @@ -76,7 +76,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( function () { throw new Error( 'Missing expected error' ); }, function ( err ) { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, targets, treeshake, useStrict' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); }); }); }); From b3f63175913b65a88bee2120bf5463a09e4f6ce8 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 13 Jun 2016 12:39:48 -0400 Subject: [PATCH 065/331] -> v0.31.2 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e58b661..5df5a29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.31.2 + +* Allow `load` plugins to provide sourcemap ([#715](https://github.com/rollup/rollup/pull/715)) +* Allow `sourceMapFile` in config options ([#717](https://github.com/rollup/rollup/issues/717)) + ## 0.31.1 * Logging for errors emitted by `rollup-watch` ([#712](https://github.com/rollup/rollup/issues/712)) diff --git a/package.json b/package.json index 20effd7..4ecb308 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.31.1", + "version": "0.31.2", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "src/rollup.js", From 6ef17527f9660a32ba1b913a15727f737fb66737 Mon Sep 17 00:00:00 2001 From: Amila Welihinda Date: Wed, 15 Jun 2016 21:15:25 -0700 Subject: [PATCH 066/331] Added travis ci support to test against modern node versions --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 9a040ed..8530cac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,8 @@ language: node_js node_js: - "0.12" - "4" + - "5" + - "6" env: global: - BUILD_TIMEOUT=10000 From 9461ed325eb43059e4f26caea3a67396acac99ef Mon Sep 17 00:00:00 2001 From: operandom Date: Fri, 17 Jun 2016 15:11:40 +0200 Subject: [PATCH 067/331] Handle options.external is a function. --- bin/src/runRollup.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index 45c305e..7299d07 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -95,8 +95,15 @@ const equivalents = { }; function execute ( options, command ) { - let external = ( options.external || [] ) - .concat( command.external ? command.external.split( ',' ) : [] ); + let external = command.external ? + typeof options.external === 'function' ? + ((fn, a) => { + return function (id) { + return fn() || a.indexOf(id) !== -1; + }; + })(options.external, command.external.split(',')) : + (options.external || []).concat(command.external.split(',')) : + options.external; if ( command.globals ) { let globals = Object.create( null ); @@ -218,4 +225,4 @@ function bundle ( options ) { process.stdout.write( code ); }); -} +} \ No newline at end of file From 30e10d2497e9bb1bfd3f9c0a2d9f12a75ee7b5a6 Mon Sep 17 00:00:00 2001 From: Max Davidson Date: Fri, 17 Jun 2016 16:57:15 +0200 Subject: [PATCH 068/331] Add build target for ES modules --- package.json | 4 ++-- rollup.config.js | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 4ecb308..4568872 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.31.2", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", - "jsnext:main": "src/rollup.js", + "jsnext:main": "dist/rollup.es.js", "bin": { "rollup": "./bin/rollup" }, @@ -14,7 +14,7 @@ "test-coverage": "rm -rf coverage/* && istanbul cover --report json node_modules/.bin/_mocha -- -u exports -R spec test/test.js", "posttest-coverage": "remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.json -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.lcov -t lcovonly -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped -t html -b dist", "ci": "npm run test-coverage && codecov < coverage/coverage-remapped.lcov", - "build": "git rev-parse HEAD > .commithash && rollup -c -o dist/rollup.js", + "build": "git rev-parse HEAD > .commithash && rollup -c", "build:cli": "rollup -c rollup.config.cli.js", "build:browser": "git rev-parse HEAD > .commithash && rollup -c rollup.config.browser.js -o dist/rollup.browser.js", "prepublish": "npm run lint && npm test && npm run build:browser", diff --git a/rollup.config.js b/rollup.config.js index e7996f4..bfd6e83 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -20,7 +20,6 @@ var banner = readFileSync( 'src/banner.js', 'utf-8' ) export default { entry: 'src/rollup.js', - format: 'cjs', plugins: [ buble({ include: [ 'src/**', 'node_modules/acorn/**' ] @@ -40,5 +39,9 @@ export default { external: [ 'fs' ], banner: banner, sourceMap: true, - moduleName: 'rollup' + moduleName: 'rollup', + targets: [ + { dest: 'dist/rollup.js', format: 'cjs' }, + { dest: 'dist/rollup.es.js', format: 'es6' } + ] }; From c542325a58c21dfb86f0a76906507bcb8df66645 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 19 Jun 2016 10:49:36 -0400 Subject: [PATCH 069/331] switch tests from babel to buble --- test/function/assignment-patterns/_config.js | 2 +- .../class-methods-not-renamed/_config.js | 2 +- test/function/cycles-pathological/_config.js | 2 +- .../deconstructed-exported-vars/_config.js | 2 +- test/function/export-destruction/_config.js | 2 +- test/function/import-default-class/_config.js | 2 +- test/function/import-named-class/_config.js | 2 +- .../_config.js | 2 +- .../object-destructuring-renaming/_config.js | 2 +- .../top-level-arrow-function/_config.js | 2 +- test/sourcemaps/transforms/_config.js | 7 +++---- test/test.js | 20 ++++++++----------- 12 files changed, 21 insertions(+), 26 deletions(-) diff --git a/test/function/assignment-patterns/_config.js b/test/function/assignment-patterns/_config.js index d4afdc3..e21b4a0 100644 --- a/test/function/assignment-patterns/_config.js +++ b/test/function/assignment-patterns/_config.js @@ -1,4 +1,4 @@ module.exports = { description: 'allows reassigments to default parameters that shadow imports', - babel: true + buble: true }; diff --git a/test/function/class-methods-not-renamed/_config.js b/test/function/class-methods-not-renamed/_config.js index 0b31fd0..99bfc6e 100644 --- a/test/function/class-methods-not-renamed/_config.js +++ b/test/function/class-methods-not-renamed/_config.js @@ -3,5 +3,5 @@ module.exports = { options: { external: [ 'path' ] }, - babel: true + buble: true }; diff --git a/test/function/cycles-pathological/_config.js b/test/function/cycles-pathological/_config.js index 4e939af..8d44d9a 100644 --- a/test/function/cycles-pathological/_config.js +++ b/test/function/cycles-pathological/_config.js @@ -4,7 +4,7 @@ var warned; module.exports = { description: 'resolves pathological cyclical dependencies gracefully', - babel: true, + buble: true, options: { onwarn: function ( message ) { assert.ok( /Module .+B\.js may be unable to evaluate without .+A\.js, but is included first due to a cyclical dependency. Consider swapping the import statements in .+main\.js to ensure correct ordering/.test( message ) ); diff --git a/test/function/deconstructed-exported-vars/_config.js b/test/function/deconstructed-exported-vars/_config.js index 0451342..a210a0f 100644 --- a/test/function/deconstructed-exported-vars/_config.js +++ b/test/function/deconstructed-exported-vars/_config.js @@ -2,7 +2,7 @@ var assert = require( 'assert' ); module.exports = { description: 'allows destructuring in exported variable declarations, synthetic or otherwise', - babel: true, + buble: true, exports: function ( exports ) { assert.equal( exports.a, 1 ); assert.equal( exports.d, 4 ); diff --git a/test/function/export-destruction/_config.js b/test/function/export-destruction/_config.js index 263c8d1..1d77b9b 100644 --- a/test/function/export-destruction/_config.js +++ b/test/function/export-destruction/_config.js @@ -2,7 +2,7 @@ var assert = require( 'assert' ); module.exports = { description: 'handle destruction patterns in export declarations', - babel: true, + buble: true, exports: function ( exports ) { assert.deepEqual( Object.keys( exports ), [ 'baz', 'quux' ] ); diff --git a/test/function/import-default-class/_config.js b/test/function/import-default-class/_config.js index 5e59ef1..e3201e1 100644 --- a/test/function/import-default-class/_config.js +++ b/test/function/import-default-class/_config.js @@ -1,6 +1,6 @@ module.exports = { description: 'imports a default class', - babel: true + buble: true }; // test copied from https://github.com/esnext/es6-module-transpiler/tree/master/test/examples/export-default-class diff --git a/test/function/import-named-class/_config.js b/test/function/import-named-class/_config.js index e7749d0..02a6302 100644 --- a/test/function/import-named-class/_config.js +++ b/test/function/import-named-class/_config.js @@ -1,6 +1,6 @@ module.exports = { description: 'imports a named class', - babel: true + buble: true }; // test copied from https://github.com/esnext/es6-module-transpiler/tree/master/test/examples/export-named-class diff --git a/test/function/import-nameless-class-expression/_config.js b/test/function/import-nameless-class-expression/_config.js index 562c561..e6cacef 100644 --- a/test/function/import-nameless-class-expression/_config.js +++ b/test/function/import-nameless-class-expression/_config.js @@ -1,6 +1,6 @@ module.exports = { description: 'imports a nameless class expression', - babel: true + buble: true }; // test copied from https://github.com/esnext/es6-module-transpiler/tree/master/test/examples/export-class-expression diff --git a/test/function/object-destructuring-renaming/_config.js b/test/function/object-destructuring-renaming/_config.js index 4a1b8b6..cae5239 100644 --- a/test/function/object-destructuring-renaming/_config.js +++ b/test/function/object-destructuring-renaming/_config.js @@ -4,7 +4,7 @@ module.exports = { description: 'renaming destructured object properties should request the correct property (#527)', // we must transpile the object destructuring to test it - babel: true, + buble: true, exports: function ( exports ) { assert.equal( exports.env, process.env ); diff --git a/test/function/top-level-arrow-function/_config.js b/test/function/top-level-arrow-function/_config.js index 6ce4fd3..5bdf0bc 100644 --- a/test/function/top-level-arrow-function/_config.js +++ b/test/function/top-level-arrow-function/_config.js @@ -1,4 +1,4 @@ module.exports = { description: 'handles naked return value from top-level arrow function expression (#403)', - babel: true + buble: true }; diff --git a/test/sourcemaps/transforms/_config.js b/test/sourcemaps/transforms/_config.js index b76a885..77b9354 100644 --- a/test/sourcemaps/transforms/_config.js +++ b/test/sourcemaps/transforms/_config.js @@ -1,4 +1,4 @@ -var babel = require( 'babel-core' ); +var buble = require( 'buble' ); var MagicString = require( 'magic-string' ); var assert = require( 'assert' ); var getLocation = require( '../../utils/getLocation' ); @@ -10,9 +10,8 @@ module.exports = { plugins: [ { transform: function ( source, id ) { - return babel.transform( source, { - blacklist: [ 'es6.modules' ], - sourceMap: true + return buble.transform( source, { + transforms: { modules: false } }); } }, diff --git a/test/test.js b/test/test.js index 639104e..df63971 100644 --- a/test/test.js +++ b/test/test.js @@ -6,7 +6,7 @@ var os = require( 'os' ); var sander = require( 'sander' ); var assert = require( 'assert' ); var exec = require( 'child_process' ).exec; -var babel = require( 'babel-core' ); +var buble = require( 'buble' ); var rollup = require( '../dist/rollup' ); var FUNCTION = path.resolve( __dirname, 'function' ); @@ -171,15 +171,12 @@ describe( 'rollup', function () { if ( unintendedError ) throw unintendedError; if ( config.error || config.generateError ) return; - var code; + var code = result.code; - if ( config.babel ) { - code = babel.transform( result.code, { - blacklist: [ 'es6.modules' ], - loose: [ 'es6.classes' ] + if ( config.buble ) { + code = buble.transform( code, { + transforms: { modules: false } }).code; - } else { - code = result.code; } if ( config.code ) config.code( code ); @@ -372,10 +369,9 @@ describe( 'rollup', function () { if ( config.execute ) { try { - if ( config.babel ) { - code = babel.transform( code, { - blacklist: [ 'es6.modules' ], - loose: [ 'es6.classes' ] + if ( config.buble ) { + code = buble.transform( code, { + transforms: { modules: false } }).code; } From f01c0e8fb16e83238f7d4874caf039d9b697c601 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 19 Jun 2016 10:49:45 -0400 Subject: [PATCH 070/331] update dependencies --- package.json | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 20effd7..49472a9 100644 --- a/package.json +++ b/package.json @@ -41,31 +41,30 @@ }, "homepage": "https://github.com/rollup/rollup", "devDependencies": { - "acorn": "^3.1.0", - "babel-core": "^5.8.32", - "buble": "^0.6.4", - "chalk": "^1.1.1", + "acorn": "^3.2.0", + "buble": "^0.11.5", + "chalk": "^1.1.3", "codecov.io": "^0.1.6", - "console-group": "^0.2.0", - "eslint": "^2.9.0", - "estree-walker": "^0.2.0", - "istanbul": "^0.4.0", + "console-group": "^0.2.1", + "eslint": "^2.13.0", + "estree-walker": "^0.2.1", + "istanbul": "^0.4.3", "magic-string": "^0.15.1", "minimist": "^1.2.0", - "mocha": "^2.3.3", - "remap-istanbul": "^0.5.1", + "mocha": "^2.5.3", + "remap-istanbul": "^0.6.4", "require-relative": "^0.8.7", - "rollup": "^0.29.1", - "rollup-plugin-buble": "^0.6.0", + "rollup": "^0.31.2", + "rollup-plugin-buble": "^0.11.0", "rollup-plugin-commonjs": "^3.0.0", "rollup-plugin-json": "^2.0.0", - "rollup-plugin-node-resolve": "^1.5.0", - "rollup-plugin-replace": "^1.0.1", + "rollup-plugin-node-resolve": "^1.7.0", + "rollup-plugin-replace": "^1.1.0", "rollup-plugin-string": "^2.0.0", - "sander": "^0.5.0", - "source-map": "^0.5.3", - "sourcemap-codec": "^1.2.1", - "uglify-js": "^2.6.1" + "sander": "^0.5.1", + "source-map": "^0.5.6", + "sourcemap-codec": "^1.3.0", + "uglify-js": "^2.6.2" }, "dependencies": { "source-map-support": "^0.4.0" From b1e6823f08a9becb6dce019f82dba53278cd141f Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 19 Jun 2016 11:04:08 -0400 Subject: [PATCH 071/331] es6 -> es --- src/Bundle.js | 9 +++++++-- src/Declaration.js | 10 +++++----- src/Module.js | 6 +++--- src/finalisers/{es6.js => es.js} | 2 +- src/finalisers/index.js | 4 ++-- 5 files changed, 18 insertions(+), 13 deletions(-) rename src/finalisers/{es6.js => es.js} (97%) diff --git a/src/Bundle.js b/src/Bundle.js index 3d4414a..92280d2 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -278,7 +278,12 @@ export default class Bundle { } render ( options = {} ) { - const format = options.format || 'es6'; + if ( options.format === 'es6' ) { + this.onwarn( 'The es6 format is deprecated – use `es` instead' ); + options.format = 'es'; + } + + const format = options.format || 'es'; // Determine export mode - 'default', 'named', 'none' const exportMode = getExportMode( this, options.exports, options.moduleName ); @@ -287,7 +292,7 @@ export default class Bundle { let usedModules = []; this.orderedModules.forEach( module => { - const source = module.render( format === 'es6' ); + const source = module.render( format === 'es' ); if ( source.toString().length ) { magicString.addSource( source ); usedModules.push( module ); diff --git a/src/Declaration.js b/src/Declaration.js index 7bf906a..c383081 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -42,8 +42,8 @@ export default class Declaration { if ( reference.isReassignment ) this.isReassigned = true; } - render ( es6 ) { - if ( es6 ) return this.name; + render ( es ) { + if ( es ) return this.name; if ( !this.isReassigned || !this.exportName ) return this.name; return `exports.${this.exportName}`; @@ -280,18 +280,18 @@ export class ExternalDeclaration { } } - render ( es6 ) { + render ( es ) { if ( this.name === '*' ) { return this.module.name; } if ( this.name === 'default' ) { - return this.module.exportsNamespace || ( !es6 && this.module.exportsNames ) ? + return this.module.exportsNamespace || ( !es && this.module.exportsNames ) ? `${this.module.name}__default` : this.module.name; } - return es6 ? this.safeName : `${this.module.name}.${this.name}`; + return es ? this.safeName : `${this.module.name}.${this.name}`; } run () { diff --git a/src/Module.js b/src/Module.js index 7bc89d3..d8ef2ab 100644 --- a/src/Module.js +++ b/src/Module.js @@ -444,7 +444,7 @@ export default class Module { return statements; } - render ( es6 ) { + render ( es ) { let magicString = this.magicString.clone(); this.statements.forEach( statement => { @@ -488,7 +488,7 @@ export default class Module { const declaration = this.declarations[ name ]; if ( declaration.exportName && declaration.isReassigned ) { - magicString.insertLeft( statement.end, `;\nexports.${name} = ${declaration.render( es6 )}` ); + magicString.insertLeft( statement.end, `;\nexports.${name} = ${declaration.render( es )}` ); } }); } @@ -513,7 +513,7 @@ export default class Module { const declaration = reference.declaration; if ( declaration ) { - const name = declaration.render( es6 ); + const name = declaration.render( es ); // the second part of this check is necessary because of // namespace optimisation – name of `foo.bar` could be `bar` diff --git a/src/finalisers/es6.js b/src/finalisers/es.js similarity index 97% rename from src/finalisers/es6.js rename to src/finalisers/es.js index bd3f93f..96b5943 100644 --- a/src/finalisers/es6.js +++ b/src/finalisers/es.js @@ -4,7 +4,7 @@ function notDefault ( name ) { return name !== 'default'; } -export default function es6 ( bundle, magicString ) { +export default function es ( bundle, magicString ) { const importBlock = bundle.externalModules .map( module => { const specifiers = []; diff --git a/src/finalisers/index.js b/src/finalisers/index.js index 3ada90a..1089ccb 100644 --- a/src/finalisers/index.js +++ b/src/finalisers/index.js @@ -1,7 +1,7 @@ import amd from './amd.js'; import cjs from './cjs.js'; -import es6 from './es6.js'; +import es from './es.js'; import iife from './iife.js'; import umd from './umd.js'; -export default { amd, cjs, es6, iife, umd }; +export default { amd, cjs, es, iife, umd }; From 9f399591b3a48bfac5b09e83911fdc15a63e58d2 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 19 Jun 2016 11:04:20 -0400 Subject: [PATCH 072/331] add test for es6 format warning --- test/test.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index 639104e..f8c112e 100644 --- a/test/test.js +++ b/test/test.js @@ -17,7 +17,7 @@ var CLI = path.resolve( __dirname, 'cli' ); var PROFILES = [ { format: 'amd' }, { format: 'cjs' }, - { format: 'es6' }, + { format: 'es' }, { format: 'iife' }, { format: 'umd' } ]; @@ -125,6 +125,26 @@ describe( 'rollup', function () { }, /You must supply options\.moduleName for IIFE bundles/ ); }); }); + + it( 'warns on es6 format', function () { + var warned; + + return rollup.rollup({ + entry: 'x', + plugins: [{ + resolveId: function () { return 'test'; }, + load: function () { + return '// empty'; + } + }], + onwarn: function ( msg ) { + if ( /The es6 format is deprecated/.test( msg ) ) warned = true; + } + }).then( function ( bundle ) { + bundle.generate({ format: 'es6' }); + assert.ok( warned ); + }); + }); }); describe( 'function', function () { From 67b5fc60189e18f45476f8b65abce36a03606458 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 19 Jun 2016 11:05:25 -0400 Subject: [PATCH 073/331] rename expected output files (es6.js -> es.js) --- test/form/absolute-path-resolver/_expected/{es6.js => es.js} | 0 .../_expected/{es6.js => es.js} | 0 test/form/banner-and-footer-plugin/_expected/{es6.js => es.js} | 0 test/form/banner-and-footer/_expected/{es6.js => es.js} | 0 test/form/block-comments/_expected/{es6.js => es.js} | 0 test/form/computed-properties/_expected/{es6.js => es.js} | 0 test/form/conflicting-imports/_expected/{es6.js => es.js} | 0 test/form/dedupes-external-imports/_expected/{es6.js => es.js} | 0 .../_expected/{es6.js => es.js} | 0 .../exclude-unnecessary-modifications/_expected/{es6.js => es.js} | 0 test/form/export-all-from-internal/_expected/{es6.js => es.js} | 0 test/form/export-default-2/_expected/{es6.js => es.js} | 0 test/form/export-default-3/_expected/{es6.js => es.js} | 0 test/form/export-default-import/_expected/{es6.js => es.js} | 0 test/form/export-default/_expected/{es6.js => es.js} | 0 test/form/export-multiple-vars/_expected/{es6.js => es.js} | 0 test/form/exports-at-end-if-possible/_expected/{es6.js => es.js} | 0 .../form/external-import-alias-shadow/_expected/{es6.js => es.js} | 0 .../_expected/{es6.js => es.js} | 0 .../external-imports-custom-names/_expected/{es6.js => es.js} | 0 test/form/external-imports/_expected/{es6.js => es.js} | 0 .../_expected/{es6.js => es.js} | 0 .../_expected/{es6.js => es.js} | 0 test/form/indent-false/_expected/{es6.js => es.js} | 0 test/form/indent-true-spaces/_expected/{es6.js => es.js} | 0 test/form/indent-true/_expected/{es6.js => es.js} | 0 .../form/internal-conflict-resolution/_expected/{es6.js => es.js} | 0 test/form/intro-and-outro/_expected/{es6.js => es.js} | 0 test/form/multiple-exports/_expected/{es6.js => es.js} | 0 test/form/namespace-optimization-b/_expected/{es6.js => es.js} | 0 test/form/namespace-optimization/_expected/{es6.js => es.js} | 0 test/form/namespaced-default-exports/_expected/{es6.js => es.js} | 0 test/form/namespaced-named-exports/_expected/{es6.js => es.js} | 0 test/form/no-imports-or-exports/_expected/{es6.js => es.js} | 0 test/form/no-treeshake/_expected/{es6.js => es.js} | 0 .../_expected/{es6.js => es.js} | 0 test/form/prefer-const/_expected/{es6.js => es.js} | 0 test/form/preserve-debugger/_expected/{es6.js => es.js} | 0 .../preserves-comments-after-imports/_expected/{es6.js => es.js} | 0 .../_expected/{es6.js => es.js} | 0 test/form/self-contained-bundle/_expected/{es6.js => es.js} | 0 test/form/shorthand-properties/_expected/{es6.js => es.js} | 0 test/form/side-effect-b/_expected/{es6.js => es.js} | 0 test/form/side-effect-c/_expected/{es6.js => es.js} | 0 test/form/side-effect-d/_expected/{es6.js => es.js} | 0 test/form/side-effect-e/_expected/{es6.js => es.js} | 0 test/form/side-effect-f/_expected/{es6.js => es.js} | 0 test/form/side-effect-g/_expected/{es6.js => es.js} | 0 test/form/side-effect-h/_expected/{es6.js => es.js} | 0 test/form/side-effect-i/_expected/{es6.js => es.js} | 0 test/form/side-effect-j/_expected/{es6.js => es.js} | 0 test/form/side-effect-k/_expected/{es6.js => es.js} | 0 test/form/side-effect-l/_expected/{es6.js => es.js} | 0 test/form/side-effect-m/_expected/{es6.js => es.js} | 0 test/form/side-effect-n/_expected/{es6.js => es.js} | 0 test/form/side-effect-o/_expected/{es6.js => es.js} | 0 test/form/side-effect/_expected/{es6.js => es.js} | 0 test/form/sourcemaps-external/_expected/{es6.js => es.js} | 0 test/form/sourcemaps-inline/_expected/{es6.js => es.js} | 0 .../_expected/{es6.js => es.js} | 0 test/form/string-indentation-b/_expected/{es6.js => es.js} | 0 test/form/string-indentation/_expected/{es6.js => es.js} | 0 test/form/this-is-undefined/_expected/{es6.js => es.js} | 0 test/form/transform-bundle-plugin/_expected/{es6.js => es.js} | 0 test/form/umd-noconflict/_expected/{es6.js => es.js} | 0 .../_expected/{es6.js => es.js} | 0 test/form/unmodified-default-exports/_expected/{es6.js => es.js} | 0 test/form/unused-default-exports/_expected/{es6.js => es.js} | 0 .../_expected/{es6.js => es.js} | 0 69 files changed, 0 insertions(+), 0 deletions(-) rename test/form/absolute-path-resolver/_expected/{es6.js => es.js} (100%) rename test/form/assignment-to-exports-class-declaration/_expected/{es6.js => es.js} (100%) rename test/form/banner-and-footer-plugin/_expected/{es6.js => es.js} (100%) rename test/form/banner-and-footer/_expected/{es6.js => es.js} (100%) rename test/form/block-comments/_expected/{es6.js => es.js} (100%) rename test/form/computed-properties/_expected/{es6.js => es.js} (100%) rename test/form/conflicting-imports/_expected/{es6.js => es.js} (100%) rename test/form/dedupes-external-imports/_expected/{es6.js => es.js} (100%) rename test/form/erroneous-nested-member-expression/_expected/{es6.js => es.js} (100%) rename test/form/exclude-unnecessary-modifications/_expected/{es6.js => es.js} (100%) rename test/form/export-all-from-internal/_expected/{es6.js => es.js} (100%) rename test/form/export-default-2/_expected/{es6.js => es.js} (100%) rename test/form/export-default-3/_expected/{es6.js => es.js} (100%) rename test/form/export-default-import/_expected/{es6.js => es.js} (100%) rename test/form/export-default/_expected/{es6.js => es.js} (100%) rename test/form/export-multiple-vars/_expected/{es6.js => es.js} (100%) rename test/form/exports-at-end-if-possible/_expected/{es6.js => es.js} (100%) rename test/form/external-import-alias-shadow/_expected/{es6.js => es.js} (100%) rename test/form/external-imports-custom-names-function/_expected/{es6.js => es.js} (100%) rename test/form/external-imports-custom-names/_expected/{es6.js => es.js} (100%) rename test/form/external-imports/_expected/{es6.js => es.js} (100%) rename test/form/import-external-namespace-and-default/_expected/{es6.js => es.js} (100%) rename test/form/import-named-exported-global-with-alias/_expected/{es6.js => es.js} (100%) rename test/form/indent-false/_expected/{es6.js => es.js} (100%) rename test/form/indent-true-spaces/_expected/{es6.js => es.js} (100%) rename test/form/indent-true/_expected/{es6.js => es.js} (100%) rename test/form/internal-conflict-resolution/_expected/{es6.js => es.js} (100%) rename test/form/intro-and-outro/_expected/{es6.js => es.js} (100%) rename test/form/multiple-exports/_expected/{es6.js => es.js} (100%) rename test/form/namespace-optimization-b/_expected/{es6.js => es.js} (100%) rename test/form/namespace-optimization/_expected/{es6.js => es.js} (100%) rename test/form/namespaced-default-exports/_expected/{es6.js => es.js} (100%) rename test/form/namespaced-named-exports/_expected/{es6.js => es.js} (100%) rename test/form/no-imports-or-exports/_expected/{es6.js => es.js} (100%) rename test/form/no-treeshake/_expected/{es6.js => es.js} (100%) rename test/form/object-destructuring-default-values/_expected/{es6.js => es.js} (100%) rename test/form/prefer-const/_expected/{es6.js => es.js} (100%) rename test/form/preserve-debugger/_expected/{es6.js => es.js} (100%) rename test/form/preserves-comments-after-imports/_expected/{es6.js => es.js} (100%) rename test/form/removes-existing-sourcemap-comments/_expected/{es6.js => es.js} (100%) rename test/form/self-contained-bundle/_expected/{es6.js => es.js} (100%) rename test/form/shorthand-properties/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-b/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-c/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-d/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-e/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-f/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-g/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-h/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-i/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-j/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-k/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-l/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-m/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-n/_expected/{es6.js => es.js} (100%) rename test/form/side-effect-o/_expected/{es6.js => es.js} (100%) rename test/form/side-effect/_expected/{es6.js => es.js} (100%) rename test/form/sourcemaps-external/_expected/{es6.js => es.js} (100%) rename test/form/sourcemaps-inline/_expected/{es6.js => es.js} (100%) rename test/form/spacing-after-function-with-semicolon/_expected/{es6.js => es.js} (100%) rename test/form/string-indentation-b/_expected/{es6.js => es.js} (100%) rename test/form/string-indentation/_expected/{es6.js => es.js} (100%) rename test/form/this-is-undefined/_expected/{es6.js => es.js} (100%) rename test/form/transform-bundle-plugin/_expected/{es6.js => es.js} (100%) rename test/form/umd-noconflict/_expected/{es6.js => es.js} (100%) rename test/form/unmodified-default-exports-function-argument/_expected/{es6.js => es.js} (100%) rename test/form/unmodified-default-exports/_expected/{es6.js => es.js} (100%) rename test/form/unused-default-exports/_expected/{es6.js => es.js} (100%) rename test/form/whitespace-around-namespace-member-expression/_expected/{es6.js => es.js} (100%) diff --git a/test/form/absolute-path-resolver/_expected/es6.js b/test/form/absolute-path-resolver/_expected/es.js similarity index 100% rename from test/form/absolute-path-resolver/_expected/es6.js rename to test/form/absolute-path-resolver/_expected/es.js diff --git a/test/form/assignment-to-exports-class-declaration/_expected/es6.js b/test/form/assignment-to-exports-class-declaration/_expected/es.js similarity index 100% rename from test/form/assignment-to-exports-class-declaration/_expected/es6.js rename to test/form/assignment-to-exports-class-declaration/_expected/es.js diff --git a/test/form/banner-and-footer-plugin/_expected/es6.js b/test/form/banner-and-footer-plugin/_expected/es.js similarity index 100% rename from test/form/banner-and-footer-plugin/_expected/es6.js rename to test/form/banner-and-footer-plugin/_expected/es.js diff --git a/test/form/banner-and-footer/_expected/es6.js b/test/form/banner-and-footer/_expected/es.js similarity index 100% rename from test/form/banner-and-footer/_expected/es6.js rename to test/form/banner-and-footer/_expected/es.js diff --git a/test/form/block-comments/_expected/es6.js b/test/form/block-comments/_expected/es.js similarity index 100% rename from test/form/block-comments/_expected/es6.js rename to test/form/block-comments/_expected/es.js diff --git a/test/form/computed-properties/_expected/es6.js b/test/form/computed-properties/_expected/es.js similarity index 100% rename from test/form/computed-properties/_expected/es6.js rename to test/form/computed-properties/_expected/es.js diff --git a/test/form/conflicting-imports/_expected/es6.js b/test/form/conflicting-imports/_expected/es.js similarity index 100% rename from test/form/conflicting-imports/_expected/es6.js rename to test/form/conflicting-imports/_expected/es.js diff --git a/test/form/dedupes-external-imports/_expected/es6.js b/test/form/dedupes-external-imports/_expected/es.js similarity index 100% rename from test/form/dedupes-external-imports/_expected/es6.js rename to test/form/dedupes-external-imports/_expected/es.js diff --git a/test/form/erroneous-nested-member-expression/_expected/es6.js b/test/form/erroneous-nested-member-expression/_expected/es.js similarity index 100% rename from test/form/erroneous-nested-member-expression/_expected/es6.js rename to test/form/erroneous-nested-member-expression/_expected/es.js diff --git a/test/form/exclude-unnecessary-modifications/_expected/es6.js b/test/form/exclude-unnecessary-modifications/_expected/es.js similarity index 100% rename from test/form/exclude-unnecessary-modifications/_expected/es6.js rename to test/form/exclude-unnecessary-modifications/_expected/es.js diff --git a/test/form/export-all-from-internal/_expected/es6.js b/test/form/export-all-from-internal/_expected/es.js similarity index 100% rename from test/form/export-all-from-internal/_expected/es6.js rename to test/form/export-all-from-internal/_expected/es.js diff --git a/test/form/export-default-2/_expected/es6.js b/test/form/export-default-2/_expected/es.js similarity index 100% rename from test/form/export-default-2/_expected/es6.js rename to test/form/export-default-2/_expected/es.js diff --git a/test/form/export-default-3/_expected/es6.js b/test/form/export-default-3/_expected/es.js similarity index 100% rename from test/form/export-default-3/_expected/es6.js rename to test/form/export-default-3/_expected/es.js diff --git a/test/form/export-default-import/_expected/es6.js b/test/form/export-default-import/_expected/es.js similarity index 100% rename from test/form/export-default-import/_expected/es6.js rename to test/form/export-default-import/_expected/es.js diff --git a/test/form/export-default/_expected/es6.js b/test/form/export-default/_expected/es.js similarity index 100% rename from test/form/export-default/_expected/es6.js rename to test/form/export-default/_expected/es.js diff --git a/test/form/export-multiple-vars/_expected/es6.js b/test/form/export-multiple-vars/_expected/es.js similarity index 100% rename from test/form/export-multiple-vars/_expected/es6.js rename to test/form/export-multiple-vars/_expected/es.js diff --git a/test/form/exports-at-end-if-possible/_expected/es6.js b/test/form/exports-at-end-if-possible/_expected/es.js similarity index 100% rename from test/form/exports-at-end-if-possible/_expected/es6.js rename to test/form/exports-at-end-if-possible/_expected/es.js diff --git a/test/form/external-import-alias-shadow/_expected/es6.js b/test/form/external-import-alias-shadow/_expected/es.js similarity index 100% rename from test/form/external-import-alias-shadow/_expected/es6.js rename to test/form/external-import-alias-shadow/_expected/es.js diff --git a/test/form/external-imports-custom-names-function/_expected/es6.js b/test/form/external-imports-custom-names-function/_expected/es.js similarity index 100% rename from test/form/external-imports-custom-names-function/_expected/es6.js rename to test/form/external-imports-custom-names-function/_expected/es.js diff --git a/test/form/external-imports-custom-names/_expected/es6.js b/test/form/external-imports-custom-names/_expected/es.js similarity index 100% rename from test/form/external-imports-custom-names/_expected/es6.js rename to test/form/external-imports-custom-names/_expected/es.js diff --git a/test/form/external-imports/_expected/es6.js b/test/form/external-imports/_expected/es.js similarity index 100% rename from test/form/external-imports/_expected/es6.js rename to test/form/external-imports/_expected/es.js diff --git a/test/form/import-external-namespace-and-default/_expected/es6.js b/test/form/import-external-namespace-and-default/_expected/es.js similarity index 100% rename from test/form/import-external-namespace-and-default/_expected/es6.js rename to test/form/import-external-namespace-and-default/_expected/es.js diff --git a/test/form/import-named-exported-global-with-alias/_expected/es6.js b/test/form/import-named-exported-global-with-alias/_expected/es.js similarity index 100% rename from test/form/import-named-exported-global-with-alias/_expected/es6.js rename to test/form/import-named-exported-global-with-alias/_expected/es.js diff --git a/test/form/indent-false/_expected/es6.js b/test/form/indent-false/_expected/es.js similarity index 100% rename from test/form/indent-false/_expected/es6.js rename to test/form/indent-false/_expected/es.js diff --git a/test/form/indent-true-spaces/_expected/es6.js b/test/form/indent-true-spaces/_expected/es.js similarity index 100% rename from test/form/indent-true-spaces/_expected/es6.js rename to test/form/indent-true-spaces/_expected/es.js diff --git a/test/form/indent-true/_expected/es6.js b/test/form/indent-true/_expected/es.js similarity index 100% rename from test/form/indent-true/_expected/es6.js rename to test/form/indent-true/_expected/es.js diff --git a/test/form/internal-conflict-resolution/_expected/es6.js b/test/form/internal-conflict-resolution/_expected/es.js similarity index 100% rename from test/form/internal-conflict-resolution/_expected/es6.js rename to test/form/internal-conflict-resolution/_expected/es.js diff --git a/test/form/intro-and-outro/_expected/es6.js b/test/form/intro-and-outro/_expected/es.js similarity index 100% rename from test/form/intro-and-outro/_expected/es6.js rename to test/form/intro-and-outro/_expected/es.js diff --git a/test/form/multiple-exports/_expected/es6.js b/test/form/multiple-exports/_expected/es.js similarity index 100% rename from test/form/multiple-exports/_expected/es6.js rename to test/form/multiple-exports/_expected/es.js diff --git a/test/form/namespace-optimization-b/_expected/es6.js b/test/form/namespace-optimization-b/_expected/es.js similarity index 100% rename from test/form/namespace-optimization-b/_expected/es6.js rename to test/form/namespace-optimization-b/_expected/es.js diff --git a/test/form/namespace-optimization/_expected/es6.js b/test/form/namespace-optimization/_expected/es.js similarity index 100% rename from test/form/namespace-optimization/_expected/es6.js rename to test/form/namespace-optimization/_expected/es.js diff --git a/test/form/namespaced-default-exports/_expected/es6.js b/test/form/namespaced-default-exports/_expected/es.js similarity index 100% rename from test/form/namespaced-default-exports/_expected/es6.js rename to test/form/namespaced-default-exports/_expected/es.js diff --git a/test/form/namespaced-named-exports/_expected/es6.js b/test/form/namespaced-named-exports/_expected/es.js similarity index 100% rename from test/form/namespaced-named-exports/_expected/es6.js rename to test/form/namespaced-named-exports/_expected/es.js diff --git a/test/form/no-imports-or-exports/_expected/es6.js b/test/form/no-imports-or-exports/_expected/es.js similarity index 100% rename from test/form/no-imports-or-exports/_expected/es6.js rename to test/form/no-imports-or-exports/_expected/es.js diff --git a/test/form/no-treeshake/_expected/es6.js b/test/form/no-treeshake/_expected/es.js similarity index 100% rename from test/form/no-treeshake/_expected/es6.js rename to test/form/no-treeshake/_expected/es.js diff --git a/test/form/object-destructuring-default-values/_expected/es6.js b/test/form/object-destructuring-default-values/_expected/es.js similarity index 100% rename from test/form/object-destructuring-default-values/_expected/es6.js rename to test/form/object-destructuring-default-values/_expected/es.js diff --git a/test/form/prefer-const/_expected/es6.js b/test/form/prefer-const/_expected/es.js similarity index 100% rename from test/form/prefer-const/_expected/es6.js rename to test/form/prefer-const/_expected/es.js diff --git a/test/form/preserve-debugger/_expected/es6.js b/test/form/preserve-debugger/_expected/es.js similarity index 100% rename from test/form/preserve-debugger/_expected/es6.js rename to test/form/preserve-debugger/_expected/es.js diff --git a/test/form/preserves-comments-after-imports/_expected/es6.js b/test/form/preserves-comments-after-imports/_expected/es.js similarity index 100% rename from test/form/preserves-comments-after-imports/_expected/es6.js rename to test/form/preserves-comments-after-imports/_expected/es.js diff --git a/test/form/removes-existing-sourcemap-comments/_expected/es6.js b/test/form/removes-existing-sourcemap-comments/_expected/es.js similarity index 100% rename from test/form/removes-existing-sourcemap-comments/_expected/es6.js rename to test/form/removes-existing-sourcemap-comments/_expected/es.js diff --git a/test/form/self-contained-bundle/_expected/es6.js b/test/form/self-contained-bundle/_expected/es.js similarity index 100% rename from test/form/self-contained-bundle/_expected/es6.js rename to test/form/self-contained-bundle/_expected/es.js diff --git a/test/form/shorthand-properties/_expected/es6.js b/test/form/shorthand-properties/_expected/es.js similarity index 100% rename from test/form/shorthand-properties/_expected/es6.js rename to test/form/shorthand-properties/_expected/es.js diff --git a/test/form/side-effect-b/_expected/es6.js b/test/form/side-effect-b/_expected/es.js similarity index 100% rename from test/form/side-effect-b/_expected/es6.js rename to test/form/side-effect-b/_expected/es.js diff --git a/test/form/side-effect-c/_expected/es6.js b/test/form/side-effect-c/_expected/es.js similarity index 100% rename from test/form/side-effect-c/_expected/es6.js rename to test/form/side-effect-c/_expected/es.js diff --git a/test/form/side-effect-d/_expected/es6.js b/test/form/side-effect-d/_expected/es.js similarity index 100% rename from test/form/side-effect-d/_expected/es6.js rename to test/form/side-effect-d/_expected/es.js diff --git a/test/form/side-effect-e/_expected/es6.js b/test/form/side-effect-e/_expected/es.js similarity index 100% rename from test/form/side-effect-e/_expected/es6.js rename to test/form/side-effect-e/_expected/es.js diff --git a/test/form/side-effect-f/_expected/es6.js b/test/form/side-effect-f/_expected/es.js similarity index 100% rename from test/form/side-effect-f/_expected/es6.js rename to test/form/side-effect-f/_expected/es.js diff --git a/test/form/side-effect-g/_expected/es6.js b/test/form/side-effect-g/_expected/es.js similarity index 100% rename from test/form/side-effect-g/_expected/es6.js rename to test/form/side-effect-g/_expected/es.js diff --git a/test/form/side-effect-h/_expected/es6.js b/test/form/side-effect-h/_expected/es.js similarity index 100% rename from test/form/side-effect-h/_expected/es6.js rename to test/form/side-effect-h/_expected/es.js diff --git a/test/form/side-effect-i/_expected/es6.js b/test/form/side-effect-i/_expected/es.js similarity index 100% rename from test/form/side-effect-i/_expected/es6.js rename to test/form/side-effect-i/_expected/es.js diff --git a/test/form/side-effect-j/_expected/es6.js b/test/form/side-effect-j/_expected/es.js similarity index 100% rename from test/form/side-effect-j/_expected/es6.js rename to test/form/side-effect-j/_expected/es.js diff --git a/test/form/side-effect-k/_expected/es6.js b/test/form/side-effect-k/_expected/es.js similarity index 100% rename from test/form/side-effect-k/_expected/es6.js rename to test/form/side-effect-k/_expected/es.js diff --git a/test/form/side-effect-l/_expected/es6.js b/test/form/side-effect-l/_expected/es.js similarity index 100% rename from test/form/side-effect-l/_expected/es6.js rename to test/form/side-effect-l/_expected/es.js diff --git a/test/form/side-effect-m/_expected/es6.js b/test/form/side-effect-m/_expected/es.js similarity index 100% rename from test/form/side-effect-m/_expected/es6.js rename to test/form/side-effect-m/_expected/es.js diff --git a/test/form/side-effect-n/_expected/es6.js b/test/form/side-effect-n/_expected/es.js similarity index 100% rename from test/form/side-effect-n/_expected/es6.js rename to test/form/side-effect-n/_expected/es.js diff --git a/test/form/side-effect-o/_expected/es6.js b/test/form/side-effect-o/_expected/es.js similarity index 100% rename from test/form/side-effect-o/_expected/es6.js rename to test/form/side-effect-o/_expected/es.js diff --git a/test/form/side-effect/_expected/es6.js b/test/form/side-effect/_expected/es.js similarity index 100% rename from test/form/side-effect/_expected/es6.js rename to test/form/side-effect/_expected/es.js diff --git a/test/form/sourcemaps-external/_expected/es6.js b/test/form/sourcemaps-external/_expected/es.js similarity index 100% rename from test/form/sourcemaps-external/_expected/es6.js rename to test/form/sourcemaps-external/_expected/es.js diff --git a/test/form/sourcemaps-inline/_expected/es6.js b/test/form/sourcemaps-inline/_expected/es.js similarity index 100% rename from test/form/sourcemaps-inline/_expected/es6.js rename to test/form/sourcemaps-inline/_expected/es.js diff --git a/test/form/spacing-after-function-with-semicolon/_expected/es6.js b/test/form/spacing-after-function-with-semicolon/_expected/es.js similarity index 100% rename from test/form/spacing-after-function-with-semicolon/_expected/es6.js rename to test/form/spacing-after-function-with-semicolon/_expected/es.js diff --git a/test/form/string-indentation-b/_expected/es6.js b/test/form/string-indentation-b/_expected/es.js similarity index 100% rename from test/form/string-indentation-b/_expected/es6.js rename to test/form/string-indentation-b/_expected/es.js diff --git a/test/form/string-indentation/_expected/es6.js b/test/form/string-indentation/_expected/es.js similarity index 100% rename from test/form/string-indentation/_expected/es6.js rename to test/form/string-indentation/_expected/es.js diff --git a/test/form/this-is-undefined/_expected/es6.js b/test/form/this-is-undefined/_expected/es.js similarity index 100% rename from test/form/this-is-undefined/_expected/es6.js rename to test/form/this-is-undefined/_expected/es.js diff --git a/test/form/transform-bundle-plugin/_expected/es6.js b/test/form/transform-bundle-plugin/_expected/es.js similarity index 100% rename from test/form/transform-bundle-plugin/_expected/es6.js rename to test/form/transform-bundle-plugin/_expected/es.js diff --git a/test/form/umd-noconflict/_expected/es6.js b/test/form/umd-noconflict/_expected/es.js similarity index 100% rename from test/form/umd-noconflict/_expected/es6.js rename to test/form/umd-noconflict/_expected/es.js diff --git a/test/form/unmodified-default-exports-function-argument/_expected/es6.js b/test/form/unmodified-default-exports-function-argument/_expected/es.js similarity index 100% rename from test/form/unmodified-default-exports-function-argument/_expected/es6.js rename to test/form/unmodified-default-exports-function-argument/_expected/es.js diff --git a/test/form/unmodified-default-exports/_expected/es6.js b/test/form/unmodified-default-exports/_expected/es.js similarity index 100% rename from test/form/unmodified-default-exports/_expected/es6.js rename to test/form/unmodified-default-exports/_expected/es.js diff --git a/test/form/unused-default-exports/_expected/es6.js b/test/form/unused-default-exports/_expected/es.js similarity index 100% rename from test/form/unused-default-exports/_expected/es6.js rename to test/form/unused-default-exports/_expected/es.js diff --git a/test/form/whitespace-around-namespace-member-expression/_expected/es6.js b/test/form/whitespace-around-namespace-member-expression/_expected/es.js similarity index 100% rename from test/form/whitespace-around-namespace-member-expression/_expected/es6.js rename to test/form/whitespace-around-namespace-member-expression/_expected/es.js From 4ecc2193301f35408fb474ab3e4d287ab071ecd9 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 19 Jun 2016 11:15:21 -0400 Subject: [PATCH 074/331] update test files --- .../_expected/{es6.js => es.js} | 2 +- test/cli/multiple-targets-shared-config/_expected/es.js.map | 1 + test/cli/multiple-targets-shared-config/_expected/es6.js.map | 1 - test/cli/multiple-targets-shared-config/rollup.config.js | 4 ++-- test/cli/multiple-targets/_expected/{es6.js => es.js} | 0 test/cli/multiple-targets/rollup.config.js | 4 ++-- test/form/sourcemaps-external/_expected/es.js | 2 +- test/form/sourcemaps-external/_expected/es.js.map | 1 + test/form/sourcemaps-external/_expected/es6.js.map | 1 - test/form/sourcemaps-inline/_expected/es.js | 2 +- 10 files changed, 9 insertions(+), 9 deletions(-) rename test/cli/multiple-targets-shared-config/_expected/{es6.js => es.js} (53%) create mode 100644 test/cli/multiple-targets-shared-config/_expected/es.js.map delete mode 100644 test/cli/multiple-targets-shared-config/_expected/es6.js.map rename test/cli/multiple-targets/_expected/{es6.js => es.js} (100%) create mode 100644 test/form/sourcemaps-external/_expected/es.js.map delete mode 100644 test/form/sourcemaps-external/_expected/es6.js.map diff --git a/test/cli/multiple-targets-shared-config/_expected/es6.js b/test/cli/multiple-targets-shared-config/_expected/es.js similarity index 53% rename from test/cli/multiple-targets-shared-config/_expected/es6.js rename to test/cli/multiple-targets-shared-config/_expected/es.js index e24bdc9..9c36d9f 100644 --- a/test/cli/multiple-targets-shared-config/_expected/es6.js +++ b/test/cli/multiple-targets-shared-config/_expected/es.js @@ -1,4 +1,4 @@ var main = 0; export default main; -//# sourceMappingURL=es6.js.map \ No newline at end of file +//# sourceMappingURL=es.js.map diff --git a/test/cli/multiple-targets-shared-config/_expected/es.js.map b/test/cli/multiple-targets-shared-config/_expected/es.js.map new file mode 100644 index 0000000..6cc964b --- /dev/null +++ b/test/cli/multiple-targets-shared-config/_expected/es.js.map @@ -0,0 +1 @@ +{"version":3,"file":"es.js","sources":["../main.js"],"sourcesContent":["export default 0;\n"],"names":[],"mappings":"AAAA,WAAe,CAAC,CAAC,;;"} diff --git a/test/cli/multiple-targets-shared-config/_expected/es6.js.map b/test/cli/multiple-targets-shared-config/_expected/es6.js.map deleted file mode 100644 index 8b3e60e..0000000 --- a/test/cli/multiple-targets-shared-config/_expected/es6.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"es6.js","sources":["../main.js"],"sourcesContent":["export default 0;\n"],"names":[],"mappings":"AAAA,WAAe,CAAC,CAAC,;;"} diff --git a/test/cli/multiple-targets-shared-config/rollup.config.js b/test/cli/multiple-targets-shared-config/rollup.config.js index e99ab56..1a2d8a1 100644 --- a/test/cli/multiple-targets-shared-config/rollup.config.js +++ b/test/cli/multiple-targets-shared-config/rollup.config.js @@ -7,8 +7,8 @@ export default { dest: '_actual/cjs.js' }, { - format: 'es6', - dest: '_actual/es6.js' + format: 'es', + dest: '_actual/es.js' } ] }; diff --git a/test/cli/multiple-targets/_expected/es6.js b/test/cli/multiple-targets/_expected/es.js similarity index 100% rename from test/cli/multiple-targets/_expected/es6.js rename to test/cli/multiple-targets/_expected/es.js diff --git a/test/cli/multiple-targets/rollup.config.js b/test/cli/multiple-targets/rollup.config.js index db165db..f12e0c7 100644 --- a/test/cli/multiple-targets/rollup.config.js +++ b/test/cli/multiple-targets/rollup.config.js @@ -6,8 +6,8 @@ export default { dest: '_actual/cjs.js' }, { - format: 'es6', - dest: '_actual/es6.js' + format: 'es', + dest: '_actual/es.js' } ] }; diff --git a/test/form/sourcemaps-external/_expected/es.js b/test/form/sourcemaps-external/_expected/es.js index f1d6ef7..c7263f8 100644 --- a/test/form/sourcemaps-external/_expected/es.js +++ b/test/form/sourcemaps-external/_expected/es.js @@ -10,4 +10,4 @@ console.log( 'hello from main.js' ); foo(); bar(); -//# sourceMappingURL=es6.js.map \ No newline at end of file +//# sourceMappingURL=es.js.map diff --git a/test/form/sourcemaps-external/_expected/es.js.map b/test/form/sourcemaps-external/_expected/es.js.map new file mode 100644 index 0000000..ec8dd24 --- /dev/null +++ b/test/form/sourcemaps-external/_expected/es.js.map @@ -0,0 +1 @@ +{"version":3,"file":"es.js","sources":["../foo.js","../bar.js","../main.js"],"sourcesContent":["export default function foo () {\n\tconsole.log( 'hello from foo.js' );\n}\n","export default function bar () {\n\tconsole.log( 'hello from bar.js' );\n}\n","import foo from './foo';\nimport bar from './bar';\n\nconsole.log( 'hello from main.js' );\n\nfoo();\nbar();\n"],"names":[],"mappings":"AAAe,SAAS,GAAG,IAAI;CAC9B,OAAO,CAAC,GAAG,EAAE,mBAAmB,EAAE,CAAC;CACnC;;ACFc,SAAS,GAAG,IAAI;CAC9B,OAAO,CAAC,GAAG,EAAE,mBAAmB,EAAE,CAAC;CACnC;;ACCD,OAAO,CAAC,GAAG,EAAE,oBAAoB,EAAE,CAAC;;AAEpC,GAAG,EAAE,CAAC;AACN,GAAG,EAAE,CAAC"} diff --git a/test/form/sourcemaps-external/_expected/es6.js.map b/test/form/sourcemaps-external/_expected/es6.js.map deleted file mode 100644 index 2b48a49..0000000 --- a/test/form/sourcemaps-external/_expected/es6.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"es6.js","sources":["../foo.js","../bar.js","../main.js"],"sourcesContent":["export default function foo () {\n\tconsole.log( 'hello from foo.js' );\n}\n","export default function bar () {\n\tconsole.log( 'hello from bar.js' );\n}\n","import foo from './foo';\nimport bar from './bar';\n\nconsole.log( 'hello from main.js' );\n\nfoo();\nbar();\n"],"names":[],"mappings":"AAAe,SAAS,GAAG,IAAI;CAC9B,OAAO,CAAC,GAAG,EAAE,mBAAmB,EAAE,CAAC;CACnC;;ACFc,SAAS,GAAG,IAAI;CAC9B,OAAO,CAAC,GAAG,EAAE,mBAAmB,EAAE,CAAC;CACnC;;ACCD,OAAO,CAAC,GAAG,EAAE,oBAAoB,EAAE,CAAC;;AAEpC,GAAG,EAAE,CAAC;AACN,GAAG,EAAE,CAAC"} \ No newline at end of file diff --git a/test/form/sourcemaps-inline/_expected/es.js b/test/form/sourcemaps-inline/_expected/es.js index c07d67a..b823f1d 100644 --- a/test/form/sourcemaps-inline/_expected/es.js +++ b/test/form/sourcemaps-inline/_expected/es.js @@ -10,4 +10,4 @@ console.log( 'hello from main.js' ); foo(); bar(); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXM2LmpzIiwic291cmNlcyI6WyIuLi9mb28uanMiLCIuLi9iYXIuanMiLCIuLi9tYWluLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGZvbyAoKSB7XG5cdGNvbnNvbGUubG9nKCAnaGVsbG8gZnJvbSBmb28uanMnICk7XG59XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBiYXIgKCkge1xuXHRjb25zb2xlLmxvZyggJ2hlbGxvIGZyb20gYmFyLmpzJyApO1xufVxuIiwiaW1wb3J0IGZvbyBmcm9tICcuL2Zvbyc7XG5pbXBvcnQgYmFyIGZyb20gJy4vYmFyJztcblxuY29uc29sZS5sb2coICdoZWxsbyBmcm9tIG1haW4uanMnICk7XG5cbmZvbygpO1xuYmFyKCk7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQWUsU0FBUyxHQUFHLElBQUk7Q0FDOUIsT0FBTyxDQUFDLEdBQUcsRUFBRSxtQkFBbUIsRUFBRSxDQUFDO0NBQ25DOztBQ0ZjLFNBQVMsR0FBRyxJQUFJO0NBQzlCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQztDQUNuQzs7QUNDRCxPQUFPLENBQUMsR0FBRyxFQUFFLG9CQUFvQixFQUFFLENBQUM7O0FBRXBDLEdBQUcsRUFBRSxDQUFDO0FBQ04sR0FBRyxFQUFFLENBQUMifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXMuanMiLCJzb3VyY2VzIjpbIi4uL2Zvby5qcyIsIi4uL2Jhci5qcyIsIi4uL21haW4uanMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZm9vICgpIHtcblx0Y29uc29sZS5sb2coICdoZWxsbyBmcm9tIGZvby5qcycgKTtcbn1cbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGJhciAoKSB7XG5cdGNvbnNvbGUubG9nKCAnaGVsbG8gZnJvbSBiYXIuanMnICk7XG59XG4iLCJpbXBvcnQgZm9vIGZyb20gJy4vZm9vJztcbmltcG9ydCBiYXIgZnJvbSAnLi9iYXInO1xuXG5jb25zb2xlLmxvZyggJ2hlbGxvIGZyb20gbWFpbi5qcycgKTtcblxuZm9vKCk7XG5iYXIoKTtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBZSxTQUFTLEdBQUcsSUFBSTtDQUM5QixPQUFPLENBQUMsR0FBRyxFQUFFLG1CQUFtQixFQUFFLENBQUM7Q0FDbkM7O0FDRmMsU0FBUyxHQUFHLElBQUk7Q0FDOUIsT0FBTyxDQUFDLEdBQUcsRUFBRSxtQkFBbUIsRUFBRSxDQUFDO0NBQ25DOztBQ0NELE9BQU8sQ0FBQyxHQUFHLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQzs7QUFFcEMsR0FBRyxFQUFFLENBQUM7QUFDTixHQUFHLEVBQUUsQ0FBQyJ9 From 8c258786084713a866a1f6f6d0a6957673a7f156 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 19 Jun 2016 11:41:00 -0400 Subject: [PATCH 075/331] ensure local rollup build is used --- test/test.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/test/test.js b/test/test.js index f8c112e..47acb64 100644 --- a/test/test.js +++ b/test/test.js @@ -368,15 +368,9 @@ describe( 'rollup', function () { ( config.skip ? it.skip : config.solo ? it.only : it )( dir, function ( done ) { process.chdir( path.resolve( CLI, dir ) ); - if (os.platform() === 'win32') { - config.command = "node " + path.resolve( __dirname, '../bin' ) + path.sep + config.command; - } + const command = 'node ' + path.resolve( __dirname, '../bin' ) + path.sep + config.command; - exec( config.command, { - env: { - PATH: path.resolve( __dirname, '../bin' ) + path.delimiter + process.env.PATH - } - }, function ( err, code, stderr ) { + exec( command, {}, function ( err, code, stderr ) { if ( err ) { if ( config.error ) { config.error( err ); From 8950d406b754a5d954aa23dad865d703aa149a0b Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 19 Jun 2016 13:10:54 -0400 Subject: [PATCH 076/331] -> v0.32.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5df5a29..f5756d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.32.0 + +* Deprecate `es6` format in favour of `es` ([#468](https://github.com/rollup/rollup/issues/468)) +* Add correct `jsnext:main` build ([#726](https://github.com/rollup/rollup/pull/726)) + ## 0.31.2 * Allow `load` plugins to provide sourcemap ([#715](https://github.com/rollup/rollup/pull/715)) diff --git a/package.json b/package.json index f7c2bed..de52c12 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.31.2", + "version": "0.32.0", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "dist/rollup.es.js", From 391dee5c981a3c164aea55d0b4ce9009648df46a Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 19 Jun 2016 13:17:48 -0400 Subject: [PATCH 077/331] fix test --- test/sourcemaps/loaders/_config.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/sourcemaps/loaders/_config.js b/test/sourcemaps/loaders/_config.js index 8665133..53bae64 100644 --- a/test/sourcemaps/loaders/_config.js +++ b/test/sourcemaps/loaders/_config.js @@ -1,4 +1,4 @@ -var babel = require( 'babel-core' ); +var buble = require( 'buble' ); var fs = require( 'fs' ); var assert = require( 'assert' ); var getLocation = require( '../../utils/getLocation' ); @@ -16,10 +16,12 @@ module.exports = { id = id.replace( /bar.js$/, 'foo.js' ); } - var out = babel.transformFileSync( id, { - blacklist: [ 'es6.modules' ], + var code = fs.readFileSync( id, 'utf-8' ); + + var out = buble.transform( code, { + transforms: { modules: false }, sourceMap: true, - comments: false // misalign the columns + source: id }); if ( /main.js$/.test( id ) ) { From 6b1ac41bdc0131ef8a333700048ad065427ab8c2 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 19 Jun 2016 13:18:02 -0400 Subject: [PATCH 078/331] update self-dependency, move to es format --- package.json | 2 +- rollup.config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index de52c12..13d1692 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "mocha": "^2.5.3", "remap-istanbul": "^0.6.4", "require-relative": "^0.8.7", - "rollup": "^0.31.2", + "rollup": "^0.32.0", "rollup-plugin-buble": "^0.11.0", "rollup-plugin-commonjs": "^3.0.0", "rollup-plugin-json": "^2.0.0", diff --git a/rollup.config.js b/rollup.config.js index bfd6e83..bac62f2 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -42,6 +42,6 @@ export default { moduleName: 'rollup', targets: [ { dest: 'dist/rollup.js', format: 'cjs' }, - { dest: 'dist/rollup.es.js', format: 'es6' } + { dest: 'dist/rollup.es.js', format: 'es' } ] }; From 9454281953fce3472460421ec5d4a779ed76cac1 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 19 Jun 2016 13:19:11 -0400 Subject: [PATCH 079/331] remove unused promise helper --- browser/promise.js | 1 - rollup.config.browser.js | 1 - 2 files changed, 2 deletions(-) delete mode 100644 browser/promise.js diff --git a/browser/promise.js b/browser/promise.js deleted file mode 100644 index 06b8309..0000000 --- a/browser/promise.js +++ /dev/null @@ -1 +0,0 @@ -export default window.Promise; diff --git a/rollup.config.browser.js b/rollup.config.browser.js index adee949..86a0985 100644 --- a/rollup.config.browser.js +++ b/rollup.config.browser.js @@ -4,7 +4,6 @@ import config from './rollup.config.js'; config.plugins.push({ load: function ( id ) { if ( ~id.indexOf( 'fs.js' ) ) return readFileSync( 'browser/fs.js' ).toString(); - if ( ~id.indexOf( 'es6-promise' ) ) return readFileSync( 'browser/promise.js' ).toString(); } }); From d5c232d6ccc1f5f75b246e84323d4aefaabe8cb8 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 19 Jun 2016 23:06:46 +0300 Subject: [PATCH 080/331] Fail on duplicating in export * from --- src/Bundle.js | 19 ++++++++++++++++++- src/utils/object.js | 3 ++- .../double-named-export-from/_config.js | 14 ++++++++++++++ test/function/double-named-export-from/bar.js | 1 + .../function/double-named-export-from/deep.js | 1 + test/function/double-named-export-from/foo.js | 1 + .../function/double-named-export-from/main.js | 2 ++ 7 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 test/function/double-named-export-from/_config.js create mode 100644 test/function/double-named-export-from/bar.js create mode 100644 test/function/double-named-export-from/deep.js create mode 100644 test/function/double-named-export-from/foo.js create mode 100644 test/function/double-named-export-from/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 7d6904d..4c2f5a8 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -210,7 +210,24 @@ export default class Bundle { this.modules.push( module ); this.moduleById.set( id, module ); - return this.fetchAllDependencies( module ).then( () => module ); + return this.fetchAllDependencies( module ).then( () => { + module.exportsAll = blank(); + keys( module.exports ).forEach( name => { + module.exportsAll[name] = module.id; + }); + module.exportAllSources.forEach( source => { + const id = module.resolvedIds[ source ]; + const exportAllModule = this.moduleById.get( id ); + keys( exportAllModule.exportsAll ).forEach( name => { + if ( name in module.exportsAll ) { + throw new Error( `A module cannot have multiple exports with the same name ('${name}')` + + ` from ${module.exportsAll[ name ] } and ${exportAllModule.exportsAll[ name ]}` ); + } + module.exportsAll[ name ] = exportAllModule.exportsAll[ name ]; + }); + }); + return module; + }); }); } diff --git a/src/utils/object.js b/src/utils/object.js index 688b1ca..62c3a07 100644 --- a/src/utils/object.js +++ b/src/utils/object.js @@ -1,3 +1,4 @@ +const { hasOwnProperty } = Object.prototype; export const { keys } = Object; export function blank () { @@ -11,7 +12,7 @@ export function forOwn ( object, func ) { export function assign ( target, ...sources ) { sources.forEach( source => { for ( let key in source ) { - if ( source.hasOwnProperty( key ) ) target[ key ] = source[ key ]; + if ( hasOwnProperty.call( source, key ) ) target[ key ] = source[ key ]; } }); diff --git a/test/function/double-named-export-from/_config.js b/test/function/double-named-export-from/_config.js new file mode 100644 index 0000000..1b402d3 --- /dev/null +++ b/test/function/double-named-export-from/_config.js @@ -0,0 +1,14 @@ +const path = require('path'); +const assert = require( 'assert' ); + +function normalize( file ) { + return path.resolve( __dirname, file ).split( '\\' ).join( '/' ); +} + +module.exports = { + description: 'throws on duplicate export * from', + error: err => { + assert.equal( err.message, `A module cannot have multiple exports with the same name ('foo')` + + ` from ${normalize( 'foo.js' )} and ${normalize( 'deep.js' )}` ); + } +}; diff --git a/test/function/double-named-export-from/bar.js b/test/function/double-named-export-from/bar.js new file mode 100644 index 0000000..0dfd7e9 --- /dev/null +++ b/test/function/double-named-export-from/bar.js @@ -0,0 +1 @@ +export * from './deep.js'; \ No newline at end of file diff --git a/test/function/double-named-export-from/deep.js b/test/function/double-named-export-from/deep.js new file mode 100644 index 0000000..a7b877b --- /dev/null +++ b/test/function/double-named-export-from/deep.js @@ -0,0 +1 @@ +export var foo = 2; \ No newline at end of file diff --git a/test/function/double-named-export-from/foo.js b/test/function/double-named-export-from/foo.js new file mode 100644 index 0000000..467f528 --- /dev/null +++ b/test/function/double-named-export-from/foo.js @@ -0,0 +1 @@ +export var foo = 1; \ No newline at end of file diff --git a/test/function/double-named-export-from/main.js b/test/function/double-named-export-from/main.js new file mode 100644 index 0000000..ae6aade --- /dev/null +++ b/test/function/double-named-export-from/main.js @@ -0,0 +1,2 @@ +export * from './foo.js'; +export * from './bar.js'; \ No newline at end of file From 705b1e97a5d24de68be26d390b3d6e9f0be29d61 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 19 Jun 2016 23:09:47 +0300 Subject: [PATCH 081/331] Revert assign mod --- src/utils/object.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils/object.js b/src/utils/object.js index 62c3a07..688b1ca 100644 --- a/src/utils/object.js +++ b/src/utils/object.js @@ -1,4 +1,3 @@ -const { hasOwnProperty } = Object.prototype; export const { keys } = Object; export function blank () { @@ -12,7 +11,7 @@ export function forOwn ( object, func ) { export function assign ( target, ...sources ) { sources.forEach( source => { for ( let key in source ) { - if ( hasOwnProperty.call( source, key ) ) target[ key ] = source[ key ]; + if ( source.hasOwnProperty( key ) ) target[ key ] = source[ key ]; } }); From 69176879961a937ae4547d1c80b56975105e74be Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Mon, 20 Jun 2016 07:34:47 +0300 Subject: [PATCH 082/331] Fail on export all dup optionally --- src/Bundle.js | 5 +++++ src/rollup.js | 3 ++- test/function/double-named-export-from/_config.js | 3 +++ test/test.js | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 4c2f5a8..1f7c78a 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -26,6 +26,8 @@ export default class Bundle { }); } + this.failOnExportAllDup = Boolean( options.failOnExportAllDup ); + this.plugins = ensureArray( options.plugins ); this.plugins.forEach( plugin => { @@ -211,6 +213,9 @@ export default class Bundle { this.moduleById.set( id, module ); return this.fetchAllDependencies( module ).then( () => { + if ( !this.failOnExportAllDup ) { + return module; + } module.exportsAll = blank(); keys( module.exports ).forEach( name => { module.exportsAll[name] = module.id; diff --git a/src/rollup.js b/src/rollup.js index a9c50fd..5399dc3 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -31,7 +31,8 @@ const ALLOWED_KEYS = [ 'sourceMapFile', 'targets', 'treeshake', - 'useStrict' + 'useStrict', + 'failOnExportAllDup' ]; export function rollup ( options ) { diff --git a/test/function/double-named-export-from/_config.js b/test/function/double-named-export-from/_config.js index 1b402d3..0aaa1f5 100644 --- a/test/function/double-named-export-from/_config.js +++ b/test/function/double-named-export-from/_config.js @@ -7,6 +7,9 @@ function normalize( file ) { module.exports = { description: 'throws on duplicate export * from', + options: { + failOnExportAllDup: true + }, error: err => { assert.equal( err.message, `A module cannot have multiple exports with the same name ('foo')` + ` from ${normalize( 'foo.js' )} and ${normalize( 'deep.js' )}` ); diff --git a/test/test.js b/test/test.js index 30ec5f2..6bd60b1 100644 --- a/test/test.js +++ b/test/test.js @@ -76,7 +76,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( function () { throw new Error( 'Missing expected error' ); }, function ( err ) { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict, failOnExportAllDup' ); }); }); }); From a335283a73d2ef991773de8f9dd8fe2181f85565 Mon Sep 17 00:00:00 2001 From: operandom Date: Mon, 20 Jun 2016 12:25:05 +0200 Subject: [PATCH 083/331] Add test : handle external is a function in config. --- test/cli/config-external-function/_config.js | 4 +++ .../cli/config-external-function/_expected.js | 8 ++++++ test/cli/config-external-function/main.js | 6 +++++ .../config-external-function/rollup.config.js | 25 +++++++++++++++++++ 4 files changed, 43 insertions(+) create mode 100644 test/cli/config-external-function/_config.js create mode 100644 test/cli/config-external-function/_expected.js create mode 100644 test/cli/config-external-function/main.js create mode 100644 test/cli/config-external-function/rollup.config.js diff --git a/test/cli/config-external-function/_config.js b/test/cli/config-external-function/_config.js new file mode 100644 index 0000000..9f21d96 --- /dev/null +++ b/test/cli/config-external-function/_config.js @@ -0,0 +1,4 @@ +module.exports = { + description: 'external option gets passed from config', + command: 'rollup -c -e assert,external-module' +}; diff --git a/test/cli/config-external-function/_expected.js b/test/cli/config-external-function/_expected.js new file mode 100644 index 0000000..d760df4 --- /dev/null +++ b/test/cli/config-external-function/_expected.js @@ -0,0 +1,8 @@ +'use strict'; + +var ___config_js = require('./_config.js'); +var assert = require('assert'); +var externalModule = require('external-module'); + +assert.ok( ___config_js.execute ); +externalModule.method(); diff --git a/test/cli/config-external-function/main.js b/test/cli/config-external-function/main.js new file mode 100644 index 0000000..cfefa8c --- /dev/null +++ b/test/cli/config-external-function/main.js @@ -0,0 +1,6 @@ +import { execute } from './_config.js'; +import { ok } from 'assert'; +import { method } from 'external-module'; + +ok( execute ); +method(); diff --git a/test/cli/config-external-function/rollup.config.js b/test/cli/config-external-function/rollup.config.js new file mode 100644 index 0000000..ea45a3a --- /dev/null +++ b/test/cli/config-external-function/rollup.config.js @@ -0,0 +1,25 @@ +import assert from 'assert'; +import { resolve, sep } from 'path'; + +var config = resolve( './_config.js' ).split(sep).join('/'); + +export default { + entry: 'main.js', + format: 'cjs', + + external: function (id) { + if (id === config) { + return true; + } + + return false; + }, + + plugins: [ + { + load: function ( id ) { + assert.notEqual( id, config ); + } + } + ] +}; From 3b1275229784d4bd38f7cfd82061f7678fac3bff Mon Sep 17 00:00:00 2001 From: operandom Date: Mon, 20 Jun 2016 12:25:24 +0200 Subject: [PATCH 084/331] Add missing parameter. --- bin/src/runRollup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index 7299d07..ff89f41 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -99,7 +99,7 @@ function execute ( options, command ) { typeof options.external === 'function' ? ((fn, a) => { return function (id) { - return fn() || a.indexOf(id) !== -1; + return fn(id) || a.indexOf(id) !== -1; }; })(options.external, command.external.split(',')) : (options.external || []).concat(command.external.split(',')) : From 52511ef264e4f48a2084a8a55b2aa119c7d970c9 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 21 Jun 2016 13:48:17 -0400 Subject: [PATCH 085/331] remove node 5 from travis config, add node 6 to appveyor config --- .travis.yml | 1 - appveyor.yml | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8530cac..83d1bca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ language: node_js node_js: - "0.12" - "4" - - "5" - "6" env: global: diff --git a/appveyor.yml b/appveyor.yml index 6877afb..a4389cb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,6 +12,7 @@ environment: # node.js - nodejs_version: 0.12 - nodejs_version: 4 + - nodejs_version: 6 install: - ps: Install-Product node $env:nodejs_version From f6ac48283fa3b5675b2460e5c69d8b543c5afb31 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 21 Jun 2016 17:16:29 -0400 Subject: [PATCH 086/331] failing test for #733 --- test/function/export-two-ways-default/_config.js | 3 +++ test/function/export-two-ways-default/bar.js | 6 ++++++ test/function/export-two-ways-default/foo.js | 8 ++++++++ test/function/export-two-ways-default/main.js | 4 ++++ test/function/export-two-ways-default/x.js | 6 ++++++ 5 files changed, 27 insertions(+) create mode 100644 test/function/export-two-ways-default/_config.js create mode 100644 test/function/export-two-ways-default/bar.js create mode 100644 test/function/export-two-ways-default/foo.js create mode 100644 test/function/export-two-ways-default/main.js create mode 100644 test/function/export-two-ways-default/x.js diff --git a/test/function/export-two-ways-default/_config.js b/test/function/export-two-ways-default/_config.js new file mode 100644 index 0000000..88b207f --- /dev/null +++ b/test/function/export-two-ways-default/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'side-effects are preserved if subject is exported in multiple ways (#733)' +}; diff --git a/test/function/export-two-ways-default/bar.js b/test/function/export-two-ways-default/bar.js new file mode 100644 index 0000000..77de92f --- /dev/null +++ b/test/function/export-two-ways-default/bar.js @@ -0,0 +1,6 @@ +import { X } from './x.js'; // import X works + +X.prototype.bar = function () { + console.log( 'bar' ); + return this; +}; diff --git a/test/function/export-two-ways-default/foo.js b/test/function/export-two-ways-default/foo.js new file mode 100644 index 0000000..d31091b --- /dev/null +++ b/test/function/export-two-ways-default/foo.js @@ -0,0 +1,8 @@ +export function X () {} + +X.prototype.foo = function () { + console.log( 'foo' ); + return this; +}; + +export default X; // export {X as Y} with corresponding export {Y as X} in x.js works diff --git a/test/function/export-two-ways-default/main.js b/test/function/export-two-ways-default/main.js new file mode 100644 index 0000000..792e5a4 --- /dev/null +++ b/test/function/export-two-ways-default/main.js @@ -0,0 +1,4 @@ +import { x } from './x.js'; +import './bar.js'; + +x().foo().bar(); diff --git a/test/function/export-two-ways-default/x.js b/test/function/export-two-ways-default/x.js new file mode 100644 index 0000000..722cf4c --- /dev/null +++ b/test/function/export-two-ways-default/x.js @@ -0,0 +1,6 @@ +export { default as X } from './foo.js'; // export {X} works +import { X } from './foo.js'; // import X works + +export function x () { + return new X(); +} From e628775a424877bb1c49cb22426267da753e2eee Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 21 Jun 2016 17:27:21 -0400 Subject: [PATCH 087/331] track side-effects to default exports - fixes #733, sort of --- src/utils/run.js | 2 +- test/function/export-two-ways-default/bar.js | 2 +- test/function/export-two-ways-default/foo.js | 2 +- test/function/export-two-ways-default/main.js | 4 +++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/utils/run.js b/src/utils/run.js index 3e91d63..23b0493 100644 --- a/src/utils/run.js +++ b/src/utils/run.js @@ -104,7 +104,7 @@ export default function run ( node, scope, statement, strongDependencies, force } else { declaration = statement.module.trace( subject.name ); - if ( !declaration || declaration.isExternal || declaration.isUsed ) { + if ( !declaration || declaration.isExternal || declaration.isUsed || ( declaration.original && declaration.original.isUsed ) ) { hasSideEffect = true; } } diff --git a/test/function/export-two-ways-default/bar.js b/test/function/export-two-ways-default/bar.js index 77de92f..73801a6 100644 --- a/test/function/export-two-ways-default/bar.js +++ b/test/function/export-two-ways-default/bar.js @@ -1,6 +1,6 @@ import { X } from './x.js'; // import X works X.prototype.bar = function () { - console.log( 'bar' ); + this.didBar = true; return this; }; diff --git a/test/function/export-two-ways-default/foo.js b/test/function/export-two-ways-default/foo.js index d31091b..5b9b01e 100644 --- a/test/function/export-two-ways-default/foo.js +++ b/test/function/export-two-ways-default/foo.js @@ -1,7 +1,7 @@ export function X () {} X.prototype.foo = function () { - console.log( 'foo' ); + this.didFoo = true; return this; }; diff --git a/test/function/export-two-ways-default/main.js b/test/function/export-two-ways-default/main.js index 792e5a4..9b7c1d7 100644 --- a/test/function/export-two-ways-default/main.js +++ b/test/function/export-two-ways-default/main.js @@ -1,4 +1,6 @@ import { x } from './x.js'; import './bar.js'; -x().foo().bar(); +var result = x().foo().bar(); +assert.ok( result.didFoo ); +assert.ok( result.didBar ); From b0582a5384ab8be24f67f4715480930a3e3617a5 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 21 Jun 2016 17:34:52 -0400 Subject: [PATCH 088/331] add another failing test for #733, but skip it for now --- test/function/export-two-ways-default-b/_config.js | 4 ++++ test/function/export-two-ways-default-b/bar.js | 6 ++++++ test/function/export-two-ways-default-b/foo.js | 8 ++++++++ test/function/export-two-ways-default-b/main.js | 6 ++++++ test/function/export-two-ways-default-b/x.js | 6 ++++++ test/function/export-two-ways-default/bar.js | 2 +- test/function/export-two-ways-default/foo.js | 2 +- test/function/export-two-ways-default/x.js | 4 ++-- 8 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 test/function/export-two-ways-default-b/_config.js create mode 100644 test/function/export-two-ways-default-b/bar.js create mode 100644 test/function/export-two-ways-default-b/foo.js create mode 100644 test/function/export-two-ways-default-b/main.js create mode 100644 test/function/export-two-ways-default-b/x.js diff --git a/test/function/export-two-ways-default-b/_config.js b/test/function/export-two-ways-default-b/_config.js new file mode 100644 index 0000000..79fd012 --- /dev/null +++ b/test/function/export-two-ways-default-b/_config.js @@ -0,0 +1,4 @@ +module.exports = { + skip: true, + description: 'side-effects are preserved if subject is exported in multiple ways, even if default export has no direct link to original (#733)' +}; diff --git a/test/function/export-two-ways-default-b/bar.js b/test/function/export-two-ways-default-b/bar.js new file mode 100644 index 0000000..1ec6df4 --- /dev/null +++ b/test/function/export-two-ways-default-b/bar.js @@ -0,0 +1,6 @@ +import { X } from './x.js'; + +X.prototype.bar = function () { + this.didBar = true; + return this; +}; diff --git a/test/function/export-two-ways-default-b/foo.js b/test/function/export-two-ways-default-b/foo.js new file mode 100644 index 0000000..8c72ffc --- /dev/null +++ b/test/function/export-two-ways-default-b/foo.js @@ -0,0 +1,8 @@ +export function X () {} + +X.prototype.foo = function () { + this.didFoo = true; + return this; +}; + +export default ( false || X ); diff --git a/test/function/export-two-ways-default-b/main.js b/test/function/export-two-ways-default-b/main.js new file mode 100644 index 0000000..9b7c1d7 --- /dev/null +++ b/test/function/export-two-ways-default-b/main.js @@ -0,0 +1,6 @@ +import { x } from './x.js'; +import './bar.js'; + +var result = x().foo().bar(); +assert.ok( result.didFoo ); +assert.ok( result.didBar ); diff --git a/test/function/export-two-ways-default-b/x.js b/test/function/export-two-ways-default-b/x.js new file mode 100644 index 0000000..dcbe278 --- /dev/null +++ b/test/function/export-two-ways-default-b/x.js @@ -0,0 +1,6 @@ +export { default as X } from './foo.js'; +import { X } from './foo.js'; + +export function x () { + return new X(); +} diff --git a/test/function/export-two-ways-default/bar.js b/test/function/export-two-ways-default/bar.js index 73801a6..1ec6df4 100644 --- a/test/function/export-two-ways-default/bar.js +++ b/test/function/export-two-ways-default/bar.js @@ -1,4 +1,4 @@ -import { X } from './x.js'; // import X works +import { X } from './x.js'; X.prototype.bar = function () { this.didBar = true; diff --git a/test/function/export-two-ways-default/foo.js b/test/function/export-two-ways-default/foo.js index 5b9b01e..499b332 100644 --- a/test/function/export-two-ways-default/foo.js +++ b/test/function/export-two-ways-default/foo.js @@ -5,4 +5,4 @@ X.prototype.foo = function () { return this; }; -export default X; // export {X as Y} with corresponding export {Y as X} in x.js works +export default X; diff --git a/test/function/export-two-ways-default/x.js b/test/function/export-two-ways-default/x.js index 722cf4c..dcbe278 100644 --- a/test/function/export-two-ways-default/x.js +++ b/test/function/export-two-ways-default/x.js @@ -1,5 +1,5 @@ -export { default as X } from './foo.js'; // export {X} works -import { X } from './foo.js'; // import X works +export { default as X } from './foo.js'; +import { X } from './foo.js'; export function x () { return new X(); From 9edf864078be54858483559dbdcabb754c3aaeff Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 21 Jun 2016 18:03:02 -0400 Subject: [PATCH 089/331] only ignore top-level node_modules --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index c461514..f5abf8d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ .DS_Store -node_modules -!test/node_modules +/node_modules .gobble* dist _actual From e0e4dc1cd2f7abd0564432370189fe606e67eda3 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 21 Jun 2016 18:16:59 -0400 Subject: [PATCH 090/331] support rollup --config node:whatever (#736) --- bin/src/handleError.js | 4 ++++ bin/src/runRollup.js | 21 +++++++++++++++++-- test/cli/node-config-auto-prefix/_config.js | 5 +++++ test/cli/node-config-auto-prefix/_expected.js | 11 ++++++++++ test/cli/node-config-auto-prefix/main.js | 1 + .../rollup-config-foo/lib/config.js | 9 ++++++++ .../rollup-config-foo/package.json | 3 +++ test/cli/node-config/_config.js | 5 +++++ test/cli/node-config/_expected.js | 11 ++++++++++ test/cli/node-config/main.js | 1 + .../node_modules/foo/lib/config.js | 9 ++++++++ .../node-config/node_modules/foo/package.json | 3 +++ 12 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 test/cli/node-config-auto-prefix/_config.js create mode 100644 test/cli/node-config-auto-prefix/_expected.js create mode 100644 test/cli/node-config-auto-prefix/main.js create mode 100644 test/cli/node-config-auto-prefix/node_modules/rollup-config-foo/lib/config.js create mode 100644 test/cli/node-config-auto-prefix/node_modules/rollup-config-foo/package.json create mode 100644 test/cli/node-config/_config.js create mode 100644 test/cli/node-config/_expected.js create mode 100644 test/cli/node-config/main.js create mode 100644 test/cli/node-config/node_modules/foo/lib/config.js create mode 100644 test/cli/node-config/node_modules/foo/package.json diff --git a/bin/src/handleError.js b/bin/src/handleError.js index 243592c..80892fd 100644 --- a/bin/src/handleError.js +++ b/bin/src/handleError.js @@ -9,6 +9,10 @@ const handlers = { stderr( chalk.red( 'Config file must export an options object. See https://github.com/rollup/rollup/wiki/Command-Line-Interface#using-a-config-file' ) ); }, + MISSING_EXTERNAL_CONFIG: err => { + stderr( chalk.red( `Could not resolve config file ${err.config}` ) ); + }, + MISSING_INPUT_OPTION: () => { stderr( chalk.red( 'You must specify an --input (-i) option' ) ); }, diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index ff89f41..ce82d80 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -38,7 +38,24 @@ export default function runRollup ( command ) { let config = command.config === true ? 'rollup.config.js' : command.config; if ( config ) { - config = resolve( config ); + if ( config.slice( 0, 5 ) === 'node:' ) { + const pkgName = config.slice( 5 ); + try { + config = relative.resolve( pkgName, process.cwd() ); + } catch ( err ) { + try { + config = relative.resolve( `rollup-config-${pkgName}`, process.cwd() ); + } catch ( err ) { + if ( err.code === 'MODULE_NOT_FOUND' ) { + handleError({ code: 'MISSING_EXTERNAL_CONFIG', config }); + } + + throw err; + } + } + } else { + config = resolve( config ); + } rollup.rollup({ entry: config, @@ -225,4 +242,4 @@ function bundle ( options ) { process.stdout.write( code ); }); -} \ No newline at end of file +} diff --git a/test/cli/node-config-auto-prefix/_config.js b/test/cli/node-config-auto-prefix/_config.js new file mode 100644 index 0000000..88b1368 --- /dev/null +++ b/test/cli/node-config-auto-prefix/_config.js @@ -0,0 +1,5 @@ +module.exports = { + description: 'uses config file installed from npm', + command: 'rollup --config node:foo', + execute: true +}; diff --git a/test/cli/node-config-auto-prefix/_expected.js b/test/cli/node-config-auto-prefix/_expected.js new file mode 100644 index 0000000..b5aa08a --- /dev/null +++ b/test/cli/node-config-auto-prefix/_expected.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + global.myBundle = factory(); +}(this, function () { 'use strict'; + + var main = 42; + + return main; + +})); diff --git a/test/cli/node-config-auto-prefix/main.js b/test/cli/node-config-auto-prefix/main.js new file mode 100644 index 0000000..df16c1b --- /dev/null +++ b/test/cli/node-config-auto-prefix/main.js @@ -0,0 +1 @@ +assert.equal( ANSWER, 42 ); diff --git a/test/cli/node-config-auto-prefix/node_modules/rollup-config-foo/lib/config.js b/test/cli/node-config-auto-prefix/node_modules/rollup-config-foo/lib/config.js new file mode 100644 index 0000000..3cc995e --- /dev/null +++ b/test/cli/node-config-auto-prefix/node_modules/rollup-config-foo/lib/config.js @@ -0,0 +1,9 @@ +var replace = require( 'rollup-plugin-replace' ); + +module.exports = { + entry: 'main.js', + format: 'cjs', + plugins: [ + replace({ 'ANSWER': 42 }) + ] +}; diff --git a/test/cli/node-config-auto-prefix/node_modules/rollup-config-foo/package.json b/test/cli/node-config-auto-prefix/node_modules/rollup-config-foo/package.json new file mode 100644 index 0000000..fbd4901 --- /dev/null +++ b/test/cli/node-config-auto-prefix/node_modules/rollup-config-foo/package.json @@ -0,0 +1,3 @@ +{ + "main": "lib/config.js" +} diff --git a/test/cli/node-config/_config.js b/test/cli/node-config/_config.js new file mode 100644 index 0000000..88b1368 --- /dev/null +++ b/test/cli/node-config/_config.js @@ -0,0 +1,5 @@ +module.exports = { + description: 'uses config file installed from npm', + command: 'rollup --config node:foo', + execute: true +}; diff --git a/test/cli/node-config/_expected.js b/test/cli/node-config/_expected.js new file mode 100644 index 0000000..b5aa08a --- /dev/null +++ b/test/cli/node-config/_expected.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + global.myBundle = factory(); +}(this, function () { 'use strict'; + + var main = 42; + + return main; + +})); diff --git a/test/cli/node-config/main.js b/test/cli/node-config/main.js new file mode 100644 index 0000000..df16c1b --- /dev/null +++ b/test/cli/node-config/main.js @@ -0,0 +1 @@ +assert.equal( ANSWER, 42 ); diff --git a/test/cli/node-config/node_modules/foo/lib/config.js b/test/cli/node-config/node_modules/foo/lib/config.js new file mode 100644 index 0000000..3cc995e --- /dev/null +++ b/test/cli/node-config/node_modules/foo/lib/config.js @@ -0,0 +1,9 @@ +var replace = require( 'rollup-plugin-replace' ); + +module.exports = { + entry: 'main.js', + format: 'cjs', + plugins: [ + replace({ 'ANSWER': 42 }) + ] +}; diff --git a/test/cli/node-config/node_modules/foo/package.json b/test/cli/node-config/node_modules/foo/package.json new file mode 100644 index 0000000..fbd4901 --- /dev/null +++ b/test/cli/node-config/node_modules/foo/package.json @@ -0,0 +1,3 @@ +{ + "main": "lib/config.js" +} From 52729b190cb8d2142b9b743d16076f97a20bb603 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 22 Jun 2016 16:23:53 -0400 Subject: [PATCH 091/331] -> v0.32.1 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5756d5..045188b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.32.1 + +* Preserve side-effects to default exports that coincide with used named exports ([#733](https://github.com/rollup/rollup/issues/733)) +* Support `rollup -c node:pkgname` ([#736](https://github.com/rollup/rollup/issues/736)) + ## 0.32.0 * Deprecate `es6` format in favour of `es` ([#468](https://github.com/rollup/rollup/issues/468)) diff --git a/package.json b/package.json index 13d1692..d30eb52 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.32.0", + "version": "0.32.1", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "dist/rollup.es.js", From b478c19894fb2038bae555732cfe5191104e5a39 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 22 Jun 2016 16:28:49 -0400 Subject: [PATCH 092/331] look for rollup-config-whatever before looking for whatever, to avoid requiring wrong package --- bin/src/runRollup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index ce82d80..f959aac 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -41,10 +41,10 @@ export default function runRollup ( command ) { if ( config.slice( 0, 5 ) === 'node:' ) { const pkgName = config.slice( 5 ); try { - config = relative.resolve( pkgName, process.cwd() ); + config = relative.resolve( `rollup-config-${pkgName}`, process.cwd() ); } catch ( err ) { try { - config = relative.resolve( `rollup-config-${pkgName}`, process.cwd() ); + config = relative.resolve( pkgName, process.cwd() ); } catch ( err ) { if ( err.code === 'MODULE_NOT_FOUND' ) { handleError({ code: 'MISSING_EXTERNAL_CONFIG', config }); From b28a01901462d91960fce852d9a4b913c0ae673b Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 22 Jun 2016 18:19:05 -0400 Subject: [PATCH 093/331] synchronous ongenerate hook (#353) --- src/rollup.js | 24 ++++++++++++++++++++---- test/test.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/rollup.js b/src/rollup.js index a9c50fd..9a7df6f 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -1,6 +1,6 @@ import { basename } from './utils/path.js'; import { writeFile } from './utils/fs.js'; -import { keys } from './utils/object.js'; +import { assign, keys } from './utils/object.js'; import validateKeys from './utils/validateKeys.js'; import SOURCEMAPPING_URL from './utils/sourceMappingURL.js'; import Bundle from './Bundle.js'; @@ -52,19 +52,33 @@ export function rollup ( options ) { const bundle = new Bundle( options ); return bundle.build().then( () => { - return { + function generate ( options ) { + const rendered = bundle.render( options ); + + bundle.plugins.forEach( plugin => { + if ( plugin.ongenerate ) { + plugin.ongenerate( assign({ + bundle: result + }, options )); + } + }); + + return rendered; + } + + var result = { imports: bundle.externalModules.map( module => module.id ), exports: keys( bundle.entryModule.exports ), modules: bundle.orderedModules.map( module => module.toJSON() ), - generate: options => bundle.render( options ), + generate, write: options => { if ( !options || !options.dest ) { throw new Error( 'You must supply options.dest to bundle.write' ); } const dest = options.dest; - let { code, map } = bundle.render( options ); + let { code, map } = generate( options ); let promises = []; @@ -85,5 +99,7 @@ export function rollup ( options ) { return Promise.all( promises ); } }; + + return result; }); } diff --git a/test/test.js b/test/test.js index 30ec5f2..b494e5d 100644 --- a/test/test.js +++ b/test/test.js @@ -44,6 +44,18 @@ function loadConfig ( path ) { } } +function loader ( modules ) { + return { + resolveId ( id ) { + return id; + }, + + load ( id ) { + return modules[ id ]; + } + }; +} + describe( 'rollup', function () { this.timeout( 10000 ); @@ -533,4 +545,34 @@ describe( 'rollup', function () { }); }); }); + + describe( 'hooks', () => { + it( 'calls ongenerate hooks in sequence', () => { + var result = []; + + return rollup.rollup({ + entry: 'entry', + plugins: [ + loader({ entry: `alert('hello')` }), + { + ongenerate ( info ) { + result.push({ a: info.format }); + } + }, + { + ongenerate ( info ) { + result.push({ b: info.format }); + } + } + ] + }).then( bundle => { + bundle.generate({ format: 'cjs' }); + + assert.deepEqual( result, [ + { a: 'cjs' }, + { b: 'cjs' } + ]); + }); + }); + }); }); From 2a8bc9569e6131d1cc1683bc5dfb48029f47e249 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 22 Jun 2016 18:33:14 -0400 Subject: [PATCH 094/331] ass async onwrite hook --- src/rollup.js | 9 ++++++++- test/test.js | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/rollup.js b/src/rollup.js index 9a7df6f..1b4110e 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -1,6 +1,7 @@ import { basename } from './utils/path.js'; import { writeFile } from './utils/fs.js'; import { assign, keys } from './utils/object.js'; +import { mapSequence } from './utils/promise.js'; import validateKeys from './utils/validateKeys.js'; import SOURCEMAPPING_URL from './utils/sourceMappingURL.js'; import Bundle from './Bundle.js'; @@ -96,7 +97,13 @@ export function rollup ( options ) { } promises.push( writeFile( dest, code ) ); - return Promise.all( promises ); + return Promise.all( promises ).then( () => { + return mapSequence( bundle.plugins.filter( plugin => plugin.onwrite ), plugin => { + return Promise.resolve( plugin.onwrite( assign({ + bundle: result + }, options ))); + }); + }); } }; diff --git a/test/test.js b/test/test.js index b494e5d..1a8ea43 100644 --- a/test/test.js +++ b/test/test.js @@ -574,5 +574,44 @@ describe( 'rollup', function () { ]); }); }); + + it( 'calls onwrite hooks in sequence', () => { + var result = []; + var dest = path.join( __dirname, 'tmp/bundle.js' ); + + return rollup.rollup({ + entry: 'entry', + plugins: [ + loader({ entry: `alert('hello')` }), + { + onwrite ( info ) { + return new Promise( ( fulfil ) => { + result.push({ a: info.dest, format: info.format }); + fulfil(); + }); + } + }, + { + onwrite ( info ) { + result.push({ b: info.dest, format: info.format }); + } + } + ] + }).then( bundle => { + return bundle.write({ + dest, + format: 'cjs' + }); + + + }).then( () => { + assert.deepEqual( result, [ + { a: dest, format: 'cjs' }, + { b: dest, format: 'cjs' } + ]); + + return sander.unlink( dest ); + }); + }); }); }); From ec5b11f76b019ebf7418c78ffdb7f0d41ea13d61 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 22 Jun 2016 20:42:12 -0400 Subject: [PATCH 095/331] failing test for #743 --- test/cli/external-modules-auto-global/_config.js | 7 +++++++ test/cli/external-modules-auto-global/main.js | 3 +++ 2 files changed, 10 insertions(+) create mode 100644 test/cli/external-modules-auto-global/_config.js create mode 100644 test/cli/external-modules-auto-global/main.js diff --git a/test/cli/external-modules-auto-global/_config.js b/test/cli/external-modules-auto-global/_config.js new file mode 100644 index 0000000..7dbf418 --- /dev/null +++ b/test/cli/external-modules-auto-global/_config.js @@ -0,0 +1,7 @@ +const assert = require( 'assert' ); + +module.exports = { + description: 'populates options.external with --global keys', + command: 'rollup main.js --format iife --globals mathematics:Math', + execute: true +}; diff --git a/test/cli/external-modules-auto-global/main.js b/test/cli/external-modules-auto-global/main.js new file mode 100644 index 0000000..dcd8569 --- /dev/null +++ b/test/cli/external-modules-auto-global/main.js @@ -0,0 +1,3 @@ +import { max } from 'mathematics'; + +assert.equal( max( 1, 2, 3 ), 3 ); From 03ed02c0f63b8972216bc1f32ebf364e5796d276 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 22 Jun 2016 20:45:18 -0400 Subject: [PATCH 096/331] allow --globals to work with --external and options.external in whatever configuration (#743) --- bin/src/runRollup.js | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index f959aac..923fb1e 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -112,15 +112,10 @@ const equivalents = { }; function execute ( options, command ) { - let external = command.external ? - typeof options.external === 'function' ? - ((fn, a) => { - return function (id) { - return fn(id) || a.indexOf(id) !== -1; - }; - })(options.external, command.external.split(',')) : - (options.external || []).concat(command.external.split(',')) : - options.external; + let external; + + const commandExternal = ( command.external || '' ).split( ',' ); + const optionsExternal = options.external; if ( command.globals ) { let globals = Object.create( null ); @@ -130,14 +125,22 @@ function execute ( options, command ) { globals[ names[0] ] = names[1]; // Add missing Module IDs to external. - if ( external.indexOf( names[0] ) === -1 ) { - external.push( names[0] ); + if ( commandExternal.indexOf( names[0] ) === -1 ) { + commandExternal.push( names[0] ); } }); command.globals = globals; } + if ( typeof optionsExternal === 'function' ) { + external = id => { + return optionsExternal( id ) || ~commandExternal.indexOf( id ); + }; + } else { + external = ( optionsExternal || [] ).concat( commandExternal ); + } + options.onwarn = options.onwarn || stderr; options.external = external; From 19900ff17f25461a30f6dc2c2554db0b152510e8 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 22 Jun 2016 20:52:21 -0400 Subject: [PATCH 097/331] -> v0.32.2 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 045188b..1cc0ce5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.32.2 + +* Allow `--globals` to work with `--external` or `options.external` in whatever configuration ([#743](https://github.com/rollup/rollup/issues/743)) + ## 0.32.1 * Preserve side-effects to default exports that coincide with used named exports ([#733](https://github.com/rollup/rollup/issues/733)) diff --git a/package.json b/package.json index d30eb52..d7ccf56 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.32.1", + "version": "0.32.2", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "dist/rollup.es.js", From 87983313895ca2aea0ad0fb3c732636e96bc2e49 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Thu, 23 Jun 2016 09:02:32 +0300 Subject: [PATCH 098/331] Warn on namespace conflicts --- src/Bundle.js | 7 +------ src/rollup.js | 3 +-- test/function/double-named-export-from/_config.js | 9 ++++----- test/test.js | 2 +- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 1f7c78a..988ef7e 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -26,8 +26,6 @@ export default class Bundle { }); } - this.failOnExportAllDup = Boolean( options.failOnExportAllDup ); - this.plugins = ensureArray( options.plugins ); this.plugins.forEach( plugin => { @@ -213,9 +211,6 @@ export default class Bundle { this.moduleById.set( id, module ); return this.fetchAllDependencies( module ).then( () => { - if ( !this.failOnExportAllDup ) { - return module; - } module.exportsAll = blank(); keys( module.exports ).forEach( name => { module.exportsAll[name] = module.id; @@ -225,7 +220,7 @@ export default class Bundle { const exportAllModule = this.moduleById.get( id ); keys( exportAllModule.exportsAll ).forEach( name => { if ( name in module.exportsAll ) { - throw new Error( `A module cannot have multiple exports with the same name ('${name}')` + + this.onwarn( `A module cannot have multiple exports with the same name ('${name}')` + ` from ${module.exportsAll[ name ] } and ${exportAllModule.exportsAll[ name ]}` ); } module.exportsAll[ name ] = exportAllModule.exportsAll[ name ]; diff --git a/src/rollup.js b/src/rollup.js index 5399dc3..a9c50fd 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -31,8 +31,7 @@ const ALLOWED_KEYS = [ 'sourceMapFile', 'targets', 'treeshake', - 'useStrict', - 'failOnExportAllDup' + 'useStrict' ]; export function rollup ( options ) { diff --git a/test/function/double-named-export-from/_config.js b/test/function/double-named-export-from/_config.js index 0aaa1f5..183bb4c 100644 --- a/test/function/double-named-export-from/_config.js +++ b/test/function/double-named-export-from/_config.js @@ -6,12 +6,11 @@ function normalize( file ) { } module.exports = { + solo: true, description: 'throws on duplicate export * from', - options: { - failOnExportAllDup: true - }, - error: err => { - assert.equal( err.message, `A module cannot have multiple exports with the same name ('foo')` + + warnings(warnings) { + assert.equal( warnings[0], `A module cannot have multiple exports with the same name ('foo')` + ` from ${normalize( 'foo.js' )} and ${normalize( 'deep.js' )}` ); + assert.equal( warnings.length, 1 ); } }; diff --git a/test/test.js b/test/test.js index 6bd60b1..30ec5f2 100644 --- a/test/test.js +++ b/test/test.js @@ -76,7 +76,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( function () { throw new Error( 'Missing expected error' ); }, function ( err ) { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict, failOnExportAllDup' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); }); }); }); From 5028da3a27b703a2ced9b02645ff7aea136b0aad Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Thu, 23 Jun 2016 09:06:09 +0300 Subject: [PATCH 099/331] Test all --- test/function/double-named-export-from/_config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/function/double-named-export-from/_config.js b/test/function/double-named-export-from/_config.js index 183bb4c..ee0880f 100644 --- a/test/function/double-named-export-from/_config.js +++ b/test/function/double-named-export-from/_config.js @@ -6,7 +6,6 @@ function normalize( file ) { } module.exports = { - solo: true, description: 'throws on duplicate export * from', warnings(warnings) { assert.equal( warnings[0], `A module cannot have multiple exports with the same name ('foo')` + From 9f2a92d900aac1b796d99412d27cfd66ad700c55 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Thu, 23 Jun 2016 08:54:49 -0400 Subject: [PATCH 100/331] exclude plugin helpers from sourcemaps --- src/Module.js | 3 +- src/utils/collapseSourcemaps.js | 2 +- .../excludes-plugin-helpers/_config.js | 28 +++++++++++++++++++ .../excludes-plugin-helpers/helper.js | 3 ++ .../excludes-plugin-helpers/main.js | 3 ++ 5 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 test/sourcemaps/excludes-plugin-helpers/_config.js create mode 100644 test/sourcemaps/excludes-plugin-helpers/helper.js create mode 100644 test/sourcemaps/excludes-plugin-helpers/main.js diff --git a/src/Module.js b/src/Module.js index 98be8b1..4dd1b53 100644 --- a/src/Module.js +++ b/src/Module.js @@ -25,6 +25,7 @@ export default class Module { this.bundle = bundle; this.id = id; + this.excludeFromSourcemap = /\0/.test( id ); // all dependencies this.sources = []; @@ -42,7 +43,7 @@ export default class Module { // By default, `id` is the filename. Custom resolvers and loaders // can change that, but it makes sense to use it for the source filename this.magicString = new MagicString( code, { - filename: id, + filename: this.excludeFromSourcemap ? null : id, // don't include plugin helpers in sourcemap indentExclusionRanges: [] }); diff --git a/src/utils/collapseSourcemaps.js b/src/utils/collapseSourcemaps.js index 68a97e0..1820c30 100644 --- a/src/utils/collapseSourcemaps.js +++ b/src/utils/collapseSourcemaps.js @@ -98,7 +98,7 @@ class Link { } export default function collapseSourcemaps ( file, map, modules, bundleSourcemapChain ) { - const moduleSources = modules.map( module => { + const moduleSources = modules.filter( module => !module.excludeFromSourcemap ).map( module => { let sourceMapChain = module.sourceMapChain; let source; diff --git a/test/sourcemaps/excludes-plugin-helpers/_config.js b/test/sourcemaps/excludes-plugin-helpers/_config.js new file mode 100644 index 0000000..2014d88 --- /dev/null +++ b/test/sourcemaps/excludes-plugin-helpers/_config.js @@ -0,0 +1,28 @@ +const fs = require( 'fs' ); +const path = require( 'path' ); +const assert = require( 'assert' ); + +const HELPER = '\0helper'; + +module.exports = { + description: 'excludes plugin helpers from sources', + options: { + format: 'cjs', + plugins: [{ + resolveId ( id ) { + if ( id === HELPER ) return id; + }, + + load ( id ) { + if ( id === HELPER ) { + return fs.readFileSync( path.join( __dirname, 'helper.js' ), 'utf-8' ); + } + } + }] + }, + test: ( code, map ) => { + assert.equal( map.sources.length, 1 ); + assert.equal( map.sourcesContent.length, 1 ); + assert.ok( /main/.test( map.sources[0] ) ); + } +}; diff --git a/test/sourcemaps/excludes-plugin-helpers/helper.js b/test/sourcemaps/excludes-plugin-helpers/helper.js new file mode 100644 index 0000000..40205b6 --- /dev/null +++ b/test/sourcemaps/excludes-plugin-helpers/helper.js @@ -0,0 +1,3 @@ +export default function foo ( input ) { + assert.equal( input, 42 ); +} diff --git a/test/sourcemaps/excludes-plugin-helpers/main.js b/test/sourcemaps/excludes-plugin-helpers/main.js new file mode 100644 index 0000000..64577b6 --- /dev/null +++ b/test/sourcemaps/excludes-plugin-helpers/main.js @@ -0,0 +1,3 @@ +import foo from '\0helper'; + +foo( 42 ); From 3eae936dbc55c66849494cff31e14a0741bd6ff4 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 23 Jun 2016 11:25:30 -0400 Subject: [PATCH 101/331] generate correct sourcemap with reified namespaces (#668) --- package.json | 3 ++- test/sourcemaps/reified-namespace/_config.js | 22 ++++++++++++++++++++ test/sourcemaps/reified-namespace/foo.js | 1 + test/sourcemaps/reified-namespace/main.js | 3 +++ test/utils/getLocation.js | 4 +++- 5 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 test/sourcemaps/reified-namespace/_config.js create mode 100644 test/sourcemaps/reified-namespace/foo.js create mode 100644 test/sourcemaps/reified-namespace/main.js diff --git a/package.json b/package.json index d7ccf56..76ee2e6 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "posttest-coverage": "remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.json -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.lcov -t lcovonly -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped -t html -b dist", "ci": "npm run test-coverage && codecov < coverage/coverage-remapped.lcov", "build": "git rev-parse HEAD > .commithash && rollup -c", + "watch": "rollup -c -w", "build:cli": "rollup -c rollup.config.cli.js", "build:browser": "git rev-parse HEAD > .commithash && rollup -c rollup.config.browser.js -o dist/rollup.browser.js", "prepublish": "npm run lint && npm test && npm run build:browser", @@ -49,7 +50,7 @@ "eslint": "^2.13.0", "estree-walker": "^0.2.1", "istanbul": "^0.4.3", - "magic-string": "^0.15.1", + "magic-string": "^0.15.2", "minimist": "^1.2.0", "mocha": "^2.5.3", "remap-istanbul": "^0.6.4", diff --git a/test/sourcemaps/reified-namespace/_config.js b/test/sourcemaps/reified-namespace/_config.js new file mode 100644 index 0000000..8870098 --- /dev/null +++ b/test/sourcemaps/reified-namespace/_config.js @@ -0,0 +1,22 @@ +const fs = require( 'fs' ); +const path = require( 'path' ); +const assert = require( 'assert' ); +const getLocation = require( '../../utils/getLocation' ); +const SourceMapConsumer = require( 'source-map' ).SourceMapConsumer; + +module.exports = { + description: 'generates correct sourcemap with reified namespace (#668)', + test: ( code, map ) => { + const smc = new SourceMapConsumer( map ); + + const main = fs.readFileSync( path.join( __dirname, 'main.js' ), 'utf-8' ); + const generatedLoc = getLocation( code, 'deepEqual' ); + + const actual = smc.originalPositionFor( generatedLoc ); + const expected = getLocation( main, 'deepEqual' ); + + assert.equal( actual.line, expected.line ); + assert.equal( actual.column, expected.column ); + assert.equal( actual.source, '../main.js' ); + } +}; diff --git a/test/sourcemaps/reified-namespace/foo.js b/test/sourcemaps/reified-namespace/foo.js new file mode 100644 index 0000000..ab0c7db --- /dev/null +++ b/test/sourcemaps/reified-namespace/foo.js @@ -0,0 +1 @@ +export var bar = 42; diff --git a/test/sourcemaps/reified-namespace/main.js b/test/sourcemaps/reified-namespace/main.js new file mode 100644 index 0000000..565c1eb --- /dev/null +++ b/test/sourcemaps/reified-namespace/main.js @@ -0,0 +1,3 @@ +import * as foo from './foo.js'; + +assert.deepEqual( foo, { bar: 42 }); diff --git a/test/utils/getLocation.js b/test/utils/getLocation.js index 4993997..b92d38b 100644 --- a/test/utils/getLocation.js +++ b/test/utils/getLocation.js @@ -1,10 +1,12 @@ -module.exports = function getLocation ( source, charIndex ) { +module.exports = function getLocation ( source, search ) { var lines = source.split( '\n' ); var len = lines.length; var lineStart = 0; var i; + const charIndex = typeof search === 'number' ? search : source.indexOf( search ); + for ( i = 0; i < len; i += 1 ) { var line = lines[i]; var lineEnd = lineStart + line.length + 1; // +1 for newline From d3bd8217329fac62616d1f6bb1142d7687e4e117 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 23 Jun 2016 11:33:25 -0400 Subject: [PATCH 102/331] -> v0.32.3 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cc0ce5..fca57fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.32.3 + +* Generated correct sourcemaps with reified namespaces ([#668](https://github.com/rollup/rollup/issues/668)) +* Exclude plugin helper modules from sourcemaps ([#747](https://github.com/rollup/rollup/pull/747)) + ## 0.32.2 * Allow `--globals` to work with `--external` or `options.external` in whatever configuration ([#743](https://github.com/rollup/rollup/issues/743)) diff --git a/package.json b/package.json index 76ee2e6..9dd3eef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.32.2", + "version": "0.32.3", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "dist/rollup.es.js", From 53edfac1f2625d78110fa56021182c32510096f4 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 23 Jun 2016 14:08:56 -0400 Subject: [PATCH 103/331] -> v0.32.4 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fca57fe..f1c5945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.32.4 + +* Add `ongenerate` and `onwrite` plugin hooks ([#742](https://github.com/rollup/rollup/pull/742)) + ## 0.32.3 * Generated correct sourcemaps with reified namespaces ([#668](https://github.com/rollup/rollup/issues/668)) diff --git a/package.json b/package.json index 9dd3eef..3c3bc58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.32.3", + "version": "0.32.4", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "dist/rollup.es.js", From 84cccae433dc554af43dc3b0b4dfccbb2d2a8764 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 23 Jun 2016 14:28:16 -0400 Subject: [PATCH 104/331] change language to reflect the fact that conflicting namespaces are permitted, if discouraged --- src/Bundle.js | 3 +-- test/function/double-named-export-from/_config.js | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 988ef7e..489c45d 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -220,8 +220,7 @@ export default class Bundle { const exportAllModule = this.moduleById.get( id ); keys( exportAllModule.exportsAll ).forEach( name => { if ( name in module.exportsAll ) { - this.onwarn( `A module cannot have multiple exports with the same name ('${name}')` + - ` from ${module.exportsAll[ name ] } and ${exportAllModule.exportsAll[ name ]}` ); + this.onwarn( `Conflicting namespaces: ${module.id} re-exports '${name}' from both ${module.exportsAll[ name ]} (will be ignored) and ${exportAllModule.exportsAll[ name ]}.` ); } module.exportsAll[ name ] = exportAllModule.exportsAll[ name ]; }); diff --git a/test/function/double-named-export-from/_config.js b/test/function/double-named-export-from/_config.js index ee0880f..09cb582 100644 --- a/test/function/double-named-export-from/_config.js +++ b/test/function/double-named-export-from/_config.js @@ -1,15 +1,15 @@ const path = require('path'); const assert = require( 'assert' ); -function normalize( file ) { +function normalize ( file ) { return path.resolve( __dirname, file ).split( '\\' ).join( '/' ); } module.exports = { description: 'throws on duplicate export * from', - warnings(warnings) { - assert.equal( warnings[0], `A module cannot have multiple exports with the same name ('foo')` + - ` from ${normalize( 'foo.js' )} and ${normalize( 'deep.js' )}` ); - assert.equal( warnings.length, 1 ); + warnings ( warnings ) { + assert.deepEqual( warnings, [ + `Conflicting namespaces: ${normalize('main.js')} re-exports 'foo' from both ${normalize('foo.js')} (will be ignored) and ${normalize('deep.js')}.` + ]); } }; From 78db6134afd2e371e75d06abe846e51064ef61f6 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 23 Jun 2016 15:30:46 -0400 Subject: [PATCH 105/331] indicate source of transform error where possible, and downgrade non-sourcemap-generating transforms to a warning (#746) --- src/Bundle.js | 17 ++++-------- src/utils/array.js | 7 +++++ src/utils/collapseSourcemaps.js | 13 +++++++--- src/utils/transform.js | 23 ++++++++-------- src/utils/transformBundle.js | 16 +++++++++--- .../transform-without-sourcemap/_config.js | 26 +++++++++++++++++++ .../transform-without-sourcemap/main.js | 1 + test/test.js | 1 + 8 files changed, 75 insertions(+), 29 deletions(-) create mode 100644 src/utils/array.js create mode 100644 test/sourcemaps/transform-without-sourcemap/_config.js create mode 100644 test/sourcemaps/transform-without-sourcemap/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 489c45d..5d8f5bd 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -1,5 +1,6 @@ import { Bundle as MagicStringBundle } from 'magic-string'; import first from './utils/first.js'; +import { find } from './utils/array.js'; import { blank, forOwn, keys } from './utils/object.js'; import Module from './Module.js'; import ExternalModule from './ExternalModule.js'; @@ -52,14 +53,6 @@ export default class Bundle { this.hasLoaders = loaders.length !== 0; this.load = first( loaders.concat( load ) ); - this.transformers = this.plugins - .map( plugin => plugin.transform ) - .filter( Boolean ); - - this.bundleTransformers = this.plugins - .map( plugin => plugin.transformBundle ) - .filter( Boolean ); - this.moduleById = new Map(); this.modules = []; @@ -200,7 +193,7 @@ export default class Bundle { return this.cachedModules.get( id ); } - return transform( source, id, this.transformers ); + return transform( source, id, this.plugins ); }) .then( source => { const { code, originalCode, originalSourceMap, ast, sourceMapChain } = source; @@ -350,16 +343,16 @@ export default class Bundle { let map = null; let bundleSourcemapChain = []; - code = transformBundle( code, this.bundleTransformers, bundleSourcemapChain ) + code = transformBundle( code, this.plugins, bundleSourcemapChain ) .replace( new RegExp( `\\/\\/#\\s+${SOURCEMAPPING_URL}=.+\\n?`, 'g' ), '' ); if ( options.sourceMap ) { let file = options.sourceMapFile || options.dest; if ( file ) file = resolve( typeof process !== 'undefined' ? process.cwd() : '', file ); - if ( this.hasLoaders || this.transformers.length || this.bundleTransformers.length ) { + if ( this.hasLoaders || find( this.plugins, plugin => plugin.transform || plugin.transformBundle ) ) { map = magicString.generateMap( {} ); - map = collapseSourcemaps( file, map, usedModules, bundleSourcemapChain ); + map = collapseSourcemaps( file, map, usedModules, bundleSourcemapChain, this.onwarn ); } else { map = magicString.generateMap({ file, includeContent: true }); } diff --git a/src/utils/array.js b/src/utils/array.js new file mode 100644 index 0000000..c7910e2 --- /dev/null +++ b/src/utils/array.js @@ -0,0 +1,7 @@ +export function find ( array, fn ) { + for ( let i = 0; i < array.length; i += 1 ) { + if ( fn( array[i], i ) ) return array[i]; + } + + return null; +} diff --git a/src/utils/collapseSourcemaps.js b/src/utils/collapseSourcemaps.js index 1820c30..ddf2dc5 100644 --- a/src/utils/collapseSourcemaps.js +++ b/src/utils/collapseSourcemaps.js @@ -15,8 +15,6 @@ class Source { class Link { constructor ( map, sources ) { - if ( !map ) throw new Error( 'Cannot generate a sourcemap if non-sourcemap-generating transformers are used' ); - this.sources = sources; this.names = map.names; this.mappings = decode( map.mappings ); @@ -97,7 +95,7 @@ class Link { } } -export default function collapseSourcemaps ( file, map, modules, bundleSourcemapChain ) { +export default function collapseSourcemaps ( file, map, modules, bundleSourcemapChain, onwarn ) { const moduleSources = modules.filter( module => !module.excludeFromSourcemap ).map( module => { let sourceMapChain = module.sourceMapChain; @@ -125,6 +123,15 @@ export default function collapseSourcemaps ( file, map, modules, bundleSourcemap } sourceMapChain.forEach( map => { + if ( map.missing ) { + onwarn( `Sourcemap is likely to be incorrect: a plugin${map.plugin ? ` ('${map.plugin}')` : ``} was used to transform files, but didn't generate a sourcemap for the transformation. Consult https://github.com/rollup/rollup/wiki/Troubleshooting and the plugin documentation for more information` ); + + map = { + names: [], + mappings: '' + }; + } + source = new Link( map, [ source ]); }); diff --git a/src/utils/transform.js b/src/utils/transform.js index 285eea0..a1286b2 100644 --- a/src/utils/transform.js +++ b/src/utils/transform.js @@ -1,4 +1,4 @@ -export default function transform ( source, id, transformers ) { +export default function transform ( source, id, plugins ) { let sourceMapChain = []; const originalSourceMap = typeof source.map === 'string' ? JSON.parse( source.map ) : source.map; @@ -6,9 +6,11 @@ export default function transform ( source, id, transformers ) { let originalCode = source.code; let ast = source.ast; - return transformers.reduce( ( promise, transformer ) => { + return plugins.reduce( ( promise, plugin ) => { return promise.then( previous => { - return Promise.resolve( transformer( previous, id ) ).then( result => { + if ( !plugin.transform ) return previous; + + return Promise.resolve( plugin.transform( previous, id ) ).then( result => { if ( result == null ) return previous; if ( typeof result === 'string' ) { @@ -23,19 +25,18 @@ export default function transform ( source, id, transformers ) { result.map = JSON.parse( result.map ); } - sourceMapChain.push( result.map ); + sourceMapChain.push( result.map || { missing: true, plugin: plugin.name }); // lil' bit hacky but it works ast = result.ast; return result.code; }); + }).catch( err => { + err.id = id; + err.plugin = plugin.name; + err.message = `Error transforming ${id}${plugin.name ? ` with '${plugin.name}' plugin` : ''}: ${err.message}`; + throw err; }); - }, Promise.resolve( source.code ) ) - .then( code => ({ code, originalCode, originalSourceMap, ast, sourceMapChain }) ) - .catch( err => { - err.id = id; - err.message = `Error loading ${id}: ${err.message}`; - throw err; - }); + .then( code => ({ code, originalCode, originalSourceMap, ast, sourceMapChain }) ); } diff --git a/src/utils/transformBundle.js b/src/utils/transformBundle.js index 56a4359..400e994 100644 --- a/src/utils/transformBundle.js +++ b/src/utils/transformBundle.js @@ -1,6 +1,16 @@ -export default function transformBundle ( code, transformers, sourceMapChain ) { - return transformers.reduce( ( code, transformer ) => { - let result = transformer( code ); +export default function transformBundle ( code, plugins, sourceMapChain ) { + return plugins.reduce( ( code, plugin ) => { + if ( !plugin.transformBundle ) return code; + + let result; + + try { + result = plugin.transformBundle( code ); + } catch ( err ) { + err.plugin = plugin.name; + err.message = `Error transforming bundle${plugin.name ? ` with '${plugin.name}' plugin` : ''}: ${err.message}`; + throw err; + } if ( result == null ) return code; diff --git a/test/sourcemaps/transform-without-sourcemap/_config.js b/test/sourcemaps/transform-without-sourcemap/_config.js new file mode 100644 index 0000000..ad33354 --- /dev/null +++ b/test/sourcemaps/transform-without-sourcemap/_config.js @@ -0,0 +1,26 @@ +const assert = require( 'assert' ); + +let warnings = []; + +module.exports = { + description: 'preserves sourcemap chains when transforming', + before: () => warnings = [], // reset + options: { + plugins: [ + { + name: 'fake plugin', + transform: function ( code ) { + return code; + } + } + ], + onwarn ( msg ) { + warnings.push( msg ); + } + }, + test: () => { + assert.deepEqual( warnings, [ + `Sourcemap is likely to be incorrect: a plugin ('fake plugin') was used to transform files, but didn't generate a sourcemap for the transformation. Consult https://github.com/rollup/rollup/wiki/Troubleshooting and the plugin documentation for more information` + ]); + } +}; diff --git a/test/sourcemaps/transform-without-sourcemap/main.js b/test/sourcemaps/transform-without-sourcemap/main.js new file mode 100644 index 0000000..5c72ff3 --- /dev/null +++ b/test/sourcemaps/transform-without-sourcemap/main.js @@ -0,0 +1 @@ +console.log( 42 ); diff --git a/test/test.js b/test/test.js index 1a8ea43..3cc959b 100644 --- a/test/test.js +++ b/test/test.js @@ -358,6 +358,7 @@ describe( 'rollup', function () { bundle.write( options ); + if ( config.before ) config.before(); var result = bundle.generate( options ); config.test( result.code, result.map ); }); From 85f5e1f3473991fc9fd9d4736936cbf306822e0c Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Thu, 23 Jun 2016 21:55:31 -0400 Subject: [PATCH 106/331] -> v0.33.0 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1c5945..d7e14ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.33.0 + +* Downgrade missing transformer sourcemap to a warning, not an error, and print the name of the offending plugin if possible ([#746](https://github.com/rollup/rollup/issues/746)) +* Warn if same name is re-exported from two modules ([#722](https://github.com/rollup/rollup/issues/722)) + ## 0.32.4 * Add `ongenerate` and `onwrite` plugin hooks ([#742](https://github.com/rollup/rollup/pull/742)) diff --git a/package.json b/package.json index 3c3bc58..74d2b5b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.32.4", + "version": "0.33.0", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "dist/rollup.es.js", From 28491ea5403736c1a0746b32042debdba3aa1573 Mon Sep 17 00:00:00 2001 From: 1111hui <26634873@qq.com> Date: Sat, 25 Jun 2016 13:51:35 +0800 Subject: [PATCH 107/331] FIX: --no-strict command line option not map bug --- bin/src/runRollup.js | 1 + test/cli/no-strict/_config.js | 4 ++++ test/cli/no-strict/_expected.js | 4 ++++ test/cli/no-strict/main.js | 1 + 4 files changed, 10 insertions(+) create mode 100644 test/cli/no-strict/_config.js create mode 100644 test/cli/no-strict/_expected.js create mode 100644 test/cli/no-strict/main.js diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index 923fb1e..c7e09d5 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -96,6 +96,7 @@ export default function runRollup ( command ) { } const equivalents = { + useStrict: 'useStrict', banner: 'banner', footer: 'footer', format: 'format', diff --git a/test/cli/no-strict/_config.js b/test/cli/no-strict/_config.js new file mode 100644 index 0000000..efc646d --- /dev/null +++ b/test/cli/no-strict/_config.js @@ -0,0 +1,4 @@ +module.exports = { + description: 'use no strict option', + command: 'rollup -i main.js -f iife --no-strict' +}; diff --git a/test/cli/no-strict/_expected.js b/test/cli/no-strict/_expected.js new file mode 100644 index 0000000..d7c1012 --- /dev/null +++ b/test/cli/no-strict/_expected.js @@ -0,0 +1,4 @@ +(function () { + console.log( 42 ); + +}()); diff --git a/test/cli/no-strict/main.js b/test/cli/no-strict/main.js new file mode 100644 index 0000000..5c72ff3 --- /dev/null +++ b/test/cli/no-strict/main.js @@ -0,0 +1 @@ +console.log( 42 ); From ce1c784f5b6a3d476518fd4ee0a9c62c2499366a Mon Sep 17 00:00:00 2001 From: Kurt Blackwell Date: Thu, 30 Jun 2016 20:38:20 +0800 Subject: [PATCH 108/331] Use fs.realpathSync() rather than path.resolve() to match filenames passed to require.extensions[]. On Windows resolve(...) returns "c:\..." but realpath(...) returns "C:\...". --- bin/src/runRollup.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index 923fb1e..5613dbb 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -1,4 +1,4 @@ -import { resolve } from 'path'; +import { realpathSync } from 'fs'; import relative from 'require-relative'; import handleError from './handleError'; import SOURCEMAPPING_URL from './sourceMappingUrl.js'; @@ -54,7 +54,8 @@ export default function runRollup ( command ) { } } } else { - config = resolve( config ); + // find real path of config so it matches what Node provides to callbacks in require.extensions + config = realpathSync( config ); } rollup.rollup({ @@ -79,7 +80,7 @@ export default function runRollup ( command ) { }; try { - const options = require( resolve( config ) ); + const options = require( config ); if ( Object.keys( options ).length === 0 ) { handleError({ code: 'MISSING_CONFIG' }); } From 5605ce5c85c48a7f3e2cff30fb059f803866aec0 Mon Sep 17 00:00:00 2001 From: Kurt Blackwell Date: Fri, 1 Jul 2016 22:21:26 +0800 Subject: [PATCH 109/331] Add a test for loading config when the drive letter doesn't match after realpath. List 'fs' as external dependency. --- rollup.config.cli.js | 1 + test/cli/config-cwd-case-insensitive/_config.js | 13 +++++++++++++ test/cli/config-cwd-case-insensitive/main.js | 1 + .../config-cwd-case-insensitive/rollup.config.js | 9 +++++++++ test/test.js | 2 +- 5 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test/cli/config-cwd-case-insensitive/_config.js create mode 100644 test/cli/config-cwd-case-insensitive/main.js create mode 100644 test/cli/config-cwd-case-insensitive/rollup.config.js diff --git a/rollup.config.cli.js b/rollup.config.cli.js index 0e0eed6..95e8588 100644 --- a/rollup.config.cli.js +++ b/rollup.config.cli.js @@ -22,6 +22,7 @@ export default { }) ], external: [ + 'fs', 'path', 'module', 'source-map-support' diff --git a/test/cli/config-cwd-case-insensitive/_config.js b/test/cli/config-cwd-case-insensitive/_config.js new file mode 100644 index 0000000..d07b87d --- /dev/null +++ b/test/cli/config-cwd-case-insensitive/_config.js @@ -0,0 +1,13 @@ +var os = require( 'os' ); + +function toggleCase ( s ) { + return ( s == s.toLowerCase() ) ? s.toUpperCase() : s.toLowerCase(); +} + +module.exports = { + skip: os.platform() !== 'win32', + description: "can load config with cwd that doesn't match realpath", + command: 'rollup -c', + cwd: process.cwd().replace( /^[A-Z]:\\/ig, toggleCase ), + execute: true +}; diff --git a/test/cli/config-cwd-case-insensitive/main.js b/test/cli/config-cwd-case-insensitive/main.js new file mode 100644 index 0000000..df16c1b --- /dev/null +++ b/test/cli/config-cwd-case-insensitive/main.js @@ -0,0 +1 @@ +assert.equal( ANSWER, 42 ); diff --git a/test/cli/config-cwd-case-insensitive/rollup.config.js b/test/cli/config-cwd-case-insensitive/rollup.config.js new file mode 100644 index 0000000..3cc995e --- /dev/null +++ b/test/cli/config-cwd-case-insensitive/rollup.config.js @@ -0,0 +1,9 @@ +var replace = require( 'rollup-plugin-replace' ); + +module.exports = { + entry: 'main.js', + format: 'cjs', + plugins: [ + replace({ 'ANSWER': 42 }) + ] +}; diff --git a/test/test.js b/test/test.js index 3cc959b..0ba18fe 100644 --- a/test/test.js +++ b/test/test.js @@ -376,7 +376,7 @@ describe( 'rollup', function () { var config = loadConfig( CLI + '/' + dir + '/_config.js' ); ( config.skip ? it.skip : config.solo ? it.only : it )( dir, function ( done ) { - process.chdir( path.resolve( CLI, dir ) ); + process.chdir( config.cwd || path.resolve( CLI, dir ) ); const command = 'node ' + path.resolve( __dirname, '../bin' ) + path.sep + config.command; From e37bc0be8de47ee80905c3700c2ff23cee33f777 Mon Sep 17 00:00:00 2001 From: Kurt Blackwell Date: Sat, 2 Jul 2016 21:04:42 +0800 Subject: [PATCH 110/331] Set directory before each sourcemap test so that it can be depended on. Remove relative-paths' dependency on path.relative with process.cwd() which doesn't work in some situations. --- test/cli/config-cwd-case-insensitive/_config.js | 2 +- test/sourcemaps/relative-paths/_config.js | 6 ++---- test/test.js | 2 ++ 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/cli/config-cwd-case-insensitive/_config.js b/test/cli/config-cwd-case-insensitive/_config.js index d07b87d..3bd80d0 100644 --- a/test/cli/config-cwd-case-insensitive/_config.js +++ b/test/cli/config-cwd-case-insensitive/_config.js @@ -8,6 +8,6 @@ module.exports = { skip: os.platform() !== 'win32', description: "can load config with cwd that doesn't match realpath", command: 'rollup -c', - cwd: process.cwd().replace( /^[A-Z]:\\/ig, toggleCase ), + cwd: __dirname.replace( /^[A-Z]:\\/i, toggleCase ), execute: true }; diff --git a/test/sourcemaps/relative-paths/_config.js b/test/sourcemaps/relative-paths/_config.js index 5c12d05..1d72cda 100644 --- a/test/sourcemaps/relative-paths/_config.js +++ b/test/sourcemaps/relative-paths/_config.js @@ -1,13 +1,11 @@ var path = require( 'path' ); var assert = require( 'assert' ); -var pathRelativeToCwd = path.relative( process.cwd(), path.resolve( __dirname, '_actual/bundle.js' ) ); - module.exports = { - description: 'source paths are relative (#344)', + description: 'source paths are relative with relative dest (#344)', options: { moduleName: 'myModule', - dest: pathRelativeToCwd + dest: path.resolve( '_actual/bundle.js' ) }, test: function ( code, map ) { assert.deepEqual( map.sources, [ '../main.js' ]); diff --git a/test/test.js b/test/test.js index 0ba18fe..8996b27 100644 --- a/test/test.js +++ b/test/test.js @@ -338,6 +338,7 @@ describe( 'rollup', function () { if ( dir[0] === '.' ) return; // .DS_Store... describe( dir, function () { + process.chdir( SOURCEMAPS + '/' + dir ); var config = loadConfig( SOURCEMAPS + '/' + dir + '/_config.js' ); var entry = path.resolve( SOURCEMAPS, dir, 'main.js' ); @@ -349,6 +350,7 @@ describe( 'rollup', function () { PROFILES.forEach( function ( profile ) { ( config.skip ? it.skip : config.solo ? it.only : it )( 'generates ' + profile.format, function () { + process.chdir( SOURCEMAPS + '/' + dir ); return rollup.rollup( options ).then( function ( bundle ) { var options = extend( {}, { format: profile.format, From c043a413b2110ec169d3cbc37b91a112726e0d59 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Thu, 7 Jul 2016 22:58:32 -0400 Subject: [PATCH 111/331] -> v0.33.1 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e14ef..1adfd50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.33.1 + +* Fix `--no-strict` option ([#751](https://github.com/rollup/rollup/pull/751)) +* Fix Windows edge case with case-sensitive paths ([#760](https://github.com/rollup/rollup/pull/760)) + ## 0.33.0 * Downgrade missing transformer sourcemap to a warning, not an error, and print the name of the offending plugin if possible ([#746](https://github.com/rollup/rollup/issues/746)) diff --git a/package.json b/package.json index 74d2b5b..4dbfed1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.33.0", + "version": "0.33.1", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "dist/rollup.es.js", From a9c5850c8552e297945e9ee7f324be17593f14e6 Mon Sep 17 00:00:00 2001 From: bmaurer Date: Thu, 7 Jul 2016 19:58:34 -0700 Subject: [PATCH 112/331] Avoid lazy parsing by adding parens around factory Most javascript engines do a lazy parsing optimization. For example if they see: function X() {...} They won't parse the contents of X until it is executed. However they often have to read the contents of X so that they can see if X uses any variables from the outer scope. Thus X ends up getting parsed twice. Realizing that often one immediately executes a function, browser have optimized statements of the form: (function X() {...})() So that X is not parsed lazily. Traditionally this optimization looks for an open paren before the function. For example, here's the optimization in v8: https://github.com/v8/v8/blob/203391bcc0e970d3cae27ba99afd337c1c5f6d42/src/parsing/parser.cc#L4256 Since the factory is immediately executed (at least in the commonJS and global export case), this change avoids the double parsing that comes with parsing the function lazily. --- src/finalisers/umd.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index a31c5c9..9c91e46 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -59,7 +59,7 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, typeof exports === 'object' && typeof module !== 'undefined' ? ${cjsExport}factory(${cjsDeps.join( ', ' )}) : typeof define === 'function' && define.amd ? define(${amdParams}factory) : ${globalExport}; - }(this, function (${args}) {${useStrict} + }(this, (function (${args}) {${useStrict} `.replace( /^\t\t/gm, '' ).replace( /^\t/gm, magicString.getIndentString() ); @@ -77,6 +77,6 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, return magicString .trim() .indent( indentString ) - .append( '\n\n}));' ) + .append( '\n\n})));' ) .prepend( intro ); } From 4a8ce666abcf47471e0726d0fba135ece1ccf8f9 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Thu, 7 Jul 2016 23:22:34 -0400 Subject: [PATCH 113/331] =?UTF-8?q?warn=20on=20top-level=20`this`=20?= =?UTF-8?q?=E2=80=93=20fixes=20#770?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Statement.js | 1 + test/form/this-is-undefined/_config.js | 5 ++++- test/function/warn-on-top-level-this/_config.js | 13 +++++++++++++ test/function/warn-on-top-level-this/main.js | 1 + test/test.js | 4 ++-- 5 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 test/function/warn-on-top-level-this/_config.js create mode 100644 test/function/warn-on-top-level-this/main.js diff --git a/src/Statement.js b/src/Statement.js index 8723ad5..c9b01f8 100644 --- a/src/Statement.js +++ b/src/Statement.js @@ -61,6 +61,7 @@ export default class Statement { if ( node.type === 'ThisExpression' && contextDepth === 0 ) { module.magicString.overwrite( node.start, node.end, 'undefined' ); + module.bundle.onwarn( 'The `this` keyword is equivalent to `undefined` at the top level of an ES module, and has been rewritten' ); } if ( node._scope ) scope = node._scope; diff --git a/test/form/this-is-undefined/_config.js b/test/form/this-is-undefined/_config.js index 155461a..7513402 100644 --- a/test/form/this-is-undefined/_config.js +++ b/test/form/this-is-undefined/_config.js @@ -1,3 +1,6 @@ module.exports = { - description: 'top-level `this` expression is rewritten as `undefined`' + description: 'top-level `this` expression is rewritten as `undefined`', + options: { + onwarn: () => {} + } }; diff --git a/test/function/warn-on-top-level-this/_config.js b/test/function/warn-on-top-level-this/_config.js new file mode 100644 index 0000000..c667044 --- /dev/null +++ b/test/function/warn-on-top-level-this/_config.js @@ -0,0 +1,13 @@ +const assert = require( 'assert' ); + +module.exports = { + description: 'warns on top-level this (#770)', + warnings: warnings => { + assert.deepEqual( warnings, [ + 'The `this` keyword is equivalent to `undefined` at the top level of an ES module, and has been rewritten' + ]); + }, + runtimeError: err => { + assert.equal( err.message, `Cannot set property 'foo' of undefined` ); + } +}; diff --git a/test/function/warn-on-top-level-this/main.js b/test/function/warn-on-top-level-this/main.js new file mode 100644 index 0000000..3853449 --- /dev/null +++ b/test/function/warn-on-top-level-this/main.js @@ -0,0 +1 @@ +this.foo = 'bar'; diff --git a/test/test.js b/test/test.js index 8996b27..0ed678e 100644 --- a/test/test.js +++ b/test/test.js @@ -279,14 +279,14 @@ describe( 'rollup', function () { if ( config.skipIfWindows && process.platform === 'win32' ) return; - var options = extend( {}, config.options, { + var options = extend( {}, { entry: FORM + '/' + dir + '/main.js', onwarn: msg => { if ( /No name was provided for/.test( msg ) ) return; if ( /as external dependency/.test( msg ) ) return; console.error( msg ); } - }); + }, config.options ); ( config.skip ? describe.skip : config.solo ? describe.only : describe)( dir, function () { PROFILES.forEach( function ( profile ) { From 9acb92dcd02d0f9f008b284a7a8be22cd3048bcb Mon Sep 17 00:00:00 2001 From: Pat Cavit Date: Thu, 7 Jul 2016 10:21:34 -0700 Subject: [PATCH 114/331] Try making ongenerate/onwrite more useful --- src/rollup.js | 7 ++++--- test/test.js | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/rollup.js b/src/rollup.js index 1b4110e..e3a91b2 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -60,7 +60,7 @@ export function rollup ( options ) { if ( plugin.ongenerate ) { plugin.ongenerate( assign({ bundle: result - }, options )); + }, options ), rendered); } }); @@ -79,7 +79,8 @@ export function rollup ( options ) { } const dest = options.dest; - let { code, map } = generate( options ); + let output = generate( options ); + let { code, map } = output; let promises = []; @@ -101,7 +102,7 @@ export function rollup ( options ) { return mapSequence( bundle.plugins.filter( plugin => plugin.onwrite ), plugin => { return Promise.resolve( plugin.onwrite( assign({ bundle: result - }, options ))); + }, options ), output)); }); }); } diff --git a/test/test.js b/test/test.js index 8996b27..4f2bce1 100644 --- a/test/test.js +++ b/test/test.js @@ -550,6 +550,32 @@ describe( 'rollup', function () { }); describe( 'hooks', () => { + it( 'passes bundle & output object to ongenerate & onwrite hooks', () => { + var dest = path.join( __dirname, 'tmp/bundle.js' ); + + return rollup.rollup({ + entry: 'entry', + plugins: [ + loader({ entry: `alert('hello')` }), + { + ongenerate ( bundle, out ) { + out.ongenerate = true; + }, + + onwrite (bundle, out ) { + assert.equal(out.ongenerate, true); + } + } + ] + }).then( bundle => { + return bundle.write({ + dest + }); + }).then( () => { + return sander.unlink( dest ); + }); + }); + it( 'calls ongenerate hooks in sequence', () => { var result = []; From fdaf343911ae1512bdc3c58e833ec2f5856c05e9 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 10:06:58 -0400 Subject: [PATCH 115/331] -> v0.33.2 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1adfd50..c3c4e34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.33.2 + +* Add `bundle` as second argument to `ongenerate` and `onwrite` hooks ([#773](https://github.com/rollup/rollup/pull/773)) +* Warn on top-level `this` ([#770](https://github.com/rollup/rollup/issues/770)) + ## 0.33.1 * Fix `--no-strict` option ([#751](https://github.com/rollup/rollup/pull/751)) diff --git a/package.json b/package.json index 4dbfed1..4abcd9d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.33.1", + "version": "0.33.2", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "dist/rollup.es.js", From 31f55a47552f21f4b2c573c36244f46531c70550 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 12:19:04 -0400 Subject: [PATCH 116/331] use resolved IDs for external modules to allow options.globals to work with relative imports (#763) --- src/Bundle.js | 59 +++++++------------ src/ExternalModule.js | 6 +- src/finalisers/amd.js | 4 +- src/finalisers/cjs.js | 8 +-- src/finalisers/es.js | 4 +- src/finalisers/umd.js | 4 +- src/utils/map-helpers.js | 6 +- .../relative-external-with-global/_config.js | 13 ++++ .../_expected/amd.js | 11 ++++ .../_expected/cjs.js | 11 ++++ .../_expected/es.js | 7 +++ .../_expected/iife.js | 12 ++++ .../_expected/umd.js | 15 +++++ .../relative-external-with-global/main.js | 7 +++ test/test.js | 4 +- 15 files changed, 118 insertions(+), 53 deletions(-) create mode 100644 test/form/relative-external-with-global/_config.js create mode 100644 test/form/relative-external-with-global/_expected/amd.js create mode 100644 test/form/relative-external-with-global/_expected/cjs.js create mode 100644 test/form/relative-external-with-global/_expected/es.js create mode 100644 test/form/relative-external-with-global/_expected/iife.js create mode 100644 test/form/relative-external-with-global/_expected/umd.js create mode 100644 test/form/relative-external-with-global/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 5d8f5bd..74a7800 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -227,40 +227,27 @@ export default class Bundle { return mapSequence( module.sources, source => { return this.resolveId( source, module.id ) .then( resolvedId => { - let externalName; - if ( resolvedId ) { - // If the `resolvedId` is supposed to be external, make it so. - externalName = resolvedId.replace( /[\/\\]/g, '/' ); - } else if ( isRelative( source ) ) { - // This could be an external, relative dependency, based on the current module's parent dir. - externalName = resolve( module.id, '..', source ); + const externalId = resolvedId ? resolvedId.replace( /[\/\\]/g, '/' ) : + isRelative( source ) ? resolve( module.id, '..', source ) : source; + + let isExternal = this.isExternal( externalId ); + + if ( !resolvedId && !isExternal ) { + if ( isRelative( source ) ) throw new Error( `Could not resolve ${source} from ${module.id}` ); + + this.onwarn( `Treating '${source}' as external dependency` ); + isExternal = true; } - const forcedExternal = externalName && this.isExternal( externalName ); - - if ( !resolvedId || forcedExternal ) { - let normalizedExternal = source; - - if ( !forcedExternal ) { - if ( isRelative( source ) ) throw new Error( `Could not resolve ${source} from ${module.id}` ); - if ( !this.isExternal( source ) ) this.onwarn( `Treating '${source}' as external dependency` ); - } else if ( resolvedId ) { - if ( isRelative(resolvedId) || isAbsolute(resolvedId) ) { - // Try to deduce relative path from entry dir if resolvedId is defined as a relative path. - normalizedExternal = this.getPathRelativeToEntryDirname( resolvedId ); - } else { - normalizedExternal = resolvedId; - } - } - module.resolvedIds[ source ] = normalizedExternal; - if ( !this.moduleById.has( normalizedExternal ) ) { - const module = new ExternalModule( normalizedExternal ); + if ( isExternal ) { + module.resolvedIds[ source ] = externalId; + + if ( !this.moduleById.has( externalId ) ) { + const module = new ExternalModule( externalId, this.getPathRelativeToEntryDirname( externalId ) ); this.externalModules.push( module ); - this.moduleById.set( normalizedExternal, module ); + this.moduleById.set( externalId, module ); } - } - - else { + } else { if ( resolvedId === module.id ) { throw new Error( `A module cannot import itself (${resolvedId})` ); } @@ -273,16 +260,14 @@ export default class Bundle { } getPathRelativeToEntryDirname ( resolvedId ) { - // Get a path relative to the resolved entry directory - const entryDirname = dirname( this.entryId ); - const relativeToEntry = relative( entryDirname, resolvedId ); + if ( isRelative( resolvedId ) || isAbsolute( resolvedId ) ) { + const entryDirname = dirname( this.entryId ); + const relativeToEntry = relative( entryDirname, resolvedId ); - if ( isRelative( relativeToEntry )) { - return relativeToEntry; + return isRelative( relativeToEntry ) ? relativeToEntry : `./${relativeToEntry}`; } - // The path is missing the `./` prefix - return `./${relativeToEntry}`; + return resolvedId; } render ( options = {} ) { diff --git a/src/ExternalModule.js b/src/ExternalModule.js index db9c062..e532f25 100644 --- a/src/ExternalModule.js +++ b/src/ExternalModule.js @@ -3,9 +3,11 @@ import makeLegalIdentifier from './utils/makeLegalIdentifier.js'; import { ExternalDeclaration } from './Declaration.js'; export default class ExternalModule { - constructor ( id ) { + constructor ( id, relativePath ) { this.id = id; - this.name = makeLegalIdentifier( id ); + this.path = relativePath; + + this.name = makeLegalIdentifier( relativePath ); this.nameSuggestions = blank(); this.mostCommonSuggestion = 0; diff --git a/src/finalisers/amd.js b/src/finalisers/amd.js index 2ac7e6d..8567ad6 100644 --- a/src/finalisers/amd.js +++ b/src/finalisers/amd.js @@ -1,10 +1,10 @@ -import { getName, quoteId } from '../utils/map-helpers.js'; +import { getName, quotePath } from '../utils/map-helpers.js'; import getInteropBlock from './shared/getInteropBlock.js'; import getExportBlock from './shared/getExportBlock.js'; import esModuleExport from './shared/esModuleExport.js'; export default function amd ( bundle, magicString, { exportMode, indentString }, options ) { - let deps = bundle.externalModules.map( quoteId ); + let deps = bundle.externalModules.map( quotePath ); let args = bundle.externalModules.map( getName ); if ( exportMode === 'named' ) { diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index a7500aa..6900f6d 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -14,20 +14,20 @@ export default function cjs ( bundle, magicString, { exportMode }, options ) { .map( module => { if ( module.declarations.default ) { if ( module.exportsNamespace ) { - return `${varOrConst} ${module.name} = require('${module.id}');` + + return `${varOrConst} ${module.name} = require('${module.path}');` + `\n${varOrConst} ${module.name}__default = ${module.name}['default'];`; } needsInterop = true; if ( module.exportsNames ) { - return `${varOrConst} ${module.name} = require('${module.id}');` + + return `${varOrConst} ${module.name} = require('${module.path}');` + `\n${varOrConst} ${module.name}__default = _interopDefault(${module.name});`; } - return `${varOrConst} ${module.name} = _interopDefault(require('${module.id}'));`; + return `${varOrConst} ${module.name} = _interopDefault(require('${module.path}'));`; } else { - return `${varOrConst} ${module.name} = require('${module.id}');`; + return `${varOrConst} ${module.name} = require('${module.path}');`; } }) .join( '\n' ); diff --git a/src/finalisers/es.js b/src/finalisers/es.js index 96b5943..45036de 100644 --- a/src/finalisers/es.js +++ b/src/finalisers/es.js @@ -42,8 +42,8 @@ export default function es ( bundle, magicString ) { return specifiersList .map( specifiers => specifiers.length ? - `import ${specifiers.join( ', ' )} from '${module.id}';` : - `import '${module.id}';` + `import ${specifiers.join( ', ' )} from '${module.path}';` : + `import '${module.path}';` ) .join( '\n' ); }) diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index a31c5c9..0039a7b 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -1,5 +1,5 @@ import { blank } from '../utils/object.js'; -import { getName, quoteId, req } from '../utils/map-helpers.js'; +import { getName, quotePath, req } from '../utils/map-helpers.js'; import getInteropBlock from './shared/getInteropBlock.js'; import getExportBlock from './shared/getExportBlock.js'; import getGlobalNameMaker from './shared/getGlobalNameMaker.js'; @@ -23,7 +23,7 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, const globalNameMaker = getGlobalNameMaker( options.globals || blank(), bundle.onwarn ); - let amdDeps = bundle.externalModules.map( quoteId ); + let amdDeps = bundle.externalModules.map( quotePath ); let cjsDeps = bundle.externalModules.map( req ); let globalDeps = bundle.externalModules.map( module => `global.${globalNameMaker( module )}` ); diff --git a/src/utils/map-helpers.js b/src/utils/map-helpers.js index 49e0942..6ce7293 100644 --- a/src/utils/map-helpers.js +++ b/src/utils/map-helpers.js @@ -2,10 +2,10 @@ export function getName ( x ) { return x.name; } -export function quoteId ( x ) { - return `'${x.id}'`; +export function quotePath ( x ) { + return `'${x.path}'`; } export function req ( x ) { - return `require('${x.id}')`; + return `require('${x.path}')`; } diff --git a/test/form/relative-external-with-global/_config.js b/test/form/relative-external-with-global/_config.js new file mode 100644 index 0000000..677bef1 --- /dev/null +++ b/test/form/relative-external-with-global/_config.js @@ -0,0 +1,13 @@ +const { resolve } = require( 'path' ); + +const throttle = resolve( __dirname, 'lib/throttle.js' ); + +module.exports = { + description: 'applies globals to externalised relative imports', + options: { + external: [ throttle ], + globals: { + [ throttle ]: 'Lib.throttle' + } + } +}; diff --git a/test/form/relative-external-with-global/_expected/amd.js b/test/form/relative-external-with-global/_expected/amd.js new file mode 100644 index 0000000..538e97a --- /dev/null +++ b/test/form/relative-external-with-global/_expected/amd.js @@ -0,0 +1,11 @@ +define(['./lib/throttle.js'], function (throttle) { 'use strict'; + + throttle = 'default' in throttle ? throttle['default'] : throttle; + + const fn = throttle( () => { + console.log( '.' ); + }, 500 ); + + window.addEventListener( 'mousemove', throttle ); + +}); \ No newline at end of file diff --git a/test/form/relative-external-with-global/_expected/cjs.js b/test/form/relative-external-with-global/_expected/cjs.js new file mode 100644 index 0000000..1b74d56 --- /dev/null +++ b/test/form/relative-external-with-global/_expected/cjs.js @@ -0,0 +1,11 @@ +'use strict'; + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var throttle = _interopDefault(require('./lib/throttle.js')); + +const fn = throttle( () => { + console.log( '.' ); +}, 500 ); + +window.addEventListener( 'mousemove', throttle ); \ No newline at end of file diff --git a/test/form/relative-external-with-global/_expected/es.js b/test/form/relative-external-with-global/_expected/es.js new file mode 100644 index 0000000..fe8f7cf --- /dev/null +++ b/test/form/relative-external-with-global/_expected/es.js @@ -0,0 +1,7 @@ +import throttle from './lib/throttle.js'; + +const fn = throttle( () => { + console.log( '.' ); +}, 500 ); + +window.addEventListener( 'mousemove', throttle ); \ No newline at end of file diff --git a/test/form/relative-external-with-global/_expected/iife.js b/test/form/relative-external-with-global/_expected/iife.js new file mode 100644 index 0000000..a0efcee --- /dev/null +++ b/test/form/relative-external-with-global/_expected/iife.js @@ -0,0 +1,12 @@ +(function (throttle) { + 'use strict'; + + throttle = 'default' in throttle ? throttle['default'] : throttle; + + const fn = throttle( () => { + console.log( '.' ); + }, 500 ); + + window.addEventListener( 'mousemove', throttle ); + +}(Lib.throttle)); diff --git a/test/form/relative-external-with-global/_expected/umd.js b/test/form/relative-external-with-global/_expected/umd.js new file mode 100644 index 0000000..4dc4fc9 --- /dev/null +++ b/test/form/relative-external-with-global/_expected/umd.js @@ -0,0 +1,15 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('./lib/throttle.js')) : + typeof define === 'function' && define.amd ? define(['./lib/throttle.js'], factory) : + (factory(global.Lib.throttle)); +}(this, function (throttle) { 'use strict'; + + throttle = 'default' in throttle ? throttle['default'] : throttle; + + const fn = throttle( () => { + console.log( '.' ); + }, 500 ); + + window.addEventListener( 'mousemove', throttle ); + +})); diff --git a/test/form/relative-external-with-global/main.js b/test/form/relative-external-with-global/main.js new file mode 100644 index 0000000..750ac95 --- /dev/null +++ b/test/form/relative-external-with-global/main.js @@ -0,0 +1,7 @@ +import throttle from './lib/throttle.js'; + +const fn = throttle( () => { + console.log( '.' ); +}, 500 ); + +window.addEventListener( 'mousemove', throttle ); diff --git a/test/test.js b/test/test.js index f44c61a..c7ea116 100644 --- a/test/test.js +++ b/test/test.js @@ -40,6 +40,8 @@ function loadConfig ( path ) { try { return require( path ); } catch ( err ) { + console.error( err.message ); + console.error( err.stack ); throw new Error( 'Failed to load ' + path + '. An old test perhaps? You should probably delete the directory' ); } } @@ -552,7 +554,7 @@ describe( 'rollup', function () { describe( 'hooks', () => { it( 'passes bundle & output object to ongenerate & onwrite hooks', () => { var dest = path.join( __dirname, 'tmp/bundle.js' ); - + return rollup.rollup({ entry: 'entry', plugins: [ From 6a03009faa27313db26aa7e48baf4deb30d246a4 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 12:47:18 -0400 Subject: [PATCH 117/331] dont normalize ID before checking if its external --- src/Bundle.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 74a7800..8e5bcdb 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -227,8 +227,9 @@ export default class Bundle { return mapSequence( module.sources, source => { return this.resolveId( source, module.id ) .then( resolvedId => { - const externalId = resolvedId ? resolvedId.replace( /[\/\\]/g, '/' ) : - isRelative( source ) ? resolve( module.id, '..', source ) : source; + const externalId = resolvedId || ( + isRelative( source ) ? resolve( module.id, '..', source ) : source + ); let isExternal = this.isExternal( externalId ); From 5b4f70725dbee1a78063415adff3aaf70af1f03d Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 13:21:22 -0400 Subject: [PATCH 118/331] experimenting with using native path methods to try and fix windows bugs --- src/utils/path.js | 66 +---------------------------------------------- 1 file changed, 1 insertion(+), 65 deletions(-) diff --git a/src/utils/path.js b/src/utils/path.js index ec749a4..57ecf7e 100644 --- a/src/utils/path.js +++ b/src/utils/path.js @@ -11,68 +11,4 @@ export function isRelative ( path ) { return relativePath.test( path ); } -export function basename ( path ) { - return path.split( /(\/|\\)/ ).pop(); -} - -export function dirname ( path ) { - const match = /(\/|\\)[^\/\\]*$/.exec( path ); - if ( !match ) return '.'; - - const dir = path.slice( 0, -match[0].length ); - - // If `dir` is the empty string, we're at root. - return dir ? dir : '/'; -} - -export function extname ( path ) { - const match = /\.[^\.]+$/.exec( basename( path ) ); - if ( !match ) return ''; - return match[0]; -} - -export function relative ( from, to ) { - const fromParts = from.split( /[\/\\]/ ).filter( Boolean ); - const toParts = to.split( /[\/\\]/ ).filter( Boolean ); - - while ( fromParts[0] && toParts[0] && fromParts[0] === toParts[0] ) { - fromParts.shift(); - toParts.shift(); - } - - while ( toParts[0] === '.' || toParts[0] === '..' ) { - const toPart = toParts.shift(); - if ( toPart === '..' ) { - fromParts.pop(); - } - } - - while ( fromParts.pop() ) { - toParts.unshift( '..' ); - } - - return toParts.join( '/' ); -} - -export function resolve ( ...paths ) { - let resolvedParts = paths.shift().split( /[\/\\]/ ); - - paths.forEach( path => { - if ( isAbsolute( path ) ) { - resolvedParts = path.split( /[\/\\]/ ); - } else { - const parts = path.split( /[\/\\]/ ); - - while ( parts[0] === '.' || parts[0] === '..' ) { - const part = parts.shift(); - if ( part === '..' ) { - resolvedParts.pop(); - } - } - - resolvedParts.push.apply( resolvedParts, parts ); - } - }); - - return resolvedParts.join( '/' ); // TODO windows... -} +export { basename, dirname, extname, relative, resolve } from 'path'; From cf4d914c118dd9900ff5b90cf772cdb5cb7824f3 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 14:10:17 -0400 Subject: [PATCH 119/331] gah windows --- src/Bundle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle.js b/src/Bundle.js index 8e5bcdb..4fb290c 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -64,7 +64,7 @@ export default class Bundle { if ( typeof options.external === 'function' ) { this.isExternal = options.external; } else { - const ids = ensureArray( options.external ).map( id => id.replace( /[\/\\]/g, '/' ) ); + const ids = ensureArray( options.external ); this.isExternal = id => ids.indexOf( id ) !== -1; } From 9b165aba78a964033448681cc8789bd1fa39d1a0 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 14:16:53 -0400 Subject: [PATCH 120/331] normalize external relative paths --- src/Bundle.js | 4 ++-- src/utils/path.js | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 4fb290c..9b9d9c1 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -16,7 +16,7 @@ import transformBundle from './utils/transformBundle.js'; import collapseSourcemaps from './utils/collapseSourcemaps.js'; import SOURCEMAPPING_URL from './utils/sourceMappingURL.js'; import callIfFunction from './utils/callIfFunction.js'; -import { dirname, isRelative, isAbsolute, relative, resolve } from './utils/path.js'; +import { dirname, isRelative, isAbsolute, normalize, relative, resolve } from './utils/path.js'; export default class Bundle { constructor ( options ) { @@ -263,7 +263,7 @@ export default class Bundle { getPathRelativeToEntryDirname ( resolvedId ) { if ( isRelative( resolvedId ) || isAbsolute( resolvedId ) ) { const entryDirname = dirname( this.entryId ); - const relativeToEntry = relative( entryDirname, resolvedId ); + const relativeToEntry = normalize( relative( entryDirname, resolvedId ) ); return isRelative( relativeToEntry ) ? relativeToEntry : `./${relativeToEntry}`; } diff --git a/src/utils/path.js b/src/utils/path.js index 57ecf7e..5cdd62f 100644 --- a/src/utils/path.js +++ b/src/utils/path.js @@ -11,4 +11,8 @@ export function isRelative ( path ) { return relativePath.test( path ); } +export function normalize ( path ) { + return path.replace( /\\/g, '/' ); +} + export { basename, dirname, extname, relative, resolve } from 'path'; From 262dccfd6fbf2856a586f71d5e8394e8dbb9afce Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 14:38:35 -0400 Subject: [PATCH 121/331] update test --- test/cli/config-external-function/rollup.config.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/test/cli/config-external-function/rollup.config.js b/test/cli/config-external-function/rollup.config.js index ea45a3a..acc77cc 100644 --- a/test/cli/config-external-function/rollup.config.js +++ b/test/cli/config-external-function/rollup.config.js @@ -1,19 +1,13 @@ import assert from 'assert'; -import { resolve, sep } from 'path'; +import { resolve } from 'path'; -var config = resolve( './_config.js' ).split(sep).join('/'); +var config = resolve( './_config.js' ); export default { entry: 'main.js', format: 'cjs', - external: function (id) { - if (id === config) { - return true; - } - - return false; - }, + external: id => id === config, plugins: [ { From aa4cf42f45b162f33172d8e1d7226a3ab3d7c536 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 14:43:31 -0400 Subject: [PATCH 122/331] fix another test --- test/function/double-named-export-from/_config.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/function/double-named-export-from/_config.js b/test/function/double-named-export-from/_config.js index 09cb582..b3885d2 100644 --- a/test/function/double-named-export-from/_config.js +++ b/test/function/double-named-export-from/_config.js @@ -1,15 +1,13 @@ -const path = require('path'); +const { resolve } = require('path'); const assert = require( 'assert' ); -function normalize ( file ) { - return path.resolve( __dirname, file ).split( '\\' ).join( '/' ); -} +const r = path => resolve( __dirname, path ); module.exports = { description: 'throws on duplicate export * from', warnings ( warnings ) { assert.deepEqual( warnings, [ - `Conflicting namespaces: ${normalize('main.js')} re-exports 'foo' from both ${normalize('foo.js')} (will be ignored) and ${normalize('deep.js')}.` + `Conflicting namespaces: ${r('main.js')} re-exports 'foo' from both ${r('foo.js')} (will be ignored) and ${r('deep.js')}.` ]); } }; From bfe49e3d2ddfc5d9cd8fc46d3ce1de78a421e6fe Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 14:56:14 -0400 Subject: [PATCH 123/331] whoops, config file cant have ES6 in node 0.12 --- test/cli/config-external-function/rollup.config.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/cli/config-external-function/rollup.config.js b/test/cli/config-external-function/rollup.config.js index acc77cc..1036220 100644 --- a/test/cli/config-external-function/rollup.config.js +++ b/test/cli/config-external-function/rollup.config.js @@ -7,7 +7,9 @@ export default { entry: 'main.js', format: 'cjs', - external: id => id === config, + external: function ( id ) { + return id === config; + }, plugins: [ { From 8dfbfa3ea59fd53baa5108961cb7c12dacdcaf1e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 15:04:18 -0400 Subject: [PATCH 124/331] add back removed path methods for browser --- browser/path.js | 80 ++++++++++++++++++++++++++++++++++++++++ rollup.config.browser.js | 3 +- src/utils/path.js | 4 +- 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 browser/path.js diff --git a/browser/path.js b/browser/path.js new file mode 100644 index 0000000..279ba66 --- /dev/null +++ b/browser/path.js @@ -0,0 +1,80 @@ +export const absolutePath = /^(?:\/|(?:[A-Za-z]:)?[\\|\/])/; +export const relativePath = /^\.?\.\//; + +export function isAbsolute ( path ) { + return absolutePath.test( path ); +} + +export function isRelative ( path ) { + return relativePath.test( path ); +} + +export function normalize ( path ) { + return path.replace( /\\/g, '/' ); +} + +export function basename ( path ) { + return path.split( /(\/|\\)/ ).pop(); +} + +export function dirname ( path ) { + const match = /(\/|\\)[^\/\\]*$/.exec( path ); + if ( !match ) return '.'; + + const dir = path.slice( 0, -match[0].length ); + + // If `dir` is the empty string, we're at root. + return dir ? dir : '/'; +} + +export function extname ( path ) { + const match = /\.[^\.]+$/.exec( basename( path ) ); + if ( !match ) return ''; + return match[0]; +} + +export function relative ( from, to ) { + const fromParts = from.split( /[\/\\]/ ).filter( Boolean ); + const toParts = to.split( /[\/\\]/ ).filter( Boolean ); + + while ( fromParts[0] && toParts[0] && fromParts[0] === toParts[0] ) { + fromParts.shift(); + toParts.shift(); + } + + while ( toParts[0] === '.' || toParts[0] === '..' ) { + const toPart = toParts.shift(); + if ( toPart === '..' ) { + fromParts.pop(); + } + } + + while ( fromParts.pop() ) { + toParts.unshift( '..' ); + } + + return toParts.join( '/' ); +} + +export function resolve ( ...paths ) { + let resolvedParts = paths.shift().split( /[\/\\]/ ); + + paths.forEach( path => { + if ( isAbsolute( path ) ) { + resolvedParts = path.split( /[\/\\]/ ); + } else { + const parts = path.split( /[\/\\]/ ); + + while ( parts[0] === '.' || parts[0] === '..' ) { + const part = parts.shift(); + if ( part === '..' ) { + resolvedParts.pop(); + } + } + + resolvedParts.push.apply( resolvedParts, parts ); + } + }); + + return resolvedParts.join( '/' ); // TODO windows... +} diff --git a/rollup.config.browser.js b/rollup.config.browser.js index 86a0985..687f257 100644 --- a/rollup.config.browser.js +++ b/rollup.config.browser.js @@ -3,7 +3,8 @@ import config from './rollup.config.js'; config.plugins.push({ load: function ( id ) { - if ( ~id.indexOf( 'fs.js' ) ) return readFileSync( 'browser/fs.js' ).toString(); + if ( ~id.indexOf( 'fs.js' ) ) return readFileSync( 'browser/fs.js', 'utf-8' ); + if ( ~id.indexOf( 'path.js' ) ) return readFileSync( 'browser/path.js', 'utf-8' ); } }); diff --git a/src/utils/path.js b/src/utils/path.js index 5cdd62f..b787028 100644 --- a/src/utils/path.js +++ b/src/utils/path.js @@ -1,5 +1,3 @@ -// TODO does this all work on windows? - export const absolutePath = /^(?:\/|(?:[A-Za-z]:)?[\\|\/])/; export const relativePath = /^\.?\.\//; @@ -15,4 +13,4 @@ export function normalize ( path ) { return path.replace( /\\/g, '/' ); } -export { basename, dirname, extname, relative, resolve } from 'path'; +export * from 'path'; From 98e60efa3081501a30c3a5c21a431ead1668fe7b Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 15:11:23 -0400 Subject: [PATCH 125/331] remove superfluous helper --- src/Bundle.js | 5 ++--- src/utils/normalizePlatform.js | 3 --- 2 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 src/utils/normalizePlatform.js diff --git a/src/Bundle.js b/src/Bundle.js index 9b9d9c1..a24637e 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -9,7 +9,6 @@ import ensureArray from './utils/ensureArray.js'; import { load, makeOnwarn, resolveId } from './utils/defaults.js'; import getExportMode from './utils/getExportMode.js'; import getIndentString from './utils/getIndentString.js'; -import { unixizePath } from './utils/normalizePlatform.js'; import { mapSequence } from './utils/promise.js'; import transform from './utils/transform.js'; import transformBundle from './utils/transformBundle.js'; @@ -35,7 +34,7 @@ export default class Bundle { } }); - this.entry = unixizePath( options.entry ); + this.entry = normalize( options.entry ); this.entryId = null; this.entryModule = null; @@ -343,7 +342,7 @@ export default class Bundle { map = magicString.generateMap({ file, includeContent: true }); } - map.sources = map.sources.map( unixizePath ); + map.sources = map.sources.map( normalize ); } return { code, map }; diff --git a/src/utils/normalizePlatform.js b/src/utils/normalizePlatform.js deleted file mode 100644 index 5c8fd33..0000000 --- a/src/utils/normalizePlatform.js +++ /dev/null @@ -1,3 +0,0 @@ -export function unixizePath ( path ) { - return path.split( /[\/\\]/ ).join( '/' ); -} From 392a338c6474b69241575e8036e6af5d2703b33e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 15:41:23 -0400 Subject: [PATCH 126/331] add newline after sourcemap comment. fixes #756 --- bin/src/runRollup.js | 2 +- src/rollup.js | 2 +- test/cli/sourcemap-newline/_config.js | 10 ++++++++++ test/cli/sourcemap-newline/main.js | 1 + test/test.js | 1 + 5 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 test/cli/sourcemap-newline/_config.js create mode 100644 test/cli/sourcemap-newline/main.js diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index c798634..cbfa064 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -242,7 +242,7 @@ function bundle ( options ) { let { code, map } = bundle.generate( options ); if ( options.sourceMap === 'inline' ) { - code += `\n//# ${SOURCEMAPPING_URL}=${map.toUrl()}`; + code += `\n//# ${SOURCEMAPPING_URL}=${map.toUrl()}\n`; } process.stdout.write( code ); diff --git a/src/rollup.js b/src/rollup.js index e3a91b2..1efa49a 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -94,7 +94,7 @@ export function rollup ( options ) { promises.push( writeFile( dest + '.map', map.toString() ) ); } - code += `\n//# ${SOURCEMAPPING_URL}=${url}`; + code += `\n//# ${SOURCEMAPPING_URL}=${url}\n`; } promises.push( writeFile( dest, code ) ); diff --git a/test/cli/sourcemap-newline/_config.js b/test/cli/sourcemap-newline/_config.js new file mode 100644 index 0000000..8605e29 --- /dev/null +++ b/test/cli/sourcemap-newline/_config.js @@ -0,0 +1,10 @@ +const assert = require( 'assert' ); + +module.exports = { + solo: true, + description: 'adds a newline after the sourceMappingURL comment (#756)', + command: 'rollup -i main.js -m inline', + result: code => { + assert.equal( code.slice( -1 ), '\n' ); + } +}; diff --git a/test/cli/sourcemap-newline/main.js b/test/cli/sourcemap-newline/main.js new file mode 100644 index 0000000..5c72ff3 --- /dev/null +++ b/test/cli/sourcemap-newline/main.js @@ -0,0 +1 @@ +console.log( 42 ); diff --git a/test/test.js b/test/test.js index c7ea116..61efcb2 100644 --- a/test/test.js +++ b/test/test.js @@ -439,6 +439,7 @@ describe( 'rollup', function () { else if ( config.result ) { try { config.result( code ); + done(); } catch ( err ) { done( err ); } From 035f66e8d92dae33ee950cbaad0929a5f2c6dead Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 15:51:26 -0400 Subject: [PATCH 127/331] reinstate all tests --- test/cli/sourcemap-newline/_config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/cli/sourcemap-newline/_config.js b/test/cli/sourcemap-newline/_config.js index 8605e29..1427619 100644 --- a/test/cli/sourcemap-newline/_config.js +++ b/test/cli/sourcemap-newline/_config.js @@ -1,7 +1,6 @@ const assert = require( 'assert' ); module.exports = { - solo: true, description: 'adds a newline after the sourceMappingURL comment (#756)', command: 'rollup -i main.js -m inline', result: code => { From dbfa280fcd8badec6f16bae800c63f65d0d7e9e9 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 16:26:58 -0400 Subject: [PATCH 128/331] ensure reassigned exports are declared in an ES bundle (#755) --- src/Module.js | 18 ++++++++++++++---- .../_expected/es.js | 4 ++-- test/form/assignment-to-exports/_config.js | 6 ++++++ .../assignment-to-exports/_expected/amd.js | 7 +++++++ .../assignment-to-exports/_expected/cjs.js | 5 +++++ .../form/assignment-to-exports/_expected/es.js | 4 ++++ .../assignment-to-exports/_expected/iife.js | 6 ++++++ .../assignment-to-exports/_expected/umd.js | 11 +++++++++++ test/form/assignment-to-exports/main.js | 2 ++ 9 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 test/form/assignment-to-exports/_config.js create mode 100644 test/form/assignment-to-exports/_expected/amd.js create mode 100644 test/form/assignment-to-exports/_expected/cjs.js create mode 100644 test/form/assignment-to-exports/_expected/es.js create mode 100644 test/form/assignment-to-exports/_expected/iife.js create mode 100644 test/form/assignment-to-exports/_expected/umd.js create mode 100644 test/form/assignment-to-exports/main.js diff --git a/src/Module.js b/src/Module.js index 4dd1b53..0830a8c 100644 --- a/src/Module.js +++ b/src/Module.js @@ -462,7 +462,7 @@ export default class Module { if ( statement.node.isSynthetic ) return; // skip `export { foo, bar, baz }` - if ( statement.node.specifiers.length ) { + if ( statement.node.declaration === null ) { magicString.remove( statement.start, statement.next ); return; } @@ -555,11 +555,21 @@ export default class Module { const name = extractNames( statement.node.declaration.declarations[ 0 ].id )[ 0 ]; const declaration = this.declarations[ name ]; + // TODO is this even possible? if ( !declaration ) throw new Error( `Missing declaration for ${name}!` ); - const end = declaration.exportName && declaration.isReassigned ? - statement.node.declaration.declarations[0].start : - statement.node.declaration.start; + let end; + + if ( es ) { + end = statement.node.declaration.start; + } else { + if ( declaration.exportName && declaration.isReassigned ) { + const declarator = statement.node.declaration.declarations[0]; + end = declarator.init ? declarator.start : statement.next; + } else { + end = statement.node.declaration.start + } + } magicString.remove( statement.node.start, end ); } diff --git a/test/form/assignment-to-exports-class-declaration/_expected/es.js b/test/form/assignment-to-exports-class-declaration/_expected/es.js index 08e82c9..2631630 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/es.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/es.js @@ -1,4 +1,4 @@ -Foo = class Foo {} +let Foo = class Foo {} Foo = lol( Foo ); -export { Foo }; \ No newline at end of file +export { Foo }; diff --git a/test/form/assignment-to-exports/_config.js b/test/form/assignment-to-exports/_config.js new file mode 100644 index 0000000..3c9f6d4 --- /dev/null +++ b/test/form/assignment-to-exports/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'declares updated variable in ES output (#755)', + options: { + moduleName: 'bundle' + } +}; diff --git a/test/form/assignment-to-exports/_expected/amd.js b/test/form/assignment-to-exports/_expected/amd.js new file mode 100644 index 0000000..6f8d4d8 --- /dev/null +++ b/test/form/assignment-to-exports/_expected/amd.js @@ -0,0 +1,7 @@ +define(['exports'], function (exports) { 'use strict'; + + exports.foo = 1; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/form/assignment-to-exports/_expected/cjs.js b/test/form/assignment-to-exports/_expected/cjs.js new file mode 100644 index 0000000..9de4215 --- /dev/null +++ b/test/form/assignment-to-exports/_expected/cjs.js @@ -0,0 +1,5 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +exports.foo = 1; diff --git a/test/form/assignment-to-exports/_expected/es.js b/test/form/assignment-to-exports/_expected/es.js new file mode 100644 index 0000000..e6c6e5f --- /dev/null +++ b/test/form/assignment-to-exports/_expected/es.js @@ -0,0 +1,4 @@ +var foo; +foo = 1; + +export { foo }; diff --git a/test/form/assignment-to-exports/_expected/iife.js b/test/form/assignment-to-exports/_expected/iife.js new file mode 100644 index 0000000..3ac6c5f --- /dev/null +++ b/test/form/assignment-to-exports/_expected/iife.js @@ -0,0 +1,6 @@ +(function (exports) { + 'use strict'; + + exports.foo = 1; + +}((this.bundle = this.bundle || {}))); diff --git a/test/form/assignment-to-exports/_expected/umd.js b/test/form/assignment-to-exports/_expected/umd.js new file mode 100644 index 0000000..cc3fb1f --- /dev/null +++ b/test/form/assignment-to-exports/_expected/umd.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.bundle = global.bundle || {}))); +}(this, function (exports) { 'use strict'; + + exports.foo = 1; + + Object.defineProperty(exports, '__esModule', { value: true }); + +})); diff --git a/test/form/assignment-to-exports/main.js b/test/form/assignment-to-exports/main.js new file mode 100644 index 0000000..bd12ed8 --- /dev/null +++ b/test/form/assignment-to-exports/main.js @@ -0,0 +1,2 @@ +export var foo; +foo = 1; From b699a46978c774591e953ab859c2142e4603ee97 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 16:30:01 -0400 Subject: [PATCH 129/331] lint --- src/Module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Module.js b/src/Module.js index 0830a8c..4d57a19 100644 --- a/src/Module.js +++ b/src/Module.js @@ -567,7 +567,7 @@ export default class Module { const declarator = statement.node.declaration.declarations[0]; end = declarator.init ? declarator.start : statement.next; } else { - end = statement.node.declaration.start + end = statement.node.declaration.start; } } From 71e8ce004fe1cb0903e11e3a4cb254643f167eff Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 20:54:19 -0400 Subject: [PATCH 130/331] -> v0.34.0 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3c4e34..a9de5f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # rollup changelog +## 0.34.0 + +* Use resolved IDs for relative imports that are also external modules, to allow `options.globals` to work with them ([#763](https://github.com/rollup/rollup/issues/763)) +* Ensure reassigned exports are declared in an ES bundle, and remove empty `exports.foo;` statements ([#755](https://github.com/rollup/rollup/issues/755)) +* Add newline after sourcemap comment ([#756](https://github.com/rollup/rollup/issues/756)) + ## 0.33.2 * Add `bundle` as second argument to `ongenerate` and `onwrite` hooks ([#773](https://github.com/rollup/rollup/pull/773)) diff --git a/package.json b/package.json index 4abcd9d..c67eebf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.33.2", + "version": "0.34.0", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "dist/rollup.es.js", From 328d145221eb407262cc398008c08b87dc883ad6 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 9 Jul 2016 23:18:19 -0400 Subject: [PATCH 131/331] support paths config (#754) --- src/Bundle.js | 8 +++++++- src/rollup.js | 1 + test/form/paths-function/_config.js | 6 ++++++ test/form/paths-function/_expected/amd.js | 7 +++++++ test/form/paths-function/_expected/cjs.js | 7 +++++++ test/form/paths-function/_expected/es.js | 3 +++ test/form/paths-function/_expected/iife.js | 8 ++++++++ test/form/paths-function/_expected/umd.js | 11 +++++++++++ test/form/paths-function/main.js | 3 +++ test/form/paths-relative/_config.js | 13 +++++++++++++ test/form/paths-relative/_expected/amd.js | 7 +++++++ test/form/paths-relative/_expected/cjs.js | 7 +++++++ test/form/paths-relative/_expected/es.js | 3 +++ test/form/paths-relative/_expected/iife.js | 8 ++++++++ test/form/paths-relative/_expected/umd.js | 11 +++++++++++ test/form/paths-relative/main.js | 3 +++ test/form/paths/_config.js | 8 ++++++++ test/form/paths/_expected/amd.js | 7 +++++++ test/form/paths/_expected/cjs.js | 7 +++++++ test/form/paths/_expected/es.js | 3 +++ test/form/paths/_expected/iife.js | 8 ++++++++ test/form/paths/_expected/umd.js | 11 +++++++++++ test/form/paths/main.js | 3 +++ test/test.js | 2 +- 24 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 test/form/paths-function/_config.js create mode 100644 test/form/paths-function/_expected/amd.js create mode 100644 test/form/paths-function/_expected/cjs.js create mode 100644 test/form/paths-function/_expected/es.js create mode 100644 test/form/paths-function/_expected/iife.js create mode 100644 test/form/paths-function/_expected/umd.js create mode 100644 test/form/paths-function/main.js create mode 100644 test/form/paths-relative/_config.js create mode 100644 test/form/paths-relative/_expected/amd.js create mode 100644 test/form/paths-relative/_expected/cjs.js create mode 100644 test/form/paths-relative/_expected/es.js create mode 100644 test/form/paths-relative/_expected/iife.js create mode 100644 test/form/paths-relative/_expected/umd.js create mode 100644 test/form/paths-relative/main.js create mode 100644 test/form/paths/_config.js create mode 100644 test/form/paths/_expected/amd.js create mode 100644 test/form/paths/_expected/cjs.js create mode 100644 test/form/paths/_expected/es.js create mode 100644 test/form/paths/_expected/iife.js create mode 100644 test/form/paths/_expected/umd.js create mode 100644 test/form/paths/main.js diff --git a/src/Bundle.js b/src/Bundle.js index a24637e..022164b 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -52,6 +52,12 @@ export default class Bundle { this.hasLoaders = loaders.length !== 0; this.load = first( loaders.concat( load ) ); + this.getPath = typeof options.paths === 'function' ? + ( id => options.paths( id ) || this.getPathRelativeToEntryDirname( id ) ) : + options.paths ? + ( id => options.paths.hasOwnProperty( id ) ? options.paths[ id ] : this.getPathRelativeToEntryDirname( id ) ) : + id => this.getPathRelativeToEntryDirname( id ); + this.moduleById = new Map(); this.modules = []; @@ -243,7 +249,7 @@ export default class Bundle { module.resolvedIds[ source ] = externalId; if ( !this.moduleById.has( externalId ) ) { - const module = new ExternalModule( externalId, this.getPathRelativeToEntryDirname( externalId ) ); + const module = new ExternalModule( externalId, this.getPath( externalId ) ); this.externalModules.push( module ); this.moduleById.set( externalId, module ); } diff --git a/src/rollup.js b/src/rollup.js index 1efa49a..a726d1a 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -26,6 +26,7 @@ const ALLOWED_KEYS = [ 'noConflict', 'onwarn', 'outro', + 'paths', 'plugins', 'preferConst', 'sourceMap', diff --git a/test/form/paths-function/_config.js b/test/form/paths-function/_config.js new file mode 100644 index 0000000..d4f6a0d --- /dev/null +++ b/test/form/paths-function/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'external paths (#754)', + options: { + paths: id => `https://npmcdn.com/${id}` + } +}; diff --git a/test/form/paths-function/_expected/amd.js b/test/form/paths-function/_expected/amd.js new file mode 100644 index 0000000..fe2d243 --- /dev/null +++ b/test/form/paths-function/_expected/amd.js @@ -0,0 +1,7 @@ +define(['https://npmcdn.com/foo'], function (foo) { 'use strict'; + + foo = 'default' in foo ? foo['default'] : foo; + + assert.equal( foo, 42 ); + +}); diff --git a/test/form/paths-function/_expected/cjs.js b/test/form/paths-function/_expected/cjs.js new file mode 100644 index 0000000..864ce43 --- /dev/null +++ b/test/form/paths-function/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var foo = _interopDefault(require('https://npmcdn.com/foo')); + +assert.equal( foo, 42 ); diff --git a/test/form/paths-function/_expected/es.js b/test/form/paths-function/_expected/es.js new file mode 100644 index 0000000..1c4fe57 --- /dev/null +++ b/test/form/paths-function/_expected/es.js @@ -0,0 +1,3 @@ +import foo from 'https://npmcdn.com/foo'; + +assert.equal( foo, 42 ); diff --git a/test/form/paths-function/_expected/iife.js b/test/form/paths-function/_expected/iife.js new file mode 100644 index 0000000..28acdd1 --- /dev/null +++ b/test/form/paths-function/_expected/iife.js @@ -0,0 +1,8 @@ +(function (foo) { + 'use strict'; + + foo = 'default' in foo ? foo['default'] : foo; + + assert.equal( foo, 42 ); + +}(foo)); \ No newline at end of file diff --git a/test/form/paths-function/_expected/umd.js b/test/form/paths-function/_expected/umd.js new file mode 100644 index 0000000..7d0a45f --- /dev/null +++ b/test/form/paths-function/_expected/umd.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('https://npmcdn.com/foo')) : + typeof define === 'function' && define.amd ? define(['https://npmcdn.com/foo'], factory) : + (factory(global.foo)); +}(this, function (foo) { 'use strict'; + + foo = 'default' in foo ? foo['default'] : foo; + + assert.equal( foo, 42 ); + +})); diff --git a/test/form/paths-function/main.js b/test/form/paths-function/main.js new file mode 100644 index 0000000..2b26e36 --- /dev/null +++ b/test/form/paths-function/main.js @@ -0,0 +1,3 @@ +import foo from 'foo'; + +assert.equal( foo, 42 ); diff --git a/test/form/paths-relative/_config.js b/test/form/paths-relative/_config.js new file mode 100644 index 0000000..2895b21 --- /dev/null +++ b/test/form/paths-relative/_config.js @@ -0,0 +1,13 @@ +const { resolve } = require( 'path' ); + +const resolved = resolve( __dirname, 'foo.js' ); + +module.exports = { + description: 'external paths (#754)', + options: { + external: [ resolved ], + paths: { + [ resolved ]: '../foo' + } + } +}; diff --git a/test/form/paths-relative/_expected/amd.js b/test/form/paths-relative/_expected/amd.js new file mode 100644 index 0000000..a13383c --- /dev/null +++ b/test/form/paths-relative/_expected/amd.js @@ -0,0 +1,7 @@ +define(['../foo'], function (foo) { 'use strict'; + + foo = 'default' in foo ? foo['default'] : foo; + + assert.equal( foo, 42 ); + +}); diff --git a/test/form/paths-relative/_expected/cjs.js b/test/form/paths-relative/_expected/cjs.js new file mode 100644 index 0000000..f80ea9b --- /dev/null +++ b/test/form/paths-relative/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var foo = _interopDefault(require('../foo')); + +assert.equal( foo, 42 ); diff --git a/test/form/paths-relative/_expected/es.js b/test/form/paths-relative/_expected/es.js new file mode 100644 index 0000000..2462c87 --- /dev/null +++ b/test/form/paths-relative/_expected/es.js @@ -0,0 +1,3 @@ +import foo from '../foo'; + +assert.equal( foo, 42 ); diff --git a/test/form/paths-relative/_expected/iife.js b/test/form/paths-relative/_expected/iife.js new file mode 100644 index 0000000..28acdd1 --- /dev/null +++ b/test/form/paths-relative/_expected/iife.js @@ -0,0 +1,8 @@ +(function (foo) { + 'use strict'; + + foo = 'default' in foo ? foo['default'] : foo; + + assert.equal( foo, 42 ); + +}(foo)); \ No newline at end of file diff --git a/test/form/paths-relative/_expected/umd.js b/test/form/paths-relative/_expected/umd.js new file mode 100644 index 0000000..5ac4391 --- /dev/null +++ b/test/form/paths-relative/_expected/umd.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../foo')) : + typeof define === 'function' && define.amd ? define(['../foo'], factory) : + (factory(global.foo)); +}(this, function (foo) { 'use strict'; + + foo = 'default' in foo ? foo['default'] : foo; + + assert.equal( foo, 42 ); + +})); diff --git a/test/form/paths-relative/main.js b/test/form/paths-relative/main.js new file mode 100644 index 0000000..c01e9a1 --- /dev/null +++ b/test/form/paths-relative/main.js @@ -0,0 +1,3 @@ +import foo from './foo.js'; + +assert.equal( foo, 42 ); diff --git a/test/form/paths/_config.js b/test/form/paths/_config.js new file mode 100644 index 0000000..c9b4ca3 --- /dev/null +++ b/test/form/paths/_config.js @@ -0,0 +1,8 @@ +module.exports = { + description: 'external paths (#754)', + options: { + paths: { + foo: 'https://npmcdn.com/foo' + } + } +}; diff --git a/test/form/paths/_expected/amd.js b/test/form/paths/_expected/amd.js new file mode 100644 index 0000000..fe2d243 --- /dev/null +++ b/test/form/paths/_expected/amd.js @@ -0,0 +1,7 @@ +define(['https://npmcdn.com/foo'], function (foo) { 'use strict'; + + foo = 'default' in foo ? foo['default'] : foo; + + assert.equal( foo, 42 ); + +}); diff --git a/test/form/paths/_expected/cjs.js b/test/form/paths/_expected/cjs.js new file mode 100644 index 0000000..864ce43 --- /dev/null +++ b/test/form/paths/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var foo = _interopDefault(require('https://npmcdn.com/foo')); + +assert.equal( foo, 42 ); diff --git a/test/form/paths/_expected/es.js b/test/form/paths/_expected/es.js new file mode 100644 index 0000000..1c4fe57 --- /dev/null +++ b/test/form/paths/_expected/es.js @@ -0,0 +1,3 @@ +import foo from 'https://npmcdn.com/foo'; + +assert.equal( foo, 42 ); diff --git a/test/form/paths/_expected/iife.js b/test/form/paths/_expected/iife.js new file mode 100644 index 0000000..28acdd1 --- /dev/null +++ b/test/form/paths/_expected/iife.js @@ -0,0 +1,8 @@ +(function (foo) { + 'use strict'; + + foo = 'default' in foo ? foo['default'] : foo; + + assert.equal( foo, 42 ); + +}(foo)); \ No newline at end of file diff --git a/test/form/paths/_expected/umd.js b/test/form/paths/_expected/umd.js new file mode 100644 index 0000000..7d0a45f --- /dev/null +++ b/test/form/paths/_expected/umd.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('https://npmcdn.com/foo')) : + typeof define === 'function' && define.amd ? define(['https://npmcdn.com/foo'], factory) : + (factory(global.foo)); +}(this, function (foo) { 'use strict'; + + foo = 'default' in foo ? foo['default'] : foo; + + assert.equal( foo, 42 ); + +})); diff --git a/test/form/paths/main.js b/test/form/paths/main.js new file mode 100644 index 0000000..2b26e36 --- /dev/null +++ b/test/form/paths/main.js @@ -0,0 +1,3 @@ +import foo from 'foo'; + +assert.equal( foo, 42 ); diff --git a/test/test.js b/test/test.js index 61efcb2..245fb00 100644 --- a/test/test.js +++ b/test/test.js @@ -90,7 +90,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( function () { throw new Error( 'Missing expected error' ); }, function ( err ) { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); }); }); }); From c5fa9b2a42a8764c3cd7b291817957da878f65e8 Mon Sep 17 00:00:00 2001 From: Kurt Blackwell Date: Sun, 10 Jul 2016 13:22:01 +0800 Subject: [PATCH 132/331] Introduce eslint to tests. Complaints are fixed, but none of them major. --- .eslintrc | 1 - package.json | 2 +- src/utils/collapseSourcemaps.js | 7 +++++-- test/.eslintrc | 9 +++++++++ test/cli/config-cwd-case-insensitive/_config.js | 6 +++--- test/cli/external-modules-auto-global/_config.js | 2 -- test/cli/indent-none/_config.js | 2 -- test/form/banner-and-footer-plugin/_config.js | 2 +- test/form/transform-bundle-plugin/_config.js | 2 +- test/form/umd-noconflict/_config.js | 2 -- .../configure-relative-external-module/_config.js | 2 +- test/function/confused-default-identifier/_config.js | 2 -- test/function/consistent-renaming-e/_config.js | 2 +- test/function/custom-path-resolver-plural-b/_config.js | 2 +- test/function/default-export-is-not-bound-b/_config.js | 2 +- test/function/delete/_config.js | 2 +- test/function/export-as/_config.js | 2 -- test/function/export-from-no-local-binding/_config.js | 2 -- .../_config.js | 2 +- test/function/namespace-missing-export/_config.js | 1 - test/function/newline-after-comment/_config.js | 2 +- test/function/object-dynamic-properties/_config.js | 2 -- .../function/plugins-can-manipulate-options/_config.js | 2 +- test/function/resolves-namespace-default/_config.js | 8 ++++---- test/function/skips-dead-branches-b/_config.js | 2 +- test/function/skips-dead-branches-c/_config.js | 2 +- test/function/skips-dead-branches-d/_config.js | 2 +- test/function/skips-dead-branches-e/_config.js | 2 +- test/function/skips-dead-branches-f/_config.js | 2 +- test/function/skips-dead-branches-g/_config.js | 10 +++++----- test/function/skips-dead-branches/_config.js | 2 +- test/function/transformer-multiple/_config.js | 2 +- test/function/transformer-single/_config.js | 2 +- test/function/warn-on-eval/_config.js | 1 - test/sourcemaps/basic-support/_config.js | 1 - test/sourcemaps/loaders/_config.js | 10 ++++++---- test/test.js | 9 ++++++--- test/utils/getLocation.js | 2 +- 38 files changed, 58 insertions(+), 59 deletions(-) create mode 100644 test/.eslintrc diff --git a/.eslintrc b/.eslintrc index 0f98dff..a2b65f5 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,7 +12,6 @@ "env": { "es6": true, "browser": true, - "mocha": true, "node": true }, "extends": "eslint:recommended", diff --git a/package.json b/package.json index c67eebf..ed15d8c 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "build:cli": "rollup -c rollup.config.cli.js", "build:browser": "git rev-parse HEAD > .commithash && rollup -c rollup.config.browser.js -o dist/rollup.browser.js", "prepublish": "npm run lint && npm test && npm run build:browser", - "lint": "eslint src browser" + "lint": "eslint src browser test/test.js test/utils test/**/_config.js" }, "repository": { "type": "git", diff --git a/src/utils/collapseSourcemaps.js b/src/utils/collapseSourcemaps.js index ddf2dc5..cd06d8c 100644 --- a/src/utils/collapseSourcemaps.js +++ b/src/utils/collapseSourcemaps.js @@ -21,7 +21,9 @@ class Link { } traceMappings () { - let sources = [], sourcesContent = [], names = []; + let sources = []; + let sourcesContent = []; + let names = []; const mappings = this.mappings.map( line => { let tracedLine = []; @@ -31,7 +33,8 @@ class Link { const traced = source.traceSegment( segment[2], segment[3], this.names[ segment[4] ] ); if ( traced ) { - let sourceIndex = null, nameIndex = null; + let sourceIndex = null; + let nameIndex = null; segment = [ segment[0], null, diff --git a/test/.eslintrc b/test/.eslintrc new file mode 100644 index 0000000..3f85d4c --- /dev/null +++ b/test/.eslintrc @@ -0,0 +1,9 @@ +{ + "rules": { + "no-console": [ 0 ], + "no-unused-vars": [ "error", { "vars": "all", "args": "none" } ] + }, + "env": { + "mocha": true + } +} diff --git a/test/cli/config-cwd-case-insensitive/_config.js b/test/cli/config-cwd-case-insensitive/_config.js index 3bd80d0..c0df3fc 100644 --- a/test/cli/config-cwd-case-insensitive/_config.js +++ b/test/cli/config-cwd-case-insensitive/_config.js @@ -1,13 +1,13 @@ var os = require( 'os' ); function toggleCase ( s ) { - return ( s == s.toLowerCase() ) ? s.toUpperCase() : s.toLowerCase(); + return ( s == s.toLowerCase() ) ? s.toUpperCase() : s.toLowerCase(); } module.exports = { - skip: os.platform() !== 'win32', + skip: os.platform() !== 'win32', description: "can load config with cwd that doesn't match realpath", command: 'rollup -c', - cwd: __dirname.replace( /^[A-Z]:\\/i, toggleCase ), + cwd: __dirname.replace( /^[A-Z]:\\/i, toggleCase ), execute: true }; diff --git a/test/cli/external-modules-auto-global/_config.js b/test/cli/external-modules-auto-global/_config.js index 7dbf418..9f3e784 100644 --- a/test/cli/external-modules-auto-global/_config.js +++ b/test/cli/external-modules-auto-global/_config.js @@ -1,5 +1,3 @@ -const assert = require( 'assert' ); - module.exports = { description: 'populates options.external with --global keys', command: 'rollup main.js --format iife --globals mathematics:Math', diff --git a/test/cli/indent-none/_config.js b/test/cli/indent-none/_config.js index a9d1307..e37aead 100644 --- a/test/cli/indent-none/_config.js +++ b/test/cli/indent-none/_config.js @@ -1,5 +1,3 @@ -var assert = require( 'assert' ); - module.exports = { description: 'disables indentation with --no-indent', command: 'rollup main.js --format umd --no-indent' diff --git a/test/form/banner-and-footer-plugin/_config.js b/test/form/banner-and-footer-plugin/_config.js index 1432418..1e1367f 100644 --- a/test/form/banner-and-footer-plugin/_config.js +++ b/test/form/banner-and-footer-plugin/_config.js @@ -12,4 +12,4 @@ module.exports = { } ] } -} +}; diff --git a/test/form/transform-bundle-plugin/_config.js b/test/form/transform-bundle-plugin/_config.js index 6b54ad3..61af11d 100644 --- a/test/form/transform-bundle-plugin/_config.js +++ b/test/form/transform-bundle-plugin/_config.js @@ -14,4 +14,4 @@ module.exports = { } ] } -} +}; diff --git a/test/form/umd-noconflict/_config.js b/test/form/umd-noconflict/_config.js index 9bbcec6..9429457 100644 --- a/test/form/umd-noconflict/_config.js +++ b/test/form/umd-noconflict/_config.js @@ -1,5 +1,3 @@ -var assert = require( 'assert' ); - module.exports = { description: 'exports noConflict method for default umd when requested', options: { diff --git a/test/function/configure-relative-external-module/_config.js b/test/function/configure-relative-external-module/_config.js index bbcebcf..58e154c 100644 --- a/test/function/configure-relative-external-module/_config.js +++ b/test/function/configure-relative-external-module/_config.js @@ -11,7 +11,7 @@ module.exports = { external: [ path.join( __dirname, './nonexistent-relative-dependency.js') ] }, context: { - require: function() { + require: function () { return mockedValue; } }, diff --git a/test/function/confused-default-identifier/_config.js b/test/function/confused-default-identifier/_config.js index 1b0bbf2..3d2e253 100644 --- a/test/function/confused-default-identifier/_config.js +++ b/test/function/confused-default-identifier/_config.js @@ -1,5 +1,3 @@ -var assert = require( 'assert' ); - module.exports = { description: 'Rollup should not get confused and allow "default" as an identifier name', warnings: function () {} // suppress diff --git a/test/function/consistent-renaming-e/_config.js b/test/function/consistent-renaming-e/_config.js index 4fa443e..e93e16a 100644 --- a/test/function/consistent-renaming-e/_config.js +++ b/test/function/consistent-renaming-e/_config.js @@ -1,3 +1,3 @@ module.exports = { description: 'consistent renaming test e' -} \ No newline at end of file +}; \ No newline at end of file diff --git a/test/function/custom-path-resolver-plural-b/_config.js b/test/function/custom-path-resolver-plural-b/_config.js index 05cf37a..cb2da0c 100644 --- a/test/function/custom-path-resolver-plural-b/_config.js +++ b/test/function/custom-path-resolver-plural-b/_config.js @@ -9,7 +9,7 @@ module.exports = { throw new Error( 'nope' ); }, load: function ( id ) { - if ( id === 'main' ) return 'assert.ok( false );' + if ( id === 'main' ) return 'assert.ok( false );'; } }, { diff --git a/test/function/default-export-is-not-bound-b/_config.js b/test/function/default-export-is-not-bound-b/_config.js index 92debd4..7527035 100644 --- a/test/function/default-export-is-not-bound-b/_config.js +++ b/test/function/default-export-is-not-bound-b/_config.js @@ -4,6 +4,6 @@ module.exports = { description: 'does not move default export statement above earlier statements', exports: function ( exports ) { assert.equal( exports.bar, 42 ); - }, + } // solo: true }; diff --git a/test/function/delete/_config.js b/test/function/delete/_config.js index 4a5902c..3495183 100644 --- a/test/function/delete/_config.js +++ b/test/function/delete/_config.js @@ -1,3 +1,3 @@ module.exports = { - description: '`delete` operator at the top level is preserved' + description: '`delete` operator at the top level is preserved' }; diff --git a/test/function/export-as/_config.js b/test/function/export-as/_config.js index 3171eed..ed89b85 100644 --- a/test/function/export-as/_config.js +++ b/test/function/export-as/_config.js @@ -1,5 +1,3 @@ -var assert = require( 'assert' ); - module.exports = { description: 'allows export { x as y }' }; diff --git a/test/function/export-from-no-local-binding/_config.js b/test/function/export-from-no-local-binding/_config.js index 333c68b..7500be3 100644 --- a/test/function/export-from-no-local-binding/_config.js +++ b/test/function/export-from-no-local-binding/_config.js @@ -1,5 +1,3 @@ -var assert = require( 'assert' ); - module.exports = { description: 'export from does not create a local binding' }; diff --git a/test/function/member-expression-assignment-in-function/_config.js b/test/function/member-expression-assignment-in-function/_config.js index bf7e6fc..3166462 100644 --- a/test/function/member-expression-assignment-in-function/_config.js +++ b/test/function/member-expression-assignment-in-function/_config.js @@ -7,4 +7,4 @@ module.exports = { assert.equal( code.indexOf( 'set("bar", 2);' ) >= 0, true, code ); assert.equal( code.indexOf( 'set("qux", 3);' ) >= 0, true, code ); } -} +}; diff --git a/test/function/namespace-missing-export/_config.js b/test/function/namespace-missing-export/_config.js index 69f1405..7835ef4 100644 --- a/test/function/namespace-missing-export/_config.js +++ b/test/function/namespace-missing-export/_config.js @@ -1,5 +1,4 @@ var assert = require( 'assert' ); -var path = require( 'path' ); module.exports = { options: { diff --git a/test/function/newline-after-comment/_config.js b/test/function/newline-after-comment/_config.js index 76ebc57..d28ead5 100644 --- a/test/function/newline-after-comment/_config.js +++ b/test/function/newline-after-comment/_config.js @@ -4,6 +4,6 @@ module.exports = { description: 'inserts newline after comment', exports: function ( exports ) { assert.equal( exports(), 42 ); - }, + } // solo: true }; diff --git a/test/function/object-dynamic-properties/_config.js b/test/function/object-dynamic-properties/_config.js index 001b48f..1bcd2fa 100644 --- a/test/function/object-dynamic-properties/_config.js +++ b/test/function/object-dynamic-properties/_config.js @@ -1,5 +1,3 @@ -var assert = require('assert'); - module.exports = { description: 'dynamic object assignments should be imported' }; diff --git a/test/function/plugins-can-manipulate-options/_config.js b/test/function/plugins-can-manipulate-options/_config.js index a0e607c..15e9598 100644 --- a/test/function/plugins-can-manipulate-options/_config.js +++ b/test/function/plugins-can-manipulate-options/_config.js @@ -15,4 +15,4 @@ module.exports = { exports: function ( answer ) { assert.equal( answer, 42 ); } -} +}; diff --git a/test/function/resolves-namespace-default/_config.js b/test/function/resolves-namespace-default/_config.js index 4e28079..46de4e1 100644 --- a/test/function/resolves-namespace-default/_config.js +++ b/test/function/resolves-namespace-default/_config.js @@ -1,9 +1,9 @@ var assert = require('assert'); module.exports = { - description: "namespace's 'default' properties should be available", + description: "namespace's 'default' properties should be available", - exports: function ( exports ) { - assert.equal( exports, 42 ); - } + exports: function ( exports ) { + assert.equal( exports, 42 ); + } }; diff --git a/test/function/skips-dead-branches-b/_config.js b/test/function/skips-dead-branches-b/_config.js index bb15b49..9833915 100644 --- a/test/function/skips-dead-branches-b/_config.js +++ b/test/function/skips-dead-branches-b/_config.js @@ -5,4 +5,4 @@ module.exports = { code: function ( code ) { assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); } -} +}; diff --git a/test/function/skips-dead-branches-c/_config.js b/test/function/skips-dead-branches-c/_config.js index 47111d5..c925750 100644 --- a/test/function/skips-dead-branches-c/_config.js +++ b/test/function/skips-dead-branches-c/_config.js @@ -5,4 +5,4 @@ module.exports = { code: function ( code ) { assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); } -} +}; diff --git a/test/function/skips-dead-branches-d/_config.js b/test/function/skips-dead-branches-d/_config.js index 3cc97d3..67c8046 100644 --- a/test/function/skips-dead-branches-d/_config.js +++ b/test/function/skips-dead-branches-d/_config.js @@ -5,4 +5,4 @@ module.exports = { code: function ( code ) { assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); } -} +}; diff --git a/test/function/skips-dead-branches-e/_config.js b/test/function/skips-dead-branches-e/_config.js index 15deabf..5c6e6ab 100644 --- a/test/function/skips-dead-branches-e/_config.js +++ b/test/function/skips-dead-branches-e/_config.js @@ -5,4 +5,4 @@ module.exports = { code: function ( code ) { assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); } -} +}; diff --git a/test/function/skips-dead-branches-f/_config.js b/test/function/skips-dead-branches-f/_config.js index e43c622..d829cef 100644 --- a/test/function/skips-dead-branches-f/_config.js +++ b/test/function/skips-dead-branches-f/_config.js @@ -5,4 +5,4 @@ module.exports = { code: function ( code ) { assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); } -} +}; diff --git a/test/function/skips-dead-branches-g/_config.js b/test/function/skips-dead-branches-g/_config.js index d1e507d..90e7f11 100644 --- a/test/function/skips-dead-branches-g/_config.js +++ b/test/function/skips-dead-branches-g/_config.js @@ -1,9 +1,9 @@ var assert = require( 'assert' ); module.exports = { - description: 'skips a dead conditional expression branch (g)', - code: function ( code ) { - assert.ok( code.indexOf( 'var c = a;' ) >= 0, code ); - assert.ok( code.indexOf( 'var d = b;' ) >= 0, code ); - } + description: 'skips a dead conditional expression branch (g)', + code: function ( code ) { + assert.ok( code.indexOf( 'var c = a;' ) >= 0, code ); + assert.ok( code.indexOf( 'var d = b;' ) >= 0, code ); + } }; diff --git a/test/function/skips-dead-branches/_config.js b/test/function/skips-dead-branches/_config.js index 1278d35..9a0d225 100644 --- a/test/function/skips-dead-branches/_config.js +++ b/test/function/skips-dead-branches/_config.js @@ -5,4 +5,4 @@ module.exports = { code: function ( code ) { assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); } -} +}; diff --git a/test/function/transformer-multiple/_config.js b/test/function/transformer-multiple/_config.js index e9aab9a..916d71e 100644 --- a/test/function/transformer-multiple/_config.js +++ b/test/function/transformer-multiple/_config.js @@ -22,4 +22,4 @@ module.exports = { exports: function ( exports ) { assert.equal( exports.magicNumber, 6 ); } -} +}; diff --git a/test/function/transformer-single/_config.js b/test/function/transformer-single/_config.js index 93a1364..fb99d24 100644 --- a/test/function/transformer-single/_config.js +++ b/test/function/transformer-single/_config.js @@ -12,4 +12,4 @@ module.exports = { exports: function ( exports ) { assert.equal( exports.magicNumber, 3 ); } -} +}; diff --git a/test/function/warn-on-eval/_config.js b/test/function/warn-on-eval/_config.js index 169171c..d6ac89f 100644 --- a/test/function/warn-on-eval/_config.js +++ b/test/function/warn-on-eval/_config.js @@ -1,4 +1,3 @@ -var path = require( 'path' ); var assert = require( 'assert' ); var warned = false; diff --git a/test/sourcemaps/basic-support/_config.js b/test/sourcemaps/basic-support/_config.js index 9c8d790..53a4526 100644 --- a/test/sourcemaps/basic-support/_config.js +++ b/test/sourcemaps/basic-support/_config.js @@ -1,4 +1,3 @@ -var path = require( 'path' ); var assert = require( 'assert' ); var getLocation = require( '../../utils/getLocation' ); var SourceMapConsumer = require( 'source-map' ).SourceMapConsumer; diff --git a/test/sourcemaps/loaders/_config.js b/test/sourcemaps/loaders/_config.js index 53bae64..57ff117 100644 --- a/test/sourcemaps/loaders/_config.js +++ b/test/sourcemaps/loaders/_config.js @@ -39,16 +39,18 @@ module.exports = { }, test: function ( code, map ) { var smc = new SourceMapConsumer( map ); + var generatedLoc; + var originalLoc; - var generatedLoc = getLocation( code, code.indexOf( '22' ) ); - var originalLoc = smc.originalPositionFor( generatedLoc ); + generatedLoc = getLocation( code, code.indexOf( '22' ) ); + originalLoc = smc.originalPositionFor( generatedLoc ); assert.equal( originalLoc.source, '../foo.js' ); assert.equal( originalLoc.line, 1 ); assert.equal( originalLoc.column, 32 ); - var generatedLoc = getLocation( code, code.indexOf( '20' ) ); - var originalLoc = smc.originalPositionFor( generatedLoc ); + generatedLoc = getLocation( code, code.indexOf( '20' ) ); + originalLoc = smc.originalPositionFor( generatedLoc ); assert.equal( originalLoc.source, '../bar.js' ); assert.equal( originalLoc.line, 1 ); diff --git a/test/test.js b/test/test.js index 61efcb2..6c7e864 100644 --- a/test/test.js +++ b/test/test.js @@ -2,7 +2,6 @@ require( 'source-map-support' ).install(); require( 'console-group' ).install(); var path = require( 'path' ); -var os = require( 'os' ); var sander = require( 'sander' ); var assert = require( 'assert' ); var exec = require( 'child_process' ).exec; @@ -314,12 +313,16 @@ describe( 'rollup', function () { try { actualMap = JSON.parse( sander.readFileSync( FORM, dir, '_actual', profile.format + '.js.map' ).toString() ); actualMap.sourcesContent = actualMap.sourcesContent.map( normaliseOutput ); - } catch ( err ) {} + } catch ( err ) { + assert.equal( err.code, 'ENOENT' ); + } try { expectedMap = JSON.parse( sander.readFileSync( FORM, dir, '_expected', profile.format + '.js.map' ).toString() ); expectedMap.sourcesContent = expectedMap.sourcesContent.map( normaliseOutput ); - } catch ( err ) {} + } catch ( err ) { + assert.equal( err.code, 'ENOENT' ); + } if ( config.show ) { console.log( actualCode + '\n\n\n' ); diff --git a/test/utils/getLocation.js b/test/utils/getLocation.js index b92d38b..034e00e 100644 --- a/test/utils/getLocation.js +++ b/test/utils/getLocation.js @@ -19,4 +19,4 @@ module.exports = function getLocation ( source, search ) { } throw new Error( 'Could not determine location of character' ); -} +}; From 1e98a69e2ec80bd4f99ae363f96a04d9752464f0 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 10 Jul 2016 11:03:21 -0400 Subject: [PATCH 133/331] fix export * from external bug --- src/Bundle.js | 2 ++ test/function/export-all-from-external/_config.js | 6 ++++++ test/function/export-all-from-external/main.js | 4 ++++ test/function/export-all-from-external/path-plus.js | 5 +++++ 4 files changed, 17 insertions(+) create mode 100644 test/function/export-all-from-external/_config.js create mode 100644 test/function/export-all-from-external/main.js create mode 100644 test/function/export-all-from-external/path-plus.js diff --git a/src/Bundle.js b/src/Bundle.js index 022164b..96b2486 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -216,6 +216,8 @@ export default class Bundle { module.exportAllSources.forEach( source => { const id = module.resolvedIds[ source ]; const exportAllModule = this.moduleById.get( id ); + if ( exportAllModule.isExternal ) return; + keys( exportAllModule.exportsAll ).forEach( name => { if ( name in module.exportsAll ) { this.onwarn( `Conflicting namespaces: ${module.id} re-exports '${name}' from both ${module.exportsAll[ name ]} (will be ignored) and ${exportAllModule.exportsAll[ name ]}.` ); diff --git a/test/function/export-all-from-external/_config.js b/test/function/export-all-from-external/_config.js new file mode 100644 index 0000000..4f880de --- /dev/null +++ b/test/function/export-all-from-external/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'allows `export *` from external module, internally', + options: { + external: [ 'path' ] + } +}; diff --git a/test/function/export-all-from-external/main.js b/test/function/export-all-from-external/main.js new file mode 100644 index 0000000..3708aaa --- /dev/null +++ b/test/function/export-all-from-external/main.js @@ -0,0 +1,4 @@ +import { dirname, isRelative } from './path-plus.js'; + +assert.equal( dirname( 'foo/bar' ), 'foo' ); +assert.ok( isRelative( './foo' ) ); diff --git a/test/function/export-all-from-external/path-plus.js b/test/function/export-all-from-external/path-plus.js new file mode 100644 index 0000000..b2b8034 --- /dev/null +++ b/test/function/export-all-from-external/path-plus.js @@ -0,0 +1,5 @@ +export * from 'path'; + +export function isRelative ( path ) { + return path[0] === '.'; +} From 93ec6672285967d9baceca264b3007a5b271713e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 10 Jul 2016 22:36:48 -0400 Subject: [PATCH 134/331] more aggressive linting --- .eslintignore | 2 + .eslintrc | 11 +- src/ast/attachScopes.js | 4 +- src/rollup.js | 2 +- test/.babelrc | 20 ---- test/test.js | 241 +++++++++++++++++++--------------------- 6 files changed, 132 insertions(+), 148 deletions(-) create mode 100644 .eslintignore delete mode 100644 test/.babelrc diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..6df029f --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +test/* +!test/test.js diff --git a/.eslintrc b/.eslintrc index a2b65f5..363a56d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,7 +7,16 @@ "space-before-blocks": [ 2, "always" ], "space-before-function-paren": [ 2, "always" ], "no-mixed-spaces-and-tabs": [ 2, "smart-tabs" ], - "no-cond-assign": [ 0 ] + "no-cond-assign": [ 0 ], + "object-shorthand": [2, "always" ], + "no-const-assign": 2, + "no-class-assign": 2, + "no-this-before-super": 2, + "no-var": 2, + "quote-props": [ 2, "as-needed" ], + "one-var": [ 2, "never" ], + "prefer-arrow-callback": 2, + "arrow-spacing": 2 }, "env": { "es6": true, diff --git a/src/ast/attachScopes.js b/src/ast/attachScopes.js index 51fc28a..83cbc85 100644 --- a/src/ast/attachScopes.js +++ b/src/ast/attachScopes.js @@ -2,8 +2,8 @@ import { walk } from 'estree-walker'; import Scope from './Scope.js'; const blockDeclarations = { - 'const': true, - 'let': true + const: true, + let: true }; export default function attachScopes ( statement ) { diff --git a/src/rollup.js b/src/rollup.js index a726d1a..7358c0e 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -68,7 +68,7 @@ export function rollup ( options ) { return rendered; } - var result = { + const result = { imports: bundle.externalModules.map( module => module.id ), exports: keys( bundle.entryModule.exports ), modules: bundle.orderedModules.map( module => module.toJSON() ), diff --git a/test/.babelrc b/test/.babelrc deleted file mode 100644 index e4491c2..0000000 --- a/test/.babelrc +++ /dev/null @@ -1,20 +0,0 @@ -{ - "whitelist": [ - "es6.arrowFunctions", - "es6.blockScoping", - "es6.classes", - "es6.constants", - "es6.destructuring", - "es6.modules", - "es6.parameters", - "es6.properties.shorthand", - "es6.spread", - "es6.templateLiterals" - ], - "loose": [ - "es6.classes", - "es6.destructuring" - ], - "compact": false, - "sourceMap": true -} diff --git a/test/test.js b/test/test.js index a0a89a2..3ebe541 100644 --- a/test/test.js +++ b/test/test.js @@ -1,19 +1,19 @@ require( 'source-map-support' ).install(); require( 'console-group' ).install(); -var path = require( 'path' ); -var sander = require( 'sander' ); -var assert = require( 'assert' ); -var exec = require( 'child_process' ).exec; -var buble = require( 'buble' ); -var rollup = require( '../dist/rollup' ); - -var FUNCTION = path.resolve( __dirname, 'function' ); -var FORM = path.resolve( __dirname, 'form' ); -var SOURCEMAPS = path.resolve( __dirname, 'sourcemaps' ); -var CLI = path.resolve( __dirname, 'cli' ); - -var PROFILES = [ +const path = require( 'path' ); +const sander = require( 'sander' ); +const assert = require( 'assert' ); +const { exec } = require( 'child_process' ); +const buble = require( 'buble' ); +const rollup = require( '../dist/rollup' ); + +const FUNCTION = path.resolve( __dirname, 'function' ); +const FORM = path.resolve( __dirname, 'form' ); +const SOURCEMAPS = path.resolve( __dirname, 'sourcemaps' ); +const CLI = path.resolve( __dirname, 'cli' ); + +const PROFILES = [ { format: 'amd' }, { format: 'cjs' }, { format: 'es' }, @@ -22,8 +22,8 @@ var PROFILES = [ ]; function extend ( target ) { - [].slice.call( arguments, 1 ).forEach( function ( source ) { - source && Object.keys( source ).forEach( function ( key ) { + [].slice.call( arguments, 1 ).forEach( source => { + source && Object.keys( source ).forEach( key => { target[ key ] = source[ key ]; }); }); @@ -41,7 +41,7 @@ function loadConfig ( path ) { } catch ( err ) { console.error( err.message ); console.error( err.stack ); - throw new Error( 'Failed to load ' + path + '. An old test perhaps? You should probably delete the directory' ); + throw new Error( `Failed to load ${path}. An old test perhaps? You should probably delete the directory` ); } } @@ -57,81 +57,81 @@ function loader ( modules ) { }; } -describe( 'rollup', function () { +describe( 'rollup', () => { this.timeout( 10000 ); - describe( 'sanity checks', function () { - it( 'exists', function () { + describe( 'sanity checks', () => { + it( 'exists', () => { assert.ok( !!rollup ); }); - it( 'has a rollup method', function () { + it( 'has a rollup method', () => { assert.equal( typeof rollup.rollup, 'function' ); }); - it( 'fails without options', function () { - return rollup.rollup().then( function () { + it( 'fails without options', () => { + return rollup.rollup().then( () => { throw new Error( 'Missing expected error' ); - }, function (err) { + }, err => { assert.equal( 'You must supply options.entry to rollup', err.message ); }); }); - it( 'fails without options.entry', function () { - return rollup.rollup({}).then( function () { + it( 'fails without options.entry', () => { + return rollup.rollup({}).then( () => { throw new Error( 'Missing expected error' ); - }, function (err) { + }, err => { assert.equal( 'You must supply options.entry to rollup', err.message ); }); }); - it( 'fails with invalid keys', function () { - return rollup.rollup({ entry: 'x', plUgins: [] }).then( function () { + it( 'fails with invalid keys', () => { + return rollup.rollup({ entry: 'x', plUgins: [] }).then( () => { throw new Error( 'Missing expected error' ); - }, function ( err ) { + }, err => { assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); }); }); }); - describe( 'bundle.write()', function () { - it( 'fails without options or options.dest', function () { + describe( 'bundle.write()', () => { + it( 'fails without options or options.dest', () => { return rollup.rollup({ entry: 'x', plugins: [{ - resolveId: function () { return 'test'; }, - load: function () { + resolveId: () => { return 'test'; }, + load: () => { return '// empty'; } }] - }).then( function ( bundle ) { - assert.throws( function () { + }).then( bundle => { + assert.throws( () => { bundle.write(); }, /must supply options\.dest/ ); - assert.throws( function () { + assert.throws( () => { bundle.write({}); }, /must supply options\.dest/ ); }); }); - it( 'expects options.moduleName for IIFE and UMD bundles', function () { + it( 'expects options.moduleName for IIFE and UMD bundles', () => { return rollup.rollup({ entry: 'x', plugins: [{ - resolveId: function () { return 'test'; }, - load: function () { + resolveId: () => { return 'test'; }, + load: () => { return 'export var foo = 42;'; } }] - }).then( function ( bundle ) { - assert.throws( function () { + }).then( bundle => { + assert.throws( () => { bundle.generate({ format: 'umd' }); }, /You must supply options\.moduleName for UMD bundles/ ); - assert.throws( function () { + assert.throws( () => { bundle.generate({ format: 'iife' }); @@ -139,37 +139,37 @@ describe( 'rollup', function () { }); }); - it( 'warns on es6 format', function () { - var warned; + it( 'warns on es6 format', () => { + let warned; return rollup.rollup({ entry: 'x', plugins: [{ - resolveId: function () { return 'test'; }, - load: function () { + resolveId: () => { return 'test'; }, + load: () => { return '// empty'; } }], - onwarn: function ( msg ) { + onwarn: msg => { if ( /The es6 format is deprecated/.test( msg ) ) warned = true; } - }).then( function ( bundle ) { + }).then( bundle => { bundle.generate({ format: 'es6' }); assert.ok( warned ); }); }); }); - describe( 'function', function () { - sander.readdirSync( FUNCTION ).sort().forEach( function ( dir ) { + describe( 'function', () => { + sander.readdirSync( FUNCTION ).sort().forEach( dir => { if ( dir[0] === '.' ) return; // .DS_Store... - var config = loadConfig( FUNCTION + '/' + dir + '/_config.js' ); - ( config.skip ? it.skip : config.solo ? it.only : it )( dir, function () { - var warnings = []; - var captureWarning = msg => warnings.push( msg ); + const config = loadConfig( FUNCTION + '/' + dir + '/_config.js' ); + ( config.skip ? it.skip : config.solo ? it.only : it )( dir, () => { + let warnings = []; + const captureWarning = msg => warnings.push( msg ); - var options = extend( { + const options = extend( { entry: FUNCTION + '/' + dir + '/main.js', onwarn: captureWarning }, config.options ); @@ -177,16 +177,18 @@ describe( 'rollup', function () { if ( config.solo ) console.group( dir ); return rollup.rollup( options ) - .then( function ( bundle ) { - var unintendedError; + .then( bundle => { + let unintendedError; if ( config.error ) { throw new Error( 'Expected an error while rolling up' ); } + let result; + // try to generate output try { - var result = bundle.generate( extend( {}, config.bundleOptions, { + result = bundle.generate( extend( {}, config.bundleOptions, { format: 'cjs' })); @@ -204,7 +206,7 @@ describe( 'rollup', function () { if ( unintendedError ) throw unintendedError; if ( config.error || config.generateError ) return; - var code = result.code; + let code = result.code; if ( config.buble ) { code = buble.transform( code, { @@ -214,24 +216,17 @@ describe( 'rollup', function () { if ( config.code ) config.code( code ); - var module = { + let module = { exports: {} }; - var context = extend({ - require: require, - module: module, - exports: module.exports, - assert: assert - }, config.context || {} ); + const context = extend({ require, module, assert, exports: module.exports }, config.context || {} ); - var contextKeys = Object.keys( context ); - var contextValues = contextKeys.map( function ( key ) { - return context[ key ]; - }); + const contextKeys = Object.keys( context ); + const contextValues = contextKeys.map( key => context[ key ] ); try { - var fn = new Function( contextKeys, code ); + const fn = new Function( contextKeys, code ); fn.apply( {}, contextValues ); if ( config.runtimeError ) { @@ -261,7 +256,7 @@ describe( 'rollup', function () { if ( config.solo ) console.groupEnd(); if ( unintendedError ) throw unintendedError; - }, function ( err ) { + }, err => { if ( config.error ) { config.error( err ); } else { @@ -272,15 +267,15 @@ describe( 'rollup', function () { }); }); - describe( 'form', function () { - sander.readdirSync( FORM ).sort().forEach( function ( dir ) { + describe( 'form', () => { + sander.readdirSync( FORM ).sort().forEach( dir => { if ( dir[0] === '.' ) return; // .DS_Store... - var config = loadConfig( FORM + '/' + dir + '/_config.js' ); + const config = loadConfig( FORM + '/' + dir + '/_config.js' ); if ( config.skipIfWindows && process.platform === 'win32' ) return; - var options = extend( {}, { + const options = extend( {}, { entry: FORM + '/' + dir + '/main.js', onwarn: msg => { if ( /No name was provided for/.test( msg ) ) return; @@ -289,20 +284,20 @@ describe( 'rollup', function () { } }, config.options ); - ( config.skip ? describe.skip : config.solo ? describe.only : describe)( dir, function () { - PROFILES.forEach( function ( profile ) { - it( 'generates ' + profile.format, function () { - return rollup.rollup( options ).then( function ( bundle ) { - var options = extend( {}, config.options, { + ( config.skip ? describe.skip : config.solo ? describe.only : describe)( dir, () => { + PROFILES.forEach( profile => { + it( 'generates ' + profile.format, () => { + return rollup.rollup( options ).then( bundle => { + const options = extend( {}, config.options, { dest: FORM + '/' + dir + '/_actual/' + profile.format + '.js', format: profile.format }); - return bundle.write( options ).then( function () { - var actualCode = normaliseOutput( sander.readFileSync( FORM, dir, '_actual', profile.format + '.js' ) ); - var expectedCode; - var actualMap; - var expectedMap; + return bundle.write( options ).then( () => { + const actualCode = normaliseOutput( sander.readFileSync( FORM, dir, '_actual', profile.format + '.js' ) ); + let expectedCode; + let actualMap; + let expectedMap; try { expectedCode = normaliseOutput( sander.readFileSync( FORM, dir, '_expected', profile.format + '.js' ) ); @@ -338,26 +333,24 @@ describe( 'rollup', function () { }); }); - describe( 'sourcemaps', function () { - sander.readdirSync( SOURCEMAPS ).sort().forEach( function ( dir ) { + describe( 'sourcemaps', () => { + sander.readdirSync( SOURCEMAPS ).sort().forEach( dir => { if ( dir[0] === '.' ) return; // .DS_Store... - describe( dir, function () { + describe( dir, () => { process.chdir( SOURCEMAPS + '/' + dir ); - var config = loadConfig( SOURCEMAPS + '/' + dir + '/_config.js' ); + const config = loadConfig( SOURCEMAPS + '/' + dir + '/_config.js' ); - var entry = path.resolve( SOURCEMAPS, dir, 'main.js' ); - var dest = path.resolve( SOURCEMAPS, dir, '_actual/bundle' ); + const entry = path.resolve( SOURCEMAPS, dir, 'main.js' ); + const dest = path.resolve( SOURCEMAPS, dir, '_actual/bundle' ); - var options = extend( {}, config.options, { - entry: entry - }); + const options = extend( {}, config.options, { entry }); - PROFILES.forEach( function ( profile ) { - ( config.skip ? it.skip : config.solo ? it.only : it )( 'generates ' + profile.format, function () { + PROFILES.forEach( profile => { + ( config.skip ? it.skip : config.solo ? it.only : it )( 'generates ' + profile.format, () => { process.chdir( SOURCEMAPS + '/' + dir ); - return rollup.rollup( options ).then( function ( bundle ) { - var options = extend( {}, { + return rollup.rollup( options ).then( bundle => { + const options = extend( {}, { format: profile.format, sourceMap: true, dest: `${dest}.${profile.format}.js` @@ -366,7 +359,7 @@ describe( 'rollup', function () { bundle.write( options ); if ( config.before ) config.before(); - var result = bundle.generate( options ); + const result = bundle.generate( options ); config.test( result.code, result.map ); }); }); @@ -375,19 +368,19 @@ describe( 'rollup', function () { }); }); - describe( 'cli', function () { - sander.readdirSync( CLI ).sort().forEach( function ( dir ) { + describe( 'cli', () => { + sander.readdirSync( CLI ).sort().forEach( dir => { if ( dir[0] === '.' ) return; // .DS_Store... - describe( dir, function () { - var config = loadConfig( CLI + '/' + dir + '/_config.js' ); + describe( dir, () => { + const config = loadConfig( CLI + '/' + dir + '/_config.js' ); - ( config.skip ? it.skip : config.solo ? it.only : it )( dir, function ( done ) { + ( config.skip ? it.skip : config.solo ? it.only : it )( dir, done => { process.chdir( config.cwd || path.resolve( CLI, dir ) ); const command = 'node ' + path.resolve( __dirname, '../bin' ) + path.sep + config.command; - exec( command, {}, function ( err, code, stderr ) { + exec( command, {}, ( err, code, stderr ) => { if ( err ) { if ( config.error ) { config.error( err ); @@ -399,7 +392,7 @@ describe( 'rollup', function () { if ( stderr ) console.error( stderr ); - var unintendedError; + let unintendedError; if ( config.execute ) { try { @@ -409,8 +402,8 @@ describe( 'rollup', function () { }).code; } - var fn = new Function( 'require', 'module', 'exports', 'assert', code ); - var module = { + const fn = new Function( 'require', 'module', 'exports', 'assert', code ); + const module = { exports: {} }; fn( require, module, module.exports, assert ); @@ -449,10 +442,10 @@ describe( 'rollup', function () { } else if ( sander.existsSync( '_expected' ) && sander.statSync( '_expected' ).isDirectory() ) { - var error = null; + let error = null; sander.readdirSync( '_expected' ).forEach( child => { - var expected = sander.readFileSync( path.join( '_expected', child ) ).toString(); - var actual = sander.readFileSync( path.join( '_actual', child ) ).toString(); + const expected = sander.readFileSync( path.join( '_expected', child ) ).toString(); + const actual = sander.readFileSync( path.join( '_actual', child ) ).toString(); try { assert.equal( normaliseOutput( actual ), normaliseOutput( expected ) ); } catch ( err ) { @@ -463,7 +456,7 @@ describe( 'rollup', function () { } else { - var expected = sander.readFileSync( '_expected.js' ).toString(); + const expected = sander.readFileSync( '_expected.js' ).toString(); try { assert.equal( normaliseOutput( code ), normaliseOutput( expected ) ); done(); @@ -477,7 +470,7 @@ describe( 'rollup', function () { }); }); - describe('incremental', function () { + describe('incremental', () => { function executeBundle ( bundle ) { const cjs = bundle.generate({ format: 'cjs' }); const m = new Function( 'module', 'exports', cjs.code ); @@ -488,17 +481,17 @@ describe( 'rollup', function () { return module.exports; } - var calls; - var modules; + let calls; + let modules; - var plugin = { + const plugin = { resolveId: id => id, load: id => { return modules[ id ]; }, - transform: function ( code ) { + transform: code => { calls += 1; return code; } @@ -513,7 +506,7 @@ describe( 'rollup', function () { }; }); - it('does not transforms in the second time', function () { + it('does not transforms in the second time', () => { return rollup.rollup({ entry: 'entry', plugins: [ plugin ] @@ -530,7 +523,7 @@ describe( 'rollup', function () { }); }); - it('transforms modified sources', function () { + it('transforms modified sources', () => { let cache; return rollup.rollup({ @@ -557,7 +550,7 @@ describe( 'rollup', function () { describe( 'hooks', () => { it( 'passes bundle & output object to ongenerate & onwrite hooks', () => { - var dest = path.join( __dirname, 'tmp/bundle.js' ); + const dest = path.join( __dirname, 'tmp/bundle.js' ); return rollup.rollup({ entry: 'entry', @@ -583,7 +576,7 @@ describe( 'rollup', function () { }); it( 'calls ongenerate hooks in sequence', () => { - var result = []; + let result = []; return rollup.rollup({ entry: 'entry', @@ -611,8 +604,8 @@ describe( 'rollup', function () { }); it( 'calls onwrite hooks in sequence', () => { - var result = []; - var dest = path.join( __dirname, 'tmp/bundle.js' ); + let result = []; + const dest = path.join( __dirname, 'tmp/bundle.js' ); return rollup.rollup({ entry: 'entry', From 5c0597d70a4a0800bd320d20a229050d73c6daac Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 10 Jul 2016 22:37:15 -0400 Subject: [PATCH 135/331] -> v0.34.1 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9de5f8..163d0e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.34.1 + +* Support `paths` config ([#754](https://github.com/rollup/rollup/issues/754)) +* Allow `export *` from external module, internally + ## 0.34.0 * Use resolved IDs for relative imports that are also external modules, to allow `options.globals` to work with them ([#763](https://github.com/rollup/rollup/issues/763)) diff --git a/package.json b/package.json index ed15d8c..9f9b6f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.0", + "version": "0.34.1", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "dist/rollup.es.js", From e275a9cd607d49df1f5a1d13bda897dd5b066b63 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 10 Jul 2016 22:47:37 -0400 Subject: [PATCH 136/331] oops --- test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index 3ebe541..e68452b 100644 --- a/test/test.js +++ b/test/test.js @@ -57,7 +57,7 @@ function loader ( modules ) { }; } -describe( 'rollup', () => { +describe( 'rollup', function () { this.timeout( 10000 ); describe( 'sanity checks', () => { From 60a4e406b6927f1c910f7e4e6f5c2e242bbcabb9 Mon Sep 17 00:00:00 2001 From: Eli Skeggs Date: Thu, 28 Jul 2016 15:46:10 -0700 Subject: [PATCH 137/331] Add explicit entry resolve error message Fixes #802 --- src/Bundle.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bundle.js b/src/Bundle.js index 96b2486..84a5481 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -88,6 +88,7 @@ export default class Bundle { // of the entry module's dependencies return this.resolveId( this.entry, undefined ) .then( id => { + if ( id == null ) throw new Error( `Could not resolve entry (${this.entry})` ); this.entryId = id; return this.fetchModule( id, undefined ); }) From c2f65e75cc790dfff3fc25e7f56b6b3b13ae1f73 Mon Sep 17 00:00:00 2001 From: Eli Skeggs Date: Thu, 28 Jul 2016 16:21:25 -0700 Subject: [PATCH 138/331] Fix existing test --- test/function/load-returns-string-or-null/main.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/function/load-returns-string-or-null/main.js diff --git a/test/function/load-returns-string-or-null/main.js b/test/function/load-returns-string-or-null/main.js new file mode 100644 index 0000000..422c084 --- /dev/null +++ b/test/function/load-returns-string-or-null/main.js @@ -0,0 +1 @@ +throw new Error('should not be reached'); From 07cb66656278f1c76ce79fd877cbe9b2b5502d36 Mon Sep 17 00:00:00 2001 From: Eli Skeggs Date: Thu, 28 Jul 2016 16:21:30 -0700 Subject: [PATCH 139/331] Add new test --- test/function/check-resolve-for-entry/_config.js | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 test/function/check-resolve-for-entry/_config.js diff --git a/test/function/check-resolve-for-entry/_config.js b/test/function/check-resolve-for-entry/_config.js new file mode 100644 index 0000000..a06632d --- /dev/null +++ b/test/function/check-resolve-for-entry/_config.js @@ -0,0 +1,11 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'checks that entry is resolved', + options: { + entry: '/not/a/path/that/actually/really/exists' + }, + error: function ( err ) { + assert.ok( /Could not resolve entry/.test( err.message ) ); + } +}; From edf132eecf560ee2da194a5b18a39320c4b40db1 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 30 Jul 2016 11:18:43 +0300 Subject: [PATCH 140/331] Treat path as external dependency --- rollup.config.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rollup.config.js b/rollup.config.js index bac62f2..7847ff7 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -36,7 +36,10 @@ export default { values: { 'VERSION': pkg.version } }) ], - external: [ 'fs' ], + external: [ + 'fs', + 'path' + ], banner: banner, sourceMap: true, moduleName: 'rollup', From 684dde0a30e27247c2378d91b92f73abe3757513 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 30 Jul 2016 15:04:54 +0300 Subject: [PATCH 141/331] Cache resolvedIds in modules to improve incremental build --- src/Bundle.js | 18 ++++++-- src/Module.js | 7 +-- test/function/has-resolved-ids/_config.js | 13 ++++++ test/function/has-resolved-ids/foo.js | 1 + test/function/has-resolved-ids/main.js | 2 + test/test.js | 54 ++++++++++++++++++----- 6 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 test/function/has-resolved-ids/_config.js create mode 100644 test/function/has-resolved-ids/foo.js create mode 100644 test/function/has-resolved-ids/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 96b2486..60ad1fa 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -201,9 +201,18 @@ export default class Bundle { return transform( source, id, this.plugins ); }) .then( source => { - const { code, originalCode, originalSourceMap, ast, sourceMapChain } = source; - - const module = new Module({ id, code, originalCode, originalSourceMap, ast, sourceMapChain, bundle: this }); + const { code, originalCode, originalSourceMap, ast, sourceMapChain, resolvedIds } = source; + + const module = new Module({ + id, + code, + originalCode, + originalSourceMap, + ast, + sourceMapChain, + resolvedIds, + bundle: this + }); this.modules.push( module ); this.moduleById.set( id, module ); @@ -232,7 +241,8 @@ export default class Bundle { fetchAllDependencies ( module ) { return mapSequence( module.sources, source => { - return this.resolveId( source, module.id ) + const resolvedId = module.resolvedIds[ source ]; + return ( resolvedId ? Promise.resolve( resolvedId ) : this.resolveId( source, module.id ) ) .then( resolvedId => { const externalId = resolvedId || ( isRelative( source ) ? resolve( module.id, '..', source ) : source diff --git a/src/Module.js b/src/Module.js index 4d57a19..1cac43a 100644 --- a/src/Module.js +++ b/src/Module.js @@ -17,7 +17,7 @@ import { emptyBlockStatement } from './ast/create.js'; import extractNames from './ast/extractNames.js'; export default class Module { - constructor ({ id, code, originalCode, originalSourceMap, ast, sourceMapChain, bundle }) { + constructor ({ id, code, originalCode, originalSourceMap, ast, sourceMapChain, resolvedIds, bundle }) { this.code = code; this.originalCode = originalCode; this.originalSourceMap = originalSourceMap; @@ -30,7 +30,7 @@ export default class Module { // all dependencies this.sources = []; this.dependencies = []; - this.resolvedIds = blank(); + this.resolvedIds = resolvedIds || blank(); // imports and exports, indexed by local name this.imports = blank(); @@ -657,7 +657,8 @@ export default class Module { code: this.code, originalCode: this.originalCode, ast: this.ast, - sourceMapChain: this.sourceMapChain + sourceMapChain: this.sourceMapChain, + resolvedIds: this.resolvedIds }; } diff --git a/test/function/has-resolved-ids/_config.js b/test/function/has-resolved-ids/_config.js new file mode 100644 index 0000000..b2f3e1a --- /dev/null +++ b/test/function/has-resolved-ids/_config.js @@ -0,0 +1,13 @@ +var path = require( 'path' ); +var assert = require( 'assert' ); + +module.exports = { + description: 'user-facing bundle has resolvedIds map in every modules', + bundle: function ( bundle ) { + assert.ok( bundle.modules[ 0 ].resolvedIds ); + assert.ok( bundle.modules[ 1 ].resolvedIds ); + assert.equal( Object.keys( bundle.modules[ 0 ].resolvedIds ).length, 0 ); + assert.equal( Object.keys( bundle.modules[ 1 ].resolvedIds ).length, 1 ); + assert.equal( bundle.modules[ 1 ].resolvedIds[ './foo' ], path.resolve( __dirname, 'foo.js' ) ); + } +}; diff --git a/test/function/has-resolved-ids/foo.js b/test/function/has-resolved-ids/foo.js new file mode 100644 index 0000000..7a4e8a7 --- /dev/null +++ b/test/function/has-resolved-ids/foo.js @@ -0,0 +1 @@ +export default 42; diff --git a/test/function/has-resolved-ids/main.js b/test/function/has-resolved-ids/main.js new file mode 100644 index 0000000..3206f53 --- /dev/null +++ b/test/function/has-resolved-ids/main.js @@ -0,0 +1,2 @@ +import foo from './foo'; +assert.equal( foo, 42 ); diff --git a/test/test.js b/test/test.js index e68452b..ae8d2d1 100644 --- a/test/test.js +++ b/test/test.js @@ -470,7 +470,7 @@ describe( 'rollup', function () { }); }); - describe('incremental', () => { + describe( 'incremental', () => { function executeBundle ( bundle ) { const cjs = bundle.generate({ format: 'cjs' }); const m = new Function( 'module', 'exports', cjs.code ); @@ -481,44 +481,52 @@ describe( 'rollup', function () { return module.exports; } - let calls; + let resolveIdCalls; + let transformCalls; let modules; const plugin = { - resolveId: id => id, + resolveId: id => { + resolveIdCalls += 1; + return id; + }, load: id => { return modules[ id ]; }, transform: code => { - calls += 1; + transformCalls += 1; return code; } }; beforeEach( () => { - calls = 0; + resolveIdCalls = 0; + transformCalls = 0; modules = { entry: `import foo from 'foo'; export default foo;`, - foo: `export default 42` + foo: `export default 42`, + bar: `export default 21` }; }); - it('does not transforms in the second time', () => { + it('does not resolves id and transforms in the second time', () => { return rollup.rollup({ entry: 'entry', plugins: [ plugin ] }).then( bundle => { - assert.equal( calls, 2 ); + assert.equal( resolveIdCalls, 2 ); + assert.equal( transformCalls, 2 ); return rollup.rollup({ entry: 'entry', plugins: [ plugin ], cache: bundle }); }).then( bundle => { - assert.equal( calls, 2 ); + assert.equal( resolveIdCalls, 3 ); // +1 for entry point which is resolved every time + assert.equal( transformCalls, 2 ); assert.equal( executeBundle( bundle ), 42 ); }); }); @@ -530,7 +538,7 @@ describe( 'rollup', function () { entry: 'entry', plugins: [ plugin ] }).then( bundle => { - assert.equal( calls, 2 ); + assert.equal( transformCalls, 2 ); assert.equal( executeBundle( bundle ), 42 ); modules.foo = `export default 43`; @@ -542,10 +550,34 @@ describe( 'rollup', function () { cache }); }).then( bundle => { - assert.equal( calls, 3 ); + assert.equal( transformCalls, 3 ); assert.equal( executeBundle( bundle ), 43 ); }); }); + + it('resolves id of new imports', () => { + let cache; + + return rollup.rollup({ + entry: 'entry', + plugins: [ plugin ] + }).then( bundle => { + assert.equal( resolveIdCalls, 2 ); + assert.equal( executeBundle( bundle ), 42 ); + + modules.entry = `import bar from 'bar'; export default bar;`; + cache = bundle; + }).then( () => { + return rollup.rollup({ + entry: 'entry', + plugins: [ plugin ], + cache + }); + }).then( bundle => { + assert.equal( resolveIdCalls, 4 ); + assert.equal( executeBundle( bundle ), 21 ); + }); + }); }); describe( 'hooks', () => { From 1a2d3dce26d813e96fc73860699b1bf22ccb5181 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 30 Jul 2016 14:08:31 +0300 Subject: [PATCH 142/331] Changde indent default to false --- src/utils/getIndentString.js | 2 +- test/cli/banner-intro-outro-footer/_config.js | 2 +- test/cli/module-name/_config.js | 2 +- test/cli/no-strict/_config.js | 2 +- test/cli/no-treeshake/_config.js | 2 +- test/test.js | 6 ++++++ 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/utils/getIndentString.js b/src/utils/getIndentString.js index 8ad7b55..5130ed8 100644 --- a/src/utils/getIndentString.js +++ b/src/utils/getIndentString.js @@ -1,5 +1,5 @@ export default function getIndentString ( magicString, options ) { - if ( !( 'indent' in options ) || options.indent === true ) { + if ( options.indent === true ) { return magicString.getIndentString(); } diff --git a/test/cli/banner-intro-outro-footer/_config.js b/test/cli/banner-intro-outro-footer/_config.js index 2e30a3c..2d67639 100644 --- a/test/cli/banner-intro-outro-footer/_config.js +++ b/test/cli/banner-intro-outro-footer/_config.js @@ -1,4 +1,4 @@ module.exports = { description: 'adds banner/intro/outro/footer', - command: 'rollup -i main.js -f iife --banner "// banner" --intro "// intro" --outro "// outro" --footer "// footer"' + command: 'rollup -i main.js -f iife --indent --banner "// banner" --intro "// intro" --outro "// outro" --footer "// footer"' }; diff --git a/test/cli/module-name/_config.js b/test/cli/module-name/_config.js index da790e4..ca5d167 100644 --- a/test/cli/module-name/_config.js +++ b/test/cli/module-name/_config.js @@ -1,4 +1,4 @@ module.exports = { description: 'generates UMD export with correct moduleName', - command: 'rollup main.js --format umd --name myBundle' + command: 'rollup main.js --format umd --name myBundle --indent' }; diff --git a/test/cli/no-strict/_config.js b/test/cli/no-strict/_config.js index efc646d..72d4a32 100644 --- a/test/cli/no-strict/_config.js +++ b/test/cli/no-strict/_config.js @@ -1,4 +1,4 @@ module.exports = { description: 'use no strict option', - command: 'rollup -i main.js -f iife --no-strict' + command: 'rollup -i main.js -f iife --no-strict --indent' }; diff --git a/test/cli/no-treeshake/_config.js b/test/cli/no-treeshake/_config.js index 18d8b69..be25c45 100644 --- a/test/cli/no-treeshake/_config.js +++ b/test/cli/no-treeshake/_config.js @@ -1,4 +1,4 @@ module.exports = { description: 'generates IIFE export with all code', - command: 'rollup main.js --format iife --name shakeless --no-treeshake' + command: 'rollup main.js --format iife --name shakeless --no-treeshake --indent' }; diff --git a/test/test.js b/test/test.js index e68452b..05f400f 100644 --- a/test/test.js +++ b/test/test.js @@ -274,6 +274,12 @@ describe( 'rollup', function () { const config = loadConfig( FORM + '/' + dir + '/_config.js' ); if ( config.skipIfWindows && process.platform === 'win32' ) return; + if ( !config.options ) { + config.options = {}; + } + if ( !( 'indent' in config.options ) ) { + config.options.indent = true; + } const options = extend( {}, { entry: FORM + '/' + dir + '/main.js', From bd1c379a1791c02ea784b3d2a19e07493ad5fbd8 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 31 Jul 2016 13:28:31 +0300 Subject: [PATCH 143/331] Reduce transformers error message chain --- src/utils/transform.js | 9 ++++-- .../_config.js | 25 ++++++++++++++++ .../main.js | 1 + .../throws-only-first-transform/_config.js | 29 +++++++++++++++++++ .../throws-only-first-transform/main.js | 1 + 5 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 test/function/throws-only-first-transform-bundle/_config.js create mode 100644 test/function/throws-only-first-transform-bundle/main.js create mode 100644 test/function/throws-only-first-transform/_config.js create mode 100644 test/function/throws-only-first-transform/main.js diff --git a/src/utils/transform.js b/src/utils/transform.js index a1286b2..a5c4ccb 100644 --- a/src/utils/transform.js +++ b/src/utils/transform.js @@ -31,9 +31,12 @@ export default function transform ( source, id, plugins ) { return result.code; }); }).catch( err => { - err.id = id; - err.plugin = plugin.name; - err.message = `Error transforming ${id}${plugin.name ? ` with '${plugin.name}' plugin` : ''}: ${err.message}`; + if ( !err.rollupTransform ) { + err.rollupTransform = true; + err.id = id; + err.plugin = plugin.name; + err.message = `Error transforming ${id}${plugin.name ? ` with '${plugin.name}' plugin` : ''}: ${err.message}`; + } throw err; }); }, Promise.resolve( source.code ) ) diff --git a/test/function/throws-only-first-transform-bundle/_config.js b/test/function/throws-only-first-transform-bundle/_config.js new file mode 100644 index 0000000..9097f52 --- /dev/null +++ b/test/function/throws-only-first-transform-bundle/_config.js @@ -0,0 +1,25 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'throws error only with first plugin transformBundle', + options: { + plugins: [ + { + name: 'plugin1', + transformBundle: function () { + throw Error('Something happend 1'); + } + }, + { + name: 'plugin2', + transformBundle: function () { + throw Error('Something happend 2'); + } + } + ] + }, + generateError: function ( err ) { + assert.equal( err.plugin, 'plugin1' ); + assert.equal( err.message, 'Error transforming bundle with \'plugin1\' plugin: Something happend 1' ); + } +}; \ No newline at end of file diff --git a/test/function/throws-only-first-transform-bundle/main.js b/test/function/throws-only-first-transform-bundle/main.js new file mode 100644 index 0000000..4e2e0f5 --- /dev/null +++ b/test/function/throws-only-first-transform-bundle/main.js @@ -0,0 +1 @@ +console.log(1); \ No newline at end of file diff --git a/test/function/throws-only-first-transform/_config.js b/test/function/throws-only-first-transform/_config.js new file mode 100644 index 0000000..c97907e --- /dev/null +++ b/test/function/throws-only-first-transform/_config.js @@ -0,0 +1,29 @@ +var assert = require( 'assert' ); +var path = require( 'path' ); + +module.exports = { + description: 'throws error only with first plugin transform', + options: { + plugins: [ + { + name: 'plugin1', + transform: function () { + throw Error('Something happend 1'); + } + }, + { + name: 'plugin2', + transform: function () { + throw Error('Something happend 2'); + } + } + ] + }, + error: function ( err ) { + var id = path.resolve( __dirname, 'main.js' ); + assert.equal( err.rollupTransform, true ); + assert.equal( err.id, id ); + assert.equal( err.plugin, 'plugin1' ); + assert.equal( err.message, 'Error transforming ' + id + ' with \'plugin1\' plugin: Something happend 1' ); + } +}; \ No newline at end of file diff --git a/test/function/throws-only-first-transform/main.js b/test/function/throws-only-first-transform/main.js new file mode 100644 index 0000000..4e2e0f5 --- /dev/null +++ b/test/function/throws-only-first-transform/main.js @@ -0,0 +1 @@ +console.log(1); \ No newline at end of file From 8bca62b559e21a58b595030798b268653a316593 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 31 Jul 2016 13:34:20 +0300 Subject: [PATCH 144/331] Test for not resolved module --- test/function/throws-not-found-module/_config.js | 10 ++++++++++ test/function/throws-not-found-module/main.js | 1 + 2 files changed, 11 insertions(+) create mode 100644 test/function/throws-not-found-module/_config.js create mode 100644 test/function/throws-not-found-module/main.js diff --git a/test/function/throws-not-found-module/_config.js b/test/function/throws-not-found-module/_config.js new file mode 100644 index 0000000..eebfd47 --- /dev/null +++ b/test/function/throws-not-found-module/_config.js @@ -0,0 +1,10 @@ +var assert = require( 'assert' ); +var path = require( 'path' ); + +module.exports = { + solo: true, + description: 'throws error if module is not found', + error: function ( err ) { + assert.equal( err.message, 'Could not resolve ./mod from ' + path.resolve( __dirname, 'main.js' ) ); + } +}; \ No newline at end of file diff --git a/test/function/throws-not-found-module/main.js b/test/function/throws-not-found-module/main.js new file mode 100644 index 0000000..9ed266e --- /dev/null +++ b/test/function/throws-not-found-module/main.js @@ -0,0 +1 @@ +import './mod'; \ No newline at end of file From b215060634089526d6202b6cefdcbe1b7e307b61 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 31 Jul 2016 14:29:27 +0300 Subject: [PATCH 145/331] Wrap source id with quotes in unresolved error --- src/Bundle.js | 2 +- test/function/throws-not-found-module/_config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 96b2486..8c0fce0 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -241,7 +241,7 @@ export default class Bundle { let isExternal = this.isExternal( externalId ); if ( !resolvedId && !isExternal ) { - if ( isRelative( source ) ) throw new Error( `Could not resolve ${source} from ${module.id}` ); + if ( isRelative( source ) ) throw new Error( `Could not resolve '${source}' from ${module.id}` ); this.onwarn( `Treating '${source}' as external dependency` ); isExternal = true; diff --git a/test/function/throws-not-found-module/_config.js b/test/function/throws-not-found-module/_config.js index eebfd47..9030995 100644 --- a/test/function/throws-not-found-module/_config.js +++ b/test/function/throws-not-found-module/_config.js @@ -5,6 +5,6 @@ module.exports = { solo: true, description: 'throws error if module is not found', error: function ( err ) { - assert.equal( err.message, 'Could not resolve ./mod from ' + path.resolve( __dirname, 'main.js' ) ); + assert.equal( err.message, 'Could not resolve \'./mod\' from ' + path.resolve( __dirname, 'main.js' ) ); } }; \ No newline at end of file From 7b7709eb383c71667d5ca8ed1eda3c8d35dad3b7 Mon Sep 17 00:00:00 2001 From: Ronald Berner Date: Sun, 31 Jul 2016 11:34:04 -0400 Subject: [PATCH 146/331] If removing import statements, start at the beginning of the actualy import keyword, instead of the beginning of the file (statement.start vs statement.node.start) --- src/Module.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Module.js b/src/Module.js index 4d57a19..9510c19 100644 --- a/src/Module.js +++ b/src/Module.js @@ -451,6 +451,11 @@ export default class Module { this.statements.forEach( statement => { if ( !statement.isIncluded ) { + if ( statement.node.type === 'ImportDeclaration' ) { + magicString.remove( statement.node.start, statement.next ); + return; + } + magicString.remove( statement.start, statement.next ); return; } From 23f89abf324969d03f420654a1f12f5091586081 Mon Sep 17 00:00:00 2001 From: Chadkin Date: Mon, 1 Aug 2016 15:49:38 +0300 Subject: [PATCH 147/331] -> v0.34.2 --- CHANGELOG.md | 5 +++++ package.json | 2 +- test/function/custom-path-resolver-on-entry/_config.js | 1 - test/function/default-export-is-not-bound-b/_config.js | 1 - test/function/newline-after-comment/_config.js | 1 - test/function/no-relative-external/_config.js | 2 +- test/function/throws-not-found-module/_config.js | 1 - 7 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 163d0e2..baca6a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.34.2 + +* resolveId calls are cached now to improve incremental build +* Fixed error message recursion in plugins + ## 0.34.1 * Support `paths` config ([#754](https://github.com/rollup/rollup/issues/754)) diff --git a/package.json b/package.json index 9f9b6f6..d9dfd35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.1", + "version": "0.34.2", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "dist/rollup.es.js", diff --git a/test/function/custom-path-resolver-on-entry/_config.js b/test/function/custom-path-resolver-on-entry/_config.js index 0766b6c..b41282b 100644 --- a/test/function/custom-path-resolver-on-entry/_config.js +++ b/test/function/custom-path-resolver-on-entry/_config.js @@ -8,7 +8,6 @@ var cachedModules = { module.exports = { description: 'applies custom resolver to entry point', - //solo: true, options: { plugins: [{ resolveId: function ( importee, importer ) { diff --git a/test/function/default-export-is-not-bound-b/_config.js b/test/function/default-export-is-not-bound-b/_config.js index 7527035..a1aed25 100644 --- a/test/function/default-export-is-not-bound-b/_config.js +++ b/test/function/default-export-is-not-bound-b/_config.js @@ -5,5 +5,4 @@ module.exports = { exports: function ( exports ) { assert.equal( exports.bar, 42 ); } - // solo: true }; diff --git a/test/function/newline-after-comment/_config.js b/test/function/newline-after-comment/_config.js index d28ead5..85191d6 100644 --- a/test/function/newline-after-comment/_config.js +++ b/test/function/newline-after-comment/_config.js @@ -5,5 +5,4 @@ module.exports = { exports: function ( exports ) { assert.equal( exports(), 42 ); } - // solo: true }; diff --git a/test/function/no-relative-external/_config.js b/test/function/no-relative-external/_config.js index 37f86df..b5c37e0 100644 --- a/test/function/no-relative-external/_config.js +++ b/test/function/no-relative-external/_config.js @@ -3,6 +3,6 @@ var assert = require( 'assert' ); module.exports = { description: 'missing relative imports are an error, not a warning', error: function ( err ) { - assert.ok( /Could not resolve \.\/missing\.js from/.test( err.message ) ); + assert.ok( /Could not resolve '\.\/missing\.js' from/.test( err.message ) ); } }; diff --git a/test/function/throws-not-found-module/_config.js b/test/function/throws-not-found-module/_config.js index 9030995..04963a3 100644 --- a/test/function/throws-not-found-module/_config.js +++ b/test/function/throws-not-found-module/_config.js @@ -2,7 +2,6 @@ var assert = require( 'assert' ); var path = require( 'path' ); module.exports = { - solo: true, description: 'throws error if module is not found', error: function ( err ) { assert.equal( err.message, 'Could not resolve \'./mod\' from ' + path.resolve( __dirname, 'main.js' ) ); From 088d12bf9f206fe00d64a3f5cd332a07fadaf9d2 Mon Sep 17 00:00:00 2001 From: "ph.ter" Date: Thu, 28 Jul 2016 11:28:54 +0200 Subject: [PATCH 148/331] Avoid infinite recursion in Bundle.sort() --- src/Bundle.js | 12 +++++++----- test/function/cycles-pathological-2/_config.js | 11 +++++++++++ test/function/cycles-pathological-2/b.js | 11 +++++++++++ test/function/cycles-pathological-2/c.js | 9 +++++++++ test/function/cycles-pathological-2/d.js | 7 +++++++ test/function/cycles-pathological-2/main.js | 11 +++++++++++ 6 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 test/function/cycles-pathological-2/_config.js create mode 100644 test/function/cycles-pathological-2/b.js create mode 100644 test/function/cycles-pathological-2/c.js create mode 100644 test/function/cycles-pathological-2/d.js create mode 100644 test/function/cycles-pathological-2/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 0f46380..7b937d4 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -422,15 +422,17 @@ export default class Bundle { // b imports a, a is placed before b. We need to find the module // in question, so we can provide a useful error message let parent = '[[unknown]]'; + const visited = {}; const findParent = module => { if ( dependsOn[ module.id ][ a.id ] && dependsOn[ module.id ][ b.id ] ) { parent = module.id; - } else { - for ( let i = 0; i < module.dependencies.length; i += 1 ) { - const dependency = module.dependencies[i]; - if ( findParent( dependency ) ) return; - } + return true; + } + visited[ module.id ] = true; + for ( let i = 0; i < module.dependencies.length; i += 1 ) { + const dependency = module.dependencies[i]; + if ( !visited[ dependency.id ] && findParent( dependency ) ) return true; } }; diff --git a/test/function/cycles-pathological-2/_config.js b/test/function/cycles-pathological-2/_config.js new file mode 100644 index 0000000..87ba7d6 --- /dev/null +++ b/test/function/cycles-pathological-2/_config.js @@ -0,0 +1,11 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'resolves even more pathological cyclical dependencies gracefully', + buble: true, + options: { + onwarn: function ( message ) { + assert.ok( /unable to evaluate without/.test( message ) ); + } + } +}; diff --git a/test/function/cycles-pathological-2/b.js b/test/function/cycles-pathological-2/b.js new file mode 100644 index 0000000..1a4723b --- /dev/null +++ b/test/function/cycles-pathological-2/b.js @@ -0,0 +1,11 @@ +import { a, av } from './main'; +import { d, dv } from './d'; +import { c, cv } from './c'; + +export function b() { + a(av); + d(dv); + c(cv); +}; + +export const bv = av + dv + cv; diff --git a/test/function/cycles-pathological-2/c.js b/test/function/cycles-pathological-2/c.js new file mode 100644 index 0000000..da8f42e --- /dev/null +++ b/test/function/cycles-pathological-2/c.js @@ -0,0 +1,9 @@ +import { b, bv } from './b'; +import { a, av } from './main'; + +export function c() { + a(av); + b(bv); +}; + +export const cv = av + bv; diff --git a/test/function/cycles-pathological-2/d.js b/test/function/cycles-pathological-2/d.js new file mode 100644 index 0000000..b7d9f07 --- /dev/null +++ b/test/function/cycles-pathological-2/d.js @@ -0,0 +1,7 @@ +import { c, cv } from './c'; + +export function d() { + c(cv); +}; + +export const dv = cv; diff --git a/test/function/cycles-pathological-2/main.js b/test/function/cycles-pathological-2/main.js new file mode 100644 index 0000000..06bcc6e --- /dev/null +++ b/test/function/cycles-pathological-2/main.js @@ -0,0 +1,11 @@ +import { b, bv } from './b'; +import { d, dv } from './d'; +import { c, cv } from './c'; + +export function a() { + b(bv); + d(dv); + c(cv); +}; + +export const av = bv + dv + cv; From d248004a6a351f182aa495e914d5ab8f716a11f4 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Mon, 1 Aug 2016 21:49:01 +0300 Subject: [PATCH 149/331] Upgrade dependencies --- package.json | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index d9dfd35..c693e88 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.34.2", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", + "module": "dist/rollup.es.js", "jsnext:main": "dist/rollup.es.js", "bin": { "rollup": "./bin/rollup" @@ -34,7 +35,8 @@ ], "author": "Rich Harris", "contributors": [ - "Oskar Segersvärd " + "Oskar Segersvärd ", + "Bogdan Chadkin " ], "license": "MIT", "bugs": { @@ -43,7 +45,7 @@ "homepage": "https://github.com/rollup/rollup", "devDependencies": { "acorn": "^3.2.0", - "buble": "^0.11.5", + "buble": "^0.12.5", "chalk": "^1.1.3", "codecov.io": "^0.1.6", "console-group": "^0.2.1", @@ -52,14 +54,14 @@ "istanbul": "^0.4.3", "magic-string": "^0.15.2", "minimist": "^1.2.0", - "mocha": "^2.5.3", + "mocha": "^3.0.0", "remap-istanbul": "^0.6.4", "require-relative": "^0.8.7", - "rollup": "^0.32.0", - "rollup-plugin-buble": "^0.11.0", + "rollup": "^0.34.2", + "rollup-plugin-buble": "^0.12.1", "rollup-plugin-commonjs": "^3.0.0", "rollup-plugin-json": "^2.0.0", - "rollup-plugin-node-resolve": "^1.7.0", + "rollup-plugin-node-resolve": "^2.0.0", "rollup-plugin-replace": "^1.1.0", "rollup-plugin-string": "^2.0.0", "sander": "^0.5.1", From 6ee27c6a7dcf5619074bc9c686386d0e948aa0d1 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Mon, 1 Aug 2016 21:54:32 +0300 Subject: [PATCH 150/331] -> 0.34.3 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index baca6a6..3797789 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.34.3 + +* Avoid infinite recursion in `Bundle.sort()` ([#800](https://github.com/rollup/rollup/pull/800)) + ## 0.34.2 * resolveId calls are cached now to improve incremental build diff --git a/package.json b/package.json index c693e88..0b7f782 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.2", + "version": "0.34.3", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From b86be27b08646c345c2ed189f42aa8a9ff366987 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Mon, 1 Aug 2016 22:08:09 +0300 Subject: [PATCH 151/331] failing test for #813 --- test/function/cycles-pathological-3/_config.js | 12 ++++++++++++ test/function/cycles-pathological-3/a.js | 3 +++ test/function/cycles-pathological-3/b.js | 3 +++ test/function/cycles-pathological-3/c.js | 3 +++ test/function/cycles-pathological-3/main.js | 1 + test/function/cycles-pathological-3/x.a.js | 2 ++ test/function/cycles-pathological-3/x.b.js | 2 ++ test/function/cycles-pathological-3/x.c.js | 2 ++ 8 files changed, 28 insertions(+) create mode 100644 test/function/cycles-pathological-3/_config.js create mode 100644 test/function/cycles-pathological-3/a.js create mode 100644 test/function/cycles-pathological-3/b.js create mode 100644 test/function/cycles-pathological-3/c.js create mode 100644 test/function/cycles-pathological-3/main.js create mode 100644 test/function/cycles-pathological-3/x.a.js create mode 100644 test/function/cycles-pathological-3/x.b.js create mode 100644 test/function/cycles-pathological-3/x.c.js diff --git a/test/function/cycles-pathological-3/_config.js b/test/function/cycles-pathological-3/_config.js new file mode 100644 index 0000000..6956788 --- /dev/null +++ b/test/function/cycles-pathological-3/_config.js @@ -0,0 +1,12 @@ +var assert = require( 'assert' ); + +module.exports = { + solo: true, + description: 'resolves more pathological cyclical dependencies gracefully', + options: { + onwarn: function ( message ) { + console.log(message); + // assert.ok( /unable to evaluate without/.test( message ) ); + } + } +}; diff --git a/test/function/cycles-pathological-3/a.js b/test/function/cycles-pathological-3/a.js new file mode 100644 index 0000000..c77b86b --- /dev/null +++ b/test/function/cycles-pathological-3/a.js @@ -0,0 +1,3 @@ +import * as x from "./x.a.js"; +x.b(); +x.c(); \ No newline at end of file diff --git a/test/function/cycles-pathological-3/b.js b/test/function/cycles-pathological-3/b.js new file mode 100644 index 0000000..b93201c --- /dev/null +++ b/test/function/cycles-pathological-3/b.js @@ -0,0 +1,3 @@ +import * as x from "./x.b.js"; + +export function b() {} \ No newline at end of file diff --git a/test/function/cycles-pathological-3/c.js b/test/function/cycles-pathological-3/c.js new file mode 100644 index 0000000..60a9826 --- /dev/null +++ b/test/function/cycles-pathological-3/c.js @@ -0,0 +1,3 @@ +import * as x from "./x.c.js"; + +export function c() {} \ No newline at end of file diff --git a/test/function/cycles-pathological-3/main.js b/test/function/cycles-pathological-3/main.js new file mode 100644 index 0000000..1580611 --- /dev/null +++ b/test/function/cycles-pathological-3/main.js @@ -0,0 +1 @@ +import './a.js'; \ No newline at end of file diff --git a/test/function/cycles-pathological-3/x.a.js b/test/function/cycles-pathological-3/x.a.js new file mode 100644 index 0000000..e73df11 --- /dev/null +++ b/test/function/cycles-pathological-3/x.a.js @@ -0,0 +1,2 @@ +export * from "./b.js"; +export * from "./c.js"; \ No newline at end of file diff --git a/test/function/cycles-pathological-3/x.b.js b/test/function/cycles-pathological-3/x.b.js new file mode 100644 index 0000000..c3e2ed3 --- /dev/null +++ b/test/function/cycles-pathological-3/x.b.js @@ -0,0 +1,2 @@ +export * from "./a.js"; +export * from "./c.js"; \ No newline at end of file diff --git a/test/function/cycles-pathological-3/x.c.js b/test/function/cycles-pathological-3/x.c.js new file mode 100644 index 0000000..2f49591 --- /dev/null +++ b/test/function/cycles-pathological-3/x.c.js @@ -0,0 +1,2 @@ +export * from "./a.js"; +export * from "./b.js"; \ No newline at end of file From ebd5ead5e6f9b40960f73d03027c9ef2ad1e4c4d Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Tue, 2 Aug 2016 13:20:28 +0300 Subject: [PATCH 152/331] Module render performance tweak Ref https://github.com/rollup/rollup/issues/723 --- src/Module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Module.js b/src/Module.js index 1cac43a..9232571 100644 --- a/src/Module.js +++ b/src/Module.js @@ -447,7 +447,7 @@ export default class Module { } render ( es ) { - let magicString = this.magicString.clone(); + let magicString = this.magicString; this.statements.forEach( statement => { if ( !statement.isIncluded ) { From c64da6ebcfd244402310d6a464d395b912609357 Mon Sep 17 00:00:00 2001 From: Philipp Weinfurter Date: Fri, 5 Aug 2016 23:51:07 +0200 Subject: [PATCH 153/331] Initialize member in constructor, fixes #813 --- src/Bundle.js | 1 - src/Module.js | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle.js b/src/Bundle.js index 7b937d4..430983b 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -218,7 +218,6 @@ export default class Bundle { this.moduleById.set( id, module ); return this.fetchAllDependencies( module ).then( () => { - module.exportsAll = blank(); keys( module.exports ).forEach( name => { module.exportsAll[name] = module.id; }); diff --git a/src/Module.js b/src/Module.js index 1cac43a..5942901 100644 --- a/src/Module.js +++ b/src/Module.js @@ -35,6 +35,7 @@ export default class Module { // imports and exports, indexed by local name this.imports = blank(); this.exports = blank(); + this.exportsAll = blank(); this.reexports = blank(); this.exportAllSources = []; From d39105d6884ffcd868fd0c9c94afda896383f31c Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 6 Aug 2016 02:10:55 +0300 Subject: [PATCH 154/331] Improve linting --- .eslintrc | 8 ++++++-- src/Bundle.js | 14 +++++++------- src/Module.js | 10 +++++----- src/ast/flatten.js | 2 +- src/finalisers/amd.js | 4 ++-- src/finalisers/iife.js | 8 ++++---- src/finalisers/umd.js | 8 ++++---- src/rollup.js | 4 ++-- src/utils/collapseSourcemaps.js | 8 ++++---- src/utils/defaults.js | 2 +- src/utils/makeLegalIdentifier.js | 2 +- src/utils/object.js | 2 +- src/utils/promise.js | 2 +- src/utils/pureFunctions.js | 4 ++-- src/utils/transform.js | 4 ++-- test/test.js | 10 +++++----- 16 files changed, 48 insertions(+), 44 deletions(-) diff --git a/.eslintrc b/.eslintrc index 363a56d..cab1314 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,15 +7,19 @@ "space-before-blocks": [ 2, "always" ], "space-before-function-paren": [ 2, "always" ], "no-mixed-spaces-and-tabs": [ 2, "smart-tabs" ], - "no-cond-assign": [ 0 ], - "object-shorthand": [2, "always" ], + "no-cond-assign": 0, + "no-unused-vars": 2, + "object-shorthand": [ 2, "always" ], "no-const-assign": 2, "no-class-assign": 2, "no-this-before-super": 2, "no-var": 2, + "no-unreachable": 2, + "valid-typeof": 2, "quote-props": [ 2, "as-needed" ], "one-var": [ 2, "never" ], "prefer-arrow-callback": 2, + "prefer-const": [ 2, { "destructuring": "all" } ], "arrow-spacing": 2 }, "env": { diff --git a/src/Bundle.js b/src/Bundle.js index 7b937d4..509188b 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -130,7 +130,7 @@ export default class Bundle { } deconflict () { - let used = blank(); + const used = blank(); // ensure no conflicts with globals keys( this.assumedGlobals ).forEach( name => used[ name ] = 1 ); @@ -300,7 +300,7 @@ export default class Bundle { const exportMode = getExportMode( this, options.exports, options.moduleName ); let magicString = new MagicStringBundle({ separator: '\n\n' }); - let usedModules = []; + const usedModules = []; this.orderedModules.forEach( module => { const source = module.render( format === 'es' ); @@ -344,7 +344,7 @@ export default class Bundle { let code = magicString.toString(); let map = null; - let bundleSourcemapChain = []; + const bundleSourcemapChain = []; code = transformBundle( code, this.plugins, bundleSourcemapChain ) .replace( new RegExp( `\\/\\/#\\s+${SOURCEMAPPING_URL}=.+\\n?`, 'g' ), '' ); @@ -367,12 +367,12 @@ export default class Bundle { } sort () { - let seen = {}; let hasCycles; - let ordered = []; + const seen = {}; + const ordered = []; - let stronglyDependsOn = blank(); - let dependsOn = blank(); + const stronglyDependsOn = blank(); + const dependsOn = blank(); this.modules.forEach( module => { stronglyDependsOn[ module.id ] = blank(); diff --git a/src/Module.js b/src/Module.js index 9232571..ca4b32f 100644 --- a/src/Module.js +++ b/src/Module.js @@ -121,7 +121,7 @@ export default class Module { // export var a = 1, b = 2, c = 3; // export function foo () {} else if ( node.declaration ) { - let declaration = node.declaration; + const declaration = node.declaration; if ( declaration.type === 'VariableDeclaration' ) { declaration.declarations.forEach( decl => { @@ -274,7 +274,7 @@ export default class Module { } getExports () { - let exports = blank(); + const exports = blank(); keys( this.exports ).forEach( name => { exports[ name ] = true; @@ -353,7 +353,7 @@ export default class Module { } }); - let statements = []; + const statements = []; let lastChar = 0; let commentIndex = 0; @@ -447,7 +447,7 @@ export default class Module { } render ( es ) { - let magicString = this.magicString; + const magicString = this.magicString; this.statements.forEach( statement => { if ( !statement.isIncluded ) { @@ -503,7 +503,7 @@ export default class Module { } } - let toDeshadow = blank(); + const toDeshadow = blank(); statement.references.forEach( reference => { const { start, end } = reference; diff --git a/src/ast/flatten.js b/src/ast/flatten.js index 0cecbde..2000c89 100644 --- a/src/ast/flatten.js +++ b/src/ast/flatten.js @@ -1,5 +1,5 @@ export default function flatten ( node ) { - let parts = []; + const parts = []; while ( node.type === 'MemberExpression' ) { if ( node.computed ) return null; parts.unshift( node.property.name ); diff --git a/src/finalisers/amd.js b/src/finalisers/amd.js index 8567ad6..b2e4ec7 100644 --- a/src/finalisers/amd.js +++ b/src/finalisers/amd.js @@ -4,8 +4,8 @@ import getExportBlock from './shared/getExportBlock.js'; import esModuleExport from './shared/esModuleExport.js'; export default function amd ( bundle, magicString, { exportMode, indentString }, options ) { - let deps = bundle.externalModules.map( quotePath ); - let args = bundle.externalModules.map( getName ); + const deps = bundle.externalModules.map( quotePath ); + const args = bundle.externalModules.map( getName ); if ( exportMode === 'named' ) { args.unshift( `exports` ); diff --git a/src/finalisers/iife.js b/src/finalisers/iife.js index adb7019..5055a25 100644 --- a/src/finalisers/iife.js +++ b/src/finalisers/iife.js @@ -5,7 +5,7 @@ import getExportBlock from './shared/getExportBlock.js'; import getGlobalNameMaker from './shared/getGlobalNameMaker.js'; function setupNamespace ( keypath ) { - let parts = keypath.split( '.' ); // TODO support e.g. `foo['something-hyphenated']`? + const parts = keypath.split( '.' ); // TODO support e.g. `foo['something-hyphenated']`? parts.pop(); @@ -22,9 +22,9 @@ export default function iife ( bundle, magicString, { exportMode, indentString } const name = options.moduleName; const isNamespaced = name && ~name.indexOf( '.' ); - let dependencies = bundle.externalModules.map( globalNameMaker ); + const dependencies = bundle.externalModules.map( globalNameMaker ); - let args = bundle.externalModules.map( getName ); + const args = bundle.externalModules.map( getName ); if ( exportMode !== 'none' && !name ) { throw new Error( 'You must supply options.moduleName for IIFE bundles' ); @@ -38,7 +38,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString } const useStrict = options.useStrict !== false ? `'use strict';` : ``; let intro = `(function (${args}) {\n`; - let outro = `\n\n}(${dependencies}));`; + const outro = `\n\n}(${dependencies}));`; if ( exportMode === 'default' ) { intro = ( isNamespaced ? `this.` : `${bundle.varOrConst} ` ) + `${name} = ${intro}`; diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index 0039a7b..8d122b5 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -23,11 +23,11 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, const globalNameMaker = getGlobalNameMaker( options.globals || blank(), bundle.onwarn ); - let amdDeps = bundle.externalModules.map( quotePath ); - let cjsDeps = bundle.externalModules.map( req ); - let globalDeps = bundle.externalModules.map( module => `global.${globalNameMaker( module )}` ); + const amdDeps = bundle.externalModules.map( quotePath ); + const cjsDeps = bundle.externalModules.map( req ); + const globalDeps = bundle.externalModules.map( module => `global.${globalNameMaker( module )}` ); - let args = bundle.externalModules.map( getName ); + const args = bundle.externalModules.map( getName ); if ( exportMode === 'named' ) { amdDeps.unshift( `'exports'` ); diff --git a/src/rollup.js b/src/rollup.js index 7358c0e..7c1ce32 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -80,10 +80,10 @@ export function rollup ( options ) { } const dest = options.dest; - let output = generate( options ); + const output = generate( options ); let { code, map } = output; - let promises = []; + const promises = []; if ( options.sourceMap ) { let url; diff --git a/src/utils/collapseSourcemaps.js b/src/utils/collapseSourcemaps.js index cd06d8c..173f714 100644 --- a/src/utils/collapseSourcemaps.js +++ b/src/utils/collapseSourcemaps.js @@ -21,12 +21,12 @@ class Link { } traceMappings () { - let sources = []; - let sourcesContent = []; - let names = []; + const sources = []; + const sourcesContent = []; + const names = []; const mappings = this.mappings.map( line => { - let tracedLine = []; + const tracedLine = []; line.forEach( segment => { const source = this.sources[ segment[1] ]; diff --git a/src/utils/defaults.js b/src/utils/defaults.js index e275f69..3073e81 100644 --- a/src/utils/defaults.js +++ b/src/utils/defaults.js @@ -32,7 +32,7 @@ export function resolveId ( importee, importer ) { export function makeOnwarn () { - let warned = blank(); + const warned = blank(); return msg => { if ( msg in warned ) return; diff --git a/src/utils/makeLegalIdentifier.js b/src/utils/makeLegalIdentifier.js index fd75ee8..c9733e5 100644 --- a/src/utils/makeLegalIdentifier.js +++ b/src/utils/makeLegalIdentifier.js @@ -3,7 +3,7 @@ import { blank } from './object.js'; const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public'.split( ' ' ); const builtins = 'Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl'.split( ' ' ); -let blacklisted = blank(); +const blacklisted = blank(); reservedWords.concat( builtins ).forEach( word => blacklisted[ word ] = true ); diff --git a/src/utils/object.js b/src/utils/object.js index 688b1ca..4234de3 100644 --- a/src/utils/object.js +++ b/src/utils/object.js @@ -10,7 +10,7 @@ export function forOwn ( object, func ) { export function assign ( target, ...sources ) { sources.forEach( source => { - for ( let key in source ) { + for ( const key in source ) { if ( source.hasOwnProperty( key ) ) target[ key ] = source[ key ]; } }); diff --git a/src/utils/promise.js b/src/utils/promise.js index d18a22d..096343c 100644 --- a/src/utils/promise.js +++ b/src/utils/promise.js @@ -1,5 +1,5 @@ export function mapSequence ( array, fn ) { - let results = []; + const results = []; let promise = Promise.resolve(); function next ( member, i ) { diff --git a/src/utils/pureFunctions.js b/src/utils/pureFunctions.js index 3642a05..3301085 100644 --- a/src/utils/pureFunctions.js +++ b/src/utils/pureFunctions.js @@ -1,9 +1,9 @@ -let pureFunctions = {}; +const pureFunctions = {}; const arrayTypes = 'Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split( ' ' ); const simdTypes = 'Int8x16 Int16x8 Int32x4 Float32x4 Float64x2'.split( ' ' ); const simdMethods = 'abs add and bool check div equal extractLane fromFloat32x4 fromFloat32x4Bits fromFloat64x2 fromFloat64x2Bits fromInt16x8Bits fromInt32x4 fromInt32x4Bits fromInt8x16Bits greaterThan greaterThanOrEqual lessThan lessThanOrEqual load max maxNum min minNum mul neg not notEqual or reciprocalApproximation reciprocalSqrtApproximation replaceLane select selectBits shiftLeftByScalar shiftRightArithmeticByScalar shiftRightLogicalByScalar shuffle splat sqrt store sub swizzle xor'.split( ' ' ); -let allSimdMethods = []; +const allSimdMethods = []; simdTypes.forEach( t => { simdMethods.forEach( m => { allSimdMethods.push( `SIMD.${t}.${m}` ); diff --git a/src/utils/transform.js b/src/utils/transform.js index a5c4ccb..b8ba263 100644 --- a/src/utils/transform.js +++ b/src/utils/transform.js @@ -1,9 +1,9 @@ export default function transform ( source, id, plugins ) { - let sourceMapChain = []; + const sourceMapChain = []; const originalSourceMap = typeof source.map === 'string' ? JSON.parse( source.map ) : source.map; - let originalCode = source.code; + const originalCode = source.code; let ast = source.ast; return plugins.reduce( ( promise, plugin ) => { diff --git a/test/test.js b/test/test.js index ae8d2d1..184ceff 100644 --- a/test/test.js +++ b/test/test.js @@ -166,7 +166,7 @@ describe( 'rollup', function () { const config = loadConfig( FUNCTION + '/' + dir + '/_config.js' ); ( config.skip ? it.skip : config.solo ? it.only : it )( dir, () => { - let warnings = []; + const warnings = []; const captureWarning = msg => warnings.push( msg ); const options = extend( { @@ -216,7 +216,7 @@ describe( 'rollup', function () { if ( config.code ) config.code( code ); - let module = { + const module = { exports: {} }; @@ -475,7 +475,7 @@ describe( 'rollup', function () { const cjs = bundle.generate({ format: 'cjs' }); const m = new Function( 'module', 'exports', cjs.code ); - let module = { exports: {} }; + const module = { exports: {} }; m( module, module.exports ); return module.exports; @@ -608,7 +608,7 @@ describe( 'rollup', function () { }); it( 'calls ongenerate hooks in sequence', () => { - let result = []; + const result = []; return rollup.rollup({ entry: 'entry', @@ -636,7 +636,7 @@ describe( 'rollup', function () { }); it( 'calls onwrite hooks in sequence', () => { - let result = []; + const result = []; const dest = path.join( __dirname, 'tmp/bundle.js' ); return rollup.rollup({ From 0ddc0a06738359470fbd631ea67728c2653118e7 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 6 Aug 2016 11:37:53 +0300 Subject: [PATCH 155/331] -> v0.34.4 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3797789..1fe559e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.34.4 + +* Module render performance tweak ([#823](https://github.com/rollup/rollup/pull/823)) + ## 0.34.3 * Avoid infinite recursion in `Bundle.sort()` ([#800](https://github.com/rollup/rollup/pull/800)) diff --git a/package.json b/package.json index 0b7f782..ffbeb4f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.3", + "version": "0.34.4", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From a945b77eb31c9fc8dcbeb004a1e69bb5093cfeb5 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 6 Aug 2016 14:38:49 +0300 Subject: [PATCH 156/331] Clean up test --- test/function/cycles-pathological-3/_config.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/test/function/cycles-pathological-3/_config.js b/test/function/cycles-pathological-3/_config.js index 6956788..155e2f6 100644 --- a/test/function/cycles-pathological-3/_config.js +++ b/test/function/cycles-pathological-3/_config.js @@ -1,12 +1,3 @@ -var assert = require( 'assert' ); - module.exports = { - solo: true, - description: 'resolves more pathological cyclical dependencies gracefully', - options: { - onwarn: function ( message ) { - console.log(message); - // assert.ok( /unable to evaluate without/.test( message ) ); - } - } + description: 'resolves more pathological cyclical dependencies gracefully' }; From d478aaf51a5b5f33174ddd3c659c9cf0c180e8d6 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 6 Aug 2016 14:58:40 +0300 Subject: [PATCH 157/331] -> v0.34.5 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fe559e..00281df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.34.5 + +* Fix circular export ([#813](https://github.com/rollup/rollup/issues/813)) + ## 0.34.4 * Module render performance tweak ([#823](https://github.com/rollup/rollup/pull/823)) diff --git a/package.json b/package.json index ffbeb4f..8bfe1de 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.4", + "version": "0.34.5", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From d8addbb82e9eaa07077ddf3dc7321258d1285784 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 7 Aug 2016 01:46:04 +0300 Subject: [PATCH 158/331] Cache decoded mappings --- src/Bundle.js | 4 ++++ src/utils/collapseSourcemaps.js | 4 ++-- src/utils/transform.js | 10 ++++++++++ src/utils/transformBundle.js | 6 ++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index cf4085a..b79057f 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -1,3 +1,4 @@ +import { decode } from 'sourcemap-codec'; import { Bundle as MagicStringBundle } from 'magic-string'; import first from './utils/first.js'; import { find } from './utils/array.js'; @@ -354,6 +355,9 @@ export default class Bundle { if ( this.hasLoaders || find( this.plugins, plugin => plugin.transform || plugin.transformBundle ) ) { map = magicString.generateMap( {} ); + if ( typeof map.mappings === 'string' ) { + map.mappings = decode( map.mappings ); + } map = collapseSourcemaps( file, map, usedModules, bundleSourcemapChain, this.onwarn ); } else { map = magicString.generateMap({ file, includeContent: true }); diff --git a/src/utils/collapseSourcemaps.js b/src/utils/collapseSourcemaps.js index 173f714..7a504ba 100644 --- a/src/utils/collapseSourcemaps.js +++ b/src/utils/collapseSourcemaps.js @@ -1,4 +1,4 @@ -import { encode, decode } from 'sourcemap-codec'; +import { encode } from 'sourcemap-codec'; import { dirname, relative, resolve } from './path.js'; class Source { @@ -17,7 +17,7 @@ class Link { constructor ( map, sources ) { this.sources = sources; this.names = map.names; - this.mappings = decode( map.mappings ); + this.mappings = map.mappings; } traceMappings () { diff --git a/src/utils/transform.js b/src/utils/transform.js index b8ba263..2f0c167 100644 --- a/src/utils/transform.js +++ b/src/utils/transform.js @@ -1,8 +1,14 @@ +import { decode } from 'sourcemap-codec'; + export default function transform ( source, id, plugins ) { const sourceMapChain = []; const originalSourceMap = typeof source.map === 'string' ? JSON.parse( source.map ) : source.map; + if ( originalSourceMap && typeof originalSourceMap.mappings === 'string' ) { + originalSourceMap.mappings = decode( originalSourceMap.mappings ); + } + const originalCode = source.code; let ast = source.ast; @@ -25,6 +31,10 @@ export default function transform ( source, id, plugins ) { result.map = JSON.parse( result.map ); } + if ( result.map && typeof result.map.mappings === 'string' ) { + result.map.mappings = decode( result.map.mappings ); + } + sourceMapChain.push( result.map || { missing: true, plugin: plugin.name }); // lil' bit hacky but it works ast = result.ast; diff --git a/src/utils/transformBundle.js b/src/utils/transformBundle.js index 400e994..027c7f0 100644 --- a/src/utils/transformBundle.js +++ b/src/utils/transformBundle.js @@ -1,3 +1,5 @@ +import { decode } from 'sourcemap-codec'; + export default function transformBundle ( code, plugins, sourceMapChain ) { return plugins.reduce( ( code, plugin ) => { if ( !plugin.transformBundle ) return code; @@ -22,6 +24,10 @@ export default function transformBundle ( code, plugins, sourceMapChain ) { } const map = typeof result.map === 'string' ? JSON.parse( result.map ) : result.map; + if ( map && typeof map.mappings === 'string' ) { + map.mappings = decode( map.mappings ); + } + sourceMapChain.push( map ); return result.code; From b7f73d6d700ad5af5b78760d988b0699afc880b1 Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 6 Aug 2016 18:44:31 -0700 Subject: [PATCH 159/331] Leave it up to resolveId to normalize the entry path --- src/Bundle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle.js b/src/Bundle.js index cf4085a..c254af5 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -34,7 +34,7 @@ export default class Bundle { } }); - this.entry = normalize( options.entry ); + this.entry = options.entry; this.entryId = null; this.entryModule = null; From 94d58778229a64d979216aa05c9a397269a0da84 Mon Sep 17 00:00:00 2001 From: Permutator Date: Sun, 7 Aug 2016 02:15:44 -0700 Subject: [PATCH 160/331] Added a test for not mangling the entry point --- .../does-not-mangle-entry-point/_config.js | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 test/function/does-not-mangle-entry-point/_config.js diff --git a/test/function/does-not-mangle-entry-point/_config.js b/test/function/does-not-mangle-entry-point/_config.js new file mode 100644 index 0000000..e93b7ff --- /dev/null +++ b/test/function/does-not-mangle-entry-point/_config.js @@ -0,0 +1,26 @@ +var path = require( 'path' ); +var fs = require( 'fs' ); +var assert = require( 'assert' ); + +var modules = { + 'x\\y': 'export default 42;', + 'x/y': 'export default 24;' +}; + +module.exports = { + description: 'does not mangle entry point', + options: { + entry: 'x\\y', + plugins: [{ + resolveId: function ( importee ) { + return importee; + }, + load: function ( moduleId ) { + return modules[ moduleId ]; + } + }] + }, + exports: function ( exports ) { + assert.equal( exports, 42 ); + } +}; From 709a4f783d5b6e67b2692891929cdc8d61d56806 Mon Sep 17 00:00:00 2001 From: Permutator Date: Sun, 7 Aug 2016 02:23:01 -0700 Subject: [PATCH 161/331] Removed unnecessary imports in does-not-mangle-entry-point test --- test/function/does-not-mangle-entry-point/_config.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/function/does-not-mangle-entry-point/_config.js b/test/function/does-not-mangle-entry-point/_config.js index e93b7ff..ef24d01 100644 --- a/test/function/does-not-mangle-entry-point/_config.js +++ b/test/function/does-not-mangle-entry-point/_config.js @@ -1,5 +1,3 @@ -var path = require( 'path' ); -var fs = require( 'fs' ); var assert = require( 'assert' ); var modules = { From 6ceb0cd9af780ac7b5c3a48ea72167672ce46794 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 7 Aug 2016 12:42:02 +0300 Subject: [PATCH 162/331] -> v0.34.7 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00281df..bb81754 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.34.7 + +* Leave it up to resolveId to normalize the entry path ([#835](https://github.com/rollup/rollup/pull/835)) +* Cache decoded mappings ([#834](https://github.com/rollup/rollup/pull/834)) + ## 0.34.5 * Fix circular export ([#813](https://github.com/rollup/rollup/issues/813)) diff --git a/package.json b/package.json index 8bfe1de..da42204 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.5", + "version": "0.34.7", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 8c737c315215307e31d852db5c2bb70ce60e3738 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 14 Aug 2016 10:28:55 -0400 Subject: [PATCH 163/331] update test results --- test/cli/indent-none/_expected.js | 4 ++-- test/cli/module-name/_expected.js | 4 ++-- test/form/absolute-path-resolver/_expected/umd.js | 4 ++-- .../assignment-to-exports-class-declaration/_expected/umd.js | 4 ++-- test/form/assignment-to-exports/_expected/umd.js | 4 ++-- test/form/banner-and-footer-plugin/_expected/umd.js | 4 ++-- test/form/banner-and-footer/_expected/umd.js | 4 ++-- test/form/block-comments/_expected/umd.js | 4 ++-- test/form/computed-properties/_expected/umd.js | 4 ++-- test/form/conflicting-imports/_expected/umd.js | 4 ++-- test/form/dedupes-external-imports/_expected/umd.js | 4 ++-- test/form/erroneous-nested-member-expression/_expected/umd.js | 4 ++-- test/form/exclude-unnecessary-modifications/_expected/umd.js | 4 ++-- test/form/export-all-from-internal/_expected/umd.js | 4 ++-- test/form/export-default-2/_expected/umd.js | 4 ++-- test/form/export-default-3/_expected/umd.js | 4 ++-- test/form/export-default-import/_expected/umd.js | 4 ++-- test/form/export-default/_expected/umd.js | 4 ++-- test/form/export-multiple-vars/_expected/umd.js | 4 ++-- test/form/exports-at-end-if-possible/_expected/umd.js | 4 ++-- test/form/external-import-alias-shadow/_expected/umd.js | 4 ++-- .../external-imports-custom-names-function/_expected/umd.js | 4 ++-- test/form/external-imports-custom-names/_expected/umd.js | 4 ++-- test/form/external-imports/_expected/umd.js | 4 ++-- .../import-external-namespace-and-default/_expected/umd.js | 4 ++-- .../import-named-exported-global-with-alias/_expected/umd.js | 4 ++-- test/form/indent-false/_expected/umd.js | 4 ++-- test/form/indent-true-spaces/_expected/umd.js | 4 ++-- test/form/indent-true/_expected/umd.js | 4 ++-- test/form/internal-conflict-resolution/_expected/umd.js | 4 ++-- test/form/intro-and-outro/_expected/umd.js | 4 ++-- test/form/multiple-exports/_expected/umd.js | 4 ++-- test/form/namespace-optimization-b/_expected/umd.js | 4 ++-- test/form/namespace-optimization/_expected/umd.js | 4 ++-- test/form/namespaced-default-exports/_expected/umd.js | 4 ++-- test/form/namespaced-named-exports/_expected/umd.js | 4 ++-- test/form/no-imports-or-exports/_expected/umd.js | 4 ++-- test/form/no-treeshake/_expected/umd.js | 4 ++-- .../form/object-destructuring-default-values/_expected/umd.js | 4 ++-- test/form/paths-function/_expected/umd.js | 4 ++-- test/form/paths-relative/_expected/umd.js | 4 ++-- test/form/paths/_expected/umd.js | 4 ++-- test/form/prefer-const/_expected/umd.js | 4 ++-- test/form/preserve-debugger/_expected/umd.js | 4 ++-- test/form/preserves-comments-after-imports/_expected/umd.js | 4 ++-- test/form/relative-external-with-global/_expected/umd.js | 4 ++-- .../form/removes-existing-sourcemap-comments/_expected/umd.js | 4 ++-- test/form/self-contained-bundle/_expected/umd.js | 4 ++-- test/form/shorthand-properties/_expected/umd.js | 4 ++-- test/form/side-effect-b/_expected/umd.js | 4 ++-- test/form/side-effect-c/_expected/umd.js | 4 ++-- test/form/side-effect-d/_expected/umd.js | 4 ++-- test/form/side-effect-e/_expected/umd.js | 4 ++-- test/form/side-effect-f/_expected/umd.js | 4 ++-- test/form/side-effect-g/_expected/umd.js | 4 ++-- test/form/side-effect-h/_expected/umd.js | 4 ++-- test/form/side-effect-i/_expected/umd.js | 4 ++-- test/form/side-effect-j/_expected/umd.js | 4 ++-- test/form/side-effect-k/_expected/umd.js | 4 ++-- test/form/side-effect-l/_expected/umd.js | 4 ++-- test/form/side-effect-m/_expected/umd.js | 4 ++-- test/form/side-effect-n/_expected/umd.js | 4 ++-- test/form/side-effect-o/_expected/umd.js | 4 ++-- test/form/side-effect/_expected/umd.js | 4 ++-- test/form/sourcemaps-external/_expected/umd.js | 4 ++-- test/form/sourcemaps-inline/_expected/umd.js | 4 ++-- .../spacing-after-function-with-semicolon/_expected/umd.js | 4 ++-- test/form/string-indentation-b/_expected/umd.js | 4 ++-- test/form/string-indentation/_expected/umd.js | 4 ++-- test/form/this-is-undefined/_expected/umd.js | 4 ++-- test/form/umd-noconflict/_expected/umd.js | 4 ++-- .../_expected/umd.js | 4 ++-- test/form/unmodified-default-exports/_expected/umd.js | 4 ++-- test/form/unused-default-exports/_expected/umd.js | 4 ++-- .../_expected/umd.js | 4 ++-- 75 files changed, 150 insertions(+), 150 deletions(-) diff --git a/test/cli/indent-none/_expected.js b/test/cli/indent-none/_expected.js index 414587c..343dda2 100644 --- a/test/cli/indent-none/_expected.js +++ b/test/cli/indent-none/_expected.js @@ -2,8 +2,8 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; assert.equal( 1 + 1, 2 ); -})); +}))); diff --git a/test/cli/module-name/_expected.js b/test/cli/module-name/_expected.js index 4a351ac..2f71587 100644 --- a/test/cli/module-name/_expected.js +++ b/test/cli/module-name/_expected.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var main = 42; return main; -})); +}))); diff --git a/test/form/absolute-path-resolver/_expected/umd.js b/test/form/absolute-path-resolver/_expected/umd.js index 02345b3..611df0c 100644 --- a/test/form/absolute-path-resolver/_expected/umd.js +++ b/test/form/absolute-path-resolver/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var a = () => { console.log('props'); @@ -11,4 +11,4 @@ a(); a(); -})); \ No newline at end of file +}))); diff --git a/test/form/assignment-to-exports-class-declaration/_expected/umd.js b/test/form/assignment-to-exports-class-declaration/_expected/umd.js index 503039e..6de079e 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/umd.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/umd.js @@ -2,11 +2,11 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.myModule = global.myModule || {}))); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; exports.Foo = class Foo {} exports.Foo = lol( exports.Foo ); Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/assignment-to-exports/_expected/umd.js b/test/form/assignment-to-exports/_expected/umd.js index cc3fb1f..80039f9 100644 --- a/test/form/assignment-to-exports/_expected/umd.js +++ b/test/form/assignment-to-exports/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.bundle = global.bundle || {}))); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; exports.foo = 1; Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/banner-and-footer-plugin/_expected/umd.js b/test/form/banner-and-footer-plugin/_expected/umd.js index 3e3bef0..29d8c60 100644 --- a/test/form/banner-and-footer-plugin/_expected/umd.js +++ b/test/form/banner-and-footer-plugin/_expected/umd.js @@ -4,10 +4,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; console.log( 1 + 1 ); -})); +}))); /* first footer */ /* second footer */ \ No newline at end of file diff --git a/test/form/banner-and-footer/_expected/umd.js b/test/form/banner-and-footer/_expected/umd.js index 356ff47..9fa72aa 100644 --- a/test/form/banner-and-footer/_expected/umd.js +++ b/test/form/banner-and-footer/_expected/umd.js @@ -3,9 +3,9 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; console.log( 'hello world' ); -})); +}))); /* this is a footer */ \ No newline at end of file diff --git a/test/form/block-comments/_expected/umd.js b/test/form/block-comments/_expected/umd.js index c00edfa..6afff4a 100644 --- a/test/form/block-comments/_expected/umd.js +++ b/test/form/block-comments/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function foo () { return embiggen( 6, 7 ); @@ -20,4 +20,4 @@ alert( foo() ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/computed-properties/_expected/umd.js b/test/form/computed-properties/_expected/umd.js index 8f247e8..2939979 100644 --- a/test/form/computed-properties/_expected/umd.js +++ b/test/form/computed-properties/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.computedProperties = global.computedProperties || {}))); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; var foo = 'foo'; var bar = 'bar'; @@ -22,4 +22,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/conflicting-imports/_expected/umd.js b/test/form/conflicting-imports/_expected/umd.js index 8254c77..8d6ea73 100644 --- a/test/form/conflicting-imports/_expected/umd.js +++ b/test/form/conflicting-imports/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('foo'), require('bar')) : typeof define === 'function' && define.amd ? define(['foo', 'bar'], factory) : (factory(global.foo,global.bar)); -}(this, function (foo,bar) { 'use strict'; +}(this, (function (foo,bar) { 'use strict'; console.log( bar.a ); console.log( foo.a ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/dedupes-external-imports/_expected/umd.js b/test/form/dedupes-external-imports/_expected/umd.js index af73333..f6ef0fe 100644 --- a/test/form/dedupes-external-imports/_expected/umd.js +++ b/test/form/dedupes-external-imports/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('external')) : typeof define === 'function' && define.amd ? define(['exports', 'external'], factory) : (factory((global.myBundle = global.myBundle || {}),global.external)); -}(this, function (exports,external) { 'use strict'; +}(this, (function (exports,external) { 'use strict'; class Foo extends external.Component { constructor () { @@ -35,4 +35,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/erroneous-nested-member-expression/_expected/umd.js b/test/form/erroneous-nested-member-expression/_expected/umd.js index d11bd9f..2a8dba1 100644 --- a/test/form/erroneous-nested-member-expression/_expected/umd.js +++ b/test/form/erroneous-nested-member-expression/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function yar() { return { @@ -14,4 +14,4 @@ yar.har(); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/exclude-unnecessary-modifications/_expected/umd.js b/test/form/exclude-unnecessary-modifications/_expected/umd.js index d5cd1bd..457d3c2 100644 --- a/test/form/exclude-unnecessary-modifications/_expected/umd.js +++ b/test/form/exclude-unnecessary-modifications/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var foo = {}; @@ -29,4 +29,4 @@ console.log( foo ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/export-all-from-internal/_expected/umd.js b/test/form/export-all-from-internal/_expected/umd.js index 1d0f5ec..5b39537 100644 --- a/test/form/export-all-from-internal/_expected/umd.js +++ b/test/form/export-all-from-internal/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.exposedInternals = global.exposedInternals || {}))); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; const a = 1; const b = 2; @@ -12,4 +12,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/export-default-2/_expected/umd.js b/test/form/export-default-2/_expected/umd.js index 69c5a70..73b73a1 100644 --- a/test/form/export-default-2/_expected/umd.js +++ b/test/form/export-default-2/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var bar = 1; return bar; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/export-default-3/_expected/umd.js b/test/form/export-default-3/_expected/umd.js index 69c5a70..73b73a1 100644 --- a/test/form/export-default-3/_expected/umd.js +++ b/test/form/export-default-3/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var bar = 1; return bar; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/export-default-import/_expected/umd.js b/test/form/export-default-import/_expected/umd.js index 4428aa4..6e689d4 100644 --- a/test/form/export-default-import/_expected/umd.js +++ b/test/form/export-default-import/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('x')) : typeof define === 'function' && define.amd ? define(['exports', 'x'], factory) : (factory((global.myBundle = global.myBundle || {}),global.x)); -}(this, function (exports,x) { 'use strict'; +}(this, (function (exports,x) { 'use strict'; x = 'default' in x ? x['default'] : x; @@ -12,4 +12,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/export-default/_expected/umd.js b/test/form/export-default/_expected/umd.js index 16d2890..2194031 100644 --- a/test/form/export-default/_expected/umd.js +++ b/test/form/export-default/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var main = 42; return main; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/export-multiple-vars/_expected/umd.js b/test/form/export-multiple-vars/_expected/umd.js index 663cb1e..fe8a09d 100644 --- a/test/form/export-multiple-vars/_expected/umd.js +++ b/test/form/export-multiple-vars/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var a = 1; @@ -14,4 +14,4 @@ assert.equal( e, 5 ); assert.equal( i, 9 ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/exports-at-end-if-possible/_expected/umd.js b/test/form/exports-at-end-if-possible/_expected/umd.js index f5557e7..c6b382b 100644 --- a/test/form/exports-at-end-if-possible/_expected/umd.js +++ b/test/form/exports-at-end-if-possible/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.myBundle = global.myBundle || {}))); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; var FOO = 'foo'; @@ -14,4 +14,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/external-import-alias-shadow/_expected/umd.js b/test/form/external-import-alias-shadow/_expected/umd.js index 7be513d..29b64b4 100644 --- a/test/form/external-import-alias-shadow/_expected/umd.js +++ b/test/form/external-import-alias-shadow/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('acorn')) : typeof define === 'function' && define.amd ? define(['acorn'], factory) : (factory(global.acorn)); -}(this, function (acorn) { 'use strict'; +}(this, (function (acorn) { 'use strict'; function parse$1(source) { return acorn.parse(source, { ecmaVersion: 6 }); @@ -10,4 +10,4 @@ console.log(parse$1('foo')); -})); +}))); diff --git a/test/form/external-imports-custom-names-function/_expected/umd.js b/test/form/external-imports-custom-names-function/_expected/umd.js index 1018b8a..c9464dd 100644 --- a/test/form/external-imports-custom-names-function/_expected/umd.js +++ b/test/form/external-imports-custom-names-function/_expected/umd.js @@ -2,8 +2,8 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('a-b-c')) : typeof define === 'function' && define.amd ? define(['a-b-c'], factory) : (factory(global.a_b_c)); -}(this, function (aBC) { 'use strict'; +}(this, (function (aBC) { 'use strict'; aBC.foo(); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/external-imports-custom-names/_expected/umd.js b/test/form/external-imports-custom-names/_expected/umd.js index 07642a1..d57479b 100644 --- a/test/form/external-imports-custom-names/_expected/umd.js +++ b/test/form/external-imports-custom-names/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : (factory(global.jQuery)); -}(this, function ($) { 'use strict'; +}(this, (function ($) { 'use strict'; $ = 'default' in $ ? $['default'] : $; @@ -10,4 +10,4 @@ $( 'body' ).html( '

hello world!

' ); }); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/external-imports/_expected/umd.js b/test/form/external-imports/_expected/umd.js index 3feb767..4b3fbbf 100644 --- a/test/form/external-imports/_expected/umd.js +++ b/test/form/external-imports/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('factory'), require('baz'), require('shipping-port'), require('alphabet')) : typeof define === 'function' && define.amd ? define(['factory', 'baz', 'shipping-port', 'alphabet'], factory) : (factory(global.factory,global.baz,global.containers,global.alphabet)); -}(this, function (factory,baz,containers,alphabet) { 'use strict'; +}(this, (function (factory,baz,containers,alphabet) { 'use strict'; factory = 'default' in factory ? factory['default'] : factory; var alphabet__default = 'default' in alphabet ? alphabet['default'] : alphabet; @@ -13,4 +13,4 @@ console.log( alphabet.a ); console.log( alphabet__default.length ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/import-external-namespace-and-default/_expected/umd.js b/test/form/import-external-namespace-and-default/_expected/umd.js index ddcdcbd..bd10a35 100644 --- a/test/form/import-external-namespace-and-default/_expected/umd.js +++ b/test/form/import-external-namespace-and-default/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('foo')) : typeof define === 'function' && define.amd ? define(['foo'], factory) : (factory(global.foo)); -}(this, function (foo) { 'use strict'; +}(this, (function (foo) { 'use strict'; var foo__default = foo['default']; @@ -10,4 +10,4 @@ console.log( foo__default ); -})); +}))); diff --git a/test/form/import-named-exported-global-with-alias/_expected/umd.js b/test/form/import-named-exported-global-with-alias/_expected/umd.js index f3395b7..d561e69 100644 --- a/test/form/import-named-exported-global-with-alias/_expected/umd.js +++ b/test/form/import-named-exported-global-with-alias/_expected/umd.js @@ -2,8 +2,8 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/indent-false/_expected/umd.js b/test/form/indent-false/_expected/umd.js index d09a506..c0289b0 100644 --- a/test/form/indent-false/_expected/umd.js +++ b/test/form/indent-false/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.foo = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function foo () { console.log( 'indented with tabs' ); @@ -10,4 +10,4 @@ function foo () { return foo; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/indent-true-spaces/_expected/umd.js b/test/form/indent-true-spaces/_expected/umd.js index fbc898e..51032c8 100644 --- a/test/form/indent-true-spaces/_expected/umd.js +++ b/test/form/indent-true-spaces/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.foo = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function foo () { console.log( 'indented with spaces' ); @@ -10,4 +10,4 @@ return foo; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/indent-true/_expected/umd.js b/test/form/indent-true/_expected/umd.js index a2b634e..786d82b 100644 --- a/test/form/indent-true/_expected/umd.js +++ b/test/form/indent-true/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.foo = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function foo () { console.log( 'indented with tabs' ); @@ -10,4 +10,4 @@ return foo; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/internal-conflict-resolution/_expected/umd.js b/test/form/internal-conflict-resolution/_expected/umd.js index a07cece..b6d7f90 100644 --- a/test/form/internal-conflict-resolution/_expected/umd.js +++ b/test/form/internal-conflict-resolution/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var bar$1 = 42; @@ -16,4 +16,4 @@ bar(); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/intro-and-outro/_expected/umd.js b/test/form/intro-and-outro/_expected/umd.js index c08f507..6332ac0 100644 --- a/test/form/intro-and-outro/_expected/umd.js +++ b/test/form/intro-and-outro/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; /* this is an intro */ console.log( 'hello world' ); /* this is an outro */ -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/multiple-exports/_expected/umd.js b/test/form/multiple-exports/_expected/umd.js index afaecf2..4ccb2ba 100644 --- a/test/form/multiple-exports/_expected/umd.js +++ b/test/form/multiple-exports/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.myBundle = global.myBundle || {}))); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; var foo = 1; var bar = 2; @@ -12,4 +12,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/namespace-optimization-b/_expected/umd.js b/test/form/namespace-optimization-b/_expected/umd.js index 866a3bd..f7fbbdf 100644 --- a/test/form/namespace-optimization-b/_expected/umd.js +++ b/test/form/namespace-optimization-b/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function foo () { console.log( 'foo' ); @@ -20,4 +20,4 @@ a(); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/namespace-optimization/_expected/umd.js b/test/form/namespace-optimization/_expected/umd.js index 67adf52..b2bc94f 100644 --- a/test/form/namespace-optimization/_expected/umd.js +++ b/test/form/namespace-optimization/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function a () {} a(); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/namespaced-default-exports/_expected/umd.js b/test/form/namespaced-default-exports/_expected/umd.js index b06132b..9bc5096 100644 --- a/test/form/namespaced-default-exports/_expected/umd.js +++ b/test/form/namespaced-default-exports/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.foo = global.foo || {}, global.foo.bar = global.foo.bar || {}, global.foo.bar.baz = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var main = 42; return main; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/namespaced-named-exports/_expected/umd.js b/test/form/namespaced-named-exports/_expected/umd.js index 37a8623..474db1f 100644 --- a/test/form/namespaced-named-exports/_expected/umd.js +++ b/test/form/namespaced-named-exports/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.foo = global.foo || {}, global.foo.bar = global.foo.bar || {}, global.foo.bar.baz = global.foo.bar.baz || {}))); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; var answer = 42; @@ -10,4 +10,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/no-imports-or-exports/_expected/umd.js b/test/form/no-imports-or-exports/_expected/umd.js index 5c8c7d3..2a478bf 100644 --- a/test/form/no-imports-or-exports/_expected/umd.js +++ b/test/form/no-imports-or-exports/_expected/umd.js @@ -2,8 +2,8 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; console.log( 'this is it' ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/no-treeshake/_expected/umd.js b/test/form/no-treeshake/_expected/umd.js index 757a187..cb1b283 100644 --- a/test/form/no-treeshake/_expected/umd.js +++ b/test/form/no-treeshake/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('external')) : typeof define === 'function' && define.amd ? define(['exports', 'external'], factory) : (factory((global.stirred = global.stirred || {}),global.external)); -}(this, function (exports,external) { 'use strict'; +}(this, (function (exports,external) { 'use strict'; var foo = 'unused'; @@ -28,4 +28,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/object-destructuring-default-values/_expected/umd.js b/test/form/object-destructuring-default-values/_expected/umd.js index a3e661b..3a1aeb7 100644 --- a/test/form/object-destructuring-default-values/_expected/umd.js +++ b/test/form/object-destructuring-default-values/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; const a = 1; const b = 2; @@ -10,4 +10,4 @@ const [ d = b ] = []; console.log(c, d); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/paths-function/_expected/umd.js b/test/form/paths-function/_expected/umd.js index 7d0a45f..8da109e 100644 --- a/test/form/paths-function/_expected/umd.js +++ b/test/form/paths-function/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('https://npmcdn.com/foo')) : typeof define === 'function' && define.amd ? define(['https://npmcdn.com/foo'], factory) : (factory(global.foo)); -}(this, function (foo) { 'use strict'; +}(this, (function (foo) { 'use strict'; foo = 'default' in foo ? foo['default'] : foo; assert.equal( foo, 42 ); -})); +}))); diff --git a/test/form/paths-relative/_expected/umd.js b/test/form/paths-relative/_expected/umd.js index 5ac4391..02bcdaf 100644 --- a/test/form/paths-relative/_expected/umd.js +++ b/test/form/paths-relative/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../foo')) : typeof define === 'function' && define.amd ? define(['../foo'], factory) : (factory(global.foo)); -}(this, function (foo) { 'use strict'; +}(this, (function (foo) { 'use strict'; foo = 'default' in foo ? foo['default'] : foo; assert.equal( foo, 42 ); -})); +}))); diff --git a/test/form/paths/_expected/umd.js b/test/form/paths/_expected/umd.js index 7d0a45f..8da109e 100644 --- a/test/form/paths/_expected/umd.js +++ b/test/form/paths/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('https://npmcdn.com/foo')) : typeof define === 'function' && define.amd ? define(['https://npmcdn.com/foo'], factory) : (factory(global.foo)); -}(this, function (foo) { 'use strict'; +}(this, (function (foo) { 'use strict'; foo = 'default' in foo ? foo['default'] : foo; assert.equal( foo, 42 ); -})); +}))); diff --git a/test/form/prefer-const/_expected/umd.js b/test/form/prefer-const/_expected/umd.js index 0c54878..0ec9750 100644 --- a/test/form/prefer-const/_expected/umd.js +++ b/test/form/prefer-const/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('external'), require('other'), require('another')) : typeof define === 'function' && define.amd ? define(['external', 'other', 'another'], factory) : (global.myBundle = factory(global.external,global.other,global.another)); -}(this, function (external,other,another) { 'use strict'; +}(this, (function (external,other,another) { 'use strict'; const a = 1; const b = 2; @@ -19,4 +19,4 @@ return main; -})); +}))); diff --git a/test/form/preserve-debugger/_expected/umd.js b/test/form/preserve-debugger/_expected/umd.js index dd19c2d..a6ca635 100644 --- a/test/form/preserve-debugger/_expected/umd.js +++ b/test/form/preserve-debugger/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; before(); debugger; after(); -})); +}))); diff --git a/test/form/preserves-comments-after-imports/_expected/umd.js b/test/form/preserves-comments-after-imports/_expected/umd.js index 96d6a7e..b1cc6a5 100644 --- a/test/form/preserves-comments-after-imports/_expected/umd.js +++ b/test/form/preserves-comments-after-imports/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.myBundle = global.myBundle || {}))); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; /** A comment for a number */ var number = 5; @@ -14,4 +14,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/relative-external-with-global/_expected/umd.js b/test/form/relative-external-with-global/_expected/umd.js index 4dc4fc9..5ab1989 100644 --- a/test/form/relative-external-with-global/_expected/umd.js +++ b/test/form/relative-external-with-global/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('./lib/throttle.js')) : typeof define === 'function' && define.amd ? define(['./lib/throttle.js'], factory) : (factory(global.Lib.throttle)); -}(this, function (throttle) { 'use strict'; +}(this, (function (throttle) { 'use strict'; throttle = 'default' in throttle ? throttle['default'] : throttle; @@ -12,4 +12,4 @@ window.addEventListener( 'mousemove', throttle ); -})); +}))); diff --git a/test/form/removes-existing-sourcemap-comments/_expected/umd.js b/test/form/removes-existing-sourcemap-comments/_expected/umd.js index ef0186e..bbfb959 100644 --- a/test/form/removes-existing-sourcemap-comments/_expected/umd.js +++ b/test/form/removes-existing-sourcemap-comments/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function foo () { return 42; @@ -10,4 +10,4 @@ console.log( foo() ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/self-contained-bundle/_expected/umd.js b/test/form/self-contained-bundle/_expected/umd.js index f828537..831b45c 100644 --- a/test/form/self-contained-bundle/_expected/umd.js +++ b/test/form/self-contained-bundle/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function foo () { console.log( bar() ); @@ -19,4 +19,4 @@ foo(); console.log( 3 ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/shorthand-properties/_expected/umd.js b/test/form/shorthand-properties/_expected/umd.js index 1a19210..9d64f6a 100644 --- a/test/form/shorthand-properties/_expected/umd.js +++ b/test/form/shorthand-properties/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function x () { return 'foo'; @@ -26,4 +26,4 @@ assert.equal( bar.x(), 'bar' ); assert.equal( baz.x(), 'baz' ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-b/_expected/umd.js b/test/form/side-effect-b/_expected/umd.js index 16d2890..2194031 100644 --- a/test/form/side-effect-b/_expected/umd.js +++ b/test/form/side-effect-b/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var main = 42; return main; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-c/_expected/umd.js b/test/form/side-effect-c/_expected/umd.js index 16d2890..2194031 100644 --- a/test/form/side-effect-c/_expected/umd.js +++ b/test/form/side-effect-c/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var main = 42; return main; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-d/_expected/umd.js b/test/form/side-effect-d/_expected/umd.js index 16d2890..2194031 100644 --- a/test/form/side-effect-d/_expected/umd.js +++ b/test/form/side-effect-d/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var main = 42; return main; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-e/_expected/umd.js b/test/form/side-effect-e/_expected/umd.js index ef3393d..4a3316f 100644 --- a/test/form/side-effect-e/_expected/umd.js +++ b/test/form/side-effect-e/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function foo () { var Object = { @@ -21,4 +21,4 @@ return main; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-f/_expected/umd.js b/test/form/side-effect-f/_expected/umd.js index 16d2890..2194031 100644 --- a/test/form/side-effect-f/_expected/umd.js +++ b/test/form/side-effect-f/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var main = 42; return main; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-g/_expected/umd.js b/test/form/side-effect-g/_expected/umd.js index 16d2890..2194031 100644 --- a/test/form/side-effect-g/_expected/umd.js +++ b/test/form/side-effect-g/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var main = 42; return main; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-h/_expected/umd.js b/test/form/side-effect-h/_expected/umd.js index 16d2890..2194031 100644 --- a/test/form/side-effect-h/_expected/umd.js +++ b/test/form/side-effect-h/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var main = 42; return main; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-i/_expected/umd.js b/test/form/side-effect-i/_expected/umd.js index b090f9a..87d4d59 100644 --- a/test/form/side-effect-i/_expected/umd.js +++ b/test/form/side-effect-i/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; if ( !ok ) { throw new Error( 'this will be included' ); @@ -12,4 +12,4 @@ return main; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-j/_expected/umd.js b/test/form/side-effect-j/_expected/umd.js index 2da816b..1d7d727 100644 --- a/test/form/side-effect-j/_expected/umd.js +++ b/test/form/side-effect-j/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var augment; augment = x => x.augmented = true; @@ -12,4 +12,4 @@ return x; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-k/_expected/umd.js b/test/form/side-effect-k/_expected/umd.js index 5b7f3d6..3d6da0b 100644 --- a/test/form/side-effect-k/_expected/umd.js +++ b/test/form/side-effect-k/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.myBundle = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function augment ( x ) { var prop, source; @@ -29,4 +29,4 @@ return x; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-l/_expected/umd.js b/test/form/side-effect-l/_expected/umd.js index f3395b7..d561e69 100644 --- a/test/form/side-effect-l/_expected/umd.js +++ b/test/form/side-effect-l/_expected/umd.js @@ -2,8 +2,8 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-m/_expected/umd.js b/test/form/side-effect-m/_expected/umd.js index 902026f..b0419fe 100644 --- a/test/form/side-effect-m/_expected/umd.js +++ b/test/form/side-effect-m/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function odd ( n ) { return n !== 0 && even( n - 1 ); @@ -22,4 +22,4 @@ console.log( counter ); -})); +}))); diff --git a/test/form/side-effect-n/_expected/umd.js b/test/form/side-effect-n/_expected/umd.js index c792f48..f83037e 100644 --- a/test/form/side-effect-n/_expected/umd.js +++ b/test/form/side-effect-n/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function foo () { console.log( 'foo' ); @@ -14,4 +14,4 @@ ( Math.random() < 0.5 ? foo : bar )(); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect-o/_expected/umd.js b/test/form/side-effect-o/_expected/umd.js index 80d69a3..38b9a1d 100644 --- a/test/form/side-effect-o/_expected/umd.js +++ b/test/form/side-effect-o/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function fn () { return Math.random() < 0.5 ? foo : bar; @@ -18,4 +18,4 @@ fn()(); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/side-effect/_expected/umd.js b/test/form/side-effect/_expected/umd.js index 79b4cc2..e0961e0 100644 --- a/test/form/side-effect/_expected/umd.js +++ b/test/form/side-effect/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var foo = 42; assert.equal( foo, 42 ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/sourcemaps-external/_expected/umd.js b/test/form/sourcemaps-external/_expected/umd.js index 5e77403..118c092 100644 --- a/test/form/sourcemaps-external/_expected/umd.js +++ b/test/form/sourcemaps-external/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function foo () { console.log( 'hello from foo.js' ); @@ -17,5 +17,5 @@ foo(); bar(); -})); +}))); //# sourceMappingURL=umd.js.map \ No newline at end of file diff --git a/test/form/sourcemaps-inline/_expected/umd.js b/test/form/sourcemaps-inline/_expected/umd.js index b934854..ab7ebf4 100644 --- a/test/form/sourcemaps-inline/_expected/umd.js +++ b/test/form/sourcemaps-inline/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function foo () { console.log( 'hello from foo.js' ); @@ -17,5 +17,5 @@ foo(); bar(); -})); +}))); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW1kLmpzIiwic291cmNlcyI6WyIuLi9mb28uanMiLCIuLi9iYXIuanMiLCIuLi9tYWluLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGZvbyAoKSB7XG5cdGNvbnNvbGUubG9nKCAnaGVsbG8gZnJvbSBmb28uanMnICk7XG59XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBiYXIgKCkge1xuXHRjb25zb2xlLmxvZyggJ2hlbGxvIGZyb20gYmFyLmpzJyApO1xufVxuIiwiaW1wb3J0IGZvbyBmcm9tICcuL2Zvbyc7XG5pbXBvcnQgYmFyIGZyb20gJy4vYmFyJztcblxuY29uc29sZS5sb2coICdoZWxsbyBmcm9tIG1haW4uanMnICk7XG5cbmZvbygpO1xuYmFyKCk7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0NBQWUsU0FBUyxHQUFHLElBQUk7QUFDL0IsQ0FBQSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQztBQUNwQyxDQUFBLENBQUM7O0NDRmMsU0FBUyxHQUFHLElBQUk7QUFDL0IsQ0FBQSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQztBQUNwQyxDQUFBLENBQUM7O0NDQ0QsT0FBTyxDQUFDLEdBQUcsRUFBRSxvQkFBb0IsRUFBRSxDQUFDOztBQUVwQyxDQUFBLEdBQUcsRUFBRSxDQUFDO0FBQ04sQ0FBQSxHQUFHLEVBQUUsQ0FBQyw7OyJ9 \ No newline at end of file diff --git a/test/form/spacing-after-function-with-semicolon/_expected/umd.js b/test/form/spacing-after-function-with-semicolon/_expected/umd.js index 56bca25..8b7954a 100644 --- a/test/form/spacing-after-function-with-semicolon/_expected/umd.js +++ b/test/form/spacing-after-function-with-semicolon/_expected/umd.js @@ -2,10 +2,10 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function x () { return 'x' }; assert.equal( x(), 'x' ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/string-indentation-b/_expected/umd.js b/test/form/string-indentation-b/_expected/umd.js index ad0bc29..9ebd756 100644 --- a/test/form/string-indentation-b/_expected/umd.js +++ b/test/form/string-indentation-b/_expected/umd.js @@ -2,11 +2,11 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var a = 'a'; var b = 'b'; assert.equal( a, 'a' ); assert.equal( b, 'b' ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/string-indentation/_expected/umd.js b/test/form/string-indentation/_expected/umd.js index 285a53f..ac7131e 100644 --- a/test/form/string-indentation/_expected/umd.js +++ b/test/form/string-indentation/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var a = '1\ 2'; @@ -21,4 +21,4 @@ assert.equal( c, '1\n 2' ); assert.equal( d, '1\n\t2' ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/this-is-undefined/_expected/umd.js b/test/form/this-is-undefined/_expected/umd.js index 34ce474..b7f3efa 100644 --- a/test/form/this-is-undefined/_expected/umd.js +++ b/test/form/this-is-undefined/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; const fooContext = {}; @@ -22,4 +22,4 @@ // outside a function, `this` is undefined assert.strictEqual( undefined, undefined ); -})); +}))); diff --git a/test/form/umd-noconflict/_expected/umd.js b/test/form/umd-noconflict/_expected/umd.js index e249923..89e0448 100644 --- a/test/form/umd-noconflict/_expected/umd.js +++ b/test/form/umd-noconflict/_expected/umd.js @@ -7,7 +7,7 @@ global.FooBar = exports; exports.noConflict = function() { global.FooBar = current; return exports; }; })(); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; function doThings() { console.log( 'doing things...' ); @@ -23,4 +23,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/test/form/unmodified-default-exports-function-argument/_expected/umd.js b/test/form/unmodified-default-exports-function-argument/_expected/umd.js index 07f1781..81d4424 100644 --- a/test/form/unmodified-default-exports-function-argument/_expected/umd.js +++ b/test/form/unmodified-default-exports-function-argument/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var foo = function () { return 42; @@ -17,4 +17,4 @@ console.log( answer ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/unmodified-default-exports/_expected/umd.js b/test/form/unmodified-default-exports/_expected/umd.js index d83a806..f74ed8e 100644 --- a/test/form/unmodified-default-exports/_expected/umd.js +++ b/test/form/unmodified-default-exports/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var Foo = function () { this.isFoo = true; @@ -16,4 +16,4 @@ var foo = new Foo(); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/unused-default-exports/_expected/umd.js b/test/form/unused-default-exports/_expected/umd.js index 8c9c2e0..b38f629 100644 --- a/test/form/unused-default-exports/_expected/umd.js +++ b/test/form/unused-default-exports/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; var foo = { value: 1 }; @@ -15,4 +15,4 @@ assert.equal( foo.value, 2 ); -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/test/form/whitespace-around-namespace-member-expression/_expected/umd.js b/test/form/whitespace-around-namespace-member-expression/_expected/umd.js index ae6ce6f..e260775 100644 --- a/test/form/whitespace-around-namespace-member-expression/_expected/umd.js +++ b/test/form/whitespace-around-namespace-member-expression/_expected/umd.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; function yar() { console.log('yar?'); @@ -10,4 +10,4 @@ yar(); -})); \ No newline at end of file +}))); \ No newline at end of file From 7463c9f36c8a3e82e134657905b408babea59d5c Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 14 Aug 2016 10:30:18 -0400 Subject: [PATCH 164/331] -> v0.34.8 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb81754..5f6884e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.34.8 + +* Wrap UMD factory function in parens to avoid lazy parsing ([#774](https://github.com/rollup/rollup/pull/774)) + ## 0.34.7 * Leave it up to resolveId to normalize the entry path ([#835](https://github.com/rollup/rollup/pull/835)) diff --git a/package.json b/package.json index da42204..d51bbfd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.7", + "version": "0.34.8", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 4ed3909d71a95c3eeccdd27f6eb006ad1c243de1 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 16 Aug 2016 07:38:04 -0400 Subject: [PATCH 165/331] add test --- test/form/comment-before-import/_config.js | 3 +++ test/form/comment-before-import/_expected/amd.js | 12 ++++++++++++ test/form/comment-before-import/_expected/cjs.js | 10 ++++++++++ test/form/comment-before-import/_expected/es.js | 8 ++++++++ .../form/comment-before-import/_expected/iife.js | 13 +++++++++++++ test/form/comment-before-import/_expected/umd.js | 16 ++++++++++++++++ test/form/comment-before-import/bar.js | 2 ++ test/form/comment-before-import/foo.js | 4 ++++ test/form/comment-before-import/main.js | 4 ++++ 9 files changed, 72 insertions(+) create mode 100644 test/form/comment-before-import/_config.js create mode 100644 test/form/comment-before-import/_expected/amd.js create mode 100644 test/form/comment-before-import/_expected/cjs.js create mode 100644 test/form/comment-before-import/_expected/es.js create mode 100644 test/form/comment-before-import/_expected/iife.js create mode 100644 test/form/comment-before-import/_expected/umd.js create mode 100644 test/form/comment-before-import/bar.js create mode 100644 test/form/comment-before-import/foo.js create mode 100644 test/form/comment-before-import/main.js diff --git a/test/form/comment-before-import/_config.js b/test/form/comment-before-import/_config.js new file mode 100644 index 0000000..823ac63 --- /dev/null +++ b/test/form/comment-before-import/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'preserves comments before imports' +}; diff --git a/test/form/comment-before-import/_expected/amd.js b/test/form/comment-before-import/_expected/amd.js new file mode 100644 index 0000000..8ee5782 --- /dev/null +++ b/test/form/comment-before-import/_expected/amd.js @@ -0,0 +1,12 @@ +define(function () { 'use strict'; + + // bar.js + var bar = 21; + + // foo.js + var foo = bar * 2; + + // main.js + console.log( foo ); + +}); \ No newline at end of file diff --git a/test/form/comment-before-import/_expected/cjs.js b/test/form/comment-before-import/_expected/cjs.js new file mode 100644 index 0000000..04e5550 --- /dev/null +++ b/test/form/comment-before-import/_expected/cjs.js @@ -0,0 +1,10 @@ +'use strict'; + +// bar.js +var bar = 21; + +// foo.js +var foo = bar * 2; + +// main.js +console.log( foo ); \ No newline at end of file diff --git a/test/form/comment-before-import/_expected/es.js b/test/form/comment-before-import/_expected/es.js new file mode 100644 index 0000000..1c21cb3 --- /dev/null +++ b/test/form/comment-before-import/_expected/es.js @@ -0,0 +1,8 @@ +// bar.js +var bar = 21; + +// foo.js +var foo = bar * 2; + +// main.js +console.log( foo ); \ No newline at end of file diff --git a/test/form/comment-before-import/_expected/iife.js b/test/form/comment-before-import/_expected/iife.js new file mode 100644 index 0000000..7d1e8f9 --- /dev/null +++ b/test/form/comment-before-import/_expected/iife.js @@ -0,0 +1,13 @@ +(function () { + 'use strict'; + + // bar.js + var bar = 21; + + // foo.js + var foo = bar * 2; + + // main.js + console.log( foo ); + +}()); \ No newline at end of file diff --git a/test/form/comment-before-import/_expected/umd.js b/test/form/comment-before-import/_expected/umd.js new file mode 100644 index 0000000..9d40700 --- /dev/null +++ b/test/form/comment-before-import/_expected/umd.js @@ -0,0 +1,16 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + // bar.js + var bar = 21; + + // foo.js + var foo = bar * 2; + + // main.js + console.log( foo ); + +}))); \ No newline at end of file diff --git a/test/form/comment-before-import/bar.js b/test/form/comment-before-import/bar.js new file mode 100644 index 0000000..3595594 --- /dev/null +++ b/test/form/comment-before-import/bar.js @@ -0,0 +1,2 @@ +// bar.js +export default 21; diff --git a/test/form/comment-before-import/foo.js b/test/form/comment-before-import/foo.js new file mode 100644 index 0000000..b3747d0 --- /dev/null +++ b/test/form/comment-before-import/foo.js @@ -0,0 +1,4 @@ +// foo.js +import bar from './bar.js'; + +export default bar * 2; diff --git a/test/form/comment-before-import/main.js b/test/form/comment-before-import/main.js new file mode 100644 index 0000000..d8169ae --- /dev/null +++ b/test/form/comment-before-import/main.js @@ -0,0 +1,4 @@ +// main.js +import foo from './foo.js'; + +console.log( foo ); From de37d478f6b4b74d4bcb714840efc4a048a1ac94 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 16 Aug 2016 07:40:30 -0400 Subject: [PATCH 166/331] -> v0.34.9 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f6884e..269ceaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # rollup changelog +## 0.34.9 + +* Disable indentation by default, for faster bundle generation ([#812](https://github.com/rollup/rollup/pull/812)) +* More helpful error on missing entry file ([#802](https://github.com/rollup/rollup/issues/802)) +* Preserve comments before import declarations ([#815](https://github.com/rollup/rollup/pull/815)) + ## 0.34.8 * Wrap UMD factory function in parens to avoid lazy parsing ([#774](https://github.com/rollup/rollup/pull/774)) diff --git a/package.json b/package.json index d51bbfd..8007949 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.8", + "version": "0.34.9", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From ebbb5bec62a9dd42b478d3fbbf12b8f72ac4de45 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 16 Aug 2016 16:24:04 -0400 Subject: [PATCH 167/331] put outro after export block, not before (#852) --- src/Bundle.js | 1 - src/finalisers/amd.js | 6 ++---- src/finalisers/cjs.js | 1 + src/finalisers/es.js | 7 +++---- src/finalisers/iife.js | 1 + src/finalisers/umd.js | 6 ++---- test/form/intro-and-outro/_config.js | 3 ++- test/form/intro-and-outro/_expected/amd.js | 4 ++++ test/form/intro-and-outro/_expected/cjs.js | 4 ++++ test/form/intro-and-outro/_expected/es.js | 4 ++++ test/form/intro-and-outro/_expected/iife.js | 6 +++++- test/form/intro-and-outro/_expected/umd.js | 10 +++++++--- test/form/intro-and-outro/main.js | 2 ++ 13 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index f48411f..5124cae 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -319,7 +319,6 @@ export default class Bundle { .join( '\n\n' ); if ( intro ) magicString.prepend( intro + '\n' ); - if ( options.outro ) magicString.append( '\n' + options.outro ); const indentString = getIndentString( magicString, options ); diff --git a/src/finalisers/amd.js b/src/finalisers/amd.js index b2e4ec7..c04c88b 100644 --- a/src/finalisers/amd.js +++ b/src/finalisers/amd.js @@ -25,10 +25,8 @@ export default function amd ( bundle, magicString, { exportMode, indentString }, const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); - - if ( exportMode === 'named' ) { - magicString.append( `\n\n${esModuleExport}` ); - } + if ( exportMode === 'named' ) magicString.append( `\n\n${esModuleExport}` ); + if ( options.outro ) magicString.append( `\n${options.outro}` ); return magicString .indent( indentString ) diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index 6900f6d..b12d621 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -44,6 +44,7 @@ export default function cjs ( bundle, magicString, { exportMode }, options ) { const exportBlock = getExportBlock( bundle.entryModule, exportMode, 'module.exports =' ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); + if ( options.outro ) magicString.append( `\n${options.outro}` ); return magicString; } diff --git a/src/finalisers/es.js b/src/finalisers/es.js index 45036de..a788083 100644 --- a/src/finalisers/es.js +++ b/src/finalisers/es.js @@ -4,7 +4,7 @@ function notDefault ( name ) { return name !== 'default'; } -export default function es ( bundle, magicString ) { +export default function es ( bundle, magicString, config, options ) { const importBlock = bundle.externalModules .map( module => { const specifiers = []; @@ -71,9 +71,8 @@ export default function es ( bundle, magicString ) { exportBlock += `export default ${module.traceExport( 'default' ).render( true )};`; } - if ( exportBlock ) { - magicString.append( '\n\n' + exportBlock.trim() ); - } + if ( exportBlock ) magicString.append( '\n\n' + exportBlock.trim() ); + if ( options.outro ) magicString.append( `\n${options.outro}` ); return magicString.trim(); } diff --git a/src/finalisers/iife.js b/src/finalisers/iife.js index 5055a25..319bd90 100644 --- a/src/finalisers/iife.js +++ b/src/finalisers/iife.js @@ -54,6 +54,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString } if ( useStrict ) magicString.prepend( useStrict + '\n\n' ); const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); + if ( options.outro ) magicString.append( `\n${options.outro}` ); return magicString .indent( indentString ) diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index 85040ea..11631f5 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -69,10 +69,8 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); - - if (exportMode === 'named') { - magicString.append( `\n\n${esModuleExport}` ); - } + if ( exportMode === 'named' ) magicString.append( `\n\n${esModuleExport}` ); + if ( options.outro ) magicString.append( `\n${options.outro}` ); return magicString .trim() diff --git a/test/form/intro-and-outro/_config.js b/test/form/intro-and-outro/_config.js index 36b7a9d..843e554 100644 --- a/test/form/intro-and-outro/_config.js +++ b/test/form/intro-and-outro/_config.js @@ -2,6 +2,7 @@ module.exports = { description: 'adds an intro/outro', options: { intro: '/* this is an intro */', - outro: '/* this is an outro */' + outro: '/* this is an outro */', + moduleName: 'foo' } }; diff --git a/test/form/intro-and-outro/_expected/amd.js b/test/form/intro-and-outro/_expected/amd.js index a58ac95..3c16c97 100644 --- a/test/form/intro-and-outro/_expected/amd.js +++ b/test/form/intro-and-outro/_expected/amd.js @@ -2,6 +2,10 @@ define(function () { 'use strict'; /* this is an intro */ console.log( 'hello world' ); + + var main = 42; + + return main; /* this is an outro */ }); diff --git a/test/form/intro-and-outro/_expected/cjs.js b/test/form/intro-and-outro/_expected/cjs.js index 662c938..dde8f6b 100644 --- a/test/form/intro-and-outro/_expected/cjs.js +++ b/test/form/intro-and-outro/_expected/cjs.js @@ -2,4 +2,8 @@ /* this is an intro */ console.log( 'hello world' ); + +var main = 42; + +module.exports = main; /* this is an outro */ diff --git a/test/form/intro-and-outro/_expected/es.js b/test/form/intro-and-outro/_expected/es.js index c017a45..7459f70 100644 --- a/test/form/intro-and-outro/_expected/es.js +++ b/test/form/intro-and-outro/_expected/es.js @@ -1,3 +1,7 @@ /* this is an intro */ console.log( 'hello world' ); + +var main = 42; + +export default main; /* this is an outro */ diff --git a/test/form/intro-and-outro/_expected/iife.js b/test/form/intro-and-outro/_expected/iife.js index 15a21d9..ef591fc 100644 --- a/test/form/intro-and-outro/_expected/iife.js +++ b/test/form/intro-and-outro/_expected/iife.js @@ -1,8 +1,12 @@ -(function () { +var foo = (function () { 'use strict'; /* this is an intro */ console.log( 'hello world' ); + + var main = 42; + + return main; /* this is an outro */ }()); diff --git a/test/form/intro-and-outro/_expected/umd.js b/test/form/intro-and-outro/_expected/umd.js index 6332ac0..97b8e3e 100644 --- a/test/form/intro-and-outro/_expected/umd.js +++ b/test/form/intro-and-outro/_expected/umd.js @@ -1,11 +1,15 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : - (factory()); + (global.foo = factory()); }(this, (function () { 'use strict'; /* this is an intro */ console.log( 'hello world' ); + + var main = 42; + + return main; /* this is an outro */ -}))); \ No newline at end of file +}))); diff --git a/test/form/intro-and-outro/main.js b/test/form/intro-and-outro/main.js index 3b5a604..6054017 100644 --- a/test/form/intro-and-outro/main.js +++ b/test/form/intro-and-outro/main.js @@ -1 +1,3 @@ console.log( 'hello world' ); + +export default 42; From 98b4da0f355c4abf6fa71f1ae835ac71b65eb58f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 16 Aug 2016 16:47:30 -0400 Subject: [PATCH 168/331] allow custom bundle context (#851) --- src/Bundle.js | 1 + src/Statement.js | 4 ++-- src/rollup.js | 1 + test/form/custom-context/_config.js | 6 ++++++ test/form/custom-context/_expected/amd.js | 5 +++++ test/form/custom-context/_expected/cjs.js | 3 +++ test/form/custom-context/_expected/es.js | 1 + test/form/custom-context/_expected/iife.js | 6 ++++++ test/form/custom-context/_expected/umd.js | 9 +++++++++ test/form/custom-context/main.js | 1 + test/test.js | 2 +- 11 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 test/form/custom-context/_config.js create mode 100644 test/form/custom-context/_expected/amd.js create mode 100644 test/form/custom-context/_expected/cjs.js create mode 100644 test/form/custom-context/_expected/es.js create mode 100644 test/form/custom-context/_expected/iife.js create mode 100644 test/form/custom-context/_expected/umd.js create mode 100644 test/form/custom-context/main.js diff --git a/src/Bundle.js b/src/Bundle.js index f48411f..b60d6d5 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -65,6 +65,7 @@ export default class Bundle { this.externalModules = []; this.internalNamespaces = []; + this.context = String( options.context ); this.assumedGlobals = blank(); if ( typeof options.external === 'function' ) { diff --git a/src/Statement.js b/src/Statement.js index c9b01f8..7ab8bf8 100644 --- a/src/Statement.js +++ b/src/Statement.js @@ -60,8 +60,8 @@ export default class Statement { } if ( node.type === 'ThisExpression' && contextDepth === 0 ) { - module.magicString.overwrite( node.start, node.end, 'undefined' ); - module.bundle.onwarn( 'The `this` keyword is equivalent to `undefined` at the top level of an ES module, and has been rewritten' ); + module.magicString.overwrite( node.start, node.end, module.bundle.context ); + if ( module.bundle.context === 'undefined' ) module.bundle.onwarn( 'The `this` keyword is equivalent to `undefined` at the top level of an ES module, and has been rewritten' ); } if ( node._scope ) scope = node._scope; diff --git a/src/rollup.js b/src/rollup.js index 7c1ce32..4c1a076 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -12,6 +12,7 @@ const ALLOWED_KEYS = [ 'acorn', 'banner', 'cache', + 'context', 'dest', 'entry', 'exports', diff --git a/test/form/custom-context/_config.js b/test/form/custom-context/_config.js new file mode 100644 index 0000000..84f2dbd --- /dev/null +++ b/test/form/custom-context/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'allows custom context', + options: { + context: `lolwut` + } +}; diff --git a/test/form/custom-context/_expected/amd.js b/test/form/custom-context/_expected/amd.js new file mode 100644 index 0000000..a160d17 --- /dev/null +++ b/test/form/custom-context/_expected/amd.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + lolwut.prop = '???'; + +}); diff --git a/test/form/custom-context/_expected/cjs.js b/test/form/custom-context/_expected/cjs.js new file mode 100644 index 0000000..f42cf3c --- /dev/null +++ b/test/form/custom-context/_expected/cjs.js @@ -0,0 +1,3 @@ +'use strict'; + +lolwut.prop = '???'; diff --git a/test/form/custom-context/_expected/es.js b/test/form/custom-context/_expected/es.js new file mode 100644 index 0000000..fa83c3d --- /dev/null +++ b/test/form/custom-context/_expected/es.js @@ -0,0 +1 @@ +lolwut.prop = '???'; diff --git a/test/form/custom-context/_expected/iife.js b/test/form/custom-context/_expected/iife.js new file mode 100644 index 0000000..a41619e --- /dev/null +++ b/test/form/custom-context/_expected/iife.js @@ -0,0 +1,6 @@ +(function () { + 'use strict'; + + lolwut.prop = '???'; + +}()); diff --git a/test/form/custom-context/_expected/umd.js b/test/form/custom-context/_expected/umd.js new file mode 100644 index 0000000..a73a22c --- /dev/null +++ b/test/form/custom-context/_expected/umd.js @@ -0,0 +1,9 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + lolwut.prop = '???'; + +}))); diff --git a/test/form/custom-context/main.js b/test/form/custom-context/main.js new file mode 100644 index 0000000..169f08b --- /dev/null +++ b/test/form/custom-context/main.js @@ -0,0 +1 @@ +this.prop = '???'; diff --git a/test/test.js b/test/test.js index b2af38b..4eb73a6 100644 --- a/test/test.js +++ b/test/test.js @@ -89,7 +89,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( () => { throw new Error( 'Missing expected error' ); }, err => { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, context, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); }); }); }); From 3ed945c8e1cd40d65f9092b72be7127c69ba8676 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 16 Aug 2016 18:16:31 -0400 Subject: [PATCH 169/331] fix noConflict when used via config file (#846) --- bin/src/runRollup.js | 5 +---- test/cli/no-conflict/_config.js | 4 ++++ test/cli/no-conflict/_expected.js | 16 ++++++++++++++++ test/cli/no-conflict/main.js | 1 + test/cli/no-conflict/rollup.config.js | 6 ++++++ 5 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 test/cli/no-conflict/_config.js create mode 100644 test/cli/no-conflict/_expected.js create mode 100644 test/cli/no-conflict/main.js create mode 100644 test/cli/no-conflict/rollup.config.js diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index cbfa064..270654f 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -70,7 +70,7 @@ export default function runRollup ( command ) { }); // temporarily override require - var defaultLoader = require.extensions[ '.js' ]; + const defaultLoader = require.extensions[ '.js' ]; require.extensions[ '.js' ] = ( m, filename ) => { if ( filename === config ) { m._compile( code, filename ); @@ -147,9 +147,6 @@ function execute ( options, command ) { options.external = external; - options.noConflict = command.conflict === false; - delete command.conflict; - // Use any options passed through the CLI as overrides. Object.keys( equivalents ).forEach( cliOption => { if ( command.hasOwnProperty( cliOption ) ) { diff --git a/test/cli/no-conflict/_config.js b/test/cli/no-conflict/_config.js new file mode 100644 index 0000000..cc870f8 --- /dev/null +++ b/test/cli/no-conflict/_config.js @@ -0,0 +1,4 @@ +module.exports = { + description: 'respects noConflict option', + command: 'rollup --config rollup.config.js' +}; diff --git a/test/cli/no-conflict/_expected.js b/test/cli/no-conflict/_expected.js new file mode 100644 index 0000000..1b363c9 --- /dev/null +++ b/test/cli/no-conflict/_expected.js @@ -0,0 +1,16 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (function() { + var current = global.conflictyName; + var exports = factory(); + global.conflictyName = exports; + exports.noConflict = function() { global.conflictyName = current; return exports; }; + })(); +}(this, (function () { 'use strict'; + +var main = {}; + +return main; + +}))); diff --git a/test/cli/no-conflict/main.js b/test/cli/no-conflict/main.js new file mode 100644 index 0000000..ff8b4c5 --- /dev/null +++ b/test/cli/no-conflict/main.js @@ -0,0 +1 @@ +export default {}; diff --git a/test/cli/no-conflict/rollup.config.js b/test/cli/no-conflict/rollup.config.js new file mode 100644 index 0000000..a1b8d7d --- /dev/null +++ b/test/cli/no-conflict/rollup.config.js @@ -0,0 +1,6 @@ +module.exports = { + entry: 'main.js', + format: 'umd', + moduleName: 'conflictyName', + noConflict: true +}; From f8129e496acab3cffd246e8478e43a1cb2b8bf0c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 17 Aug 2016 11:16:50 -0400 Subject: [PATCH 170/331] -> v0.34.10 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 269ceaf..acd43df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # rollup changelog +## 0.34.10 + +* Allow custom `options.context` to replace top-level `this` ([#851](https://github.com/rollup/rollup/issues/851)) +* Fix `noConflict` when used via `rollup --config` ([#846](https://github.com/rollup/rollup/issues/846)) +* Place `outro` block *after* export block ([#852](https://github.com/rollup/rollup/issues/852)) + ## 0.34.9 * Disable indentation by default, for faster bundle generation ([#812](https://github.com/rollup/rollup/pull/812)) diff --git a/package.json b/package.json index 8007949..25191db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.9", + "version": "0.34.10", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 00c70e35cb177b3856d1521f96dba7ed8274f2c9 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 17 Aug 2016 13:57:43 -0400 Subject: [PATCH 171/331] failing test for #860 --- test/function/export-as-default/_config.js | 6 ++++++ test/function/export-as-default/foo.js | 3 +++ test/function/export-as-default/main.js | 3 +++ 3 files changed, 12 insertions(+) create mode 100644 test/function/export-as-default/_config.js create mode 100644 test/function/export-as-default/foo.js create mode 100644 test/function/export-as-default/main.js diff --git a/test/function/export-as-default/_config.js b/test/function/export-as-default/_config.js new file mode 100644 index 0000000..0f4773a --- /dev/null +++ b/test/function/export-as-default/_config.js @@ -0,0 +1,6 @@ +var assert = require( 'assert' ); + +module.exports = { + solo: true, + description: 'export { foo as default } does not create a live binding' +}; diff --git a/test/function/export-as-default/foo.js b/test/function/export-as-default/foo.js new file mode 100644 index 0000000..2e5b275 --- /dev/null +++ b/test/function/export-as-default/foo.js @@ -0,0 +1,3 @@ +let foo = 1; +export { foo as default }; +foo = 2; diff --git a/test/function/export-as-default/main.js b/test/function/export-as-default/main.js new file mode 100644 index 0000000..e2b1718 --- /dev/null +++ b/test/function/export-as-default/main.js @@ -0,0 +1,3 @@ +import foo from './foo.js'; + +assert.equal( foo, 1 ); From 4ccb7e744f90f0c798efb8c4540872a08a5826a3 Mon Sep 17 00:00:00 2001 From: Nelson Date: Thu, 25 Aug 2016 17:51:36 +0100 Subject: [PATCH 172/331] Update link to codecov image. fixes https://github.com/rollup/rollup/issues/878 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6e02e51..c5de896 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ alt="dependency status"> - Coverage via Codecov + Coverage via Codecov Date: Mon, 29 Aug 2016 16:03:24 -0400 Subject: [PATCH 173/331] ensure intro appears before interop block (#880) --- src/Bundle.js | 6 +++--- src/finalisers/amd.js | 8 +++++--- src/finalisers/cjs.js | 6 +++--- src/finalisers/es.js | 7 +++---- src/finalisers/iife.js | 20 +++++++++++--------- src/finalisers/umd.js | 12 ++++++++---- test/form/intro-and-outro/_config.js | 3 ++- test/form/intro-and-outro/_expected/amd.js | 7 +++++-- test/form/intro-and-outro/_expected/cjs.js | 8 +++++++- test/form/intro-and-outro/_expected/es.js | 5 ++++- test/form/intro-and-outro/_expected/iife.js | 9 ++++++--- test/form/intro-and-outro/_expected/umd.js | 13 ++++++++----- test/form/intro-and-outro/main.js | 5 ++++- 13 files changed, 69 insertions(+), 40 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index ffffbf6..e458975 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -312,21 +312,21 @@ export default class Bundle { } }); - const intro = [ options.intro ] + let intro = [ options.intro ] .concat( this.plugins.map( plugin => plugin.intro && plugin.intro() ) ) .filter( Boolean ) .join( '\n\n' ); - if ( intro ) magicString.prepend( intro + '\n' ); + if ( intro ) intro += '\n'; const indentString = getIndentString( magicString, options ); const finalise = finalisers[ format ]; if ( !finalise ) throw new Error( `You must specify an output type - valid options are ${keys( finalisers ).join( ', ' )}` ); - magicString = finalise( this, magicString.trim(), { exportMode, indentString }, options ); + magicString = finalise( this, magicString.trim(), { exportMode, indentString, intro }, options ); const banner = [ options.banner ] .concat( this.plugins.map( plugin => plugin.banner ) ) diff --git a/src/finalisers/amd.js b/src/finalisers/amd.js index c04c88b..456dd86 100644 --- a/src/finalisers/amd.js +++ b/src/finalisers/amd.js @@ -3,7 +3,7 @@ import getInteropBlock from './shared/getInteropBlock.js'; import getExportBlock from './shared/getExportBlock.js'; import esModuleExport from './shared/esModuleExport.js'; -export default function amd ( bundle, magicString, { exportMode, indentString }, options ) { +export default function amd ( bundle, magicString, { exportMode, indentString, intro }, options ) { const deps = bundle.externalModules.map( quotePath ); const args = bundle.externalModules.map( getName ); @@ -17,12 +17,14 @@ export default function amd ( bundle, magicString, { exportMode, indentString }, ( deps.length ? `[${deps.join( ', ' )}], ` : `` ); const useStrict = options.useStrict !== false ? ` 'use strict';` : ``; - const intro = `define(${params}function (${args.join( ', ' )}) {${useStrict}\n\n`; + const wrapperStart = `define(${params}function (${args.join( ', ' )}) {${useStrict}\n\n`; // var foo__default = 'default' in foo ? foo['default'] : foo; const interopBlock = getInteropBlock( bundle ); if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' ); + if ( intro ) magicString.prepend( intro ); + const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); if ( exportMode === 'named' ) magicString.append( `\n\n${esModuleExport}` ); @@ -31,5 +33,5 @@ export default function amd ( bundle, magicString, { exportMode, indentString }, return magicString .indent( indentString ) .append( '\n\n});' ) - .prepend( intro ); + .prepend( wrapperStart ); } diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index b12d621..0ffbce8 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -1,9 +1,9 @@ import getExportBlock from './shared/getExportBlock.js'; import esModuleExport from './shared/esModuleExport.js'; -export default function cjs ( bundle, magicString, { exportMode }, options ) { - let intro = ( options.useStrict === false ? `` : `'use strict';\n\n` ) + - ( exportMode === 'named' ? `${esModuleExport}\n\n` : '' ); +export default function cjs ( bundle, magicString, { exportMode, intro }, options ) { + intro = ( options.useStrict === false ? intro : `'use strict';\n\n${intro}` ) + + ( exportMode === 'named' ? `${esModuleExport}\n\n` : '' ); let needsInterop = false; diff --git a/src/finalisers/es.js b/src/finalisers/es.js index a788083..4e08ce3 100644 --- a/src/finalisers/es.js +++ b/src/finalisers/es.js @@ -4,7 +4,7 @@ function notDefault ( name ) { return name !== 'default'; } -export default function es ( bundle, magicString, config, options ) { +export default function es ( bundle, magicString, { intro }, options ) { const importBlock = bundle.externalModules .map( module => { const specifiers = []; @@ -49,9 +49,8 @@ export default function es ( bundle, magicString, config, options ) { }) .join( '\n' ); - if ( importBlock ) { - magicString.prepend( importBlock + '\n\n' ); - } + if ( importBlock ) intro += importBlock + '\n\n'; + if ( intro ) magicString.prepend( intro ); const module = bundle.entryModule; diff --git a/src/finalisers/iife.js b/src/finalisers/iife.js index 319bd90..612f70f 100644 --- a/src/finalisers/iife.js +++ b/src/finalisers/iife.js @@ -16,7 +16,7 @@ function setupNamespace ( keypath ) { .join( '\n' ) + '\n'; } -export default function iife ( bundle, magicString, { exportMode, indentString }, options ) { +export default function iife ( bundle, magicString, { exportMode, indentString, intro }, options ) { const globalNameMaker = getGlobalNameMaker( options.globals || blank(), bundle.onwarn ); const name = options.moduleName; @@ -35,29 +35,31 @@ export default function iife ( bundle, magicString, { exportMode, indentString } args.unshift( 'exports' ); } - const useStrict = options.useStrict !== false ? `'use strict';` : ``; + const useStrict = options.useStrict !== false ? `${indentString}'use strict';\n\n` : ``; - let intro = `(function (${args}) {\n`; - const outro = `\n\n}(${dependencies}));`; + let wrapperIntro = `(function (${args}) {\n${useStrict}`; + const wrapperOutro = `\n\n}(${dependencies}));`; if ( exportMode === 'default' ) { - intro = ( isNamespaced ? `this.` : `${bundle.varOrConst} ` ) + `${name} = ${intro}`; + wrapperIntro = ( isNamespaced ? `this.` : `${bundle.varOrConst} ` ) + `${name} = ${wrapperIntro}`; } if ( isNamespaced ) { - intro = setupNamespace( name ) + intro; + wrapperIntro = setupNamespace( name ) + wrapperIntro; } // var foo__default = 'default' in foo ? foo['default'] : foo; const interopBlock = getInteropBlock( bundle ); if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' ); - if ( useStrict ) magicString.prepend( useStrict + '\n\n' ); + + if ( intro ) magicString.prepend( intro ); + const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); if ( options.outro ) magicString.append( `\n${options.outro}` ); return magicString .indent( indentString ) - .prepend( intro ) - .append( outro ); + .prepend( wrapperIntro ) + .append( wrapperOutro ); } diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index 11631f5..a36db02 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -16,7 +16,9 @@ function setupNamespace ( name ) { .join( ', ' ); } -export default function umd ( bundle, magicString, { exportMode, indentString }, options ) { +const wrapperOutro = '\n\n})));'; + +export default function umd ( bundle, magicString, { exportMode, indentString, intro }, options ) { if ( exportMode !== 'none' && !options.moduleName ) { throw new Error( 'You must supply options.moduleName for UMD bundles' ); } @@ -54,7 +56,7 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, exports.noConflict = function() { global.${options.moduleName} = current; return exports; }; })()` : `(${defaultExport}factory(${globalDeps}))`; - const intro = + const wrapperIntro = `(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? ${cjsExport}factory(${cjsDeps.join( ', ' )}) : typeof define === 'function' && define.amd ? define(${amdParams}factory) : @@ -67,6 +69,8 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, const interopBlock = getInteropBlock( bundle ); if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' ); + if ( intro ) magicString.prepend( intro ); + const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); if ( exportMode === 'named' ) magicString.append( `\n\n${esModuleExport}` ); @@ -75,6 +79,6 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, return magicString .trim() .indent( indentString ) - .append( '\n\n})));' ) - .prepend( intro ); + .append( wrapperOutro ) + .prepend( wrapperIntro ); } diff --git a/test/form/intro-and-outro/_config.js b/test/form/intro-and-outro/_config.js index 843e554..410d586 100644 --- a/test/form/intro-and-outro/_config.js +++ b/test/form/intro-and-outro/_config.js @@ -3,6 +3,7 @@ module.exports = { options: { intro: '/* this is an intro */', outro: '/* this is an outro */', - moduleName: 'foo' + moduleName: 'foo', + external: [ 'external' ] } }; diff --git a/test/form/intro-and-outro/_expected/amd.js b/test/form/intro-and-outro/_expected/amd.js index 3c16c97..ca940e4 100644 --- a/test/form/intro-and-outro/_expected/amd.js +++ b/test/form/intro-and-outro/_expected/amd.js @@ -1,7 +1,10 @@ -define(function () { 'use strict'; +define(['external'], function (a) { 'use strict'; /* this is an intro */ - console.log( 'hello world' ); + var a__default = 'default' in a ? a['default'] : a; + + console.log( a__default ); + console.log( a.b ); var main = 42; diff --git a/test/form/intro-and-outro/_expected/cjs.js b/test/form/intro-and-outro/_expected/cjs.js index dde8f6b..6c68e67 100644 --- a/test/form/intro-and-outro/_expected/cjs.js +++ b/test/form/intro-and-outro/_expected/cjs.js @@ -1,7 +1,13 @@ 'use strict'; /* this is an intro */ -console.log( 'hello world' ); +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var a = require('external'); +var a__default = _interopDefault(a); + +console.log( a__default ); +console.log( a.b ); var main = 42; diff --git a/test/form/intro-and-outro/_expected/es.js b/test/form/intro-and-outro/_expected/es.js index 7459f70..2da2a74 100644 --- a/test/form/intro-and-outro/_expected/es.js +++ b/test/form/intro-and-outro/_expected/es.js @@ -1,5 +1,8 @@ /* this is an intro */ -console.log( 'hello world' ); +import a, { b } from 'external'; + +console.log( a ); +console.log( b ); var main = 42; diff --git a/test/form/intro-and-outro/_expected/iife.js b/test/form/intro-and-outro/_expected/iife.js index ef591fc..2c716d3 100644 --- a/test/form/intro-and-outro/_expected/iife.js +++ b/test/form/intro-and-outro/_expected/iife.js @@ -1,12 +1,15 @@ -var foo = (function () { +var foo = (function (a) { 'use strict'; /* this is an intro */ - console.log( 'hello world' ); + var a__default = 'default' in a ? a['default'] : a; + + console.log( a__default ); + console.log( a.b ); var main = 42; return main; /* this is an outro */ -}()); +}(a)); diff --git a/test/form/intro-and-outro/_expected/umd.js b/test/form/intro-and-outro/_expected/umd.js index 97b8e3e..232db4e 100644 --- a/test/form/intro-and-outro/_expected/umd.js +++ b/test/form/intro-and-outro/_expected/umd.js @@ -1,11 +1,14 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.foo = factory()); -}(this, (function () { 'use strict'; + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('external')) : + typeof define === 'function' && define.amd ? define(['external'], factory) : + (global.foo = factory(global.a)); +}(this, (function (a) { 'use strict'; /* this is an intro */ - console.log( 'hello world' ); + var a__default = 'default' in a ? a['default'] : a; + + console.log( a__default ); + console.log( a.b ); var main = 42; diff --git a/test/form/intro-and-outro/main.js b/test/form/intro-and-outro/main.js index 6054017..663ee99 100644 --- a/test/form/intro-and-outro/main.js +++ b/test/form/intro-and-outro/main.js @@ -1,3 +1,6 @@ -console.log( 'hello world' ); +import a, { b } from 'external' + +console.log( a ); +console.log( b ); export default 42; From 1d7c853ce6fabec207401a53d8210ea25f08d72e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 29 Aug 2016 16:20:40 -0400 Subject: [PATCH 174/331] prevent leaky state, always clone magic-string --- src/Module.js | 2 +- test/test.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Module.js b/src/Module.js index 11abeca..d015182 100644 --- a/src/Module.js +++ b/src/Module.js @@ -448,7 +448,7 @@ export default class Module { } render ( es ) { - const magicString = this.magicString; + const magicString = this.magicString.clone(); this.statements.forEach( statement => { if ( !statement.isIncluded ) { diff --git a/test/test.js b/test/test.js index 4eb73a6..92a88f0 100644 --- a/test/test.js +++ b/test/test.js @@ -290,10 +290,12 @@ describe( 'rollup', function () { } }, config.options ); - ( config.skip ? describe.skip : config.solo ? describe.only : describe)( dir, () => { + ( config.skip ? describe.skip : config.solo ? describe.only : describe )( dir, () => { + const promise = rollup.rollup( options ); + PROFILES.forEach( profile => { it( 'generates ' + profile.format, () => { - return rollup.rollup( options ).then( bundle => { + return promise.then( bundle => { const options = extend( {}, config.options, { dest: FORM + '/' + dir + '/_actual/' + profile.format + '.js', format: profile.format From 3817b74002b66f901bdf3cce64eff9bafc7dc1c7 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Mon, 29 Aug 2016 20:01:39 -0400 Subject: [PATCH 175/331] replace require kludge in runRollup.js (#706 - comment) --- bin/src/runRollup.js | 7 +++---- rollup.config.cli.js | 10 +++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index 270654f..70e028e 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -1,10 +1,9 @@ import { realpathSync } from 'fs'; +import { rollup } from 'rollup'; import relative from 'require-relative'; import handleError from './handleError'; import SOURCEMAPPING_URL from './sourceMappingUrl.js'; -const rollup = require( '../dist/rollup.js' ); // TODO make this an import, somehow - import { install as installSourcemapSupport } from 'source-map-support'; installSourcemapSupport(); @@ -58,7 +57,7 @@ export default function runRollup ( command ) { config = realpathSync( config ); } - rollup.rollup({ + rollup({ entry: config, onwarn: message => { if ( /Treating .+ as external dependency/.test( message ) ) return; @@ -217,7 +216,7 @@ function bundle ( options ) { handleError({ code: 'MISSING_INPUT_OPTION' }); } - return rollup.rollup( options ).then( bundle => { + return rollup( options ).then( bundle => { if ( options.dest ) { return bundle.write( options ); } diff --git a/rollup.config.cli.js b/rollup.config.cli.js index 95e8588..982f6b0 100644 --- a/rollup.config.cli.js +++ b/rollup.config.cli.js @@ -15,7 +15,7 @@ export default { buble(), commonjs({ include: 'node_modules/**', - namedExports: { 'chalk': [ 'red', 'cyan', 'grey' ] } + namedExports: { chalk: [ 'red', 'cyan', 'grey' ] } }), nodeResolve({ main: true @@ -25,6 +25,10 @@ export default { 'fs', 'path', 'module', - 'source-map-support' - ] + 'source-map-support', + 'rollup' + ], + paths: { + rollup: '../dist/rollup.js' + } }; From 32aa67583c543a474d1ccf4e0c98dbb9ae7a9ac2 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 30 Aug 2016 17:41:36 -0400 Subject: [PATCH 176/331] -> v0.34.11 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index acd43df..b63e3c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.34.11 + +* Prevent leaky state when `bundle` is reused ([#875](https://github.com/rollup/rollup/issues/875)) +* Ensure `intro` appears before interop block ([#880](https://github.com/rollup/rollup/issues/880)) + ## 0.34.10 * Allow custom `options.context` to replace top-level `this` ([#851](https://github.com/rollup/rollup/issues/851)) diff --git a/package.json b/package.json index 25191db..b63da00 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.10", + "version": "0.34.11", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From dab40ce0b98cb5fc5eb99e6c98b981373cd15e4f Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 30 Aug 2016 20:09:35 -0400 Subject: [PATCH 177/331] handle non-existent dir of import --- src/utils/defaults.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/utils/defaults.js b/src/utils/defaults.js index 08e16f2..c746a7f 100644 --- a/src/utils/defaults.js +++ b/src/utils/defaults.js @@ -7,11 +7,15 @@ export function load ( id ) { } function addJsExtensionIfNecessary ( file ) { - const name = basename( file ); - const files = readdirSync( dirname( file ) ); - - if ( ~files.indexOf( name ) && isFile( file ) ) return file; - if ( ~files.indexOf( `${name}.js` ) && isFile( `${file}.js` ) ) return `${file}.js`; + try { + const name = basename( file ); + const files = readdirSync( dirname( file ) ); + + if ( ~files.indexOf( name ) && isFile( file ) ) return file; + if ( ~files.indexOf( `${name}.js` ) && isFile( `${file}.js` ) ) return `${file}.js`; + } catch ( err ) { + // noop + } return null; } From 3de477137ac14e3cac5ae5350d2e4e3728dc4d37 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 31 Aug 2016 23:11:55 -0400 Subject: [PATCH 178/331] fix rollup-watch (#887) --- bin/src/runRollup.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index 70e028e..53a6231 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -1,5 +1,5 @@ import { realpathSync } from 'fs'; -import { rollup } from 'rollup'; +import * as rollup from 'rollup'; import relative from 'require-relative'; import handleError from './handleError'; import SOURCEMAPPING_URL from './sourceMappingUrl.js'; @@ -57,7 +57,7 @@ export default function runRollup ( command ) { config = realpathSync( config ); } - rollup({ + rollup.rollup({ entry: config, onwarn: message => { if ( /Treating .+ as external dependency/.test( message ) ) return; @@ -216,7 +216,7 @@ function bundle ( options ) { handleError({ code: 'MISSING_INPUT_OPTION' }); } - return rollup( options ).then( bundle => { + return rollup.rollup( options ).then( bundle => { if ( options.dest ) { return bundle.write( options ); } From 7ad9f6914d3a39fac01906fa1c2344c09f034c37 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 31 Aug 2016 23:12:25 -0400 Subject: [PATCH 179/331] -> v0.34.12 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b63e3c4..78270b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.34.12 + +* Fix `rollup --watch` ([#887](https://github.com/rollup/rollup/issues/887)) + ## 0.34.11 * Prevent leaky state when `bundle` is reused ([#875](https://github.com/rollup/rollup/issues/875)) diff --git a/package.json b/package.json index b63da00..fdd52f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.11", + "version": "0.34.12", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From a27ba30aa6ab400d0dde858e0f086cc554c5cbff Mon Sep 17 00:00:00 2001 From: Pat Cavit Date: Wed, 31 Aug 2016 23:24:19 -0700 Subject: [PATCH 180/331] Add options as second arg to .transformBundle Currently only piping through `format`, could certainly pass others if necessary. Maybe all should be brought through? --- src/Bundle.js | 2 +- src/utils/transformBundle.js | 4 ++-- test/form/transform-bundle-plugin-options/_config.js | 12 ++++++++++++ .../transform-bundle-plugin-options/_expected/amd.js | 1 + .../transform-bundle-plugin-options/_expected/cjs.js | 1 + .../transform-bundle-plugin-options/_expected/es.js | 1 + .../_expected/iife.js | 1 + .../transform-bundle-plugin-options/_expected/umd.js | 1 + test/form/transform-bundle-plugin-options/main.js | 1 + 9 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 test/form/transform-bundle-plugin-options/_config.js create mode 100644 test/form/transform-bundle-plugin-options/_expected/amd.js create mode 100644 test/form/transform-bundle-plugin-options/_expected/cjs.js create mode 100644 test/form/transform-bundle-plugin-options/_expected/es.js create mode 100644 test/form/transform-bundle-plugin-options/_expected/iife.js create mode 100644 test/form/transform-bundle-plugin-options/_expected/umd.js create mode 100644 test/form/transform-bundle-plugin-options/main.js diff --git a/src/Bundle.js b/src/Bundle.js index e458975..36d1675 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -347,7 +347,7 @@ export default class Bundle { let map = null; const bundleSourcemapChain = []; - code = transformBundle( code, this.plugins, bundleSourcemapChain ) + code = transformBundle( code, this.plugins, bundleSourcemapChain, options ) .replace( new RegExp( `\\/\\/#\\s+${SOURCEMAPPING_URL}=.+\\n?`, 'g' ), '' ); if ( options.sourceMap ) { diff --git a/src/utils/transformBundle.js b/src/utils/transformBundle.js index 027c7f0..8569ad5 100644 --- a/src/utils/transformBundle.js +++ b/src/utils/transformBundle.js @@ -1,13 +1,13 @@ import { decode } from 'sourcemap-codec'; -export default function transformBundle ( code, plugins, sourceMapChain ) { +export default function transformBundle ( code, plugins, sourceMapChain, options ) { return plugins.reduce( ( code, plugin ) => { if ( !plugin.transformBundle ) return code; let result; try { - result = plugin.transformBundle( code ); + result = plugin.transformBundle( code, { format : options.format } ); } catch ( err ) { err.plugin = plugin.name; err.message = `Error transforming bundle${plugin.name ? ` with '${plugin.name}' plugin` : ''}: ${err.message}`; diff --git a/test/form/transform-bundle-plugin-options/_config.js b/test/form/transform-bundle-plugin-options/_config.js new file mode 100644 index 0000000..417e38f --- /dev/null +++ b/test/form/transform-bundle-plugin-options/_config.js @@ -0,0 +1,12 @@ +module.exports = { + description: 'plugin .transformBundle gets passed options', + options: { + plugins: [ + { + transformBundle: function (code, options) { + return JSON.stringify(options); + } + } + ] + } +}; diff --git a/test/form/transform-bundle-plugin-options/_expected/amd.js b/test/form/transform-bundle-plugin-options/_expected/amd.js new file mode 100644 index 0000000..69904ec --- /dev/null +++ b/test/form/transform-bundle-plugin-options/_expected/amd.js @@ -0,0 +1 @@ +{"format":"amd"} diff --git a/test/form/transform-bundle-plugin-options/_expected/cjs.js b/test/form/transform-bundle-plugin-options/_expected/cjs.js new file mode 100644 index 0000000..72dd9eb --- /dev/null +++ b/test/form/transform-bundle-plugin-options/_expected/cjs.js @@ -0,0 +1 @@ +{"format":"cjs"} diff --git a/test/form/transform-bundle-plugin-options/_expected/es.js b/test/form/transform-bundle-plugin-options/_expected/es.js new file mode 100644 index 0000000..3a0913b --- /dev/null +++ b/test/form/transform-bundle-plugin-options/_expected/es.js @@ -0,0 +1 @@ +{"format":"es"} diff --git a/test/form/transform-bundle-plugin-options/_expected/iife.js b/test/form/transform-bundle-plugin-options/_expected/iife.js new file mode 100644 index 0000000..9bdbe7b --- /dev/null +++ b/test/form/transform-bundle-plugin-options/_expected/iife.js @@ -0,0 +1 @@ +{"format":"iife"} diff --git a/test/form/transform-bundle-plugin-options/_expected/umd.js b/test/form/transform-bundle-plugin-options/_expected/umd.js new file mode 100644 index 0000000..c7dad30 --- /dev/null +++ b/test/form/transform-bundle-plugin-options/_expected/umd.js @@ -0,0 +1 @@ +{"format":"umd"} diff --git a/test/form/transform-bundle-plugin-options/main.js b/test/form/transform-bundle-plugin-options/main.js new file mode 100644 index 0000000..934dee7 --- /dev/null +++ b/test/form/transform-bundle-plugin-options/main.js @@ -0,0 +1 @@ +console.log( 1 + 1 ); From 72e4637c3f26251d2f96a6fcbfd32d42926391d3 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Thu, 1 Sep 2016 08:36:21 -0400 Subject: [PATCH 181/331] missing changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78270b5..d50425a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 0.34.12 * Fix `rollup --watch` ([#887](https://github.com/rollup/rollup/issues/887)) +* Case-sensitive paths ([#862](https://github.com/rollup/rollup/issues/862)) ## 0.34.11 From 7fb7ee494d70cd9cab3555474b66c4b307a6dcb2 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 1 Sep 2016 09:45:26 -0400 Subject: [PATCH 182/331] -> v0.34.13 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d50425a..3739a73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.34.13 + +* Pass `{ format }` through to `transformBundle` ([#867](https://github.com/rollup/rollup/issues/867)) + ## 0.34.12 * Fix `rollup --watch` ([#887](https://github.com/rollup/rollup/issues/887)) diff --git a/package.json b/package.json index fdd52f6..7845b4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.12", + "version": "0.34.13", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 62503515f3d94d89670472c36891d77019f20b26 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Mon, 5 Sep 2016 00:01:54 +0300 Subject: [PATCH 183/331] Fix --help format description --- bin/src/help.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/src/help.md b/bin/src/help.md index cf2ef8b..58482d5 100644 --- a/bin/src/help.md +++ b/bin/src/help.md @@ -12,7 +12,7 @@ Basic options: -w, --watch Watch files in bundle and rebuild on changes -i, --input Input (alternative to ) -o, --output Output (if absent, prints to stdout) --f, --format [es6] Type of output (amd, cjs, es6, iife, umd) +-f, --format [es] Type of output (amd, cjs, es, iife, umd) -e, --external Comma-separate list of module IDs to exclude -g, --globals Comma-separate list of `module ID:Global` pairs Any module IDs defined here are added to external From 173cfc0df75e84ed4303887741d18831ed0076c8 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 6 Sep 2016 08:33:37 -0400 Subject: [PATCH 184/331] rewrite --- .eslintrc | 6 +- package.json | 4 +- rollup.config.js | 5 +- src/Bundle.js | 77 ++- src/Declaration.js | 242 ++------- src/Module.js | 494 +++--------------- src/Reference.js | 30 -- src/Statement.js | 160 ------ src/ast/Node.js | 92 ++++ src/ast/Scope.js | 52 -- src/ast/attachScopes.js | 78 --- src/ast/conditions.js | 38 -- src/ast/create.js | 7 - src/ast/enhance.js | 63 +++ src/ast/isFunctionDeclaration.js | 6 - src/ast/keys.js | 3 + src/ast/modifierNodes.js | 19 - src/ast/nodes/ArrayExpression.js | 8 + src/ast/nodes/ArrowFunctionExpression.js | 35 ++ src/ast/nodes/AssignmentExpression.js | 45 ++ src/ast/nodes/BinaryExpression.js | 38 ++ src/ast/nodes/BlockStatement.js | 71 +++ src/ast/nodes/CallExpression.js | 40 ++ src/ast/nodes/ClassDeclaration.js | 40 ++ src/ast/nodes/ClassExpression.js | 26 + src/ast/nodes/ConditionalExpression.js | 65 +++ src/ast/nodes/ExportAllDeclaration.js | 11 + src/ast/nodes/ExportDefaultDeclaration.js | 124 +++++ src/ast/nodes/ExportNamedDeclaration.js | 25 + src/ast/nodes/ExpressionStatement.js | 16 + src/ast/nodes/FunctionDeclaration.js | 53 ++ src/ast/nodes/FunctionExpression.js | 21 + src/ast/nodes/Identifier.js | 35 ++ src/ast/nodes/IfStatement.js | 73 +++ src/ast/nodes/ImportDeclaration.js | 16 + src/ast/nodes/Literal.js | 17 + src/ast/nodes/MemberExpression.js | 74 +++ src/ast/nodes/NewExpression.js | 8 + src/ast/nodes/ObjectExpression.js | 8 + src/ast/nodes/ParenthesizedExpression.js | 11 + src/ast/nodes/ReturnStatement.js | 7 + src/ast/nodes/TemplateLiteral.js | 7 + src/ast/nodes/ThisExpression.js | 20 + src/ast/nodes/UnaryExpression.js | 34 ++ src/ast/nodes/UpdateExpression.js | 35 ++ src/ast/nodes/VariableDeclaration.js | 86 +++ src/ast/nodes/VariableDeclarator.js | 89 ++++ src/ast/nodes/index.js | 63 +++ src/ast/nodes/shared/callHasEffects.js | 65 +++ .../shared/disallowIllegalReassignment.js | 28 + src/ast/nodes/shared/isUsedByBundle.js | 48 ++ .../nodes/shared}/pureFunctions.js | 0 src/ast/scopes/BundleScope.js | 40 ++ src/ast/scopes/ModuleScope.js | 47 ++ src/ast/scopes/Scope.js | 91 ++++ src/ast/{ => utils}/extractNames.js | 0 src/ast/{ => utils}/flatten.js | 0 src/ast/{ => utils}/isReference.js | 0 src/ast/values.js | 8 + src/finalisers/es.js | 8 +- src/finalisers/shared/getExportBlock.js | 6 +- src/utils/run.js | 119 ----- .../_config.js | 2 +- test/form/external-imports/_expected/es.js | 4 +- .../_expected/es.js | 5 +- .../namespace-optimization/_expected/amd.js | 2 +- .../namespace-optimization/_expected/cjs.js | 2 +- .../namespace-optimization/_expected/es.js | 2 +- .../namespace-optimization/_expected/iife.js | 2 +- .../namespace-optimization/_expected/umd.js | 4 +- test/form/namespace-optimization/main.js | 2 +- test/form/no-treeshake/_expected/es.js | 3 +- .../_expected/amd.js | 2 +- .../_expected/cjs.js | 2 +- .../_expected/es.js | 2 +- .../_expected/iife.js | 2 +- .../_expected/umd.js | 4 +- test/form/side-effect-k/_expected/amd.js | 5 +- test/form/side-effect-k/_expected/cjs.js | 5 +- test/form/side-effect-k/_expected/es.js | 5 +- test/form/side-effect-k/_expected/iife.js | 5 +- test/form/side-effect-k/_expected/umd.js | 5 +- test/form/skips-dead-branches-b/_config.js | 3 + .../skips-dead-branches-b/_expected/amd.js | 9 + .../skips-dead-branches-b/_expected/cjs.js | 7 + .../skips-dead-branches-b/_expected/es.js | 5 + .../skips-dead-branches-b/_expected/iife.js | 10 + .../skips-dead-branches-b/_expected/umd.js | 13 + .../skips-dead-branches-b/main.js | 0 test/form/skips-dead-branches-c/_config.js | 3 + .../skips-dead-branches-c/_expected/amd.js | 9 + .../skips-dead-branches-c/_expected/cjs.js | 7 + .../skips-dead-branches-c/_expected/es.js | 5 + .../skips-dead-branches-c/_expected/iife.js | 10 + .../skips-dead-branches-c/_expected/umd.js | 13 + .../skips-dead-branches-c/main.js | 0 test/form/skips-dead-branches-d/_config.js | 3 + .../skips-dead-branches-d/_expected/amd.js | 9 + .../skips-dead-branches-d/_expected/cjs.js | 7 + .../skips-dead-branches-d/_expected/es.js | 5 + .../skips-dead-branches-d/_expected/iife.js | 10 + .../skips-dead-branches-d/_expected/umd.js | 13 + .../skips-dead-branches-d/main.js | 0 test/form/skips-dead-branches-e/_config.js | 3 + .../skips-dead-branches-e/_expected/amd.js | 9 + .../skips-dead-branches-e/_expected/cjs.js | 7 + .../skips-dead-branches-e/_expected/es.js | 5 + .../skips-dead-branches-e/_expected/iife.js | 10 + .../skips-dead-branches-e/_expected/umd.js | 13 + .../skips-dead-branches-e/main.js | 0 test/form/skips-dead-branches-f/_config.js | 3 + .../skips-dead-branches-f/_expected/amd.js | 9 + .../skips-dead-branches-f/_expected/cjs.js | 7 + .../skips-dead-branches-f/_expected/es.js | 5 + .../skips-dead-branches-f/_expected/iife.js | 10 + .../skips-dead-branches-f/_expected/umd.js | 13 + .../skips-dead-branches-f/main.js | 0 test/form/skips-dead-branches-g/_config.js | 3 + .../skips-dead-branches-g/_expected/amd.js | 10 + .../skips-dead-branches-g/_expected/cjs.js | 8 + .../skips-dead-branches-g/_expected/es.js | 6 + .../skips-dead-branches-g/_expected/iife.js | 11 + .../skips-dead-branches-g/_expected/umd.js | 14 + test/form/skips-dead-branches-g/main.js | 8 + test/form/skips-dead-branches/_config.js | 3 + .../form/skips-dead-branches/_expected/amd.js | 9 + .../form/skips-dead-branches/_expected/cjs.js | 7 + test/form/skips-dead-branches/_expected/es.js | 5 + .../skips-dead-branches/_expected/iife.js | 10 + .../form/skips-dead-branches/_expected/umd.js | 13 + .../skips-dead-branches/main.js | 0 .../string-indentation-b/_expected/amd.js | 3 +- .../string-indentation-b/_expected/cjs.js | 3 +- .../form/string-indentation-b/_expected/es.js | 3 +- .../string-indentation-b/_expected/iife.js | 3 +- .../string-indentation-b/_expected/umd.js | 3 +- .../function/consistent-renaming-b/_config.js | 2 +- .../consistent-renaming-b/altdir/two.js | 3 +- .../consistent-renaming-b/subdir/one.js | 2 +- .../consistent-renaming-b/subdir/two.js | 3 +- test/function/cycles-pathological/_config.js | 13 +- .../iife-strong-dependencies/_config.js | 13 +- .../_config.js | 2 +- test/function/no-imports/_config.js | 2 +- .../function/reassign-import-fails/_config.js | 2 +- .../function/skips-dead-branches-b/_config.js | 8 - .../function/skips-dead-branches-c/_config.js | 8 - .../function/skips-dead-branches-d/_config.js | 8 - .../function/skips-dead-branches-e/_config.js | 8 - .../function/skips-dead-branches-f/_config.js | 8 - .../function/skips-dead-branches-g/_config.js | 9 - test/function/skips-dead-branches-g/main.js | 6 - test/function/skips-dead-branches/_config.js | 8 - test/function/tracks-alias-mutations/bar.js | 6 +- test/test.js | 13 +- 155 files changed, 2285 insertions(+), 1298 deletions(-) delete mode 100644 src/Reference.js delete mode 100644 src/Statement.js create mode 100644 src/ast/Node.js delete mode 100644 src/ast/Scope.js delete mode 100644 src/ast/attachScopes.js delete mode 100644 src/ast/conditions.js delete mode 100644 src/ast/create.js create mode 100644 src/ast/enhance.js delete mode 100644 src/ast/isFunctionDeclaration.js create mode 100644 src/ast/keys.js delete mode 100644 src/ast/modifierNodes.js create mode 100644 src/ast/nodes/ArrayExpression.js create mode 100644 src/ast/nodes/ArrowFunctionExpression.js create mode 100644 src/ast/nodes/AssignmentExpression.js create mode 100644 src/ast/nodes/BinaryExpression.js create mode 100644 src/ast/nodes/BlockStatement.js create mode 100644 src/ast/nodes/CallExpression.js create mode 100644 src/ast/nodes/ClassDeclaration.js create mode 100644 src/ast/nodes/ClassExpression.js create mode 100644 src/ast/nodes/ConditionalExpression.js create mode 100644 src/ast/nodes/ExportAllDeclaration.js create mode 100644 src/ast/nodes/ExportDefaultDeclaration.js create mode 100644 src/ast/nodes/ExportNamedDeclaration.js create mode 100644 src/ast/nodes/ExpressionStatement.js create mode 100644 src/ast/nodes/FunctionDeclaration.js create mode 100644 src/ast/nodes/FunctionExpression.js create mode 100644 src/ast/nodes/Identifier.js create mode 100644 src/ast/nodes/IfStatement.js create mode 100644 src/ast/nodes/ImportDeclaration.js create mode 100644 src/ast/nodes/Literal.js create mode 100644 src/ast/nodes/MemberExpression.js create mode 100644 src/ast/nodes/NewExpression.js create mode 100644 src/ast/nodes/ObjectExpression.js create mode 100644 src/ast/nodes/ParenthesizedExpression.js create mode 100644 src/ast/nodes/ReturnStatement.js create mode 100644 src/ast/nodes/TemplateLiteral.js create mode 100644 src/ast/nodes/ThisExpression.js create mode 100644 src/ast/nodes/UnaryExpression.js create mode 100644 src/ast/nodes/UpdateExpression.js create mode 100644 src/ast/nodes/VariableDeclaration.js create mode 100644 src/ast/nodes/VariableDeclarator.js create mode 100644 src/ast/nodes/index.js create mode 100644 src/ast/nodes/shared/callHasEffects.js create mode 100644 src/ast/nodes/shared/disallowIllegalReassignment.js create mode 100644 src/ast/nodes/shared/isUsedByBundle.js rename src/{utils => ast/nodes/shared}/pureFunctions.js (100%) create mode 100644 src/ast/scopes/BundleScope.js create mode 100644 src/ast/scopes/ModuleScope.js create mode 100644 src/ast/scopes/Scope.js rename src/ast/{ => utils}/extractNames.js (100%) rename src/ast/{ => utils}/flatten.js (100%) rename src/ast/{ => utils}/isReference.js (100%) create mode 100644 src/ast/values.js delete mode 100644 src/utils/run.js create mode 100644 test/form/skips-dead-branches-b/_config.js create mode 100644 test/form/skips-dead-branches-b/_expected/amd.js create mode 100644 test/form/skips-dead-branches-b/_expected/cjs.js create mode 100644 test/form/skips-dead-branches-b/_expected/es.js create mode 100644 test/form/skips-dead-branches-b/_expected/iife.js create mode 100644 test/form/skips-dead-branches-b/_expected/umd.js rename test/{function => form}/skips-dead-branches-b/main.js (100%) create mode 100644 test/form/skips-dead-branches-c/_config.js create mode 100644 test/form/skips-dead-branches-c/_expected/amd.js create mode 100644 test/form/skips-dead-branches-c/_expected/cjs.js create mode 100644 test/form/skips-dead-branches-c/_expected/es.js create mode 100644 test/form/skips-dead-branches-c/_expected/iife.js create mode 100644 test/form/skips-dead-branches-c/_expected/umd.js rename test/{function => form}/skips-dead-branches-c/main.js (100%) create mode 100644 test/form/skips-dead-branches-d/_config.js create mode 100644 test/form/skips-dead-branches-d/_expected/amd.js create mode 100644 test/form/skips-dead-branches-d/_expected/cjs.js create mode 100644 test/form/skips-dead-branches-d/_expected/es.js create mode 100644 test/form/skips-dead-branches-d/_expected/iife.js create mode 100644 test/form/skips-dead-branches-d/_expected/umd.js rename test/{function => form}/skips-dead-branches-d/main.js (100%) create mode 100644 test/form/skips-dead-branches-e/_config.js create mode 100644 test/form/skips-dead-branches-e/_expected/amd.js create mode 100644 test/form/skips-dead-branches-e/_expected/cjs.js create mode 100644 test/form/skips-dead-branches-e/_expected/es.js create mode 100644 test/form/skips-dead-branches-e/_expected/iife.js create mode 100644 test/form/skips-dead-branches-e/_expected/umd.js rename test/{function => form}/skips-dead-branches-e/main.js (100%) create mode 100644 test/form/skips-dead-branches-f/_config.js create mode 100644 test/form/skips-dead-branches-f/_expected/amd.js create mode 100644 test/form/skips-dead-branches-f/_expected/cjs.js create mode 100644 test/form/skips-dead-branches-f/_expected/es.js create mode 100644 test/form/skips-dead-branches-f/_expected/iife.js create mode 100644 test/form/skips-dead-branches-f/_expected/umd.js rename test/{function => form}/skips-dead-branches-f/main.js (100%) create mode 100644 test/form/skips-dead-branches-g/_config.js create mode 100644 test/form/skips-dead-branches-g/_expected/amd.js create mode 100644 test/form/skips-dead-branches-g/_expected/cjs.js create mode 100644 test/form/skips-dead-branches-g/_expected/es.js create mode 100644 test/form/skips-dead-branches-g/_expected/iife.js create mode 100644 test/form/skips-dead-branches-g/_expected/umd.js create mode 100644 test/form/skips-dead-branches-g/main.js create mode 100644 test/form/skips-dead-branches/_config.js create mode 100644 test/form/skips-dead-branches/_expected/amd.js create mode 100644 test/form/skips-dead-branches/_expected/cjs.js create mode 100644 test/form/skips-dead-branches/_expected/es.js create mode 100644 test/form/skips-dead-branches/_expected/iife.js create mode 100644 test/form/skips-dead-branches/_expected/umd.js rename test/{function => form}/skips-dead-branches/main.js (100%) delete mode 100644 test/function/skips-dead-branches-b/_config.js delete mode 100644 test/function/skips-dead-branches-c/_config.js delete mode 100644 test/function/skips-dead-branches-d/_config.js delete mode 100644 test/function/skips-dead-branches-e/_config.js delete mode 100644 test/function/skips-dead-branches-f/_config.js delete mode 100644 test/function/skips-dead-branches-g/_config.js delete mode 100644 test/function/skips-dead-branches-g/main.js delete mode 100644 test/function/skips-dead-branches/_config.js diff --git a/.eslintrc b/.eslintrc index cab1314..9fded74 100644 --- a/.eslintrc +++ b/.eslintrc @@ -27,7 +27,11 @@ "browser": true, "node": true }, - "extends": "eslint:recommended", + "extends": [ + "eslint:recommended", + "plugin:import/errors", + "plugin:import/warnings" + ], "parserOptions": { "ecmaVersion": 6, "sourceType": "module" diff --git a/package.json b/package.json index 7845b4c..0eabb8c 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "scripts": { "pretest": "npm run build && npm run build:cli", "test": "mocha", + "test:quick": "rollup -c && mocha", "pretest-coverage": "npm run build", "test-coverage": "rm -rf coverage/* && istanbul cover --report json node_modules/.bin/_mocha -- -u exports -R spec test/test.js", "posttest-coverage": "remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.json -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.lcov -t lcovonly -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped -t html -b dist", @@ -48,8 +49,9 @@ "buble": "^0.12.5", "chalk": "^1.1.3", "codecov.io": "^0.1.6", - "console-group": "^0.2.1", + "console-group": "^0.3.1", "eslint": "^2.13.0", + "eslint-plugin-import": "^1.14.0", "estree-walker": "^0.2.1", "istanbul": "^0.4.3", "magic-string": "^0.15.2", diff --git a/rollup.config.js b/rollup.config.js index 7847ff7..a8ac2c8 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -22,7 +22,10 @@ export default { entry: 'src/rollup.js', plugins: [ buble({ - include: [ 'src/**', 'node_modules/acorn/**' ] + include: [ 'src/**', 'node_modules/acorn/**' ], + target: { + node: 4 + } }), nodeResolve({ diff --git a/src/Bundle.js b/src/Bundle.js index 36d1675..9e5f010 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -17,6 +17,7 @@ import collapseSourcemaps from './utils/collapseSourcemaps.js'; import SOURCEMAPPING_URL from './utils/sourceMappingURL.js'; import callIfFunction from './utils/callIfFunction.js'; import { dirname, isRelative, isAbsolute, normalize, relative, resolve } from './utils/path.js'; +import BundleScope from './ast/scopes/BundleScope.js'; export default class Bundle { constructor ( options ) { @@ -59,14 +60,17 @@ export default class Bundle { ( id => options.paths.hasOwnProperty( id ) ? options.paths[ id ] : this.getPathRelativeToEntryDirname( id ) ) : id => this.getPathRelativeToEntryDirname( id ); + this.scope = new BundleScope(); + // TODO strictly speaking, this only applies with non-ES6, non-default-only bundles + [ 'module', 'exports', '_interopDefault' ].forEach( name => { + this.scope.findDeclaration( name ); // creates global declaration as side-effect + }); + this.moduleById = new Map(); this.modules = []; - this.externalModules = []; - this.internalNamespaces = []; this.context = String( options.context ); - this.assumedGlobals = blank(); if ( typeof options.external === 'function' ) { this.isExternal = options.external; @@ -77,11 +81,10 @@ export default class Bundle { this.onwarn = options.onwarn || makeOnwarn(); - // TODO strictly speaking, this only applies with non-ES6, non-default-only bundles - [ 'module', 'exports', '_interopDefault' ].forEach( global => this.assumedGlobals[ global ] = true ); - this.varOrConst = options.preferConst ? 'const' : 'var'; this.acornOptions = options.acorn || {}; + + this.dependentExpressions = []; } build () { @@ -100,7 +103,6 @@ export default class Bundle { // Phase 2 – binding. We link references to their declarations // to generate a complete picture of the bundle this.modules.forEach( module => module.bindImportSpecifiers() ); - this.modules.forEach( module => module.bindAliases() ); this.modules.forEach( module => module.bindReferences() ); // Phase 3 – marking. We 'run' each statement to see which ones @@ -109,21 +111,47 @@ export default class Bundle { // mark all export statements entryModule.getExports().forEach( name => { const declaration = entryModule.traceExport( name ); + declaration.exportName = name; + declaration.activate(); - declaration.use(); + if ( declaration.isNamespace ) { + declaration.needsNamespaceBlock = true; + } }); // mark statements that should appear in the bundle - let settled = false; - while ( !settled ) { - settled = true; - + if ( this.treeshake ) { this.modules.forEach( module => { - if ( module.run( this.treeshake ) ) settled = false; + module.run(); }); + + let settled = false; + while ( !settled ) { + settled = true; + + for ( const expression of this.dependentExpressions ) { + if ( expression.isUsedByBundle() ) { + const statement = expression.findParent( /ExpressionStatement/ ); + + if ( statement && !statement.ran ) { + settled = false; + statement.run( statement.findScope() ); + } + } + } + } } + // let settled = false; + // while ( !settled ) { + // settled = true; + // + // this.modules.forEach( module => { + // if ( module.run( this.treeshake ) ) settled = false; + // }); + // } + // Phase 4 – final preparation. We order the modules with an // enhanced topological sort that accounts for cycles, then // ensure that names are deconflicted throughout the bundle @@ -136,7 +164,7 @@ export default class Bundle { const used = blank(); // ensure no conflicts with globals - keys( this.assumedGlobals ).forEach( name => used[ name ] = 1 ); + keys( this.scope.declarations ).forEach( name => used[ name ] = 1 ); function getSafeName ( name ) { while ( used[ name ] ) { @@ -147,27 +175,33 @@ export default class Bundle { return name; } + const toDeshadow = new Map(); + this.externalModules.forEach( module => { - module.name = getSafeName( module.name ); + const safeName = getSafeName( module.name ); + toDeshadow.set( safeName, true ); + module.name = safeName; // ensure we don't shadow named external imports, if // we're creating an ES6 bundle forOwn( module.declarations, ( declaration, name ) => { - declaration.setSafeName( getSafeName( name ) ); + const safeName = getSafeName( name ); + toDeshadow.set( safeName, true ); + declaration.setSafeName( safeName ); }); }); this.modules.forEach( module => { - forOwn( module.declarations, ( declaration, originalName ) => { - if ( declaration.isGlobal ) return; - - if ( originalName === 'default' ) { - if ( declaration.original && !declaration.original.isReassigned ) return; + forOwn( module.scope.declarations, ( declaration ) => { + if ( declaration.isDefault && declaration.declaration.id ) { + return; } declaration.name = getSafeName( declaration.name ); }); }); + + this.scope.deshadow( toDeshadow ); } fetchModule ( id, importer ) { @@ -306,6 +340,7 @@ export default class Bundle { this.orderedModules.forEach( module => { const source = module.render( format === 'es' ); + if ( source.toString().length ) { magicString.addSource( source ); usedModules.push( module ); diff --git a/src/Declaration.js b/src/Declaration.js index c383081..8d0934e 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -1,35 +1,24 @@ import { blank, forOwn, keys } from './utils/object.js'; import makeLegalIdentifier from './utils/makeLegalIdentifier.js'; -import run from './utils/run.js'; -import { SyntheticReference } from './Reference.js'; - -const use = alias => alias.use(); +import { UNKNOWN } from './ast/values.js'; export default class Declaration { - constructor ( node, isParam, statement ) { - if ( node ) { - if ( node.type === 'FunctionDeclaration' ) { - this.isFunctionDeclaration = true; - this.functionNode = node; - } else if ( node.type === 'VariableDeclarator' && node.init && /FunctionExpression/.test( node.init.type ) ) { - this.isFunctionDeclaration = true; - this.functionNode = node.init; - } - } + constructor ( node, isParam ) { + this.node = node; - this.statement = statement; this.name = node.id ? node.id.name : node.name; this.exportName = null; this.isParam = isParam; this.isReassigned = false; - this.aliases = []; - - this.isUsed = false; } - addAlias ( declaration ) { - this.aliases.push( declaration ); + activate () { + if ( this.activated ) return; + this.activated = true; + + if ( this.isParam ) return; + this.node.activate(); } addReference ( reference ) { @@ -48,142 +37,15 @@ export default class Declaration { return `exports.${this.exportName}`; } - - run ( strongDependencies ) { - if ( this.tested ) return this.hasSideEffects; - - - if ( !this.functionNode ) { - this.hasSideEffects = true; // err on the side of caution. TODO handle unambiguous `var x; x = y => z` cases - } else { - if ( this.running ) return true; // short-circuit infinite loop - this.running = true; - - this.hasSideEffects = run( this.functionNode.body, this.functionNode._scope, this.statement, strongDependencies, false ); - - this.running = false; - } - - this.tested = true; - return this.hasSideEffects; - } - - use () { - if ( this.isUsed ) return; - - this.isUsed = true; - if ( this.statement ) this.statement.mark(); - - this.aliases.forEach( use ); - } -} - -export class SyntheticDefaultDeclaration { - constructor ( node, statement, name ) { - this.node = node; - this.statement = statement; - this.name = name; - - this.original = null; - this.exportName = null; - this.aliases = []; - } - - addAlias ( declaration ) { - this.aliases.push( declaration ); - } - - addReference ( reference ) { - // Bind the reference to `this` declaration. - reference.declaration = this; - - // Don't change the name to `default`; it's not a valid identifier name. - if ( reference.name === 'default' ) return; - - this.name = reference.name; - } - - bind ( declaration ) { - this.original = declaration; - } - - render () { - return !this.original || this.original.isReassigned ? - this.name : - this.original.render(); - } - - run ( strongDependencies ) { - if ( this.original ) { - return this.original.run( strongDependencies ); - } - - let declaration = this.node.declaration; - while ( declaration.type === 'ParenthesizedExpression' ) declaration = declaration.expression; - - if ( /FunctionExpression/.test( declaration.type ) ) { - return run( declaration.body, this.statement.scope, this.statement, strongDependencies, false ); - } - - // otherwise assume the worst - return true; - } - - use () { - this.isUsed = true; - this.statement.mark(); - - if ( this.original ) this.original.use(); - - this.aliases.forEach( use ); - } -} - -export class SyntheticGlobalDeclaration { - constructor ( name ) { - this.name = name; - this.isExternal = true; - this.isGlobal = true; - this.isReassigned = false; - - this.aliases = []; - - this.isUsed = false; - } - - addAlias ( declaration ) { - this.aliases.push( declaration ); - } - - addReference ( reference ) { - reference.declaration = this; - if ( reference.isReassignment ) this.isReassigned = true; - } - - render () { - return this.name; - } - - run () { - return true; - } - - use () { - if ( this.isUsed ) return; - this.isUsed = true; - - this.aliases.forEach( use ); - } } export class SyntheticNamespaceDeclaration { constructor ( module ) { this.isNamespace = true; this.module = module; - this.name = null; + this.name = module.basename(); this.needsNamespaceBlock = false; - this.aliases = []; this.originals = blank(); module.getExports().forEach( name => { @@ -191,70 +53,40 @@ export class SyntheticNamespaceDeclaration { }); } - addAlias ( declaration ) { - this.aliases.push( declaration ); - } + activate () { + this.needsNamespaceBlock = true; - addReference ( reference ) { - // if we have e.g. `foo.bar`, we can optimise - // the reference by pointing directly to `bar` - if ( reference.parts.length ) { - const ref = reference.parts.shift(); - reference.name = ref.name; - reference.end = ref.end; - - const original = this.originals[ reference.name ]; - - // throw with an informative error message if the reference doesn't exist. - if ( !original ) { - this.module.bundle.onwarn( `Export '${reference.name}' is not defined by '${this.module.id}'` ); - reference.isUndefined = true; - return; - } + // add synthetic references, in case of chained + // namespace imports + forOwn( this.originals, original => { + original.activate(); + }); + } - original.addReference( reference ); - return; - } + addReference ( node ) { + this.name = node.name; + } - // otherwise we're accessing the namespace directly, - // which means we need to mark all of this module's - // exports and render a namespace block in the bundle - if ( !this.needsNamespaceBlock ) { - this.needsNamespaceBlock = true; - this.module.bundle.internalNamespaces.push( this ); - - // add synthetic references, in case of chained - // namespace imports - forOwn( this.originals, ( original, name ) => { - original.addReference( new SyntheticReference( name ) ); - }); - } + gatherPossibleValues ( values ) { + values.add( UNKNOWN ); + } - reference.declaration = this; - this.name = reference.name; + getName () { + return this.name; } - renderBlock ( indentString ) { + renderBlock ( es, indentString ) { const members = keys( this.originals ).map( name => { const original = this.originals[ name ]; if ( original.isReassigned ) { - return `${indentString}get ${name} () { return ${original.render()}; }`; + return `${indentString}get ${name} () { return ${original.getName( es )}; }`; } - return `${indentString}${name}: ${original.render()}`; + return `${indentString}${name}: ${original.getName( es )}`; }); - return `${this.module.bundle.varOrConst} ${this.render()} = Object.freeze({\n${members.join( ',\n' )}\n});\n\n`; - } - - render () { - return this.name; - } - - use () { - forOwn( this.originals, use ); - this.aliases.forEach( use ); + return `${this.module.bundle.varOrConst} ${this.getName( es )} = Object.freeze({\n${members.join( ',\n' )}\n});\n\n`; } } @@ -265,10 +97,12 @@ export class ExternalDeclaration { this.safeName = null; this.isExternal = true; + this.activated = true; + this.isNamespace = name === '*'; } - addAlias () { + activate () { // noop } @@ -280,7 +114,7 @@ export class ExternalDeclaration { } } - render ( es ) { + getName ( es ) { if ( this.name === '*' ) { return this.module.name; } @@ -294,15 +128,7 @@ export class ExternalDeclaration { return es ? this.safeName : `${this.module.name}.${this.name}`; } - run () { - return true; - } - setSafeName ( name ) { this.safeName = name; } - - use () { - // noop? - } } diff --git a/src/Module.js b/src/Module.js index d015182..d6a418f 100644 --- a/src/Module.js +++ b/src/Module.js @@ -1,20 +1,30 @@ import { parse } from 'acorn/src/index.js'; import MagicString from 'magic-string'; -import { walk } from 'estree-walker'; -import Statement from './Statement.js'; import { assign, blank, keys } from './utils/object.js'; import { basename, extname } from './utils/path.js'; import getLocation from './utils/getLocation.js'; import makeLegalIdentifier from './utils/makeLegalIdentifier.js'; import SOURCEMAPPING_URL from './utils/sourceMappingURL.js'; -import { - SyntheticDefaultDeclaration, - SyntheticGlobalDeclaration, - SyntheticNamespaceDeclaration -} from './Declaration.js'; -import { isFalsy, isTruthy } from './ast/conditions.js'; -import { emptyBlockStatement } from './ast/create.js'; -import extractNames from './ast/extractNames.js'; +import { SyntheticNamespaceDeclaration } from './Declaration.js'; +import extractNames from './ast/utils/extractNames.js'; +import enhance from './ast/enhance.js'; +import ModuleScope from './ast/scopes/ModuleScope.js'; + +function tryParse ( code, comments, acornOptions, id ) { + try { + return parse( code, assign({ + ecmaVersion: 6, + sourceType: 'module', + onComment: ( block, text, start, end ) => comments.push({ block, text, start, end }), + preserveParens: true + }, acornOptions )); + } catch ( err ) { + err.code = 'PARSE_ERROR'; + err.file = id; // see above - not necessarily true, but true enough + err.message += ` in ${id}`; + throw err; + } +} export default class Module { constructor ({ id, code, originalCode, originalSourceMap, ast, sourceMapChain, resolvedIds, bundle }) { @@ -23,6 +33,9 @@ export default class Module { this.originalSourceMap = originalSourceMap; this.sourceMapChain = sourceMapChain; + this.comments = []; + this.ast = ast || tryParse( code, this.comments, bundle.acornOptions, id ); // TODO what happens to comments if AST is provided? + this.bundle = bundle; this.id = id; this.excludeFromSourcemap = /\0/.test( id ); @@ -55,18 +68,15 @@ export default class Module { this.magicString.remove( match.index, match.index + match[0].length ); } - this.comments = []; - this.ast = ast; - this.statements = this.parse(); - this.declarations = blank(); + this.type === 'Module'; // TODO only necessary so that Scope knows this should be treated as a function scope... messy + this.scope = new ModuleScope( this ); this.analyse(); this.strongDependencies = []; } - addExport ( statement ) { - const node = statement.node; + addExport ( node ) { const source = node.source && node.source.value; // export { name } from './other.js' @@ -114,7 +124,7 @@ export default class Module { }; // create a synthetic declaration - this.declarations.default = new SyntheticDefaultDeclaration( node, statement, identifier || this.basename() ); + //this.declarations.default = new SyntheticDefaultDeclaration( node, identifier || this.basename() ); } // export var { foo, bar } = ... @@ -156,8 +166,7 @@ export default class Module { } } - addImport ( statement ) { - const node = statement.node; + addImport ( node ) { const source = node.source.value; if ( !~this.sources.indexOf( source ) ) this.sources.push( source ); @@ -181,17 +190,21 @@ export default class Module { } analyse () { + enhance( this.ast, this, this.comments ); + // discover this module's imports and exports - this.statements.forEach( statement => { - if ( statement.isImportDeclaration ) this.addImport( statement ); - else if ( statement.isExportDeclaration ) this.addExport( statement ); + let lastNode; - statement.firstPass(); + for ( const node of this.ast.body ) { + if ( node.isImportDeclaration ) { + this.addImport( node ); + } else if ( node.isExportDeclaration ) { + this.addExport( node ); + } - statement.scope.eachDeclaration( ( name, declaration ) => { - this.declarations[ name ] = declaration; - }); - }); + if ( lastNode ) lastNode.next = node.leadingCommentStart || node.start; + lastNode = node; + } } basename () { @@ -201,27 +214,6 @@ export default class Module { return makeLegalIdentifier( ext ? base.slice( 0, -ext.length ) : base ); } - bindAliases () { - keys( this.declarations ).forEach( name => { - if ( name === '*' ) return; - - const declaration = this.declarations[ name ]; - const statement = declaration.statement; - - if ( !statement || statement.node.type !== 'VariableDeclaration' ) return; - - const init = statement.node.declarations[0].init; - if ( !init || init.type === 'FunctionExpression' ) return; - - statement.references.forEach( reference => { - if ( reference.name === name ) return; - - const otherDeclaration = this.trace( reference.name ); - if ( otherDeclaration ) otherDeclaration.addAlias( declaration ); - }); - }); - } - bindImportSpecifiers () { [ this.imports, this.reexports ].forEach( specifiers => { keys( specifiers ).forEach( name => { @@ -246,32 +238,25 @@ export default class Module { } bindReferences () { - if ( this.declarations.default ) { - if ( this.exports.default.identifier ) { - const declaration = this.trace( this.exports.default.identifier ); - if ( declaration ) this.declarations.default.bind( declaration ); - } + for ( const node of this.ast.body ) { + node.bind( this.scope ); } - this.statements.forEach( statement => { - // skip `export { foo, bar, baz }`... - if ( statement.node.type === 'ExportNamedDeclaration' && statement.node.specifiers.length ) { - // ...unless this is the entry module - if ( this !== this.bundle.entryModule ) return; - } + // if ( this.declarations.default ) { + // if ( this.exports.default.identifier ) { + // const declaration = this.trace( this.exports.default.identifier ); + // if ( declaration ) this.declarations.default.bind( declaration ); + // } + // } + } - statement.references.forEach( reference => { - const declaration = reference.scope.findDeclaration( reference.name ) || - this.trace( reference.name ); + findParent () { + // TODO what does it mean if we're here? + return null; + } - if ( declaration ) { - declaration.addReference( reference ); - } else { - // TODO handle globals - this.bundle.assumedGlobals[ reference.name ] = true; - } - }); - }); + findScope () { + return this.scope; } getExports () { @@ -286,6 +271,8 @@ export default class Module { }); this.exportAllModules.forEach( module => { + if ( module.isExternal ) return; // TODO + module.getExports().forEach( name => { if ( name !== 'default' ) exports[ name ] = true; }); @@ -302,359 +289,26 @@ export default class Module { return this.declarations['*']; } - parse () { - // The ast can be supplied programmatically (but usually won't be) - if ( !this.ast ) { - // Try to extract a list of top-level statements/declarations. If - // the parse fails, attach file info and abort - try { - this.ast = parse( this.code, assign({ - ecmaVersion: 6, - sourceType: 'module', - onComment: ( block, text, start, end ) => this.comments.push({ block, text, start, end }), - preserveParens: true - }, this.bundle.acornOptions )); - } catch ( err ) { - err.code = 'PARSE_ERROR'; - err.file = this.id; // see above - not necessarily true, but true enough - err.message += ` in ${this.id}`; - throw err; - } - } - - walk( this.ast, { - enter: node => { - // eliminate dead branches early - if ( node.type === 'IfStatement' ) { - if ( isFalsy( node.test ) ) { - this.magicString.overwrite( node.consequent.start, node.consequent.end, '{}' ); - node.consequent = emptyBlockStatement( node.consequent.start, node.consequent.end ); - } else if ( node.alternate && isTruthy( node.test ) ) { - this.magicString.overwrite( node.alternate.start, node.alternate.end, '{}' ); - node.alternate = emptyBlockStatement( node.alternate.start, node.alternate.end ); - } - } - - this.magicString.addSourcemapLocation( node.start ); - this.magicString.addSourcemapLocation( node.end ); - }, - - leave: ( node, parent, prop ) => { - // eliminate dead branches early - if ( node.type === 'ConditionalExpression' ) { - if ( isFalsy( node.test ) ) { - this.magicString.remove( node.start, node.alternate.start ); - parent[prop] = node.alternate; - } else if ( isTruthy( node.test ) ) { - this.magicString.remove( node.start, node.consequent.start ); - this.magicString.remove( node.consequent.end, node.end ); - parent[prop] = node.consequent; - } - } - } - }); - - const statements = []; - let lastChar = 0; - let commentIndex = 0; - - this.ast.body.forEach( node => { - if ( node.type === 'EmptyStatement' ) return; - - if ( - node.type === 'ExportNamedDeclaration' && - node.declaration && - node.declaration.type === 'VariableDeclaration' && - node.declaration.declarations && - node.declaration.declarations.length > 1 - ) { - // push a synthetic export declaration - const syntheticNode = { - type: 'ExportNamedDeclaration', - specifiers: node.declaration.declarations.map( declarator => { - const id = { name: declarator.id.name }; - return { - local: id, - exported: id - }; - }), - isSynthetic: true - }; - - const statement = new Statement( syntheticNode, this, node.start, node.start ); - statements.push( statement ); - - this.magicString.remove( node.start, node.declaration.start ); - node = node.declaration; - } - - // special case - top-level var declarations with multiple declarators - // should be split up. Otherwise, we may end up including code we - // don't need, just because an unwanted declarator is included - if ( node.type === 'VariableDeclaration' && node.declarations.length > 1 ) { - // remove the leading var/let/const... UNLESS the previous node - // was also a synthetic node, in which case it'll get removed anyway - const lastStatement = statements[ statements.length - 1 ]; - if ( !lastStatement || !lastStatement.node.isSynthetic ) { - this.magicString.remove( node.start, node.declarations[0].start ); - } - - node.declarations.forEach( declarator => { - const { start, end } = declarator; - - const syntheticNode = { - type: 'VariableDeclaration', - kind: node.kind, - start, - end, - declarations: [ declarator ], - isSynthetic: true - }; - - const statement = new Statement( syntheticNode, this, start, end ); - statements.push( statement ); - }); - - lastChar = node.end; // TODO account for trailing line comment - } - - else { - let comment; - do { - comment = this.comments[ commentIndex ]; - if ( !comment ) break; - if ( comment.start > node.start ) break; - commentIndex += 1; - } while ( comment.end < lastChar ); - - const start = comment ? Math.min( comment.start, node.start ) : node.start; - const end = node.end; // TODO account for trailing line comment - - const statement = new Statement( node, this, start, end ); - statements.push( statement ); - - lastChar = end; - } - }); - - let i = statements.length; - let next = this.code.length; - while ( i-- ) { - statements[i].next = next; - if ( !statements[i].isSynthetic ) next = statements[i].start; - } - - return statements; - } - render ( es ) { const magicString = this.magicString.clone(); - this.statements.forEach( statement => { - if ( !statement.isIncluded ) { - if ( statement.node.type === 'ImportDeclaration' ) { - magicString.remove( statement.node.start, statement.next ); - return; - } - - magicString.remove( statement.start, statement.next ); - return; - } - - statement.stringLiteralRanges.forEach( range => magicString.indentExclusionRanges.push( range ) ); - - // skip `export { foo, bar, baz }` - if ( statement.node.type === 'ExportNamedDeclaration' ) { - if ( statement.node.isSynthetic ) return; - - // skip `export { foo, bar, baz }` - if ( statement.node.declaration === null ) { - magicString.remove( statement.start, statement.next ); - return; - } - } - - // split up/remove var declarations as necessary - if ( statement.node.type === 'VariableDeclaration' ) { - const declarator = statement.node.declarations[0]; - - if ( declarator.id.type === 'Identifier' ) { - const declaration = this.declarations[ declarator.id.name ]; - - if ( declaration.exportName && declaration.isReassigned ) { // `var foo = ...` becomes `exports.foo = ...` - magicString.remove( statement.start, declarator.init ? declarator.start : statement.next ); - if ( !declarator.init ) return; - } - } - - else { - // we handle destructuring differently, because whereas we can rewrite - // `var foo = ...` as `exports.foo = ...`, in a case like `var { a, b } = c()` - // where `a` or `b` is exported and reassigned, we have to append - // `exports.a = a;` and `exports.b = b` instead - extractNames( declarator.id ).forEach( name => { - const declaration = this.declarations[ name ]; - - if ( declaration.exportName && declaration.isReassigned ) { - magicString.insertLeft( statement.end, `;\nexports.${name} = ${declaration.render( es )}` ); - } - }); - } - - if ( statement.node.isSynthetic ) { - // insert `var/let/const` if necessary - magicString.insertRight( statement.start, `${statement.node.kind} ` ); - magicString.insertLeft( statement.end, ';' ); - magicString.overwrite( statement.end, statement.next, '\n' ); // TODO account for trailing newlines - } - } - - const toDeshadow = blank(); - - statement.references.forEach( reference => { - const { start, end } = reference; - - if ( reference.isUndefined ) { - magicString.overwrite( start, end, 'undefined', true ); - } - - const declaration = reference.declaration; - - if ( declaration ) { - const name = declaration.render( es ); - - // the second part of this check is necessary because of - // namespace optimisation – name of `foo.bar` could be `bar` - if ( reference.name === name && name.length === end - start ) return; - - reference.rewritten = true; - - // prevent local variables from shadowing renamed references - const identifier = name.match( /[^\.]+/ )[0]; - if ( reference.scope.contains( identifier ) ) { - toDeshadow[ identifier ] = `${identifier}$$`; // TODO more robust mechanism - } - - if ( reference.isShorthandProperty ) { - magicString.insertLeft( end, `: ${name}` ); - } else { - magicString.overwrite( start, end, name, true ); - } - } - }); - - if ( keys( toDeshadow ).length ) { - statement.references.forEach( reference => { - if ( !reference.rewritten && reference.name in toDeshadow ) { - const replacement = toDeshadow[ reference.name ]; - magicString.overwrite( reference.start, reference.end, reference.isShorthandProperty ? `${reference.name}: ${replacement}` : replacement, true ); - } - }); - } - - // modify exports as necessary - if ( statement.isExportDeclaration ) { - // remove `export` from `export var foo = 42` - // TODO: can we do something simpler here? - // we just want to remove `export`, right? - if ( statement.node.type === 'ExportNamedDeclaration' && statement.node.declaration.type === 'VariableDeclaration' ) { - const name = extractNames( statement.node.declaration.declarations[ 0 ].id )[ 0 ]; - const declaration = this.declarations[ name ]; - - // TODO is this even possible? - if ( !declaration ) throw new Error( `Missing declaration for ${name}!` ); - - let end; - - if ( es ) { - end = statement.node.declaration.start; - } else { - if ( declaration.exportName && declaration.isReassigned ) { - const declarator = statement.node.declaration.declarations[0]; - end = declarator.init ? declarator.start : statement.next; - } else { - end = statement.node.declaration.start; - } - } - - magicString.remove( statement.node.start, end ); - } - - else if ( statement.node.type === 'ExportAllDeclaration' ) { - // TODO: remove once `export * from 'external'` is supported. - magicString.remove( statement.start, statement.next ); - } - - // remove `export` from `export class Foo {...}` or `export default Foo` - // TODO default exports need different treatment - else if ( statement.node.declaration.id ) { - magicString.remove( statement.node.start, statement.node.declaration.start ); - } - - else if ( statement.node.type === 'ExportDefaultDeclaration' ) { - const defaultDeclaration = this.declarations.default; - - // prevent `var foo = foo` - if ( defaultDeclaration.original && !defaultDeclaration.original.isReassigned ) { - magicString.remove( statement.start, statement.next ); - return; - } - - const defaultName = defaultDeclaration.render(); - - // prevent `var undefined = sideEffectyDefault(foo)` - if ( !defaultDeclaration.exportName && !defaultDeclaration.isUsed ) { - magicString.remove( statement.start, statement.node.declaration.start ); - return; - } - - // anonymous functions should be converted into declarations - if ( statement.node.declaration.type === 'FunctionExpression' ) { - magicString.overwrite( statement.node.start, statement.node.declaration.start + 8, `function ${defaultName}` ); - } else { - magicString.overwrite( statement.node.start, statement.node.declaration.start, `${this.bundle.varOrConst} ${defaultName} = ` ); - } - } - - else { - throw new Error( 'Unhandled export' ); - } - } - }); + for ( const node of this.ast.body ) { + node.render( magicString, es ); + } - // add namespace block if necessary - const namespace = this.declarations['*']; - if ( namespace && namespace.needsNamespaceBlock ) { - magicString.append( '\n\n' + namespace.renderBlock( magicString.getIndentString() ) ); + if ( this.namespace().needsNamespaceBlock ) { + magicString.append( '\n\n' + this.namespace().renderBlock( es, '\t' ) ); // TODO use correct indentation } return magicString.trim(); } - /** - * Statically runs the module marking the top-level statements that must be - * included for the module to execute successfully. - * - * @param {boolean} treeshake - if we should tree-shake the module - * @return {boolean} marked - if any new statements were marked for inclusion - */ - run ( treeshake ) { - if ( !treeshake ) { - this.statements.forEach( statement => { - if ( statement.isImportDeclaration || ( statement.isExportDeclaration && statement.node.isSynthetic ) ) return; - - statement.mark(); - }); - return false; + run () { + for ( const node of this.ast.body ) { + if ( node.hasEffects( this.scope ) ) { + node.run( this.scope ); + } } - - let marked = false; - - this.statements.forEach( statement => { - marked = statement.run( this.strongDependencies ) || marked; - }); - - return marked; } toJSON () { @@ -662,14 +316,19 @@ export default class Module { id: this.id, code: this.code, originalCode: this.originalCode, - ast: this.ast, + // TODO reinstate AST caching (rewrite broke it, because AST is enhanced) + // ast: this.ast, sourceMapChain: this.sourceMapChain, resolvedIds: this.resolvedIds }; } trace ( name ) { - if ( name in this.declarations ) return this.declarations[ name ]; + // TODO this is slightly circular + if ( name in this.scope.declarations ) { + return this.scope.declarations[ name ]; + } + if ( name in this.imports ) { const importDeclaration = this.imports[ name ]; const otherModule = importDeclaration.module; @@ -708,10 +367,7 @@ export default class Module { const name = exportDeclaration.localName; const declaration = this.trace( name ); - if ( declaration ) return declaration; - - this.bundle.assumedGlobals[ name ] = true; - return ( this.declarations[ name ] = new SyntheticGlobalDeclaration( name ) ); + return declaration || this.bundle.scope.findDeclaration( name ); } for ( let i = 0; i < this.exportAllModules.length; i += 1 ) { diff --git a/src/Reference.js b/src/Reference.js deleted file mode 100644 index 5c5c3e9..0000000 --- a/src/Reference.js +++ /dev/null @@ -1,30 +0,0 @@ -export class Reference { - constructor ( node, scope, statement ) { - this.node = node; - this.scope = scope; - this.statement = statement; - - this.declaration = null; // bound later - - this.parts = []; - - let root = node; - while ( root.type === 'MemberExpression' ) { - this.parts.unshift( root.property ); - root = root.object; - } - - this.name = root.name; - - this.start = node.start; - this.end = node.start + this.name.length; // can be overridden in the case of namespace members - this.rewritten = false; - } -} - -export class SyntheticReference { - constructor ( name ) { - this.name = name; - this.parts = []; - } -} diff --git a/src/Statement.js b/src/Statement.js deleted file mode 100644 index 7ab8bf8..0000000 --- a/src/Statement.js +++ /dev/null @@ -1,160 +0,0 @@ -import { walk } from 'estree-walker'; -import Scope from './ast/Scope.js'; -import attachScopes from './ast/attachScopes.js'; -import modifierNodes, { isModifierNode } from './ast/modifierNodes.js'; -import isFunctionDeclaration from './ast/isFunctionDeclaration.js'; -import isReference from './ast/isReference.js'; -import getLocation from './utils/getLocation.js'; -import run from './utils/run.js'; -import { Reference } from './Reference.js'; - -export default class Statement { - constructor ( node, module, start, end ) { - this.node = node; - this.module = module; - this.start = start; - this.end = end; - this.next = null; // filled in later - - this.scope = new Scope({ statement: this }); - - this.references = []; - this.stringLiteralRanges = []; - - this.isIncluded = false; - this.ran = false; - - this.isImportDeclaration = node.type === 'ImportDeclaration'; - this.isExportDeclaration = /^Export/.test( node.type ); - this.isReexportDeclaration = this.isExportDeclaration && !!node.source; - - this.isFunctionDeclaration = isFunctionDeclaration( node ) || - this.isExportDeclaration && isFunctionDeclaration( node.declaration ); - } - - firstPass () { - if ( this.isImportDeclaration ) return; // nothing to analyse - - // attach scopes - attachScopes( this ); - - // find references - const statement = this; - let { module, references, scope, stringLiteralRanges } = this; - let contextDepth = 0; - - walk( this.node, { - enter ( node, parent, prop ) { - // warn about eval - if ( node.type === 'CallExpression' && node.callee.name === 'eval' && !scope.contains( 'eval' ) ) { - // TODO show location - module.bundle.onwarn( `Use of \`eval\` (in ${module.id}) is strongly discouraged, as it poses security risks and may cause issues with minification. See https://github.com/rollup/rollup/wiki/Troubleshooting#avoiding-eval for more details` ); - } - - // skip re-export declarations - if ( node.type === 'ExportNamedDeclaration' && node.source ) return this.skip(); - - if ( node.type === 'TemplateElement' ) stringLiteralRanges.push([ node.start, node.end ]); - if ( node.type === 'Literal' && typeof node.value === 'string' && /\n/.test( node.raw ) ) { - stringLiteralRanges.push([ node.start + 1, node.end - 1 ]); - } - - if ( node.type === 'ThisExpression' && contextDepth === 0 ) { - module.magicString.overwrite( node.start, node.end, module.bundle.context ); - if ( module.bundle.context === 'undefined' ) module.bundle.onwarn( 'The `this` keyword is equivalent to `undefined` at the top level of an ES module, and has been rewritten' ); - } - - if ( node._scope ) scope = node._scope; - if ( /^Function/.test( node.type ) ) contextDepth += 1; - - let isReassignment; - - if ( parent && isModifierNode( parent ) ) { - let subject = parent[ modifierNodes[ parent.type ] ]; - - if ( node === subject ) { - let depth = 0; - - while ( subject.type === 'MemberExpression' ) { - subject = subject.object; - depth += 1; - } - - const importDeclaration = module.imports[ subject.name ]; - - if ( !scope.contains( subject.name ) && importDeclaration ) { - const minDepth = importDeclaration.name === '*' ? - 2 : // cannot do e.g. `namespace.foo = bar` - 1; // cannot do e.g. `foo = bar`, but `foo.bar = bar` is fine - - if ( depth < minDepth ) { - const err = new Error( `Illegal reassignment to import '${subject.name}'` ); - err.file = module.id; - err.loc = getLocation( module.magicString.original, subject.start ); - throw err; - } - } - - isReassignment = !depth; - } - } - - if ( isReference( node, parent ) ) { - // function declaration IDs are a special case – they're associated - // with the parent scope - const referenceScope = parent.type === 'FunctionDeclaration' && node === parent.id ? - scope.parent : - scope; - - const isShorthandProperty = parent.type === 'Property' && parent.shorthand; - - // Since `node.key` can equal `node.value` for shorthand properties - // we must use the `prop` argument provided by `estree-walker` to determine - // if we're looking at the key or the value. - // If they are equal, we'll return to not create duplicate references. - if ( isShorthandProperty && parent.value === parent.key && prop === 'value' ) { - return; - } - - const reference = new Reference( node, referenceScope, statement ); - reference.isReassignment = isReassignment; - reference.isShorthandProperty = isShorthandProperty; - references.push( reference ); - - this.skip(); // don't descend from `foo.bar.baz` into `foo.bar` - } - }, - leave ( node ) { - if ( node._scope ) scope = scope.parent; - if ( /^Function/.test( node.type ) ) contextDepth -= 1; - } - }); - } - - mark () { - if ( this.isIncluded ) return; // prevent infinite loops - this.isIncluded = true; - - this.references.forEach( reference => { - if ( reference.declaration ) reference.declaration.use(); - }); - } - - run ( strongDependencies ) { - if ( ( this.ran && this.isIncluded ) || this.isImportDeclaration || this.isFunctionDeclaration ) return; - this.ran = true; - - if ( run( this.node, this.scope, this, strongDependencies, false ) ) { - this.mark(); - return true; - } - } - - source () { - return this.module.source.slice( this.start, this.end ); - } - - toString () { - return this.module.magicString.slice( this.start, this.end ); - } -} diff --git a/src/ast/Node.js b/src/ast/Node.js new file mode 100644 index 0000000..0343f28 --- /dev/null +++ b/src/ast/Node.js @@ -0,0 +1,92 @@ +import { UNKNOWN } from './values.js'; +import getLocation from '../utils/getLocation.js'; + +export default class Node { + bind ( scope ) { + this.eachChild( child => child.bind( scope ) ); + } + + eachChild ( callback ) { + for ( const key of this.keys ) { + if ( this.shorthand && key === 'key' ) continue; // key and value are the same + + const value = this[ key ]; + + if ( value ) { + if ( 'length' in value ) { + for ( const child of value ) { + if ( child ) callback( child ); + } + } else if ( value ) { + callback( value ); + } + } + } + } + + findParent ( selector ) { + return selector.test( this.type ) ? this : this.parent.findParent( selector ); + } + + // TODO abolish findScope. if a node needs to store scope, store it + findScope ( functionScope ) { + return this.parent.findScope( functionScope ); + } + + gatherPossibleValues ( values ) { + //this.eachChild( child => child.gatherPossibleValues( values ) ); + values.add( UNKNOWN ); + } + + getValue () { + return UNKNOWN; + } + + hasEffects ( scope ) { + for ( const key of this.keys ) { + const value = this[ key ]; + + if ( value ) { + if ( 'length' in value ) { + for ( const child of value ) { + if ( child && child.hasEffects( scope ) ) { + return true; + } + } + } else if ( value && value.hasEffects( scope ) ) { + return true; + } + } + } + } + + initialise ( scope ) { + this.eachChild( child => child.initialise( scope ) ); + } + + locate () { + // useful for debugging + const location = getLocation( this.module.code, this.start ); + location.file = this.module.id; + location.toString = () => JSON.stringify( location ); + + return location; + } + + render ( code, es ) { + this.eachChild( child => child.render( code, es ) ); + } + + run ( scope ) { + if ( this.ran ) return; + this.ran = true; + + this.eachChild( child => { + child.run( scope ); + }); + } + + toString () { + return this.module.code.slice( this.start, this.end ); + } +} diff --git a/src/ast/Scope.js b/src/ast/Scope.js deleted file mode 100644 index 0dc48ec..0000000 --- a/src/ast/Scope.js +++ /dev/null @@ -1,52 +0,0 @@ -import { blank, keys } from '../utils/object.js'; -import Declaration from '../Declaration.js'; -import extractNames from './extractNames.js'; - -export default class Scope { - constructor ( options ) { - options = options || {}; - - this.parent = options.parent; - this.statement = options.statement || this.parent.statement; - this.isBlockScope = !!options.block; - this.isTopLevel = !this.parent || ( this.parent.isTopLevel && this.isBlockScope ); - - this.declarations = blank(); - - if ( options.params ) { - options.params.forEach( param => { - extractNames( param ).forEach( name => { - this.declarations[ name ] = new Declaration( param, true, this.statement ); - }); - }); - } - } - - addDeclaration ( node, isBlockDeclaration, isVar ) { - if ( !isBlockDeclaration && this.isBlockScope ) { - // it's a `var` or function node, and this - // is a block scope, so we need to go up - this.parent.addDeclaration( node, isBlockDeclaration, isVar ); - } else { - extractNames( node.id ).forEach( name => { - this.declarations[ name ] = new Declaration( node, false, this.statement ); - }); - } - } - - contains ( name ) { - return this.declarations[ name ] || - ( this.parent ? this.parent.contains( name ) : false ); - } - - eachDeclaration ( fn ) { - keys( this.declarations ).forEach( key => { - fn( key, this.declarations[ key ] ); - }); - } - - findDeclaration ( name ) { - return this.declarations[ name ] || - ( this.parent && this.parent.findDeclaration( name ) ); - } -} diff --git a/src/ast/attachScopes.js b/src/ast/attachScopes.js deleted file mode 100644 index 83cbc85..0000000 --- a/src/ast/attachScopes.js +++ /dev/null @@ -1,78 +0,0 @@ -import { walk } from 'estree-walker'; -import Scope from './Scope.js'; - -const blockDeclarations = { - const: true, - let: true -}; - -export default function attachScopes ( statement ) { - let { node, scope } = statement; - - walk( node, { - enter ( node, parent ) { - // function foo () {...} - // class Foo {...} - if ( /(Function|Class)Declaration/.test( node.type ) ) { - scope.addDeclaration( node, false, false ); - } - - // var foo = 1, bar = 2 - if ( node.type === 'VariableDeclaration' ) { - const isBlockDeclaration = blockDeclarations[ node.kind ]; - - node.declarations.forEach( declarator => { - scope.addDeclaration( declarator, isBlockDeclaration, true ); - }); - } - - let newScope; - - // create new function scope - if ( /(Function|Class)/.test( node.type ) ) { - newScope = new Scope({ - parent: scope, - block: false, - params: node.params - }); - - // named function expressions - the name is considered - // part of the function's scope - if ( /(Function|Class)Expression/.test( node.type ) && node.id ) { - newScope.addDeclaration( node, false, false ); - } - } - - // create new block scope - if ( node.type === 'BlockStatement' && ( !parent || !/Function/.test( parent.type ) ) ) { - newScope = new Scope({ - parent: scope, - block: true - }); - } - - // catch clause has its own block scope - if ( node.type === 'CatchClause' ) { - newScope = new Scope({ - parent: scope, - params: [ node.param ], - block: true - }); - } - - if ( newScope ) { - Object.defineProperty( node, '_scope', { - value: newScope, - configurable: true - }); - - scope = newScope; - } - }, - leave ( node ) { - if ( node._scope ) { - scope = scope.parent; - } - } - }); -} diff --git a/src/ast/conditions.js b/src/ast/conditions.js deleted file mode 100644 index b21e4d4..0000000 --- a/src/ast/conditions.js +++ /dev/null @@ -1,38 +0,0 @@ -export function isTruthy ( node ) { - if ( node.type === 'Literal' ) return !!node.value; - if ( node.type === 'ParenthesizedExpression' ) return isTruthy( node.expression ); - if ( node.operator in operators ) return operators[ node.operator ]( node ); -} - -export function isFalsy ( node ) { - return not( isTruthy( node ) ); -} - -function not ( value ) { - return value === undefined ? value : !value; -} - -function equals ( a, b, strict ) { - if ( a.type !== b.type ) return undefined; - if ( a.type === 'Literal' ) return strict ? a.value === b.value : a.value == b.value; -} - -const operators = { - '==': x => { - return equals( x.left, x.right, false ); - }, - - '!=': x => not( operators['==']( x ) ), - - '===': x => { - return equals( x.left, x.right, true ); - }, - - '!==': x => not( operators['===']( x ) ), - - '!': x => isFalsy( x.argument ), - - '&&': x => isTruthy( x.left ) && isTruthy( x.right ), - - '||': x => isTruthy( x.left ) || isTruthy( x.right ) -}; diff --git a/src/ast/create.js b/src/ast/create.js deleted file mode 100644 index e767dbd..0000000 --- a/src/ast/create.js +++ /dev/null @@ -1,7 +0,0 @@ -export function emptyBlockStatement ( start, end ) { - return { - start, end, - type: 'BlockStatement', - body: [] - }; -} diff --git a/src/ast/enhance.js b/src/ast/enhance.js new file mode 100644 index 0000000..6a86dab --- /dev/null +++ b/src/ast/enhance.js @@ -0,0 +1,63 @@ +import nodes from './nodes/index.js'; +import Node from './Node.js'; +import keys from './keys.js'; + +const newline = /\n/; + +export default function enhance ( ast, module, comments ) { + enhanceNode( ast, module, module, module.magicString ); + + let comment = comments.shift(); + + for ( const node of ast.body ) { + if ( comment && ( comment.start < node.start ) ) { + node.leadingCommentStart = comment.start; + } + + while ( comment && comment.end < node.end ) comment = comments.shift(); + + // if the next comment is on the same line as the end of the node, + // treat is as a trailing comment + if ( comment && !newline.test( module.code.slice( node.end, comment.start ) ) ) { + node.trailingCommentEnd = comment.end; // TODO is node.trailingCommentEnd used anywhere? + comment = comments.shift(); + } + + node.initialise( module.scope ); + } +} + +function enhanceNode ( raw, parent, module, code ) { + if ( !raw ) return; + + if ( 'length' in raw ) { + for ( let i = 0; i < raw.length; i += 1 ) { + enhanceNode( raw[i], parent, module, code ); + } + + return; + } + + // with e.g. shorthand properties, key and value are + // the same node. We don't want to enhance an object twice + if ( raw.__enhanced ) return; + raw.__enhanced = true; + + if ( !keys[ raw.type ] ) { + keys[ raw.type ] = Object.keys( raw ).filter( key => typeof raw[ key ] === 'object' ); + } + + raw.parent = parent; + raw.module = module; + raw.keys = keys[ raw.type ]; + + code.addSourcemapLocation( raw.start ); + code.addSourcemapLocation( raw.end ); + + for ( const key of keys[ raw.type ] ) { + enhanceNode( raw[ key ], raw, module, code ); + } + + const type = nodes[ raw.type ] || Node; + raw.__proto__ = type.prototype; +} diff --git a/src/ast/isFunctionDeclaration.js b/src/ast/isFunctionDeclaration.js deleted file mode 100644 index a1573e7..0000000 --- a/src/ast/isFunctionDeclaration.js +++ /dev/null @@ -1,6 +0,0 @@ -export default function isFunctionDeclaration ( node ) { - if ( !node ) return false; - - return node.type === 'FunctionDeclaration' || - ( node.type === 'VariableDeclaration' && node.init && /FunctionExpression/.test( node.init.type ) ); -} diff --git a/src/ast/keys.js b/src/ast/keys.js new file mode 100644 index 0000000..99d14ea --- /dev/null +++ b/src/ast/keys.js @@ -0,0 +1,3 @@ +export default { + Program: [ 'body' ] +}; diff --git a/src/ast/modifierNodes.js b/src/ast/modifierNodes.js deleted file mode 100644 index 3696fd1..0000000 --- a/src/ast/modifierNodes.js +++ /dev/null @@ -1,19 +0,0 @@ -const modifierNodes = { - AssignmentExpression: 'left', - UpdateExpression: 'argument', - UnaryExpression: 'argument' -}; - -export default modifierNodes; - -export function isModifierNode ( node ) { - if ( !( node.type in modifierNodes ) ) { - return false; - } - - if ( node.type === 'UnaryExpression' ) { - return node.operator === 'delete'; - } - - return true; -} diff --git a/src/ast/nodes/ArrayExpression.js b/src/ast/nodes/ArrayExpression.js new file mode 100644 index 0000000..ff60919 --- /dev/null +++ b/src/ast/nodes/ArrayExpression.js @@ -0,0 +1,8 @@ +import Node from '../Node.js'; +import { ARRAY } from '../values.js'; + +export default class ArrayExpression extends Node { + gatherPossibleValues ( values ) { + values.add( ARRAY ); + } +} diff --git a/src/ast/nodes/ArrowFunctionExpression.js b/src/ast/nodes/ArrowFunctionExpression.js new file mode 100644 index 0000000..2071965 --- /dev/null +++ b/src/ast/nodes/ArrowFunctionExpression.js @@ -0,0 +1,35 @@ +import Node from '../Node.js'; +import Scope from '../scopes/Scope.js'; +import extractNames from '../utils/extractNames.js'; + +export default class ArrowFunctionExpression extends Node { + initialise ( scope ) { + if ( this.body.type !== 'BlockStatement' ) { + this.scope = new Scope({ + parent: scope, + isBlockScope: false, + isLexicalBoundary: false + }); + + for ( const param of this.params ) { + for ( const name of extractNames( param ) ) { + this.scope.addDeclaration( name, null, null, true ); // TODO ugh + } + } + } + + super.initialise( scope ); + } + + bind ( scope ) { + super.bind( this.scope || scope ); + } + + findScope ( functionScope ) { + return this.scope || this.parent.findScope( functionScope ); + } + + hasEffects () { + return false; + } +} diff --git a/src/ast/nodes/AssignmentExpression.js b/src/ast/nodes/AssignmentExpression.js new file mode 100644 index 0000000..dd3347d --- /dev/null +++ b/src/ast/nodes/AssignmentExpression.js @@ -0,0 +1,45 @@ +import Node from '../Node.js'; +import disallowIllegalReassignment from './shared/disallowIllegalReassignment.js'; +import isUsedByBundle from './shared/isUsedByBundle.js'; +import { NUMBER, STRING, UNKNOWN } from '../values.js'; + +export default class AssignmentExpression extends Node { + bind ( scope ) { + let subject = this.left; + while ( this.left.type === 'ParenthesizedExpression' ) subject = subject.expression; + + this.subject = subject; + disallowIllegalReassignment( scope, subject ); + + if ( subject.type === 'Identifier' ) { + const declaration = scope.findDeclaration( subject.name ); + declaration.isReassigned = true; + + if ( declaration.possibleValues ) { // TODO this feels hacky + if ( this.operator === '=' ) { + declaration.possibleValues.add( this.right ); + } else if ( this.operator === '+=' ) { + declaration.possibleValues.add( STRING ).add( NUMBER ); + } else { + declaration.possibleValues.add( NUMBER ); + } + } + } + + super.bind( scope ); + } + + hasEffects ( scope ) { + const hasEffects = this.isUsedByBundle() || this.right.hasEffects( scope ); + return hasEffects; + } + + initialise ( scope ) { + this.module.bundle.dependentExpressions.push( this ); + super.initialise( scope ); + } + + isUsedByBundle () { + return isUsedByBundle( this.findScope(), this.subject ); + } +} diff --git a/src/ast/nodes/BinaryExpression.js b/src/ast/nodes/BinaryExpression.js new file mode 100644 index 0000000..da3d4da --- /dev/null +++ b/src/ast/nodes/BinaryExpression.js @@ -0,0 +1,38 @@ +import Node from '../Node.js'; +import { UNKNOWN } from '../values.js'; + +const operators = { + '==': ( left, right ) => left == right, + '!=': ( left, right ) => left != right, + '===': ( left, right ) => left === right, + '!==': ( left, right ) => left !== right, + '<': ( left, right ) => left < right, + '<=': ( left, right ) => left <= right, + '>': ( left, right ) => left > right, + '>=': ( left, right ) => left >= right, + '<<': ( left, right ) => left << right, + '>>': ( left, right ) => left >> right, + '>>>': ( left, right ) => left >>> right, + '+': ( left, right ) => left + right, + '-': ( left, right ) => left - right, + '*': ( left, right ) => left * right, + '/': ( left, right ) => left / right, + '%': ( left, right ) => left % right, + '|': ( left, right ) => left | right, + '^': ( left, right ) => left ^ right, + '&': ( left, right ) => left & right, + in: ( left, right ) => left in right, + instanceof: ( left, right ) => left instanceof right +}; + +export default class BinaryExpression extends Node { + getValue () { + const leftValue = this.left.getValue(); + if ( leftValue === UNKNOWN ) return UNKNOWN; + + const rightValue = this.right.getValue(); + if ( rightValue === UNKNOWN ) return UNKNOWN; + + return operators[ this.operator ]( leftValue, rightValue ); + } +} diff --git a/src/ast/nodes/BlockStatement.js b/src/ast/nodes/BlockStatement.js new file mode 100644 index 0000000..ea341d5 --- /dev/null +++ b/src/ast/nodes/BlockStatement.js @@ -0,0 +1,71 @@ +import Node from '../Node.js'; +import Scope from '../scopes/Scope.js'; +import extractNames from '../utils/extractNames.js'; + +export default class BlockStatement extends Node { + bind () { + for ( const node of this.body ) { + node.bind( this.scope ); + } + } + + createScope ( parent ) { + this.parentIsFunction = /Function/.test( this.parent.type ); + this.isFunctionBlock = this.parentIsFunction || this.parent.type === 'Module'; + + this.scope = new Scope({ + isBlockScope: !this.isFunctionBlock, + isLexicalBoundary: this.isFunctionBlock && this.parent.type !== 'ArrowFunctionExpression', + parent: parent || this.parent.findScope( false ), // TODO always supply parent + owner: this // TODO is this used anywhere? + }); + + const params = this.parent.params || ( this.parent.type === 'CatchClause' && [ this.parent.param ] ); + + if ( params && params.length ) { + params.forEach( node => { + extractNames( node ).forEach( name => { + this.scope.addDeclaration( name, node, false, true ); + }); + }); + } + } + + findScope ( functionScope ) { + return functionScope && !this.isFunctionBlock ? this.parent.findScope( functionScope ) : this.scope; + } + + hasEffects () { + for ( const node of this.body ) { + if ( node.hasEffects( this.scope ) ) return true; + } + } + + initialise () { + if ( !this.scope ) this.createScope(); // scope can be created early in some cases, e.g for (let i... ) + + let lastNode; + for ( const node of this.body ) { + node.initialise( this.scope ); + + if ( lastNode ) lastNode.next = node.start; + lastNode = node; + } + } + + render ( code, es ) { + for ( const node of this.body ) { + node.render( code, es ); + } + } + + run () { + if ( this.ran ) return; + this.ran = true; + + for ( const node of this.body ) { + // TODO only include non-top-level statements if necessary + node.run( this.scope ); + } + } +} diff --git a/src/ast/nodes/CallExpression.js b/src/ast/nodes/CallExpression.js new file mode 100644 index 0000000..8fafc91 --- /dev/null +++ b/src/ast/nodes/CallExpression.js @@ -0,0 +1,40 @@ +import getLocation from '../../utils/getLocation.js'; +import error from '../../utils/error.js'; +import Node from '../Node.js'; +import callHasEffects from './shared/callHasEffects.js'; + +export default class CallExpression extends Node { + bind ( scope ) { + if ( this.callee.type === 'Identifier' ) { + const declaration = scope.findDeclaration( this.callee.name ); + + if ( declaration.isNamespace ) { + error({ + message: `Cannot call a namespace ('${this.callee.name}')`, + file: this.module.id, + pos: this.start, + loc: getLocation( this.module.code, this.start ) + }); + } + + if ( this.callee.name === 'eval' && declaration.isGlobal ) { + this.module.bundle.onwarn( `Use of \`eval\` (in ${this.module.id}) is strongly discouraged, as it poses security risks and may cause issues with minification. See https://github.com/rollup/rollup/wiki/Troubleshooting#avoiding-eval for more details` ); + } + } + + super.bind( scope ); + } + + hasEffects ( scope ) { + return callHasEffects( scope, this.callee ); + } + + initialise ( scope ) { + this.module.bundle.dependentExpressions.push( this ); + super.initialise( scope ); + } + + isUsedByBundle () { + return this.hasEffects( this.findScope() ); + } +} diff --git a/src/ast/nodes/ClassDeclaration.js b/src/ast/nodes/ClassDeclaration.js new file mode 100644 index 0000000..a004b9f --- /dev/null +++ b/src/ast/nodes/ClassDeclaration.js @@ -0,0 +1,40 @@ +import Node from '../Node.js'; + +// TODO is this basically identical to FunctionDeclaration? +export default class ClassDeclaration extends Node { + activate () { + if ( this.activated ) return; + this.activated = true; + + this.body.run(); + } + + addReference ( reference ) { + /* noop? */ + } + + gatherPossibleValues ( values ) { + values.add( this ); + } + + getName () { + return this.id.name; + } + + hasEffects () { + return false; + } + + initialise ( scope ) { + scope.addDeclaration( this.id.name, this, false, false ); + super.initialise( scope ); + } + + render ( code, es ) { + if ( this.activated ) { + super.render( code, es ); + } else { + code.remove( this.leadingCommentStart || this.start, this.next || this.end ); + } + } +} diff --git a/src/ast/nodes/ClassExpression.js b/src/ast/nodes/ClassExpression.js new file mode 100644 index 0000000..63f1399 --- /dev/null +++ b/src/ast/nodes/ClassExpression.js @@ -0,0 +1,26 @@ +import Node from '../Node.js'; +import Scope from '../scopes/Scope.js'; + +export default class ClassExpression extends Node { + bind () { + super.bind( this.scope ); + } + + findScope () { + return this.scope; + } + + initialise () { + this.scope = new Scope({ + isBlockScope: true, + parent: this.parent.findScope( false ) + }); + + if ( this.id ) { + // function expression IDs belong to the child scope... + this.scope.addDeclaration( this.id.name, this, false, true ); + } + + super.initialise( this.scope ); + } +} diff --git a/src/ast/nodes/ConditionalExpression.js b/src/ast/nodes/ConditionalExpression.js new file mode 100644 index 0000000..6a6c803 --- /dev/null +++ b/src/ast/nodes/ConditionalExpression.js @@ -0,0 +1,65 @@ +import Node from '../Node.js'; +import { UNKNOWN } from '../values.js'; + +export default class ConditionalExpression extends Node { + initialise ( scope ) { + if ( this.module.bundle.treeshake ) { + const testValue = this.test.getValue(); + + if ( testValue === UNKNOWN ) { + super.initialise( scope ); + } + + else if ( testValue ) { + this.consequent.initialise( scope ); + this.alternate = null; + } else if ( this.alternate ) { + this.alternate.initialise( scope ); + this.consequent = null; + } + } + + else { + super.initialise( scope ); + } + } + + gatherPossibleValues ( values ) { + const testValue = this.test.getValue(); + + if ( testValue === UNKNOWN ) { + values.add( this.consequent ).add( this.alternate ); + } else { + values.add( testValue ? this.consequent : this.alternate ); + } + } + + getValue () { + const testValue = this.test.getValue(); + if ( testValue === UNKNOWN ) return UNKNOWN; + + return testValue ? this.consequent.getValue() : this.alternate.getValue(); + } + + render ( code, es ) { + if ( !this.module.bundle.treeshake ) { + super.render( code, es ); + } + + else { + const testValue = this.test.getValue(); + + if ( testValue === UNKNOWN ) { + super.render( code, es ); + } + + else if ( testValue ) { + code.remove( this.start, this.consequent.start ); + code.remove( this.consequent.end, this.end ); + } else { + code.remove( this.start, this.alternate.start ); + code.remove( this.alternate.end, this.end ); + } + } + } +} diff --git a/src/ast/nodes/ExportAllDeclaration.js b/src/ast/nodes/ExportAllDeclaration.js new file mode 100644 index 0000000..fe929b6 --- /dev/null +++ b/src/ast/nodes/ExportAllDeclaration.js @@ -0,0 +1,11 @@ +import Node from '../Node.js'; + +export default class ExportAllDeclaration extends Node { + initialise ( scope ) { + this.isExportDeclaration = true; + } + + render ( code, es ) { + code.remove( this.leadingCommentStart || this.start, this.next || this.end ); + } +} diff --git a/src/ast/nodes/ExportDefaultDeclaration.js b/src/ast/nodes/ExportDefaultDeclaration.js new file mode 100644 index 0000000..d65d675 --- /dev/null +++ b/src/ast/nodes/ExportDefaultDeclaration.js @@ -0,0 +1,124 @@ +import Node from '../Node.js'; + +const functionOrClassDeclaration = /^(?:Function|Class)Declaration/; + +class SyntheticDefaultDeclaration { + constructor ( node, name ) { + this.node = node; + this.name = name; + this.isDefault = true; + } + + activate () { + if ( this.activated ) return; + this.activated = true; + + this.node.run(); + } + + addReference ( reference ) { + this.name = reference.name; + if ( this.original ) this.original.addReference( reference ); + } + + render ( es ) { + if ( this.original && !this.original.isReassigned ) { + return this.original.getName( es ); + } + + return this.name; + } +} + +export default class ExportDefaultDeclaration extends Node { + initialise ( scope ) { + this.isExportDeclaration = true; + this.isDefault = true; + + this.name = ( this.declaration.id && this.declaration.id.name ) || this.declaration.name || this.module.basename(); + scope.declarations.default = this; + + this.declaration.initialise( scope ); + } + + activate () { + if ( this.activated ) return; + this.activated = true; + + this.run(); + } + + addReference ( reference ) { + this.name = reference.name; + if ( this.original ) this.original.addReference( reference ); + } + + bind ( scope ) { + const name = ( this.declaration.id && this.declaration.id.name ) || this.declaration.name; + if ( name ) this.original = scope.findDeclaration( name ); + + this.declaration.bind( scope ); + } + + gatherPossibleValues ( values ) { + this.declaration.gatherPossibleValues( values ); + } + + getName ( es ) { + if ( this.original && !this.original.isReassigned ) { + return this.original.getName( es ); + } + + return this.name; + } + + // TODO this is total chaos, tidy it up + render ( code, es ) { + const treeshake = this.module.bundle.treeshake; + const name = this.getName( es ); + + if ( this.shouldInclude ) { + if ( this.activated ) { + if ( functionOrClassDeclaration.test( this.declaration.type ) ) { + if ( this.declaration.id ) { + code.remove( this.start, this.declaration.start ); + } else { + throw new Error( 'TODO anonymous class/function declaration' ); + } + } + + else { + if ( this.original && this.original.getName( es ) === name ) { + // prevent `var foo = foo` + code.remove( this.leadingCommentStart || this.start, this.next || this.end ); + return; // don't render children. TODO this seems like a bit of a hack + } else { + code.overwrite( this.start, this.declaration.start, `${this.module.bundle.varOrConst} ${name} = ` ); + } + } + } else { + // remove `var foo` from `var foo = bar()`, if `foo` is unused + code.remove( this.start, this.declaration.start ); + } + + super.render( code, es ); + } else { + if ( treeshake ) { + if ( functionOrClassDeclaration.test( this.declaration.type ) && !this.declaration.activated ) { + code.remove( this.leadingCommentStart || this.start, this.next || this.end ); + } else { + const hasEffects = this.declaration.hasEffects( this.module.scope ); + code.remove( this.start, hasEffects ? this.declaration.start : this.next || this.end ); + } + } else { + code.overwrite( this.start, this.declaration.start, `${this.module.bundle.varOrConst} ${name} = ` ); + } + // code.remove( this.start, this.next || this.end ); + } + } + + run ( scope ) { + this.shouldInclude = true; + super.run( scope ); + } +} diff --git a/src/ast/nodes/ExportNamedDeclaration.js b/src/ast/nodes/ExportNamedDeclaration.js new file mode 100644 index 0000000..b815dd6 --- /dev/null +++ b/src/ast/nodes/ExportNamedDeclaration.js @@ -0,0 +1,25 @@ +import Node from '../Node.js'; + +export default class ExportNamedDeclaration extends Node { + initialise ( scope ) { + this.isExportDeclaration = true; + if ( this.declaration ) { + this.declaration.initialise( scope ); + } + } + + bind ( scope ) { + if ( this.declaration ) { + this.declaration.bind( scope ); + } + } + + render ( code, es ) { + if ( this.declaration ) { + code.remove( this.start, this.declaration.start ); + this.declaration.render( code, es ); + } else { + code.remove( this.leadingCommentStart || this.start, this.next || this.end ); + } + } +} diff --git a/src/ast/nodes/ExpressionStatement.js b/src/ast/nodes/ExpressionStatement.js new file mode 100644 index 0000000..c5c3255 --- /dev/null +++ b/src/ast/nodes/ExpressionStatement.js @@ -0,0 +1,16 @@ +import Node from '../Node.js'; + +export default class ExpressionStatement extends Node { + render ( code, es ) { + if ( !this.module.bundle.treeshake || this.shouldInclude ) { + super.render( code, es ); + } else { + code.remove( this.leadingCommentStart || this.start, this.next || this.end ); + } + } + + run ( scope ) { + this.shouldInclude = true; + super.run( scope ); + } +} diff --git a/src/ast/nodes/FunctionDeclaration.js b/src/ast/nodes/FunctionDeclaration.js new file mode 100644 index 0000000..50e93bf --- /dev/null +++ b/src/ast/nodes/FunctionDeclaration.js @@ -0,0 +1,53 @@ +import Node from '../Node.js'; + +export default class FunctionDeclaration extends Node { + activate () { + if ( this.activated ) return; + this.activated = true; + + const scope = this.body.scope; + this.params.forEach( param => param.run( scope ) ); // in case of assignment patterns + this.body.run(); + } + + addReference ( reference ) { + /* noop? */ + } + + bind ( scope ) { + this.id.bind( scope ); + this.params.forEach( param => param.bind( this.body.scope ) ); + this.body.bind( scope ); + } + + gatherPossibleValues ( values ) { + values.add( this ); + } + + getName () { + return this.name; + } + + hasEffects () { + return false; + } + + initialise ( scope ) { + this.name = this.id.name; // may be overridden by bundle.deconflict + scope.addDeclaration( this.name, this, false, false ); + + this.body.createScope(); + + this.id.initialise( scope ); + this.params.forEach( param => param.initialise( this.body.scope ) ); + this.body.initialise( scope ); + } + + render ( code, es ) { + if ( !this.module.bundle.treeshake || this.activated ) { + super.render( code, es ); + } else { + code.remove( this.leadingCommentStart || this.start, this.next || this.end ); + } + } +} diff --git a/src/ast/nodes/FunctionExpression.js b/src/ast/nodes/FunctionExpression.js new file mode 100644 index 0000000..56c87ee --- /dev/null +++ b/src/ast/nodes/FunctionExpression.js @@ -0,0 +1,21 @@ +import Node from '../Node.js'; + +export default class FunctionExpression extends Node { + bind () { + if ( this.id ) this.id.bind( this.body.scope ); + this.params.forEach( param => param.bind( this.body.scope ) ); + this.body.bind(); + } + + hasEffects () { + return false; + } + + initialise () { + this.body.createScope(); // TODO we'll also need to do this for For[Of|In]Statement + + if ( this.id ) this.id.initialise( this.body.scope ); + this.params.forEach( param => param.initialise( this.body.scope ) ); + this.body.initialise(); + } +} diff --git a/src/ast/nodes/Identifier.js b/src/ast/nodes/Identifier.js new file mode 100644 index 0000000..836462b --- /dev/null +++ b/src/ast/nodes/Identifier.js @@ -0,0 +1,35 @@ +import Node from '../Node.js'; +import isReference from '../utils/isReference.js'; + +export default class Identifier extends Node { + bind ( scope ) { + if ( isReference( this, this.parent ) ) { + this.declaration = scope.findDeclaration( this.name ); + this.declaration.addReference( this ); // TODO necessary? + } + } + + gatherPossibleValues ( values ) { + if ( isReference( this, this.parent ) ) { + values.add( this ); + } + } + + render ( code, es ) { + if ( this.declaration ) { + const name = this.declaration.getName( es ); + if ( name !== this.name ) { + code.overwrite( this.start, this.end, name, true ); + + // special case + if ( this.parent.type === 'Property' && this.parent.shorthand ) { + code.insertLeft( this.start, `${this.name}: ` ); + } + } + } + } + + run () { + if ( this.declaration ) this.declaration.activate(); + } +} diff --git a/src/ast/nodes/IfStatement.js b/src/ast/nodes/IfStatement.js new file mode 100644 index 0000000..baccbd5 --- /dev/null +++ b/src/ast/nodes/IfStatement.js @@ -0,0 +1,73 @@ +import Node from '../Node.js'; +import { UNKNOWN } from '../values.js'; + +// TODO DRY this out +export default class IfStatement extends Node { + bind ( scope ) { + if ( this.module.bundle.treeshake ) { + if ( this.testValue === UNKNOWN ) { + super.bind( scope ); + } + + else if ( this.testValue ) { + this.consequent.bind( scope ); + this.alternate = null; + } else if ( this.alternate ) { + this.alternate.bind( scope ); + this.consequent = null; + } + } + + else { + super.bind( scope ); + } + } + + initialise ( scope ) { + this.testValue = this.test.getValue(); + + if ( this.module.bundle.treeshake ) { + if ( this.testValue === UNKNOWN ) { + super.initialise( scope ); + } + + else if ( this.testValue ) { + this.consequent.initialise( scope ); + } else if ( this.alternate ) { + this.alternate.initialise( scope ); + } + } + + else { + super.initialise( scope ); + } + } + + render ( code, es ) { + if ( this.module.bundle.treeshake ) { + if ( this.testValue === UNKNOWN ) { + super.render( code, es ); + } + + else { + code.overwrite( this.test.start, this.test.end, JSON.stringify( this.testValue ) ); + + // TODO if no block-scoped declarations, remove enclosing + // curlies and dedent block (if there is a block) + + if ( this.testValue ) { + code.remove( this.start, this.consequent.start ); + code.remove( this.consequent.end, this.end ); + this.consequent.render( code, es ); + } else { + code.remove( this.start, this.alternate ? this.alternate.start : this.next || this.end ); + if ( this.alternate ) this.alternate.render( code, es ); + } + } + } + + else { + super.render( code, es ); + } + } +} diff --git a/src/ast/nodes/ImportDeclaration.js b/src/ast/nodes/ImportDeclaration.js new file mode 100644 index 0000000..0edc68b --- /dev/null +++ b/src/ast/nodes/ImportDeclaration.js @@ -0,0 +1,16 @@ +import Node from '../Node.js'; + +export default class ImportDeclaration extends Node { + bind () { + // noop + // TODO do the inter-module binding setup here? + } + + initialise () { + this.isImportDeclaration = true; + } + + render ( code ) { + code.remove( this.start, this.next || this.end ); + } +} diff --git a/src/ast/nodes/Literal.js b/src/ast/nodes/Literal.js new file mode 100644 index 0000000..3b54f14 --- /dev/null +++ b/src/ast/nodes/Literal.js @@ -0,0 +1,17 @@ +import Node from '../Node.js'; + +export default class Literal extends Node { + getValue () { + return this.value; + } + + gatherPossibleValues ( values ) { + values.add( this ); + } + + render ( code ) { + if ( typeof this.value === 'string' ) { + code.indentExclusionRanges.push([ this.start + 1, this.end - 1 ]); + } + } +} diff --git a/src/ast/nodes/MemberExpression.js b/src/ast/nodes/MemberExpression.js new file mode 100644 index 0000000..ea373cd --- /dev/null +++ b/src/ast/nodes/MemberExpression.js @@ -0,0 +1,74 @@ +import isReference from '../utils/isReference.js'; +import Node from '../Node.js'; +import { UNKNOWN } from '../values.js'; + +class Keypath { + constructor ( node ) { + this.parts = []; + + while ( node.type === 'MemberExpression' ) { + this.parts.unshift( node.property ); + node = node.object; + } + + this.root = node; + } +} + +export default class MemberExpression extends Node { + bind ( scope ) { + // if this resolves to a namespaced declaration, prepare + // to replace it + // TODO this code is a bit inefficient + if ( isReference( this ) ) { // TODO optimise namespace access like `foo['bar']` as well + const keypath = new Keypath( this ); + + let declaration = scope.findDeclaration( keypath.root.name ); + + while ( declaration.isNamespace && keypath.parts.length ) { + const part = keypath.parts[0]; + declaration = declaration.module.traceExport( part.name ); + + if ( !declaration ) { + this.module.bundle.onwarn( `Export '${part.name}' is not defined by '${this.module.id}'` ); + break; + } + + keypath.parts.shift(); + } + + if ( keypath.parts.length ) { + super.bind( scope ); + return; // not a namespaced declaration + } + + this.declaration = declaration; + + if ( declaration.isExternal ) { + declaration.module.suggestName( keypath.root.name ); + } + } + + else { + super.bind( scope ); + } + } + + gatherPossibleValues ( values ) { + values.add( UNKNOWN ); // TODO + } + + render ( code, es ) { + if ( this.declaration ) { + const name = this.declaration.getName( es ); + if ( name !== this.name ) code.overwrite( this.start, this.end, name, true ); + } + + super.render( code, es ); + } + + run ( scope ) { + if ( this.declaration ) this.declaration.activate(); + super.run( scope ); + } +} diff --git a/src/ast/nodes/NewExpression.js b/src/ast/nodes/NewExpression.js new file mode 100644 index 0000000..8bfbb33 --- /dev/null +++ b/src/ast/nodes/NewExpression.js @@ -0,0 +1,8 @@ +import Node from '../Node.js'; +import callHasEffects from './shared/callHasEffects.js'; + +export default class NewExpression extends Node { + hasEffects ( scope ) { + return callHasEffects( scope, this.callee ); + } +} diff --git a/src/ast/nodes/ObjectExpression.js b/src/ast/nodes/ObjectExpression.js new file mode 100644 index 0000000..724cb00 --- /dev/null +++ b/src/ast/nodes/ObjectExpression.js @@ -0,0 +1,8 @@ +import Node from '../Node.js'; +import { OBJECT } from '../values.js'; + +export default class ObjectExpression extends Node { + gatherPossibleValues ( values ) { + values.add( OBJECT ); + } +} diff --git a/src/ast/nodes/ParenthesizedExpression.js b/src/ast/nodes/ParenthesizedExpression.js new file mode 100644 index 0000000..7037804 --- /dev/null +++ b/src/ast/nodes/ParenthesizedExpression.js @@ -0,0 +1,11 @@ +import Node from '../Node.js'; + +export default class ParenthesizedExpression extends Node { + getPossibleValues ( values ) { + return this.expression.getPossibleValues( values ); + } + + getValue () { + return this.expression.getValue(); + } +} diff --git a/src/ast/nodes/ReturnStatement.js b/src/ast/nodes/ReturnStatement.js new file mode 100644 index 0000000..bff5ae1 --- /dev/null +++ b/src/ast/nodes/ReturnStatement.js @@ -0,0 +1,7 @@ +import Node from '../Node.js'; + +export default class ReturnStatement extends Node { + // hasEffects () { + // return true; + // } +} diff --git a/src/ast/nodes/TemplateLiteral.js b/src/ast/nodes/TemplateLiteral.js new file mode 100644 index 0000000..057ce12 --- /dev/null +++ b/src/ast/nodes/TemplateLiteral.js @@ -0,0 +1,7 @@ +import Node from '../Node.js'; + +export default class TemplateLiteral extends Node { + render ( code ) { + code.indentExclusionRanges.push([ this.start, this.end ]); + } +} diff --git a/src/ast/nodes/ThisExpression.js b/src/ast/nodes/ThisExpression.js new file mode 100644 index 0000000..e614194 --- /dev/null +++ b/src/ast/nodes/ThisExpression.js @@ -0,0 +1,20 @@ +import Node from '../Node.js'; + +export default class ThisExpression extends Node { + initialise ( scope ) { + const lexicalBoundary = scope.findLexicalBoundary(); + + if ( lexicalBoundary.isModuleScope ) { + this.alias = this.module.bundle.context; + if ( this.alias === 'undefined' ) { + this.module.bundle.onwarn( 'The `this` keyword is equivalent to `undefined` at the top level of an ES module, and has been rewritten' ); + } + } + } + + render ( code ) { + if ( this.alias ) { + code.overwrite( this.start, this.end, this.alias, true ); + } + } +} diff --git a/src/ast/nodes/UnaryExpression.js b/src/ast/nodes/UnaryExpression.js new file mode 100644 index 0000000..9be1c2c --- /dev/null +++ b/src/ast/nodes/UnaryExpression.js @@ -0,0 +1,34 @@ +import Node from '../Node.js'; +import { UNKNOWN } from '../values.js'; + +const operators = { + "-": value => -value, + "+": value => +value, + "!": value => !value, + "~": value => ~value, + typeof: value => typeof value, + void: () => undefined, + delete: () => UNKNOWN +}; + +export default class UnaryExpression extends Node { + bind ( scope ) { + if ( this.value === UNKNOWN ) super.bind( scope ); + } + + getValue () { + const argumentValue = this.argument.getValue(); + if ( argumentValue === UNKNOWN ) return UNKNOWN; + + return operators[ this.operator ]( argumentValue ); + } + + hasEffects ( scope ) { + return this.operator === 'delete' || this.argument.hasEffects( scope ); + } + + initialise ( scope ) { + this.value = this.getValue(); + if ( this.value === UNKNOWN ) super.initialise( scope ); + } +} diff --git a/src/ast/nodes/UpdateExpression.js b/src/ast/nodes/UpdateExpression.js new file mode 100644 index 0000000..fc9d1ce --- /dev/null +++ b/src/ast/nodes/UpdateExpression.js @@ -0,0 +1,35 @@ +import Node from '../Node.js'; +import disallowIllegalReassignment from './shared/disallowIllegalReassignment.js'; +import isUsedByBundle from './shared/isUsedByBundle.js'; +import { NUMBER } from '../values.js'; + +export default class UpdateExpression extends Node { + bind ( scope ) { + let subject = this.argument; + while ( this.argument.type === 'ParenthesizedExpression' ) subject = subject.expression; + + this.subject = subject; + disallowIllegalReassignment( scope, this.argument ); + + if ( subject.type === 'Identifier' ) { + const declaration = scope.findDeclaration( subject.name ); + declaration.isReassigned = true; + declaration.possibleValues.add( NUMBER ); + } + + super.bind( scope ); + } + + hasEffects ( scope ) { + return isUsedByBundle( scope, this.subject ); + } + + initialise ( scope ) { + this.module.bundle.dependentExpressions.push( this ); + super.initialise( scope ); + } + + isUsedByBundle () { + return isUsedByBundle( this.findScope(), this.subject ); + } +} diff --git a/src/ast/nodes/VariableDeclaration.js b/src/ast/nodes/VariableDeclaration.js new file mode 100644 index 0000000..5ce99e9 --- /dev/null +++ b/src/ast/nodes/VariableDeclaration.js @@ -0,0 +1,86 @@ +import Node from '../Node.js'; +import extractNames from '../utils/extractNames.js'; + +function getSeparator ( code, start ) { + let c = start; + + while ( c > 0 && code[ c - 1 ] !== '\n' ) { + c -= 1; + if ( code[c] === ';' || code[c] === '{' ) return '; '; + } + + const lineStart = code.slice( c, start ).match( /^\s*/ )[0]; + + return `;\n${lineStart}`; +} + +export default class VariableDeclaration extends Node { + render ( code, es ) { + const treeshake = this.module.bundle.treeshake; + const separator = this.declarations.length ? getSeparator( this.module.code, this.start ) : ''; + + let c = this.start; + let empty = true; + + for ( let i = 0; i < this.declarations.length; i += 1 ) { + const declarator = this.declarations[i]; + + const prefix = empty ? '' : separator; // TODO indentation + + if ( declarator.id.type === 'Identifier' ) { + const proxy = declarator.proxies.get( declarator.id.name ); + const isExportedAndReassigned = !es && proxy.exportName && proxy.isReassigned; + + if ( isExportedAndReassigned ) { + if ( declarator.init ) { + code.overwrite( c, declarator.start, prefix ); + c = declarator.end; + empty = false; + } + } else if ( !treeshake || proxy.activated ) { + code.overwrite( c, declarator.start, `${prefix}${this.kind} ` ); // TODO indentation + c = declarator.end; + empty = false; + } + } + + else { + const exportAssignments = []; + let activated = false; + + extractNames( declarator.id ).forEach( name => { + const proxy = declarator.proxies.get( name ); + const isExportedAndReassigned = !es && proxy.exportName && proxy.isReassigned; + + if ( isExportedAndReassigned ) { + // code.overwrite( c, declarator.start, prefix ); + // c = declarator.end; + // empty = false; + exportAssignments.push( 'TODO' ); + } else if ( declarator.activated ) { + activated = true; + } + }); + + if ( !treeshake || activated ) { + code.overwrite( c, declarator.start, `${prefix}${this.kind} ` ); // TODO indentation + c = declarator.end; + empty = false; + } + + if ( exportAssignments.length ) { + throw new Error( 'TODO' ); + } + } + + declarator.render( code, es ); + } + + if ( treeshake && empty ) { + code.remove( this.leadingCommentStart || this.start, this.next || this.end ); + } else if ( this.end > c ) { + const hasSemicolon = code.original[ this.end - 1 ] === ';'; + code.overwrite( c, this.end, hasSemicolon ? ';' : '' ); + } + } +} diff --git a/src/ast/nodes/VariableDeclarator.js b/src/ast/nodes/VariableDeclarator.js new file mode 100644 index 0000000..61ca51b --- /dev/null +++ b/src/ast/nodes/VariableDeclarator.js @@ -0,0 +1,89 @@ +import Node from '../Node.js'; +import extractNames from '../utils/extractNames.js'; +import { UNKNOWN } from '../values.js'; + +class DeclaratorProxy { + constructor ( name, declarator, isTopLevel, init ) { + this.name = name; + this.declarator = declarator; + + this.activated = false; + this.isReassigned = false; + this.exportName = null; + + this.possibleValues = new Set( init ? [ init ] : null ); + } + + activate () { + this.activated = true; + this.declarator.activate(); + } + + addReference () { + /* noop? */ + } + + gatherPossibleValues ( values ) { + this.possibleValues.forEach( value => values.add( value ) ); + } + + getName ( es ) { + // TODO desctructuring... + if ( es ) return this.name; + if ( !this.isReassigned || !this.exportName ) return this.name; + + return `exports.${this.exportName}`; + } + + toString () { + return this.name; + } +} + +export default class VariableDeclarator extends Node { + activate () { + if ( this.activated ) return; + this.activated = true; + + this.run( this.findScope() ); + } + + hasEffects ( scope ) { + return this.init && this.init.hasEffects( scope ); + } + + initialise ( scope ) { + this.proxies = new Map(); + + const lexicalBoundary = scope.findLexicalBoundary(); + + const init = this.init ? + ( this.id.type === 'Identifier' ? this.init : UNKNOWN ) : // TODO maybe UNKNOWN is unnecessary + null; + + extractNames( this.id ).forEach( name => { + const proxy = new DeclaratorProxy( name, this, lexicalBoundary.isModuleScope, init ); + + this.proxies.set( name, proxy ); + scope.addDeclaration( name, proxy, this.parent.kind === 'var' ); + }); + + super.initialise( scope ); + } + + render ( code, es ) { + extractNames( this.id ).forEach( name => { + const declaration = this.proxies.get( name ); + + if ( !es && declaration.exportName && declaration.isReassigned ) { + if ( this.init ) { + code.overwrite( this.start, this.id.end, declaration.getName( es ) ); + } else if ( this.module.bundle.treeshake ) { + code.remove( this.start, this.end ); + } + } + }); + + super.render( code, es ); + } +} diff --git a/src/ast/nodes/index.js b/src/ast/nodes/index.js new file mode 100644 index 0000000..c276a34 --- /dev/null +++ b/src/ast/nodes/index.js @@ -0,0 +1,63 @@ +import ArrayExpression from './ArrayExpression.js'; +import ArrowFunctionExpression from './ArrowFunctionExpression.js'; +import AssignmentExpression from './AssignmentExpression.js'; +import BinaryExpression from './BinaryExpression.js'; +import BlockStatement from './BlockStatement.js'; +import CallExpression from './CallExpression.js'; +import ClassDeclaration from './ClassDeclaration.js'; +import ClassExpression from './ClassExpression.js'; +import ConditionalExpression from './ConditionalExpression.js'; +import ExportAllDeclaration from './ExportAllDeclaration.js'; +import ExportDefaultDeclaration from './ExportDefaultDeclaration.js'; +import ExportNamedDeclaration from './ExportNamedDeclaration.js'; +import ExpressionStatement from './ExpressionStatement.js'; +import FunctionDeclaration from './FunctionDeclaration.js'; +import FunctionExpression from './FunctionExpression.js'; +import Identifier from './Identifier.js'; +import IfStatement from './IfStatement.js'; +import ImportDeclaration from './ImportDeclaration.js'; +import Literal from './Literal.js'; +import MemberExpression from './MemberExpression.js'; +import NewExpression from './NewExpression.js'; +import ObjectExpression from './ObjectExpression.js'; +import ParenthesizedExpression from './ParenthesizedExpression.js'; +import ReturnStatement from './ReturnStatement.js'; +import TemplateLiteral from './TemplateLiteral.js'; +import ThisExpression from './ThisExpression.js'; +import UnaryExpression from './UnaryExpression.js'; +import UpdateExpression from './UpdateExpression.js'; +import VariableDeclarator from './VariableDeclarator.js'; +import VariableDeclaration from './VariableDeclaration.js'; + +export default { + ArrayExpression, + ArrowFunctionExpression, + AssignmentExpression, + BinaryExpression, + BlockStatement, + CallExpression, + ClassDeclaration, + ClassExpression, + ConditionalExpression, + ExportAllDeclaration, + ExportDefaultDeclaration, + ExportNamedDeclaration, + ExpressionStatement, + FunctionDeclaration, + FunctionExpression, + Identifier, + IfStatement, + ImportDeclaration, + Literal, + MemberExpression, + NewExpression, + ObjectExpression, + ParenthesizedExpression, + ReturnStatement, + TemplateLiteral, + ThisExpression, + UnaryExpression, + UpdateExpression, + VariableDeclarator, + VariableDeclaration +}; diff --git a/src/ast/nodes/shared/callHasEffects.js b/src/ast/nodes/shared/callHasEffects.js new file mode 100644 index 0000000..74bf0ba --- /dev/null +++ b/src/ast/nodes/shared/callHasEffects.js @@ -0,0 +1,65 @@ +import flatten from '../../utils/flatten.js'; +import isReference from '../../utils/isReference.js'; +import pureFunctions from './pureFunctions.js'; +import { UNKNOWN } from '../../values.js'; + +function fnHasEffects ( fn ) { + if ( fn._calling ) return true; // prevent infinite loops... TODO there must be a better way + fn._calling = true; + + // handle body-less arrow functions + const scope = fn.body.scope || fn.scope; + const body = fn.body.body || [ fn.body ]; + + for ( const node of body ) { + if ( node.hasEffects( scope ) ) { + fn._calling = false; + return true; + } + } + + fn._calling = false; + return false; +} + +export default function callHasEffects ( scope, callee ) { + const values = new Set([ callee ]); + + for ( const node of values ) { + if ( node === UNKNOWN ) return true; // err on side of caution + + if ( /Function/.test( node.type ) ) { + if ( fnHasEffects( node ) ) return true; + } + + else if ( isReference( node ) ) { + const flattened = flatten( node ); + const declaration = scope.findDeclaration( flattened.name ); + + if ( declaration.isGlobal ) { + if ( !pureFunctions[ flattened.keypath ] ) return true; + } + + else if ( declaration.isExternal ) { + return true; // TODO make this configurable? e.g. `path.[whatever]` + } + + else { + if ( node.declaration ) { + node.declaration.gatherPossibleValues( values ); + } else { + return true; + } + } + } + + else { + if ( !node.gatherPossibleValues ) { + throw new Error( 'TODO' ); + } + node.gatherPossibleValues( values ); + } + } + + return false; +} diff --git a/src/ast/nodes/shared/disallowIllegalReassignment.js b/src/ast/nodes/shared/disallowIllegalReassignment.js new file mode 100644 index 0000000..a40969f --- /dev/null +++ b/src/ast/nodes/shared/disallowIllegalReassignment.js @@ -0,0 +1,28 @@ +import getLocation from '../../../utils/getLocation.js'; +import error from '../../../utils/error.js'; + +// TODO tidy this up a bit (e.g. they can both use node.module.imports) +export default function disallowIllegalReassignment ( scope, node ) { + if ( node.type === 'MemberExpression' && node.object.type === 'Identifier' ) { + const declaration = scope.findDeclaration( node.object.name ); + if ( declaration.isNamespace ) { + error({ + message: `Illegal reassignment to import '${node.object.name}'`, + file: node.module.id, + pos: node.start, + loc: getLocation( node.module.code, node.start ) + }); + } + } + + else if ( node.type === 'Identifier' ) { + if ( node.module.imports[ node.name ] && !scope.contains( node.name ) ) { + error({ + message: `Illegal reassignment to import '${node.name}'`, + file: node.module.id, + pos: node.start, + loc: getLocation( node.module.code, node.start ) + }); + } + } +} diff --git a/src/ast/nodes/shared/isUsedByBundle.js b/src/ast/nodes/shared/isUsedByBundle.js new file mode 100644 index 0000000..a294c0c --- /dev/null +++ b/src/ast/nodes/shared/isUsedByBundle.js @@ -0,0 +1,48 @@ +import { + ARRAY, + BOOLEAN, + FUNCTION, + NUMBER, + OBJECT, + STRING, + UNKNOWN +} from '../../values.js'; + +export default function isUsedByBundle ( scope, node ) { + while ( node.type === 'ParenthesizedExpression' ) node = node.expression; + + const expression = node; + while ( node.type === 'MemberExpression' ) node = node.object; + + const declaration = scope.findDeclaration( node.name ); + + if ( declaration.isParam ) { + return true; + + // TODO if we mutate a parameter, assume the worst + // return node !== expression; + } + + if ( declaration.activated ) return true; + + const values = new Set(); + declaration.gatherPossibleValues( values ); + for ( const value of values ) { + if ( value === UNKNOWN ) { + return true; + } + + if ( value.type === 'Identifier' ) { + if ( value.declaration.activated ) { + return true; + } + value.declaration.gatherPossibleValues( values ); + } + + else if ( value.gatherPossibleValues ) { + value.gatherPossibleValues( values ); + } + } + + return false; +} diff --git a/src/utils/pureFunctions.js b/src/ast/nodes/shared/pureFunctions.js similarity index 100% rename from src/utils/pureFunctions.js rename to src/ast/nodes/shared/pureFunctions.js diff --git a/src/ast/scopes/BundleScope.js b/src/ast/scopes/BundleScope.js new file mode 100644 index 0000000..6c0f0ea --- /dev/null +++ b/src/ast/scopes/BundleScope.js @@ -0,0 +1,40 @@ +import Scope from './Scope.js'; +import { UNKNOWN } from '../values'; + +class SyntheticGlobalDeclaration { + constructor ( name ) { + this.name = name; + this.isExternal = true; + this.isGlobal = true; + this.isReassigned = false; + + this.activated = true; + } + + activate () { + /* noop */ + } + + addReference ( reference ) { + reference.declaration = this; + if ( reference.isReassignment ) this.isReassigned = true; + } + + gatherPossibleValues ( values ) { + values.add( UNKNOWN ); + } + + getName () { + return this.name; + } +} + +export default class BundleScope extends Scope { + findDeclaration ( name ) { + if ( !this.declarations[ name ] ) { + this.declarations[ name ] = new SyntheticGlobalDeclaration( name ); + } + + return this.declarations[ name ]; + } +} diff --git a/src/ast/scopes/ModuleScope.js b/src/ast/scopes/ModuleScope.js new file mode 100644 index 0000000..f451d20 --- /dev/null +++ b/src/ast/scopes/ModuleScope.js @@ -0,0 +1,47 @@ +import { forOwn } from '../../utils/object.js'; +import Scope from './Scope.js'; + +export default class ModuleScope extends Scope { + constructor ( module ) { + super({ + isBlockScope: false, + isLexicalBoundary: true, + isModuleScope: true, + parent: module.bundle.scope + }); + + this.module = module; + } + + deshadow ( names ) { + names = new Map( names ); + + forOwn( this.module.imports, specifier => { + if ( specifier.module.isExternal ) return; + + if ( specifier.name === '*' ) { + specifier.module.getExports().forEach( name => { + names.set( name, true ); + }); + } else { + const declaration = specifier.module.traceExport( specifier.name ); + const name = declaration.getName( true ); + if ( name !== specifier.name ) names.set( declaration.getName( true ) ); + } + }); + + super.deshadow( names ); + } + + findDeclaration ( name ) { + if ( this.declarations[ name ] ) { + return this.declarations[ name ]; + } + + return this.module.trace( name ) || this.parent.findDeclaration( name ); + } + + findLexicalBoundary () { + return this; + } +} diff --git a/src/ast/scopes/Scope.js b/src/ast/scopes/Scope.js new file mode 100644 index 0000000..c77e6d2 --- /dev/null +++ b/src/ast/scopes/Scope.js @@ -0,0 +1,91 @@ +import { blank, keys } from '../../utils/object.js'; +import { UNKNOWN } from '../values.js'; + +class Parameter { + constructor ( name ) { + this.name = name; + + this.isParam = true; + this.activated = true; + } + + activate () { + // noop + } + + addReference () { + // noop? + } + + gatherPossibleValues ( values ) { + values.add( UNKNOWN ); // TODO populate this at call time + } + + getName () { + return this.name; + } +} + +export default class Scope { + constructor ( options ) { + options = options || {}; + + this.parent = options.parent; + this.isBlockScope = !!options.isBlockScope; + this.isLexicalBoundary = !!options.isLexicalBoundary; + this.isModuleScope = !!options.isModuleScope; + + this.children = []; + if ( this.parent ) this.parent.children.push( this ); + + this.declarations = blank(); + + if ( this.isLexicalBoundary && !this.isModuleScope ) { + this.declarations.arguments = new Parameter( 'arguments' ); + } + } + + addDeclaration ( name, declaration, isVar, isParam ) { + if ( isVar && this.isBlockScope ) { + this.parent.addDeclaration( name, declaration, isVar, isParam ); + } else { + this.declarations[ name ] = isParam ? new Parameter( name ) : declaration; + } + } + + contains ( name ) { + return !!this.declarations[ name ] || + ( this.parent ? this.parent.contains( name ) : false ); + } + + deshadow ( names ) { + keys( this.declarations ).forEach( key => { + const declaration = this.declarations[ key ]; + + // we can disregard exports.foo etc + if ( declaration.exportName && declaration.isReassigned ) return; + + const name = declaration.getName( true ); + let deshadowed = name; + + let i = 1; + + while ( names.has( deshadowed ) ) { + deshadowed = `${name}$$${i++}`; + } + + declaration.name = deshadowed; + }); + + this.children.forEach( scope => scope.deshadow( names ) ); + } + + findDeclaration ( name ) { + return this.declarations[ name ] || + ( this.parent && this.parent.findDeclaration( name ) ); + } + + findLexicalBoundary () { + return this.isLexicalBoundary ? this : this.parent.findLexicalBoundary(); + } +} diff --git a/src/ast/extractNames.js b/src/ast/utils/extractNames.js similarity index 100% rename from src/ast/extractNames.js rename to src/ast/utils/extractNames.js diff --git a/src/ast/flatten.js b/src/ast/utils/flatten.js similarity index 100% rename from src/ast/flatten.js rename to src/ast/utils/flatten.js diff --git a/src/ast/isReference.js b/src/ast/utils/isReference.js similarity index 100% rename from src/ast/isReference.js rename to src/ast/utils/isReference.js diff --git a/src/ast/values.js b/src/ast/values.js new file mode 100644 index 0000000..dadd74a --- /dev/null +++ b/src/ast/values.js @@ -0,0 +1,8 @@ +// properties are for debugging purposes only +export const ARRAY = { ARRAY: true, toString: () => '[[ARRAY]]' }; +export const BOOLEAN = { BOOLEAN: true, toString: () => '[[BOOLEAN]]' }; +export const FUNCTION = { FUNCTION: true, toString: () => '[[FUNCTION]]' }; +export const NUMBER = { NUMBER: true, toString: () => '[[NUMBER]]' }; +export const OBJECT = { OBJECT: true, toString: () => '[[OBJECT]]' }; +export const STRING = { STRING: true, toString: () => '[[STRING]]' }; +export const UNKNOWN = { UNKNOWN: true, toString: () => '[[UNKNOWN]]' }; diff --git a/src/finalisers/es.js b/src/finalisers/es.js index 4e08ce3..8251fe3 100644 --- a/src/finalisers/es.js +++ b/src/finalisers/es.js @@ -26,8 +26,8 @@ export default function es ( bundle, magicString, { intro }, options ) { } } - const namespaceSpecifier = module.declarations['*'] ? `* as ${module.name}` : null; - const namedSpecifier = importedNames.length ? `{ ${importedNames.join( ', ' )} }` : null; + const namespaceSpecifier = module.declarations['*'] ? `* as ${module.name}` : null; // TODO prevent unnecessary namespace import, e.g form/external-imports + const namedSpecifier = importedNames.length ? `{ ${importedNames.sort().join( ', ' )} }` : null; if ( namespaceSpecifier && namedSpecifier ) { // Namespace and named specifiers cannot be combined. @@ -56,7 +56,7 @@ export default function es ( bundle, magicString, { intro }, options ) { const specifiers = module.getExports().filter( notDefault ).map( name => { const declaration = module.traceExport( name ); - const rendered = declaration.render( true ); + const rendered = declaration.getName( true ); return rendered === name ? name : @@ -67,7 +67,7 @@ export default function es ( bundle, magicString, { intro }, options ) { const defaultExport = module.exports.default || module.reexports.default; if ( defaultExport ) { - exportBlock += `export default ${module.traceExport( 'default' ).render( true )};`; + exportBlock += `export default ${module.traceExport( 'default' ).getName( true )};`; } if ( exportBlock ) magicString.append( '\n\n' + exportBlock.trim() ); diff --git a/src/finalisers/shared/getExportBlock.js b/src/finalisers/shared/getExportBlock.js index 972da59..5a7f34f 100644 --- a/src/finalisers/shared/getExportBlock.js +++ b/src/finalisers/shared/getExportBlock.js @@ -1,6 +1,6 @@ export default function getExportBlock ( entryModule, exportMode, mechanism = 'return' ) { if ( exportMode === 'default' ) { - return `${mechanism} ${entryModule.traceExport( 'default' ).render( false )};`; + return `${mechanism} ${entryModule.traceExport( 'default' ).getName( false )};`; } return entryModule.getExports() @@ -9,7 +9,9 @@ export default function getExportBlock ( entryModule, exportMode, mechanism = 'r const declaration = entryModule.traceExport( name ); const lhs = `exports${prop}`; - const rhs = declaration.render( false ); + const rhs = declaration ? + declaration.getName( false ) : + name; // exporting a global // prevent `exports.count = exports.count` if ( lhs === rhs ) return null; diff --git a/src/utils/run.js b/src/utils/run.js deleted file mode 100644 index 23b0493..0000000 --- a/src/utils/run.js +++ /dev/null @@ -1,119 +0,0 @@ -import { walk } from 'estree-walker'; -import modifierNodes, { isModifierNode } from '../ast/modifierNodes.js'; -import isReference from '../ast/isReference.js'; -import flatten from '../ast/flatten'; -import pureFunctions from './pureFunctions.js'; -import getLocation from './getLocation.js'; -import error from './error.js'; - -function call ( callee, scope, statement, strongDependencies ) { - while ( callee.type === 'ParenthesizedExpression' ) callee = callee.expression; - - if ( callee.type === 'Identifier' ) { - const declaration = scope.findDeclaration( callee.name ) || - statement.module.trace( callee.name ); - - if ( declaration ) { - if ( declaration.isNamespace ) { - error({ - message: `Cannot call a namespace ('${callee.name}')`, - file: statement.module.id, - pos: callee.start, - loc: getLocation( statement.module.code, callee.start ) - }); - } - - return declaration.run( strongDependencies ); - } - - return !pureFunctions[ callee.name ]; - } - - if ( /FunctionExpression/.test( callee.type ) ) { - return run( callee.body, scope, statement, strongDependencies ); - } - - if ( callee.type === 'MemberExpression' ) { - const flattened = flatten( callee ); - - if ( flattened ) { - // if we're calling e.g. Object.keys(thing), there are no side-effects - // TODO make pureFunctions configurable - const declaration = scope.findDeclaration( flattened.name ) || statement.module.trace( flattened.name ); - - return ( !!declaration || !pureFunctions[ flattened.keypath ] ); - } - } - - // complex case like `( a ? b : c )()` or foo[bar].baz()` - // – err on the side of caution - return true; -} - -export default function run ( node, scope, statement, strongDependencies, force ) { - let hasSideEffect = false; - - walk( node, { - enter ( node, parent ) { - if ( !force && /Function/.test( node.type ) ) return this.skip(); - - if ( node._scope ) scope = node._scope; - - if ( isReference( node, parent ) ) { - const flattened = flatten( node ); - - if ( flattened.name === 'arguments' ) { - hasSideEffect = true; - } - - else if ( !scope.contains( flattened.name ) ) { - const declaration = statement.module.trace( flattened.name ); - if ( declaration && !declaration.isExternal ) { - const module = declaration.module || declaration.statement.module; // TODO is this right? - if ( !module.isExternal && !~strongDependencies.indexOf( module ) ) strongDependencies.push( module ); - } - } - } - - else if ( node.type === 'DebuggerStatement' ) { - hasSideEffect = true; - } - - else if ( node.type === 'ThrowStatement' ) { - // we only care about errors thrown at the top level, otherwise - // any function with error checking gets included if called - if ( scope.isTopLevel ) hasSideEffect = true; - } - - else if ( node.type === 'CallExpression' || node.type === 'NewExpression' ) { - if ( call( node.callee, scope, statement, strongDependencies ) ) { - hasSideEffect = true; - } - } - - else if ( isModifierNode( node ) ) { - let subject = node[ modifierNodes[ node.type ] ]; - while ( subject.type === 'MemberExpression' ) subject = subject.object; - - let declaration = scope.findDeclaration( subject.name ); - - if ( declaration ) { - if ( declaration.isParam ) hasSideEffect = true; - } else if ( !scope.isTopLevel ) { - hasSideEffect = true; - } else { - declaration = statement.module.trace( subject.name ); - - if ( !declaration || declaration.isExternal || declaration.isUsed || ( declaration.original && declaration.original.isUsed ) ) { - hasSideEffect = true; - } - } - } - }, - leave ( node ) { - if ( node._scope ) scope = scope.parent; - } - }); - - return hasSideEffect; -} diff --git a/test/form/assignment-to-exports-class-declaration/_config.js b/test/form/assignment-to-exports-class-declaration/_config.js index 0f3d2ef..f7296e0 100644 --- a/test/form/assignment-to-exports-class-declaration/_config.js +++ b/test/form/assignment-to-exports-class-declaration/_config.js @@ -1,5 +1,5 @@ module.exports = { - description: 'does not rewrite class declaration IDs', + description: 'does not rewrite class expression IDs', options: { moduleName: 'myModule' } diff --git a/test/form/external-imports/_expected/es.js b/test/form/external-imports/_expected/es.js index 1c632ef..59d2b5e 100644 --- a/test/form/external-imports/_expected/es.js +++ b/test/form/external-imports/_expected/es.js @@ -1,11 +1,11 @@ import factory from 'factory'; import { bar, foo } from 'baz'; -import { port } from 'shipping-port'; +import { forEach, port } from 'shipping-port'; import * as containers from 'shipping-port'; import alphabet, { a } from 'alphabet'; factory( null ); foo( bar, port ); -containers.forEach( console.log, console ); +forEach( console.log, console ); console.log( a ); console.log( alphabet.length ); diff --git a/test/form/import-external-namespace-and-default/_expected/es.js b/test/form/import-external-namespace-and-default/_expected/es.js index 5655595..07d61c1 100644 --- a/test/form/import-external-namespace-and-default/_expected/es.js +++ b/test/form/import-external-namespace-and-default/_expected/es.js @@ -1,6 +1,7 @@ -import * as foo from 'foo'; +import { bar } from 'foo'; import foo__default from 'foo'; +import * as foo from 'foo'; -console.log( foo.bar ); +console.log( bar ); console.log( foo__default ); diff --git a/test/form/namespace-optimization/_expected/amd.js b/test/form/namespace-optimization/_expected/amd.js index a244c47..95231f1 100644 --- a/test/form/namespace-optimization/_expected/amd.js +++ b/test/form/namespace-optimization/_expected/amd.js @@ -2,6 +2,6 @@ define(function () { 'use strict'; function a () {} - a(); + console.log( a() ); }); diff --git a/test/form/namespace-optimization/_expected/cjs.js b/test/form/namespace-optimization/_expected/cjs.js index b52a7e5..33a83e9 100644 --- a/test/form/namespace-optimization/_expected/cjs.js +++ b/test/form/namespace-optimization/_expected/cjs.js @@ -2,4 +2,4 @@ function a () {} -a(); +console.log( a() ); diff --git a/test/form/namespace-optimization/_expected/es.js b/test/form/namespace-optimization/_expected/es.js index 8bee044..297521e 100644 --- a/test/form/namespace-optimization/_expected/es.js +++ b/test/form/namespace-optimization/_expected/es.js @@ -1,3 +1,3 @@ function a () {} -a(); +console.log( a() ); diff --git a/test/form/namespace-optimization/_expected/iife.js b/test/form/namespace-optimization/_expected/iife.js index 206c237..64673c9 100644 --- a/test/form/namespace-optimization/_expected/iife.js +++ b/test/form/namespace-optimization/_expected/iife.js @@ -3,6 +3,6 @@ function a () {} - a(); + console.log( a() ); }()); diff --git a/test/form/namespace-optimization/_expected/umd.js b/test/form/namespace-optimization/_expected/umd.js index b2bc94f..bf379ef 100644 --- a/test/form/namespace-optimization/_expected/umd.js +++ b/test/form/namespace-optimization/_expected/umd.js @@ -6,6 +6,6 @@ function a () {} - a(); + console.log( a() ); -}))); \ No newline at end of file +}))); diff --git a/test/form/namespace-optimization/main.js b/test/form/namespace-optimization/main.js index e902244..6b955f7 100644 --- a/test/form/namespace-optimization/main.js +++ b/test/form/namespace-optimization/main.js @@ -1,3 +1,3 @@ import * as foo from './foo'; -foo.bar.quux.a(); +console.log( foo.bar.quux.a() ); diff --git a/test/form/no-treeshake/_expected/es.js b/test/form/no-treeshake/_expected/es.js index 54f2add..ddcec9b 100644 --- a/test/form/no-treeshake/_expected/es.js +++ b/test/form/no-treeshake/_expected/es.js @@ -1,3 +1,4 @@ +import { value } from 'external'; import * as external from 'external'; var foo = 'unused'; @@ -11,7 +12,7 @@ function bar () { } function baz () { - return 13 + external.value; + return 13 + value; } var create = Object.create; diff --git a/test/form/removes-existing-sourcemap-comments/_expected/amd.js b/test/form/removes-existing-sourcemap-comments/_expected/amd.js index e614344..99bdf35 100644 --- a/test/form/removes-existing-sourcemap-comments/_expected/amd.js +++ b/test/form/removes-existing-sourcemap-comments/_expected/amd.js @@ -1,6 +1,6 @@ define(function () { 'use strict'; - function foo () { + var foo = function () { return 42; } diff --git a/test/form/removes-existing-sourcemap-comments/_expected/cjs.js b/test/form/removes-existing-sourcemap-comments/_expected/cjs.js index d7a8df2..8735c93 100644 --- a/test/form/removes-existing-sourcemap-comments/_expected/cjs.js +++ b/test/form/removes-existing-sourcemap-comments/_expected/cjs.js @@ -1,6 +1,6 @@ 'use strict'; -function foo () { +var foo = function () { return 42; } diff --git a/test/form/removes-existing-sourcemap-comments/_expected/es.js b/test/form/removes-existing-sourcemap-comments/_expected/es.js index c458828..2a09cfb 100644 --- a/test/form/removes-existing-sourcemap-comments/_expected/es.js +++ b/test/form/removes-existing-sourcemap-comments/_expected/es.js @@ -1,4 +1,4 @@ -function foo () { +var foo = function () { return 42; } diff --git a/test/form/removes-existing-sourcemap-comments/_expected/iife.js b/test/form/removes-existing-sourcemap-comments/_expected/iife.js index 5867d0f..6381613 100644 --- a/test/form/removes-existing-sourcemap-comments/_expected/iife.js +++ b/test/form/removes-existing-sourcemap-comments/_expected/iife.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - function foo () { + var foo = function () { return 42; } diff --git a/test/form/removes-existing-sourcemap-comments/_expected/umd.js b/test/form/removes-existing-sourcemap-comments/_expected/umd.js index bbfb959..b291566 100644 --- a/test/form/removes-existing-sourcemap-comments/_expected/umd.js +++ b/test/form/removes-existing-sourcemap-comments/_expected/umd.js @@ -4,10 +4,10 @@ (factory()); }(this, (function () { 'use strict'; - function foo () { + var foo = function () { return 42; } console.log( foo() ); -}))); \ No newline at end of file +}))); diff --git a/test/form/side-effect-k/_expected/amd.js b/test/form/side-effect-k/_expected/amd.js index e903a01..9ce8a48 100644 --- a/test/form/side-effect-k/_expected/amd.js +++ b/test/form/side-effect-k/_expected/amd.js @@ -1,7 +1,8 @@ define(function () { 'use strict'; function augment ( x ) { - var prop, source; + var prop; + var source; var i = arguments.length; var sources = Array( i - 1 ); @@ -25,4 +26,4 @@ define(function () { 'use strict'; return x; -}); \ No newline at end of file +}); diff --git a/test/form/side-effect-k/_expected/cjs.js b/test/form/side-effect-k/_expected/cjs.js index 7ee74b0..77a3fa7 100644 --- a/test/form/side-effect-k/_expected/cjs.js +++ b/test/form/side-effect-k/_expected/cjs.js @@ -1,7 +1,8 @@ 'use strict'; function augment ( x ) { - var prop, source; + var prop; + var source; var i = arguments.length; var sources = Array( i - 1 ); @@ -23,4 +24,4 @@ function augment ( x ) { function x () {} augment( x.prototype ); -module.exports = x; \ No newline at end of file +module.exports = x; diff --git a/test/form/side-effect-k/_expected/es.js b/test/form/side-effect-k/_expected/es.js index 0cbda65..726addd 100644 --- a/test/form/side-effect-k/_expected/es.js +++ b/test/form/side-effect-k/_expected/es.js @@ -1,5 +1,6 @@ function augment ( x ) { - var prop, source; + var prop; + var source; var i = arguments.length; var sources = Array( i - 1 ); @@ -21,4 +22,4 @@ function augment ( x ) { function x () {} augment( x.prototype ); -export default x; \ No newline at end of file +export default x; diff --git a/test/form/side-effect-k/_expected/iife.js b/test/form/side-effect-k/_expected/iife.js index bccee01..6a6255f 100644 --- a/test/form/side-effect-k/_expected/iife.js +++ b/test/form/side-effect-k/_expected/iife.js @@ -2,7 +2,8 @@ var myBundle = (function () { 'use strict'; function augment ( x ) { - var prop, source; + var prop; + var source; var i = arguments.length; var sources = Array( i - 1 ); @@ -26,4 +27,4 @@ var myBundle = (function () { return x; -}()); \ No newline at end of file +}()); diff --git a/test/form/side-effect-k/_expected/umd.js b/test/form/side-effect-k/_expected/umd.js index 3d6da0b..f6fff9f 100644 --- a/test/form/side-effect-k/_expected/umd.js +++ b/test/form/side-effect-k/_expected/umd.js @@ -5,7 +5,8 @@ }(this, (function () { 'use strict'; function augment ( x ) { - var prop, source; + var prop; + var source; var i = arguments.length; var sources = Array( i - 1 ); @@ -29,4 +30,4 @@ return x; -}))); \ No newline at end of file +}))); diff --git a/test/form/skips-dead-branches-b/_config.js b/test/form/skips-dead-branches-b/_config.js new file mode 100644 index 0000000..22c399c --- /dev/null +++ b/test/form/skips-dead-branches-b/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'skips a dead branch (b)' +}; diff --git a/test/form/skips-dead-branches-b/_expected/amd.js b/test/form/skips-dead-branches-b/_expected/amd.js new file mode 100644 index 0000000..c192900 --- /dev/null +++ b/test/form/skips-dead-branches-b/_expected/amd.js @@ -0,0 +1,9 @@ +define(function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}); diff --git a/test/form/skips-dead-branches-b/_expected/cjs.js b/test/form/skips-dead-branches-b/_expected/cjs.js new file mode 100644 index 0000000..b3e974b --- /dev/null +++ b/test/form/skips-dead-branches-b/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +function bar () { + console.log( 'this should be included' ); +} + +bar(); diff --git a/test/form/skips-dead-branches-b/_expected/es.js b/test/form/skips-dead-branches-b/_expected/es.js new file mode 100644 index 0000000..ec9eb20 --- /dev/null +++ b/test/form/skips-dead-branches-b/_expected/es.js @@ -0,0 +1,5 @@ +function bar () { + console.log( 'this should be included' ); +} + +bar(); diff --git a/test/form/skips-dead-branches-b/_expected/iife.js b/test/form/skips-dead-branches-b/_expected/iife.js new file mode 100644 index 0000000..3b894d9 --- /dev/null +++ b/test/form/skips-dead-branches-b/_expected/iife.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}()); diff --git a/test/form/skips-dead-branches-b/_expected/umd.js b/test/form/skips-dead-branches-b/_expected/umd.js new file mode 100644 index 0000000..b3926b0 --- /dev/null +++ b/test/form/skips-dead-branches-b/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}))); diff --git a/test/function/skips-dead-branches-b/main.js b/test/form/skips-dead-branches-b/main.js similarity index 100% rename from test/function/skips-dead-branches-b/main.js rename to test/form/skips-dead-branches-b/main.js diff --git a/test/form/skips-dead-branches-c/_config.js b/test/form/skips-dead-branches-c/_config.js new file mode 100644 index 0000000..8674142 --- /dev/null +++ b/test/form/skips-dead-branches-c/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'skips a dead branch (c)' +}; diff --git a/test/form/skips-dead-branches-c/_expected/amd.js b/test/form/skips-dead-branches-c/_expected/amd.js new file mode 100644 index 0000000..9dc50f5 --- /dev/null +++ b/test/form/skips-dead-branches-c/_expected/amd.js @@ -0,0 +1,9 @@ +define(function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}); \ No newline at end of file diff --git a/test/form/skips-dead-branches-c/_expected/cjs.js b/test/form/skips-dead-branches-c/_expected/cjs.js new file mode 100644 index 0000000..d6aa952 --- /dev/null +++ b/test/form/skips-dead-branches-c/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +function bar () { + console.log( 'this should be included' ); +} + +bar(); \ No newline at end of file diff --git a/test/form/skips-dead-branches-c/_expected/es.js b/test/form/skips-dead-branches-c/_expected/es.js new file mode 100644 index 0000000..f39bfec --- /dev/null +++ b/test/form/skips-dead-branches-c/_expected/es.js @@ -0,0 +1,5 @@ +function bar () { + console.log( 'this should be included' ); +} + +bar(); \ No newline at end of file diff --git a/test/form/skips-dead-branches-c/_expected/iife.js b/test/form/skips-dead-branches-c/_expected/iife.js new file mode 100644 index 0000000..8d6dcb5 --- /dev/null +++ b/test/form/skips-dead-branches-c/_expected/iife.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}()); \ No newline at end of file diff --git a/test/form/skips-dead-branches-c/_expected/umd.js b/test/form/skips-dead-branches-c/_expected/umd.js new file mode 100644 index 0000000..67588d4 --- /dev/null +++ b/test/form/skips-dead-branches-c/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}))); \ No newline at end of file diff --git a/test/function/skips-dead-branches-c/main.js b/test/form/skips-dead-branches-c/main.js similarity index 100% rename from test/function/skips-dead-branches-c/main.js rename to test/form/skips-dead-branches-c/main.js diff --git a/test/form/skips-dead-branches-d/_config.js b/test/form/skips-dead-branches-d/_config.js new file mode 100644 index 0000000..9779139 --- /dev/null +++ b/test/form/skips-dead-branches-d/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'skips a dead branch (d)' +}; diff --git a/test/form/skips-dead-branches-d/_expected/amd.js b/test/form/skips-dead-branches-d/_expected/amd.js new file mode 100644 index 0000000..9dc50f5 --- /dev/null +++ b/test/form/skips-dead-branches-d/_expected/amd.js @@ -0,0 +1,9 @@ +define(function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}); \ No newline at end of file diff --git a/test/form/skips-dead-branches-d/_expected/cjs.js b/test/form/skips-dead-branches-d/_expected/cjs.js new file mode 100644 index 0000000..d6aa952 --- /dev/null +++ b/test/form/skips-dead-branches-d/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +function bar () { + console.log( 'this should be included' ); +} + +bar(); \ No newline at end of file diff --git a/test/form/skips-dead-branches-d/_expected/es.js b/test/form/skips-dead-branches-d/_expected/es.js new file mode 100644 index 0000000..f39bfec --- /dev/null +++ b/test/form/skips-dead-branches-d/_expected/es.js @@ -0,0 +1,5 @@ +function bar () { + console.log( 'this should be included' ); +} + +bar(); \ No newline at end of file diff --git a/test/form/skips-dead-branches-d/_expected/iife.js b/test/form/skips-dead-branches-d/_expected/iife.js new file mode 100644 index 0000000..8d6dcb5 --- /dev/null +++ b/test/form/skips-dead-branches-d/_expected/iife.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}()); \ No newline at end of file diff --git a/test/form/skips-dead-branches-d/_expected/umd.js b/test/form/skips-dead-branches-d/_expected/umd.js new file mode 100644 index 0000000..67588d4 --- /dev/null +++ b/test/form/skips-dead-branches-d/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}))); \ No newline at end of file diff --git a/test/function/skips-dead-branches-d/main.js b/test/form/skips-dead-branches-d/main.js similarity index 100% rename from test/function/skips-dead-branches-d/main.js rename to test/form/skips-dead-branches-d/main.js diff --git a/test/form/skips-dead-branches-e/_config.js b/test/form/skips-dead-branches-e/_config.js new file mode 100644 index 0000000..d290c80 --- /dev/null +++ b/test/form/skips-dead-branches-e/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'skips a dead branch (e)' +}; diff --git a/test/form/skips-dead-branches-e/_expected/amd.js b/test/form/skips-dead-branches-e/_expected/amd.js new file mode 100644 index 0000000..9dc50f5 --- /dev/null +++ b/test/form/skips-dead-branches-e/_expected/amd.js @@ -0,0 +1,9 @@ +define(function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}); \ No newline at end of file diff --git a/test/form/skips-dead-branches-e/_expected/cjs.js b/test/form/skips-dead-branches-e/_expected/cjs.js new file mode 100644 index 0000000..d6aa952 --- /dev/null +++ b/test/form/skips-dead-branches-e/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +function bar () { + console.log( 'this should be included' ); +} + +bar(); \ No newline at end of file diff --git a/test/form/skips-dead-branches-e/_expected/es.js b/test/form/skips-dead-branches-e/_expected/es.js new file mode 100644 index 0000000..f39bfec --- /dev/null +++ b/test/form/skips-dead-branches-e/_expected/es.js @@ -0,0 +1,5 @@ +function bar () { + console.log( 'this should be included' ); +} + +bar(); \ No newline at end of file diff --git a/test/form/skips-dead-branches-e/_expected/iife.js b/test/form/skips-dead-branches-e/_expected/iife.js new file mode 100644 index 0000000..8d6dcb5 --- /dev/null +++ b/test/form/skips-dead-branches-e/_expected/iife.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}()); \ No newline at end of file diff --git a/test/form/skips-dead-branches-e/_expected/umd.js b/test/form/skips-dead-branches-e/_expected/umd.js new file mode 100644 index 0000000..67588d4 --- /dev/null +++ b/test/form/skips-dead-branches-e/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}))); \ No newline at end of file diff --git a/test/function/skips-dead-branches-e/main.js b/test/form/skips-dead-branches-e/main.js similarity index 100% rename from test/function/skips-dead-branches-e/main.js rename to test/form/skips-dead-branches-e/main.js diff --git a/test/form/skips-dead-branches-f/_config.js b/test/form/skips-dead-branches-f/_config.js new file mode 100644 index 0000000..9ac1d23 --- /dev/null +++ b/test/form/skips-dead-branches-f/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'skips a dead branch (f)' +}; diff --git a/test/form/skips-dead-branches-f/_expected/amd.js b/test/form/skips-dead-branches-f/_expected/amd.js new file mode 100644 index 0000000..9dc50f5 --- /dev/null +++ b/test/form/skips-dead-branches-f/_expected/amd.js @@ -0,0 +1,9 @@ +define(function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}); \ No newline at end of file diff --git a/test/form/skips-dead-branches-f/_expected/cjs.js b/test/form/skips-dead-branches-f/_expected/cjs.js new file mode 100644 index 0000000..d6aa952 --- /dev/null +++ b/test/form/skips-dead-branches-f/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +function bar () { + console.log( 'this should be included' ); +} + +bar(); \ No newline at end of file diff --git a/test/form/skips-dead-branches-f/_expected/es.js b/test/form/skips-dead-branches-f/_expected/es.js new file mode 100644 index 0000000..f39bfec --- /dev/null +++ b/test/form/skips-dead-branches-f/_expected/es.js @@ -0,0 +1,5 @@ +function bar () { + console.log( 'this should be included' ); +} + +bar(); \ No newline at end of file diff --git a/test/form/skips-dead-branches-f/_expected/iife.js b/test/form/skips-dead-branches-f/_expected/iife.js new file mode 100644 index 0000000..8d6dcb5 --- /dev/null +++ b/test/form/skips-dead-branches-f/_expected/iife.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}()); \ No newline at end of file diff --git a/test/form/skips-dead-branches-f/_expected/umd.js b/test/form/skips-dead-branches-f/_expected/umd.js new file mode 100644 index 0000000..67588d4 --- /dev/null +++ b/test/form/skips-dead-branches-f/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}))); \ No newline at end of file diff --git a/test/function/skips-dead-branches-f/main.js b/test/form/skips-dead-branches-f/main.js similarity index 100% rename from test/function/skips-dead-branches-f/main.js rename to test/form/skips-dead-branches-f/main.js diff --git a/test/form/skips-dead-branches-g/_config.js b/test/form/skips-dead-branches-g/_config.js new file mode 100644 index 0000000..f592e05 --- /dev/null +++ b/test/form/skips-dead-branches-g/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'skips a dead conditional expression branch (g)' +}; diff --git a/test/form/skips-dead-branches-g/_expected/amd.js b/test/form/skips-dead-branches-g/_expected/amd.js new file mode 100644 index 0000000..41371dd --- /dev/null +++ b/test/form/skips-dead-branches-g/_expected/amd.js @@ -0,0 +1,10 @@ +define(function () { 'use strict'; + + var a = 0; + var b = 1; + var x = a; + var y = b; + + console.log( x + y ); + +}); \ No newline at end of file diff --git a/test/form/skips-dead-branches-g/_expected/cjs.js b/test/form/skips-dead-branches-g/_expected/cjs.js new file mode 100644 index 0000000..44cffbf --- /dev/null +++ b/test/form/skips-dead-branches-g/_expected/cjs.js @@ -0,0 +1,8 @@ +'use strict'; + +var a = 0; +var b = 1; +var x = a; +var y = b; + +console.log( x + y ); \ No newline at end of file diff --git a/test/form/skips-dead-branches-g/_expected/es.js b/test/form/skips-dead-branches-g/_expected/es.js new file mode 100644 index 0000000..93d5198 --- /dev/null +++ b/test/form/skips-dead-branches-g/_expected/es.js @@ -0,0 +1,6 @@ +var a = 0; +var b = 1; +var x = a; +var y = b; + +console.log( x + y ); \ No newline at end of file diff --git a/test/form/skips-dead-branches-g/_expected/iife.js b/test/form/skips-dead-branches-g/_expected/iife.js new file mode 100644 index 0000000..ce654f4 --- /dev/null +++ b/test/form/skips-dead-branches-g/_expected/iife.js @@ -0,0 +1,11 @@ +(function () { + 'use strict'; + + var a = 0; + var b = 1; + var x = a; + var y = b; + + console.log( x + y ); + +}()); \ No newline at end of file diff --git a/test/form/skips-dead-branches-g/_expected/umd.js b/test/form/skips-dead-branches-g/_expected/umd.js new file mode 100644 index 0000000..40a0a54 --- /dev/null +++ b/test/form/skips-dead-branches-g/_expected/umd.js @@ -0,0 +1,14 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + var a = 0; + var b = 1; + var x = a; + var y = b; + + console.log( x + y ); + +}))); \ No newline at end of file diff --git a/test/form/skips-dead-branches-g/main.js b/test/form/skips-dead-branches-g/main.js new file mode 100644 index 0000000..352481e --- /dev/null +++ b/test/form/skips-dead-branches-g/main.js @@ -0,0 +1,8 @@ +var a = 0; +var b = 1; +var c = 2; + +var x = true ? a : b; +var y = false ? c : b; + +console.log( x + y ); diff --git a/test/form/skips-dead-branches/_config.js b/test/form/skips-dead-branches/_config.js new file mode 100644 index 0000000..078856d --- /dev/null +++ b/test/form/skips-dead-branches/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'skips a dead branch' +}; diff --git a/test/form/skips-dead-branches/_expected/amd.js b/test/form/skips-dead-branches/_expected/amd.js new file mode 100644 index 0000000..9dc50f5 --- /dev/null +++ b/test/form/skips-dead-branches/_expected/amd.js @@ -0,0 +1,9 @@ +define(function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}); \ No newline at end of file diff --git a/test/form/skips-dead-branches/_expected/cjs.js b/test/form/skips-dead-branches/_expected/cjs.js new file mode 100644 index 0000000..d6aa952 --- /dev/null +++ b/test/form/skips-dead-branches/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +function bar () { + console.log( 'this should be included' ); +} + +bar(); \ No newline at end of file diff --git a/test/form/skips-dead-branches/_expected/es.js b/test/form/skips-dead-branches/_expected/es.js new file mode 100644 index 0000000..f39bfec --- /dev/null +++ b/test/form/skips-dead-branches/_expected/es.js @@ -0,0 +1,5 @@ +function bar () { + console.log( 'this should be included' ); +} + +bar(); \ No newline at end of file diff --git a/test/form/skips-dead-branches/_expected/iife.js b/test/form/skips-dead-branches/_expected/iife.js new file mode 100644 index 0000000..8d6dcb5 --- /dev/null +++ b/test/form/skips-dead-branches/_expected/iife.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}()); \ No newline at end of file diff --git a/test/form/skips-dead-branches/_expected/umd.js b/test/form/skips-dead-branches/_expected/umd.js new file mode 100644 index 0000000..67588d4 --- /dev/null +++ b/test/form/skips-dead-branches/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + function bar () { + console.log( 'this should be included' ); + } + + bar(); + +}))); \ No newline at end of file diff --git a/test/function/skips-dead-branches/main.js b/test/form/skips-dead-branches/main.js similarity index 100% rename from test/function/skips-dead-branches/main.js rename to test/form/skips-dead-branches/main.js diff --git a/test/form/string-indentation-b/_expected/amd.js b/test/form/string-indentation-b/_expected/amd.js index f646cb2..2eb44c9 100644 --- a/test/form/string-indentation-b/_expected/amd.js +++ b/test/form/string-indentation-b/_expected/amd.js @@ -2,7 +2,8 @@ define(function () { 'use strict'; var a = 'a'; var b = 'b'; + assert.equal( a, 'a' ); assert.equal( b, 'b' ); -}); \ No newline at end of file +}); diff --git a/test/form/string-indentation-b/_expected/cjs.js b/test/form/string-indentation-b/_expected/cjs.js index 7c799d3..8432e6e 100644 --- a/test/form/string-indentation-b/_expected/cjs.js +++ b/test/form/string-indentation-b/_expected/cjs.js @@ -2,5 +2,6 @@ var a = 'a'; var b = 'b'; + assert.equal( a, 'a' ); -assert.equal( b, 'b' ); \ No newline at end of file +assert.equal( b, 'b' ); diff --git a/test/form/string-indentation-b/_expected/es.js b/test/form/string-indentation-b/_expected/es.js index 7ab432c..6cd3b5a 100644 --- a/test/form/string-indentation-b/_expected/es.js +++ b/test/form/string-indentation-b/_expected/es.js @@ -1,4 +1,5 @@ var a = 'a'; var b = 'b'; + assert.equal( a, 'a' ); -assert.equal( b, 'b' ); \ No newline at end of file +assert.equal( b, 'b' ); diff --git a/test/form/string-indentation-b/_expected/iife.js b/test/form/string-indentation-b/_expected/iife.js index ae8c969..6907cdb 100644 --- a/test/form/string-indentation-b/_expected/iife.js +++ b/test/form/string-indentation-b/_expected/iife.js @@ -3,7 +3,8 @@ var a = 'a'; var b = 'b'; + assert.equal( a, 'a' ); assert.equal( b, 'b' ); -}()); \ No newline at end of file +}()); diff --git a/test/form/string-indentation-b/_expected/umd.js b/test/form/string-indentation-b/_expected/umd.js index 9ebd756..47597be 100644 --- a/test/form/string-indentation-b/_expected/umd.js +++ b/test/form/string-indentation-b/_expected/umd.js @@ -6,7 +6,8 @@ var a = 'a'; var b = 'b'; + assert.equal( a, 'a' ); assert.equal( b, 'b' ); -}))); \ No newline at end of file +}))); diff --git a/test/function/consistent-renaming-b/_config.js b/test/function/consistent-renaming-b/_config.js index 1b8b173..f1b3ee6 100644 --- a/test/function/consistent-renaming-b/_config.js +++ b/test/function/consistent-renaming-b/_config.js @@ -1,3 +1,3 @@ module.exports = { description: 'consistent renaming test b' -}; \ No newline at end of file +}; diff --git a/test/function/consistent-renaming-b/altdir/two.js b/test/function/consistent-renaming-b/altdir/two.js index b97aab5..bd84240 100644 --- a/test/function/consistent-renaming-b/altdir/two.js +++ b/test/function/consistent-renaming-b/altdir/two.js @@ -1,5 +1,6 @@ function two () { + // imported as _two by subdir/two.js return 2; } -export { two }; \ No newline at end of file +export { two }; diff --git a/test/function/consistent-renaming-b/subdir/one.js b/test/function/consistent-renaming-b/subdir/one.js index 0d1985f..26a060c 100644 --- a/test/function/consistent-renaming-b/subdir/one.js +++ b/test/function/consistent-renaming-b/subdir/one.js @@ -1,5 +1,5 @@ import { two } from '../altdir/two'; export default function one () { - return two() - 1; + return two() - 1; } diff --git a/test/function/consistent-renaming-b/subdir/two.js b/test/function/consistent-renaming-b/subdir/two.js index b0004b7..c31c2ff 100644 --- a/test/function/consistent-renaming-b/subdir/two.js +++ b/test/function/consistent-renaming-b/subdir/two.js @@ -1,5 +1,6 @@ import { two as _two } from '../altdir/two'; export default function two () { - return _two(); + // imported as Two by main.js + return _two(); } diff --git a/test/function/cycles-pathological/_config.js b/test/function/cycles-pathological/_config.js index 8d44d9a..e833d4f 100644 --- a/test/function/cycles-pathological/_config.js +++ b/test/function/cycles-pathological/_config.js @@ -1,17 +1,10 @@ var assert = require( 'assert' ); -var warned; - module.exports = { description: 'resolves pathological cyclical dependencies gracefully', buble: true, - options: { - onwarn: function ( message ) { - assert.ok( /Module .+B\.js may be unable to evaluate without .+A\.js, but is included first due to a cyclical dependency. Consider swapping the import statements in .+main\.js to ensure correct ordering/.test( message ) ); - warned = true; - } - }, - runtimeError: function () { - assert.ok( warned ); + warnings: warnings => { + assert.equal( warnings.length, warnings ); + assert.ok( /Module .+B\.js may be unable to evaluate without .+A\.js, but is included first due to a cyclical dependency. Consider swapping the import statements in .+main\.js to ensure correct ordering/.test( warnings[0] ) ); } }; diff --git a/test/function/iife-strong-dependencies/_config.js b/test/function/iife-strong-dependencies/_config.js index f1d7ee1..475e611 100644 --- a/test/function/iife-strong-dependencies/_config.js +++ b/test/function/iife-strong-dependencies/_config.js @@ -1,16 +1,9 @@ var assert = require( 'assert' ); -var warned; - module.exports = { description: 'does not treat references inside IIFEs as weak dependencies', // edge case encountered in THREE.js codebase - options: { - onwarn: function ( message ) { - assert.ok( /Module .+D\.js may be unable to evaluate without .+C\.js, but is included first due to a cyclical dependency. Consider swapping the import statements in .+main\.js to ensure correct ordering/.test( message ) ); - warned = true; - } - }, - runtimeError: function () { - assert.ok( warned ); + warnings: warnings => { + assert.equal( warnings.length, 1 ); + assert.ok( /Module .+D\.js may be unable to evaluate without .+C\.js, but is included first due to a cyclical dependency. Consider swapping the import statements in .+main\.js to ensure correct ordering/.test( warnings[0] ) ); } }; diff --git a/test/function/import-dependency-in-same-module/_config.js b/test/function/import-dependency-in-same-module/_config.js index 622d7d9..a08ff3c 100644 --- a/test/function/import-dependency-in-same-module/_config.js +++ b/test/function/import-dependency-in-same-module/_config.js @@ -1,3 +1,3 @@ module.exports = { description: 'imports a dependency from the same module' -}; \ No newline at end of file +}; diff --git a/test/function/no-imports/_config.js b/test/function/no-imports/_config.js index 47ae3de..be6c448 100644 --- a/test/function/no-imports/_config.js +++ b/test/function/no-imports/_config.js @@ -1,3 +1,3 @@ module.exports = { description: 'creates a bundle from a module with no imports' -}; \ No newline at end of file +}; diff --git a/test/function/reassign-import-fails/_config.js b/test/function/reassign-import-fails/_config.js index e01d090..22591fe 100644 --- a/test/function/reassign-import-fails/_config.js +++ b/test/function/reassign-import-fails/_config.js @@ -4,9 +4,9 @@ var assert = require( 'assert' ); module.exports = { description: 'disallows assignments to imported bindings', error: function ( err ) { + assert.ok( /Illegal reassignment/.test( err.message ) ); assert.equal( path.normalize(err.file), path.resolve( __dirname, 'main.js' ) ); assert.deepEqual( err.loc, { line: 8, column: 0 }); - assert.ok( /Illegal reassignment/.test( err.message ) ); } }; diff --git a/test/function/skips-dead-branches-b/_config.js b/test/function/skips-dead-branches-b/_config.js deleted file mode 100644 index 9833915..0000000 --- a/test/function/skips-dead-branches-b/_config.js +++ /dev/null @@ -1,8 +0,0 @@ -var assert = require( 'assert' ); - -module.exports = { - description: 'skips a dead branch (b)', - code: function ( code ) { - assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); - } -}; diff --git a/test/function/skips-dead-branches-c/_config.js b/test/function/skips-dead-branches-c/_config.js deleted file mode 100644 index c925750..0000000 --- a/test/function/skips-dead-branches-c/_config.js +++ /dev/null @@ -1,8 +0,0 @@ -var assert = require( 'assert' ); - -module.exports = { - description: 'skips a dead branch (c)', - code: function ( code ) { - assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); - } -}; diff --git a/test/function/skips-dead-branches-d/_config.js b/test/function/skips-dead-branches-d/_config.js deleted file mode 100644 index 67c8046..0000000 --- a/test/function/skips-dead-branches-d/_config.js +++ /dev/null @@ -1,8 +0,0 @@ -var assert = require( 'assert' ); - -module.exports = { - description: 'skips a dead branch (d)', - code: function ( code ) { - assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); - } -}; diff --git a/test/function/skips-dead-branches-e/_config.js b/test/function/skips-dead-branches-e/_config.js deleted file mode 100644 index 5c6e6ab..0000000 --- a/test/function/skips-dead-branches-e/_config.js +++ /dev/null @@ -1,8 +0,0 @@ -var assert = require( 'assert' ); - -module.exports = { - description: 'skips a dead branch (e)', - code: function ( code ) { - assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); - } -}; diff --git a/test/function/skips-dead-branches-f/_config.js b/test/function/skips-dead-branches-f/_config.js deleted file mode 100644 index d829cef..0000000 --- a/test/function/skips-dead-branches-f/_config.js +++ /dev/null @@ -1,8 +0,0 @@ -var assert = require( 'assert' ); - -module.exports = { - description: 'skips a dead branch (f)', - code: function ( code ) { - assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); - } -}; diff --git a/test/function/skips-dead-branches-g/_config.js b/test/function/skips-dead-branches-g/_config.js deleted file mode 100644 index 90e7f11..0000000 --- a/test/function/skips-dead-branches-g/_config.js +++ /dev/null @@ -1,9 +0,0 @@ -var assert = require( 'assert' ); - -module.exports = { - description: 'skips a dead conditional expression branch (g)', - code: function ( code ) { - assert.ok( code.indexOf( 'var c = a;' ) >= 0, code ); - assert.ok( code.indexOf( 'var d = b;' ) >= 0, code ); - } -}; diff --git a/test/function/skips-dead-branches-g/main.js b/test/function/skips-dead-branches-g/main.js deleted file mode 100644 index 0c271f4..0000000 --- a/test/function/skips-dead-branches-g/main.js +++ /dev/null @@ -1,6 +0,0 @@ -var a = 0; -var b = 1; -var c = true ? a : b; -var d = false ? a : b; - -console.log( c + d ); diff --git a/test/function/skips-dead-branches/_config.js b/test/function/skips-dead-branches/_config.js deleted file mode 100644 index 9a0d225..0000000 --- a/test/function/skips-dead-branches/_config.js +++ /dev/null @@ -1,8 +0,0 @@ -var assert = require( 'assert' ); - -module.exports = { - description: 'skips a dead branch', - code: function ( code ) { - assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); - } -}; diff --git a/test/function/tracks-alias-mutations/bar.js b/test/function/tracks-alias-mutations/bar.js index 4ec5140..88a92e5 100644 --- a/test/function/tracks-alias-mutations/bar.js +++ b/test/function/tracks-alias-mutations/bar.js @@ -1,6 +1,8 @@ import { foo } from './foo'; -var f = foo; -f.wasMutated = true; +var f = Math.random() <= 1 ? foo : {}; +var f2; +f2 = Math.random() <= 1 ? f : {}; +f2.wasMutated = true; export var bar = 'whatever'; diff --git a/test/test.js b/test/test.js index 92a88f0..615742f 100644 --- a/test/test.js +++ b/test/test.js @@ -243,16 +243,16 @@ describe( 'rollup', function () { } } + if ( config.show || unintendedError ) { + console.log( result.code + '\n\n\n' ); + } + if ( config.warnings ) { config.warnings( warnings ); } else if ( warnings.length ) { throw new Error( `Got unexpected warnings:\n${warnings.join('\n')}` ); } - if ( config.show || unintendedError ) { - console.log( code + '\n\n\n' ); - } - if ( config.solo ) console.groupEnd(); if ( unintendedError ) throw unintendedError; @@ -291,11 +291,12 @@ describe( 'rollup', function () { }, config.options ); ( config.skip ? describe.skip : config.solo ? describe.only : describe )( dir, () => { - const promise = rollup.rollup( options ); + let promise; + const createBundle = () => ( promise || ( promise = rollup.rollup( options ) ) ); PROFILES.forEach( profile => { it( 'generates ' + profile.format, () => { - return promise.then( bundle => { + return createBundle().then( bundle => { const options = extend( {}, config.options, { dest: FORM + '/' + dir + '/_actual/' + profile.format + '.js', format: profile.format From 9ded29e9ec1933708d496c5e6494af5434c0f40d Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 6 Sep 2016 09:38:56 -0400 Subject: [PATCH 185/331] add test for #901 --- test/form/side-effect-p/_config.js | 3 +++ test/form/side-effect-p/_expected/amd.js | 11 +++++++++++ test/form/side-effect-p/_expected/cjs.js | 9 +++++++++ test/form/side-effect-p/_expected/es.js | 7 +++++++ test/form/side-effect-p/_expected/iife.js | 12 ++++++++++++ test/form/side-effect-p/_expected/umd.js | 15 +++++++++++++++ test/form/side-effect-p/bool.js | 1 + test/form/side-effect-p/main.js | 7 +++++++ 8 files changed, 65 insertions(+) create mode 100644 test/form/side-effect-p/_config.js create mode 100644 test/form/side-effect-p/_expected/amd.js create mode 100644 test/form/side-effect-p/_expected/cjs.js create mode 100644 test/form/side-effect-p/_expected/es.js create mode 100644 test/form/side-effect-p/_expected/iife.js create mode 100644 test/form/side-effect-p/_expected/umd.js create mode 100644 test/form/side-effect-p/bool.js create mode 100644 test/form/side-effect-p/main.js diff --git a/test/form/side-effect-p/_config.js b/test/form/side-effect-p/_config.js new file mode 100644 index 0000000..7a8d84b --- /dev/null +++ b/test/form/side-effect-p/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'detects mutation of globals' +}; diff --git a/test/form/side-effect-p/_expected/amd.js b/test/form/side-effect-p/_expected/amd.js new file mode 100644 index 0000000..35e8591 --- /dev/null +++ b/test/form/side-effect-p/_expected/amd.js @@ -0,0 +1,11 @@ +define(function () { 'use strict'; + + var bool = true; + + const hs = document.documentElement.style; + + if ( bool ) { + hs.color = "#222" + } + +}); \ No newline at end of file diff --git a/test/form/side-effect-p/_expected/cjs.js b/test/form/side-effect-p/_expected/cjs.js new file mode 100644 index 0000000..08dc383 --- /dev/null +++ b/test/form/side-effect-p/_expected/cjs.js @@ -0,0 +1,9 @@ +'use strict'; + +var bool = true; + +const hs = document.documentElement.style; + +if ( bool ) { + hs.color = "#222" +} \ No newline at end of file diff --git a/test/form/side-effect-p/_expected/es.js b/test/form/side-effect-p/_expected/es.js new file mode 100644 index 0000000..8e80199 --- /dev/null +++ b/test/form/side-effect-p/_expected/es.js @@ -0,0 +1,7 @@ +var bool = true; + +const hs = document.documentElement.style; + +if ( bool ) { + hs.color = "#222" +} \ No newline at end of file diff --git a/test/form/side-effect-p/_expected/iife.js b/test/form/side-effect-p/_expected/iife.js new file mode 100644 index 0000000..4ea2e35 --- /dev/null +++ b/test/form/side-effect-p/_expected/iife.js @@ -0,0 +1,12 @@ +(function () { + 'use strict'; + + var bool = true; + + const hs = document.documentElement.style; + + if ( bool ) { + hs.color = "#222" + } + +}()); \ No newline at end of file diff --git a/test/form/side-effect-p/_expected/umd.js b/test/form/side-effect-p/_expected/umd.js new file mode 100644 index 0000000..f99ce83 --- /dev/null +++ b/test/form/side-effect-p/_expected/umd.js @@ -0,0 +1,15 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + var bool = true; + + const hs = document.documentElement.style; + + if ( bool ) { + hs.color = "#222" + } + +}))); \ No newline at end of file diff --git a/test/form/side-effect-p/bool.js b/test/form/side-effect-p/bool.js new file mode 100644 index 0000000..ff3177b --- /dev/null +++ b/test/form/side-effect-p/bool.js @@ -0,0 +1 @@ +export default true; diff --git a/test/form/side-effect-p/main.js b/test/form/side-effect-p/main.js new file mode 100644 index 0000000..1ee7791 --- /dev/null +++ b/test/form/side-effect-p/main.js @@ -0,0 +1,7 @@ +import bool from './bool'; + +const hs = document.documentElement.style; + +if ( bool ) { + hs.color = "#222" +} From c096eb4b26d8aef573f657e97642f8fb1ae795ce Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 6 Sep 2016 09:46:54 -0400 Subject: [PATCH 186/331] test for #898 --- test/form/includes-all-namespace-declarations/_config.js | 4 ++++ .../includes-all-namespace-declarations/_expected/amd.js | 5 +++++ .../includes-all-namespace-declarations/_expected/cjs.js | 2 ++ .../includes-all-namespace-declarations/_expected/es.js | 0 .../_expected/iife.js | 6 ++++++ .../includes-all-namespace-declarations/_expected/umd.js | 9 +++++++++ .../includes-all-namespace-declarations/indirection.js | 7 +++++++ test/form/includes-all-namespace-declarations/main.js | 1 + test/form/includes-all-namespace-declarations/unused.js | 3 +++ 9 files changed, 37 insertions(+) create mode 100644 test/form/includes-all-namespace-declarations/_config.js create mode 100644 test/form/includes-all-namespace-declarations/_expected/amd.js create mode 100644 test/form/includes-all-namespace-declarations/_expected/cjs.js create mode 100644 test/form/includes-all-namespace-declarations/_expected/es.js create mode 100644 test/form/includes-all-namespace-declarations/_expected/iife.js create mode 100644 test/form/includes-all-namespace-declarations/_expected/umd.js create mode 100644 test/form/includes-all-namespace-declarations/indirection.js create mode 100644 test/form/includes-all-namespace-declarations/main.js create mode 100644 test/form/includes-all-namespace-declarations/unused.js diff --git a/test/form/includes-all-namespace-declarations/_config.js b/test/form/includes-all-namespace-declarations/_config.js new file mode 100644 index 0000000..66bd7c5 --- /dev/null +++ b/test/form/includes-all-namespace-declarations/_config.js @@ -0,0 +1,4 @@ +module.exports = { + solo: true, + description: 'includes all declarations referenced by reified namespaces' +} diff --git a/test/form/includes-all-namespace-declarations/_expected/amd.js b/test/form/includes-all-namespace-declarations/_expected/amd.js new file mode 100644 index 0000000..ec759b1 --- /dev/null +++ b/test/form/includes-all-namespace-declarations/_expected/amd.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + + +}); \ No newline at end of file diff --git a/test/form/includes-all-namespace-declarations/_expected/cjs.js b/test/form/includes-all-namespace-declarations/_expected/cjs.js new file mode 100644 index 0000000..eb109ab --- /dev/null +++ b/test/form/includes-all-namespace-declarations/_expected/cjs.js @@ -0,0 +1,2 @@ +'use strict'; + diff --git a/test/form/includes-all-namespace-declarations/_expected/es.js b/test/form/includes-all-namespace-declarations/_expected/es.js new file mode 100644 index 0000000..e69de29 diff --git a/test/form/includes-all-namespace-declarations/_expected/iife.js b/test/form/includes-all-namespace-declarations/_expected/iife.js new file mode 100644 index 0000000..f3d1016 --- /dev/null +++ b/test/form/includes-all-namespace-declarations/_expected/iife.js @@ -0,0 +1,6 @@ +(function () { + 'use strict'; + + + +}()); \ No newline at end of file diff --git a/test/form/includes-all-namespace-declarations/_expected/umd.js b/test/form/includes-all-namespace-declarations/_expected/umd.js new file mode 100644 index 0000000..d561e69 --- /dev/null +++ b/test/form/includes-all-namespace-declarations/_expected/umd.js @@ -0,0 +1,9 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + + +}))); \ No newline at end of file diff --git a/test/form/includes-all-namespace-declarations/indirection.js b/test/form/includes-all-namespace-declarations/indirection.js new file mode 100644 index 0000000..d98c18c --- /dev/null +++ b/test/form/includes-all-namespace-declarations/indirection.js @@ -0,0 +1,7 @@ +import * as unused from './unused.js'; + +var indirection = { + unused: unused +}; + +export { indirection }; diff --git a/test/form/includes-all-namespace-declarations/main.js b/test/form/includes-all-namespace-declarations/main.js new file mode 100644 index 0000000..0b45d9e --- /dev/null +++ b/test/form/includes-all-namespace-declarations/main.js @@ -0,0 +1 @@ +import { indirection } from './indirection.js'; diff --git a/test/form/includes-all-namespace-declarations/unused.js b/test/form/includes-all-namespace-declarations/unused.js new file mode 100644 index 0000000..b0ff512 --- /dev/null +++ b/test/form/includes-all-namespace-declarations/unused.js @@ -0,0 +1,3 @@ +function foo () {} + +export { foo }; From 0eecb7d5097039f022a78c51ea1b55a30e9b6dc9 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 6 Sep 2016 09:49:41 -0400 Subject: [PATCH 187/331] re-enable all tests --- test/form/includes-all-namespace-declarations/_config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/form/includes-all-namespace-declarations/_config.js b/test/form/includes-all-namespace-declarations/_config.js index 66bd7c5..30ffc5e 100644 --- a/test/form/includes-all-namespace-declarations/_config.js +++ b/test/form/includes-all-namespace-declarations/_config.js @@ -1,4 +1,3 @@ module.exports = { - solo: true, description: 'includes all declarations referenced by reified namespaces' } From 37d8950d99e56f150c7e7f1a3d2294e9b9904a78 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 6 Sep 2016 09:50:50 -0400 Subject: [PATCH 188/331] skip module order tests for now --- test/function/cycles-pathological/_config.js | 1 + test/function/iife-strong-dependencies/_config.js | 1 + 2 files changed, 2 insertions(+) diff --git a/test/function/cycles-pathological/_config.js b/test/function/cycles-pathological/_config.js index e833d4f..f6d8526 100644 --- a/test/function/cycles-pathological/_config.js +++ b/test/function/cycles-pathological/_config.js @@ -1,6 +1,7 @@ var assert = require( 'assert' ); module.exports = { + skip: true, description: 'resolves pathological cyclical dependencies gracefully', buble: true, warnings: warnings => { diff --git a/test/function/iife-strong-dependencies/_config.js b/test/function/iife-strong-dependencies/_config.js index 475e611..110fa77 100644 --- a/test/function/iife-strong-dependencies/_config.js +++ b/test/function/iife-strong-dependencies/_config.js @@ -1,6 +1,7 @@ var assert = require( 'assert' ); module.exports = { + skip: true, description: 'does not treat references inside IIFEs as weak dependencies', // edge case encountered in THREE.js codebase warnings: warnings => { assert.equal( warnings.length, 1 ); From ad4ca750a59be6a710d322b9a7372dc631907c6a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 6 Sep 2016 10:08:04 -0400 Subject: [PATCH 189/331] linting --- .eslintrc | 5 ++++ src/ast/nodes/AssignmentExpression.js | 2 +- src/ast/nodes/ClassDeclaration.js | 2 +- src/ast/nodes/ExportAllDeclaration.js | 4 ++-- src/ast/nodes/ExportDefaultDeclaration.js | 28 ----------------------- src/ast/nodes/FunctionDeclaration.js | 2 +- src/ast/nodes/shared/isUsedByBundle.js | 12 ++-------- src/utils/path.js | 2 +- 8 files changed, 13 insertions(+), 44 deletions(-) diff --git a/.eslintrc b/.eslintrc index 9fded74..d9150f9 100644 --- a/.eslintrc +++ b/.eslintrc @@ -35,5 +35,10 @@ "parserOptions": { "ecmaVersion": 6, "sourceType": "module" + }, + "settings": { + "import/ignore": [ 0, [ + "\\.path.js$" + ] ] } } diff --git a/src/ast/nodes/AssignmentExpression.js b/src/ast/nodes/AssignmentExpression.js index dd3347d..b8dc0e2 100644 --- a/src/ast/nodes/AssignmentExpression.js +++ b/src/ast/nodes/AssignmentExpression.js @@ -1,7 +1,7 @@ import Node from '../Node.js'; import disallowIllegalReassignment from './shared/disallowIllegalReassignment.js'; import isUsedByBundle from './shared/isUsedByBundle.js'; -import { NUMBER, STRING, UNKNOWN } from '../values.js'; +import { NUMBER, STRING } from '../values.js'; export default class AssignmentExpression extends Node { bind ( scope ) { diff --git a/src/ast/nodes/ClassDeclaration.js b/src/ast/nodes/ClassDeclaration.js index a004b9f..ed773da 100644 --- a/src/ast/nodes/ClassDeclaration.js +++ b/src/ast/nodes/ClassDeclaration.js @@ -9,7 +9,7 @@ export default class ClassDeclaration extends Node { this.body.run(); } - addReference ( reference ) { + addReference () { /* noop? */ } diff --git a/src/ast/nodes/ExportAllDeclaration.js b/src/ast/nodes/ExportAllDeclaration.js index fe929b6..a0f5308 100644 --- a/src/ast/nodes/ExportAllDeclaration.js +++ b/src/ast/nodes/ExportAllDeclaration.js @@ -1,11 +1,11 @@ import Node from '../Node.js'; export default class ExportAllDeclaration extends Node { - initialise ( scope ) { + initialise () { this.isExportDeclaration = true; } - render ( code, es ) { + render ( code ) { code.remove( this.leadingCommentStart || this.start, this.next || this.end ); } } diff --git a/src/ast/nodes/ExportDefaultDeclaration.js b/src/ast/nodes/ExportDefaultDeclaration.js index d65d675..716ffcf 100644 --- a/src/ast/nodes/ExportDefaultDeclaration.js +++ b/src/ast/nodes/ExportDefaultDeclaration.js @@ -2,34 +2,6 @@ import Node from '../Node.js'; const functionOrClassDeclaration = /^(?:Function|Class)Declaration/; -class SyntheticDefaultDeclaration { - constructor ( node, name ) { - this.node = node; - this.name = name; - this.isDefault = true; - } - - activate () { - if ( this.activated ) return; - this.activated = true; - - this.node.run(); - } - - addReference ( reference ) { - this.name = reference.name; - if ( this.original ) this.original.addReference( reference ); - } - - render ( es ) { - if ( this.original && !this.original.isReassigned ) { - return this.original.getName( es ); - } - - return this.name; - } -} - export default class ExportDefaultDeclaration extends Node { initialise ( scope ) { this.isExportDeclaration = true; diff --git a/src/ast/nodes/FunctionDeclaration.js b/src/ast/nodes/FunctionDeclaration.js index 50e93bf..96cba0c 100644 --- a/src/ast/nodes/FunctionDeclaration.js +++ b/src/ast/nodes/FunctionDeclaration.js @@ -10,7 +10,7 @@ export default class FunctionDeclaration extends Node { this.body.run(); } - addReference ( reference ) { + addReference () { /* noop? */ } diff --git a/src/ast/nodes/shared/isUsedByBundle.js b/src/ast/nodes/shared/isUsedByBundle.js index a294c0c..07e315f 100644 --- a/src/ast/nodes/shared/isUsedByBundle.js +++ b/src/ast/nodes/shared/isUsedByBundle.js @@ -1,17 +1,9 @@ -import { - ARRAY, - BOOLEAN, - FUNCTION, - NUMBER, - OBJECT, - STRING, - UNKNOWN -} from '../../values.js'; +import { UNKNOWN } from '../../values.js'; export default function isUsedByBundle ( scope, node ) { while ( node.type === 'ParenthesizedExpression' ) node = node.expression; - const expression = node; + // const expression = node; while ( node.type === 'MemberExpression' ) node = node.object; const declaration = scope.findDeclaration( node.name ); diff --git a/src/utils/path.js b/src/utils/path.js index b787028..d2ce64d 100644 --- a/src/utils/path.js +++ b/src/utils/path.js @@ -13,4 +13,4 @@ export function normalize ( path ) { return path.replace( /\\/g, '/' ); } -export * from 'path'; +export { basename, dirname, extname, relative, resolve } from 'path'; From 2148516fad2a8911ba8a99d47ef3ec5f40f7b91e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 6 Sep 2016 10:13:56 -0400 Subject: [PATCH 190/331] remove 0.12 from build matrix, it doesnt matter any more --- .travis.yml | 1 - appveyor.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 83d1bca..956a81b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ sudo: false language: node_js node_js: - - "0.12" - "4" - "6" env: diff --git a/appveyor.yml b/appveyor.yml index a4389cb..8ab6c7d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,6 @@ init: environment: matrix: # node.js - - nodejs_version: 0.12 - nodejs_version: 4 - nodejs_version: 6 From db0dc75f030b6451977e3437a61c738f74860948 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 6 Sep 2016 10:34:56 -0400 Subject: [PATCH 191/331] parse as ES7 --- src/Module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Module.js b/src/Module.js index d6a418f..205b38b 100644 --- a/src/Module.js +++ b/src/Module.js @@ -13,7 +13,7 @@ import ModuleScope from './ast/scopes/ModuleScope.js'; function tryParse ( code, comments, acornOptions, id ) { try { return parse( code, assign({ - ecmaVersion: 6, + ecmaVersion: 7, sourceType: 'module', onComment: ( block, text, start, end ) => comments.push({ block, text, start, end }), preserveParens: true From 83ccb9725374e0fde9d07043959c397b15d26c67 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 6 Sep 2016 17:10:48 -0400 Subject: [PATCH 192/331] clone ASTs, for fast incremental rebuilds --- src/Module.js | 6 +++--- src/utils/object.js | 21 +++++++++++++++++++++ test/test.js | 16 ++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/Module.js b/src/Module.js index 205b38b..fc3ebd1 100644 --- a/src/Module.js +++ b/src/Module.js @@ -1,6 +1,6 @@ import { parse } from 'acorn/src/index.js'; import MagicString from 'magic-string'; -import { assign, blank, keys } from './utils/object.js'; +import { assign, blank, deepClone, keys } from './utils/object.js'; import { basename, extname } from './utils/path.js'; import getLocation from './utils/getLocation.js'; import makeLegalIdentifier from './utils/makeLegalIdentifier.js'; @@ -35,6 +35,7 @@ export default class Module { this.comments = []; this.ast = ast || tryParse( code, this.comments, bundle.acornOptions, id ); // TODO what happens to comments if AST is provided? + this.astClone = deepClone( this.ast ); this.bundle = bundle; this.id = id; @@ -316,8 +317,7 @@ export default class Module { id: this.id, code: this.code, originalCode: this.originalCode, - // TODO reinstate AST caching (rewrite broke it, because AST is enhanced) - // ast: this.ast, + ast: this.astClone, sourceMapChain: this.sourceMapChain, resolvedIds: this.resolvedIds }; diff --git a/src/utils/object.js b/src/utils/object.js index 4234de3..947c8e1 100644 --- a/src/utils/object.js +++ b/src/utils/object.js @@ -17,3 +17,24 @@ export function assign ( target, ...sources ) { return target; } + +const isArray = Array.isArray; + +// used for cloning ASTs. Not for use with cyclical structures! +export function deepClone ( obj ) { + if ( !obj ) return obj; + if ( typeof obj !== 'object' ) return obj; + + if ( isArray( obj ) ) { + const clone = new Array( obj.length ); + for ( let i = 0; i < obj.length; i += 1 ) clone[i] = deepClone( obj[i] ); + return clone; + } + + const clone = {}; + for ( const key in obj ) { + clone[ key ] = deepClone( obj[ key ] ); + } + + return clone; +} diff --git a/test/test.js b/test/test.js index 615742f..9697e6e 100644 --- a/test/test.js +++ b/test/test.js @@ -6,6 +6,7 @@ const sander = require( 'sander' ); const assert = require( 'assert' ); const { exec } = require( 'child_process' ); const buble = require( 'buble' ); +const acorn = require( 'acorn' ); const rollup = require( '../dist/rollup' ); const FUNCTION = path.resolve( __dirname, 'function' ); @@ -587,6 +588,21 @@ describe( 'rollup', function () { assert.equal( executeBundle( bundle ), 21 ); }); }); + + it( 'keeps ASTs between runs', () => { + return rollup.rollup({ + entry: 'entry', + plugins: [ plugin ] + }).then( bundle => { + const asts = {}; + bundle.modules.forEach( module => { + asts[ module.id ] = module.ast; + }); + + assert.deepEqual( asts.entry, acorn.parse( modules.entry, { sourceType: 'module' }) ); + assert.deepEqual( asts.foo, acorn.parse( modules.foo, { sourceType: 'module' }) ); + }); + }); }); describe( 'hooks', () => { From ccb28cf56b5649edc4c2b5e26f500cc0d4b303ef Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 6 Sep 2016 17:14:26 -0400 Subject: [PATCH 193/331] add test for #893 --- test/function/tracks-alias-mutations-b/_config.js | 13 +++++++++++++ test/function/tracks-alias-mutations-b/main.js | 2 ++ 2 files changed, 15 insertions(+) create mode 100644 test/function/tracks-alias-mutations-b/_config.js create mode 100644 test/function/tracks-alias-mutations-b/main.js diff --git a/test/function/tracks-alias-mutations-b/_config.js b/test/function/tracks-alias-mutations-b/_config.js new file mode 100644 index 0000000..dde47e2 --- /dev/null +++ b/test/function/tracks-alias-mutations-b/_config.js @@ -0,0 +1,13 @@ +const assert = require( 'assert' ); + +const foo = {}; + +module.exports = { + description: 'tracks mutations of aliased objects', + context: { + foo + }, + exports () { + assert.equal( foo.x, 42 ); + } +}; diff --git a/test/function/tracks-alias-mutations-b/main.js b/test/function/tracks-alias-mutations-b/main.js new file mode 100644 index 0000000..81ef7f7 --- /dev/null +++ b/test/function/tracks-alias-mutations-b/main.js @@ -0,0 +1,2 @@ +var _foo = foo; +_foo.x = 42; From 8ecbd7853920f357b937aafd5d262d08eb32e16a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 6 Sep 2016 17:23:55 -0400 Subject: [PATCH 194/331] enable previously failing test for #733 --- test/function/export-two-ways-default-b/_config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/function/export-two-ways-default-b/_config.js b/test/function/export-two-ways-default-b/_config.js index 79fd012..4fa4888 100644 --- a/test/function/export-two-ways-default-b/_config.js +++ b/test/function/export-two-ways-default-b/_config.js @@ -1,4 +1,3 @@ module.exports = { - skip: true, description: 'side-effects are preserved if subject is exported in multiple ways, even if default export has no direct link to original (#733)' }; From 7e67b8b273c09051be17c90cd09f77eb21c88780 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 6 Sep 2016 17:34:35 -0400 Subject: [PATCH 195/331] test for #669 --- test/form/unused-var/_config.js | 3 +++ test/form/unused-var/_expected/amd.js | 7 +++++++ test/form/unused-var/_expected/cjs.js | 5 +++++ test/form/unused-var/_expected/es.js | 3 +++ test/form/unused-var/_expected/iife.js | 8 ++++++++ test/form/unused-var/_expected/umd.js | 11 +++++++++++ test/form/unused-var/foo.js | 6 ++++++ test/form/unused-var/main.js | 2 ++ 8 files changed, 45 insertions(+) create mode 100644 test/form/unused-var/_config.js create mode 100644 test/form/unused-var/_expected/amd.js create mode 100644 test/form/unused-var/_expected/cjs.js create mode 100644 test/form/unused-var/_expected/es.js create mode 100644 test/form/unused-var/_expected/iife.js create mode 100644 test/form/unused-var/_expected/umd.js create mode 100644 test/form/unused-var/foo.js create mode 100644 test/form/unused-var/main.js diff --git a/test/form/unused-var/_config.js b/test/form/unused-var/_config.js new file mode 100644 index 0000000..b89eb86 --- /dev/null +++ b/test/form/unused-var/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'omits unused var declaration' +}; diff --git a/test/form/unused-var/_expected/amd.js b/test/form/unused-var/_expected/amd.js new file mode 100644 index 0000000..babb23a --- /dev/null +++ b/test/form/unused-var/_expected/amd.js @@ -0,0 +1,7 @@ +define(function () { 'use strict'; + + var foo = 'lol'; + + console.log( foo ); + +}); \ No newline at end of file diff --git a/test/form/unused-var/_expected/cjs.js b/test/form/unused-var/_expected/cjs.js new file mode 100644 index 0000000..8628267 --- /dev/null +++ b/test/form/unused-var/_expected/cjs.js @@ -0,0 +1,5 @@ +'use strict'; + +var foo = 'lol'; + +console.log( foo ); \ No newline at end of file diff --git a/test/form/unused-var/_expected/es.js b/test/form/unused-var/_expected/es.js new file mode 100644 index 0000000..2e13c75 --- /dev/null +++ b/test/form/unused-var/_expected/es.js @@ -0,0 +1,3 @@ +var foo = 'lol'; + +console.log( foo ); \ No newline at end of file diff --git a/test/form/unused-var/_expected/iife.js b/test/form/unused-var/_expected/iife.js new file mode 100644 index 0000000..a9b45df --- /dev/null +++ b/test/form/unused-var/_expected/iife.js @@ -0,0 +1,8 @@ +(function () { + 'use strict'; + + var foo = 'lol'; + + console.log( foo ); + +}()); \ No newline at end of file diff --git a/test/form/unused-var/_expected/umd.js b/test/form/unused-var/_expected/umd.js new file mode 100644 index 0000000..71ba44f --- /dev/null +++ b/test/form/unused-var/_expected/umd.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + var foo = 'lol'; + + console.log( foo ); + +}))); \ No newline at end of file diff --git a/test/form/unused-var/foo.js b/test/form/unused-var/foo.js new file mode 100644 index 0000000..3b60a87 --- /dev/null +++ b/test/form/unused-var/foo.js @@ -0,0 +1,6 @@ +var foo = 'lol'; +var bar = 'wut'; + +var baz = bar || foo; + +export { foo }; diff --git a/test/form/unused-var/main.js b/test/form/unused-var/main.js new file mode 100644 index 0000000..1b3e409 --- /dev/null +++ b/test/form/unused-var/main.js @@ -0,0 +1,2 @@ +import { foo } from './foo.js'; +console.log( foo ); From 0913247901b566af2e8e73ef60e5d0cb26b107d6 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 6 Sep 2016 20:19:35 -0400 Subject: [PATCH 196/331] transpile acorn for now, pending new release --- rollup.config.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rollup.config.js b/rollup.config.js index a8ac2c8..f55dc7c 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -22,7 +22,11 @@ export default { entry: 'src/rollup.js', plugins: [ buble({ - include: [ 'src/**', 'node_modules/acorn/**' ], + include: [ 'node_modules/acorn/**' ] + }), + + buble({ + include: [ 'src/**' ], target: { node: 4 } From 92f55845468ae28db2e3b3a761382ba1229f36f6 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 7 Sep 2016 07:30:53 -0400 Subject: [PATCH 197/331] add browser/cli watch tasks --- package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 0eabb8c..394a4ae 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,11 @@ "posttest-coverage": "remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.json -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.lcov -t lcovonly -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped -t html -b dist", "ci": "npm run test-coverage && codecov < coverage/coverage-remapped.lcov", "build": "git rev-parse HEAD > .commithash && rollup -c", - "watch": "rollup -c -w", "build:cli": "rollup -c rollup.config.cli.js", - "build:browser": "git rev-parse HEAD > .commithash && rollup -c rollup.config.browser.js -o dist/rollup.browser.js", + "build:browser": "git rev-parse HEAD > .commithash && rollup -c rollup.config.browser.js", + "watch": "rollup -c -w", + "watch:browser": "rollup -c rollup.config.browser.js -w", + "watch:cli": "rollup -c rollup.config.cli.js -w", "prepublish": "npm run lint && npm test && npm run build:browser", "lint": "eslint src browser test/test.js test/utils test/**/_config.js" }, From 4e96e95def2ad0ffe3bf0025cd3d0ceff7b03b5f Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 7 Sep 2016 07:31:26 -0400 Subject: [PATCH 198/331] configure entry in rollup.config.browser.js --- rollup.config.browser.js | 1 + 1 file changed, 1 insertion(+) diff --git a/rollup.config.browser.js b/rollup.config.browser.js index 687f257..e77e4c6 100644 --- a/rollup.config.browser.js +++ b/rollup.config.browser.js @@ -9,5 +9,6 @@ config.plugins.push({ }); config.format = 'umd'; +config.entry = 'dist/rollup.browser.js'; export default config; From 22951539647b8b098ad61ec6fbc26fa2084e7a11 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 7 Sep 2016 07:33:02 -0400 Subject: [PATCH 199/331] handle updates of parameters --- src/ast/nodes/UpdateExpression.js | 5 ++++- test/function/reassign-parameter/_config.js | 3 +++ test/function/reassign-parameter/main.js | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 test/function/reassign-parameter/_config.js create mode 100644 test/function/reassign-parameter/main.js diff --git a/src/ast/nodes/UpdateExpression.js b/src/ast/nodes/UpdateExpression.js index fc9d1ce..c5b9263 100644 --- a/src/ast/nodes/UpdateExpression.js +++ b/src/ast/nodes/UpdateExpression.js @@ -14,7 +14,10 @@ export default class UpdateExpression extends Node { if ( subject.type === 'Identifier' ) { const declaration = scope.findDeclaration( subject.name ); declaration.isReassigned = true; - declaration.possibleValues.add( NUMBER ); + + if ( declaration.possibleValues ) { + declaration.possibleValues.add( NUMBER ); + } } super.bind( scope ); diff --git a/test/function/reassign-parameter/_config.js b/test/function/reassign-parameter/_config.js new file mode 100644 index 0000000..1701a6f --- /dev/null +++ b/test/function/reassign-parameter/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'parameters can be reassigned/updated' +}; diff --git a/test/function/reassign-parameter/main.js b/test/function/reassign-parameter/main.js new file mode 100644 index 0000000..6c68061 --- /dev/null +++ b/test/function/reassign-parameter/main.js @@ -0,0 +1,7 @@ +function numbers ( i ) { + var array = new Array( i ); + while ( i-- ) array[i] = i + 1; + return array; +} + +assert.deepEqual( numbers( 5 ), [ 1, 2, 3, 4, 5 ] ); From cf1ac32a5339b6ed8f3b40b653c36442f7461199 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 7 Sep 2016 08:23:06 -0400 Subject: [PATCH 200/331] dont separate vars in for loop head --- src/ast/nodes/VariableDeclaration.js | 20 +++++++++++++++---- test/form/side-effect-k/_expected/amd.js | 3 +-- test/form/side-effect-k/_expected/cjs.js | 3 +-- test/form/side-effect-k/_expected/es.js | 3 +-- test/form/side-effect-k/_expected/iife.js | 3 +-- test/form/side-effect-k/_expected/umd.js | 3 +-- .../function/vars-in-for-loop-head/_config.js | 3 +++ test/function/vars-in-for-loop-head/main.js | 10 ++++++++++ 8 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 test/function/vars-in-for-loop-head/_config.js create mode 100644 test/function/vars-in-for-loop-head/main.js diff --git a/src/ast/nodes/VariableDeclaration.js b/src/ast/nodes/VariableDeclaration.js index 5ce99e9..767aab2 100644 --- a/src/ast/nodes/VariableDeclaration.js +++ b/src/ast/nodes/VariableDeclaration.js @@ -15,9 +15,21 @@ function getSeparator ( code, start ) { } export default class VariableDeclaration extends Node { + initialise ( scope ) { + this.scope = scope; + super.initialise( scope ); + } + render ( code, es ) { const treeshake = this.module.bundle.treeshake; - const separator = this.declarations.length ? getSeparator( this.module.code, this.start ) : ''; + + let shouldSeparate = false; + let separator; + + if ( this.scope.isModuleScope && !/forStatement/.test( this.parent.type ) ) { + shouldSeparate = true; + separator = getSeparator( this.module.code, this.start ); + } let c = this.start; let empty = true; @@ -33,12 +45,12 @@ export default class VariableDeclaration extends Node { if ( isExportedAndReassigned ) { if ( declarator.init ) { - code.overwrite( c, declarator.start, prefix ); + if ( shouldSeparate ) code.overwrite( c, declarator.start, prefix ); c = declarator.end; empty = false; } } else if ( !treeshake || proxy.activated ) { - code.overwrite( c, declarator.start, `${prefix}${this.kind} ` ); // TODO indentation + if ( shouldSeparate ) code.overwrite( c, declarator.start, `${prefix}${this.kind} ` ); // TODO indentation c = declarator.end; empty = false; } @@ -63,7 +75,7 @@ export default class VariableDeclaration extends Node { }); if ( !treeshake || activated ) { - code.overwrite( c, declarator.start, `${prefix}${this.kind} ` ); // TODO indentation + if ( shouldSeparate ) code.overwrite( c, declarator.start, `${prefix}${this.kind} ` ); // TODO indentation c = declarator.end; empty = false; } diff --git a/test/form/side-effect-k/_expected/amd.js b/test/form/side-effect-k/_expected/amd.js index 9ce8a48..abfcb98 100644 --- a/test/form/side-effect-k/_expected/amd.js +++ b/test/form/side-effect-k/_expected/amd.js @@ -1,8 +1,7 @@ define(function () { 'use strict'; function augment ( x ) { - var prop; - var source; + var prop, source; var i = arguments.length; var sources = Array( i - 1 ); diff --git a/test/form/side-effect-k/_expected/cjs.js b/test/form/side-effect-k/_expected/cjs.js index 77a3fa7..8219021 100644 --- a/test/form/side-effect-k/_expected/cjs.js +++ b/test/form/side-effect-k/_expected/cjs.js @@ -1,8 +1,7 @@ 'use strict'; function augment ( x ) { - var prop; - var source; + var prop, source; var i = arguments.length; var sources = Array( i - 1 ); diff --git a/test/form/side-effect-k/_expected/es.js b/test/form/side-effect-k/_expected/es.js index 726addd..8647986 100644 --- a/test/form/side-effect-k/_expected/es.js +++ b/test/form/side-effect-k/_expected/es.js @@ -1,6 +1,5 @@ function augment ( x ) { - var prop; - var source; + var prop, source; var i = arguments.length; var sources = Array( i - 1 ); diff --git a/test/form/side-effect-k/_expected/iife.js b/test/form/side-effect-k/_expected/iife.js index 6a6255f..eeb57d4 100644 --- a/test/form/side-effect-k/_expected/iife.js +++ b/test/form/side-effect-k/_expected/iife.js @@ -2,8 +2,7 @@ var myBundle = (function () { 'use strict'; function augment ( x ) { - var prop; - var source; + var prop, source; var i = arguments.length; var sources = Array( i - 1 ); diff --git a/test/form/side-effect-k/_expected/umd.js b/test/form/side-effect-k/_expected/umd.js index f6fff9f..302275a 100644 --- a/test/form/side-effect-k/_expected/umd.js +++ b/test/form/side-effect-k/_expected/umd.js @@ -5,8 +5,7 @@ }(this, (function () { 'use strict'; function augment ( x ) { - var prop; - var source; + var prop, source; var i = arguments.length; var sources = Array( i - 1 ); diff --git a/test/function/vars-in-for-loop-head/_config.js b/test/function/vars-in-for-loop-head/_config.js new file mode 100644 index 0000000..166d6ee --- /dev/null +++ b/test/function/vars-in-for-loop-head/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'does not break apart vars in for loop head' +}; diff --git a/test/function/vars-in-for-loop-head/main.js b/test/function/vars-in-for-loop-head/main.js new file mode 100644 index 0000000..0b35f91 --- /dev/null +++ b/test/function/vars-in-for-loop-head/main.js @@ -0,0 +1,10 @@ +function clone ( things ) { + var result = []; + for ( var i = 0, list = things; i < list.length; i += 1 ) { + var thing = list[i]; + result.push( thing ); + } + return result; +} + +assert.deepEqual( clone([ 1, 2, 3 ]), [ 1, 2, 3 ] ); From fe3647815175c59cd3cefd733fcea046a679bc05 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 7 Sep 2016 08:29:41 -0400 Subject: [PATCH 201/331] do less work at end --- src/Bundle.js | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 9e5f010..881907a 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -130,28 +130,22 @@ export default class Bundle { while ( !settled ) { settled = true; - for ( const expression of this.dependentExpressions ) { - if ( expression.isUsedByBundle() ) { - const statement = expression.findParent( /ExpressionStatement/ ); - - if ( statement && !statement.ran ) { - settled = false; - statement.run( statement.findScope() ); - } + let i = this.dependentExpressions.length; + while ( i-- ) { + const expression = this.dependentExpressions[i]; + const statement = expression.findParent( /ExpressionStatement/ ); + + if ( !statement || statement.ran ) { + this.dependentExpressions.splice( i, 1 ); + } else if ( expression.isUsedByBundle() ) { + settled = false; + statement.run( statement.findScope() ); + this.dependentExpressions.splice( i, 1 ); } } } } - // let settled = false; - // while ( !settled ) { - // settled = true; - // - // this.modules.forEach( module => { - // if ( module.run( this.treeshake ) ) settled = false; - // }); - // } - // Phase 4 – final preparation. We order the modules with an // enhanced topological sort that accounts for cycles, then // ensure that names are deconflicted throughout the bundle From 1abcb17388acc49379cf27ba69a0eeee762ed500 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 7 Sep 2016 08:49:57 -0400 Subject: [PATCH 202/331] oops --- rollup.config.browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rollup.config.browser.js b/rollup.config.browser.js index e77e4c6..95977b4 100644 --- a/rollup.config.browser.js +++ b/rollup.config.browser.js @@ -9,6 +9,6 @@ config.plugins.push({ }); config.format = 'umd'; -config.entry = 'dist/rollup.browser.js'; +config.dest = 'dist/rollup.browser.js'; export default config; From 7df2f00b57869f6cd247f191b59f8a614b08e65f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 7 Sep 2016 17:59:58 -0400 Subject: [PATCH 203/331] add test for #716 but skip it for now --- test/form/duplicated-var-declarations/_config.js | 4 ++++ test/form/duplicated-var-declarations/main.js | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 test/form/duplicated-var-declarations/_config.js create mode 100644 test/form/duplicated-var-declarations/main.js diff --git a/test/form/duplicated-var-declarations/_config.js b/test/form/duplicated-var-declarations/_config.js new file mode 100644 index 0000000..1dd69da --- /dev/null +++ b/test/form/duplicated-var-declarations/_config.js @@ -0,0 +1,4 @@ +module.exports = { + skip: true, + description: 'does not remove duplicated var declarations (#716)' +}; diff --git a/test/form/duplicated-var-declarations/main.js b/test/form/duplicated-var-declarations/main.js new file mode 100644 index 0000000..1eabb5b --- /dev/null +++ b/test/form/duplicated-var-declarations/main.js @@ -0,0 +1,10 @@ +var a = 1, b = 2; + +assert.equal( a, 1 ); +assert.equal( b, 2 ); + +var a = 3, b = 4, c = 5; + +assert.equal( a, 3 ); +assert.equal( b, 4 ); +assert.equal( c, 5 ); From beac2e6eb1032d6c1f9b4f20e070bdb5c878022b Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 7 Sep 2016 18:00:12 -0400 Subject: [PATCH 204/331] fix regex --- src/ast/nodes/VariableDeclaration.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ast/nodes/VariableDeclaration.js b/src/ast/nodes/VariableDeclaration.js index 767aab2..e1be1a0 100644 --- a/src/ast/nodes/VariableDeclaration.js +++ b/src/ast/nodes/VariableDeclaration.js @@ -14,6 +14,8 @@ function getSeparator ( code, start ) { return `;\n${lineStart}`; } +const forStatement = /^For(?:Of|In)Statement/; + export default class VariableDeclaration extends Node { initialise ( scope ) { this.scope = scope; @@ -26,7 +28,7 @@ export default class VariableDeclaration extends Node { let shouldSeparate = false; let separator; - if ( this.scope.isModuleScope && !/forStatement/.test( this.parent.type ) ) { + if ( this.scope.isModuleScope && !forStatement.test( this.parent.type ) ) { shouldSeparate = true; separator = getSeparator( this.module.code, this.start ); } From 34a13a74d0ff9414c27a55358090a580f6537ac9 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 7 Sep 2016 18:03:39 -0400 Subject: [PATCH 205/331] use a set to track which functions are being called --- src/ast/nodes/shared/callHasEffects.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ast/nodes/shared/callHasEffects.js b/src/ast/nodes/shared/callHasEffects.js index 74bf0ba..9a36717 100644 --- a/src/ast/nodes/shared/callHasEffects.js +++ b/src/ast/nodes/shared/callHasEffects.js @@ -3,9 +3,11 @@ import isReference from '../../utils/isReference.js'; import pureFunctions from './pureFunctions.js'; import { UNKNOWN } from '../../values.js'; +const currentlyCalling = new Set(); + function fnHasEffects ( fn ) { - if ( fn._calling ) return true; // prevent infinite loops... TODO there must be a better way - fn._calling = true; + if ( currentlyCalling.has( fn ) ) return true; // prevent infinite loops... TODO there must be a better way + currentlyCalling.add( fn ); // handle body-less arrow functions const scope = fn.body.scope || fn.scope; @@ -13,12 +15,12 @@ function fnHasEffects ( fn ) { for ( const node of body ) { if ( node.hasEffects( scope ) ) { - fn._calling = false; + currentlyCalling.delete( fn ); return true; } } - fn._calling = false; + currentlyCalling.delete( fn ); return false; } From 5e1e5f99c51c718cb3b4c1e4ce4e84189e9f8d54 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 7 Sep 2016 20:34:35 -0400 Subject: [PATCH 206/331] dont assume recursive function calls have side-effects --- src/ast/nodes/shared/callHasEffects.js | 2 +- .../_config.js | 3 +++ .../_expected/amd.js | 20 ++++++++++++++++ .../_expected/cjs.js | 18 ++++++++++++++ .../_expected/es.js | 16 +++++++++++++ .../_expected/iife.js | 21 ++++++++++++++++ .../_expected/umd.js | 24 +++++++++++++++++++ .../main.js | 16 +++++++++++++ test/form/self-calling-function/_config.js | 3 +++ .../self-calling-function/_expected/amd.js | 5 ++++ .../self-calling-function/_expected/cjs.js | 2 ++ .../self-calling-function/_expected/es.js | 0 .../self-calling-function/_expected/iife.js | 6 +++++ .../self-calling-function/_expected/umd.js | 9 +++++++ test/form/self-calling-function/main.js | 14 +++++++++++ 15 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 test/form/self-calling-function-with-effects/_config.js create mode 100644 test/form/self-calling-function-with-effects/_expected/amd.js create mode 100644 test/form/self-calling-function-with-effects/_expected/cjs.js create mode 100644 test/form/self-calling-function-with-effects/_expected/es.js create mode 100644 test/form/self-calling-function-with-effects/_expected/iife.js create mode 100644 test/form/self-calling-function-with-effects/_expected/umd.js create mode 100644 test/form/self-calling-function-with-effects/main.js create mode 100644 test/form/self-calling-function/_config.js create mode 100644 test/form/self-calling-function/_expected/amd.js create mode 100644 test/form/self-calling-function/_expected/cjs.js create mode 100644 test/form/self-calling-function/_expected/es.js create mode 100644 test/form/self-calling-function/_expected/iife.js create mode 100644 test/form/self-calling-function/_expected/umd.js create mode 100644 test/form/self-calling-function/main.js diff --git a/src/ast/nodes/shared/callHasEffects.js b/src/ast/nodes/shared/callHasEffects.js index 9a36717..cf8d964 100644 --- a/src/ast/nodes/shared/callHasEffects.js +++ b/src/ast/nodes/shared/callHasEffects.js @@ -6,7 +6,7 @@ import { UNKNOWN } from '../../values.js'; const currentlyCalling = new Set(); function fnHasEffects ( fn ) { - if ( currentlyCalling.has( fn ) ) return true; // prevent infinite loops... TODO there must be a better way + if ( currentlyCalling.has( fn ) ) return false; // prevent infinite loops... TODO there must be a better way currentlyCalling.add( fn ); // handle body-less arrow functions diff --git a/test/form/self-calling-function-with-effects/_config.js b/test/form/self-calling-function-with-effects/_config.js new file mode 100644 index 0000000..d20f89b --- /dev/null +++ b/test/form/self-calling-function-with-effects/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'discards a self-calling function with side-effects' +}; diff --git a/test/form/self-calling-function-with-effects/_expected/amd.js b/test/form/self-calling-function-with-effects/_expected/amd.js new file mode 100644 index 0000000..ad714bd --- /dev/null +++ b/test/form/self-calling-function-with-effects/_expected/amd.js @@ -0,0 +1,20 @@ +define(function () { 'use strict'; + + function foo ( x ) { + effect( x ); + if ( x > 0 ) foo( x - 1 ); + } + + function bar ( x ) { + effect( x ); + if ( x > 0 ) baz( x ); + } + + function baz ( x ) { + bar( x - 1 ); + } + + foo( 10 ); + bar( 10 ); + +}); \ No newline at end of file diff --git a/test/form/self-calling-function-with-effects/_expected/cjs.js b/test/form/self-calling-function-with-effects/_expected/cjs.js new file mode 100644 index 0000000..83a7a20 --- /dev/null +++ b/test/form/self-calling-function-with-effects/_expected/cjs.js @@ -0,0 +1,18 @@ +'use strict'; + +function foo ( x ) { + effect( x ); + if ( x > 0 ) foo( x - 1 ); +} + +function bar ( x ) { + effect( x ); + if ( x > 0 ) baz( x ); +} + +function baz ( x ) { + bar( x - 1 ); +} + +foo( 10 ); +bar( 10 ); \ No newline at end of file diff --git a/test/form/self-calling-function-with-effects/_expected/es.js b/test/form/self-calling-function-with-effects/_expected/es.js new file mode 100644 index 0000000..8e997b2 --- /dev/null +++ b/test/form/self-calling-function-with-effects/_expected/es.js @@ -0,0 +1,16 @@ +function foo ( x ) { + effect( x ); + if ( x > 0 ) foo( x - 1 ); +} + +function bar ( x ) { + effect( x ); + if ( x > 0 ) baz( x ); +} + +function baz ( x ) { + bar( x - 1 ); +} + +foo( 10 ); +bar( 10 ); \ No newline at end of file diff --git a/test/form/self-calling-function-with-effects/_expected/iife.js b/test/form/self-calling-function-with-effects/_expected/iife.js new file mode 100644 index 0000000..bb848ad --- /dev/null +++ b/test/form/self-calling-function-with-effects/_expected/iife.js @@ -0,0 +1,21 @@ +(function () { + 'use strict'; + + function foo ( x ) { + effect( x ); + if ( x > 0 ) foo( x - 1 ); + } + + function bar ( x ) { + effect( x ); + if ( x > 0 ) baz( x ); + } + + function baz ( x ) { + bar( x - 1 ); + } + + foo( 10 ); + bar( 10 ); + +}()); \ No newline at end of file diff --git a/test/form/self-calling-function-with-effects/_expected/umd.js b/test/form/self-calling-function-with-effects/_expected/umd.js new file mode 100644 index 0000000..a9fd5b2 --- /dev/null +++ b/test/form/self-calling-function-with-effects/_expected/umd.js @@ -0,0 +1,24 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + function foo ( x ) { + effect( x ); + if ( x > 0 ) foo( x - 1 ); + } + + function bar ( x ) { + effect( x ); + if ( x > 0 ) baz( x ); + } + + function baz ( x ) { + bar( x - 1 ); + } + + foo( 10 ); + bar( 10 ); + +}))); \ No newline at end of file diff --git a/test/form/self-calling-function-with-effects/main.js b/test/form/self-calling-function-with-effects/main.js new file mode 100644 index 0000000..7ec54d9 --- /dev/null +++ b/test/form/self-calling-function-with-effects/main.js @@ -0,0 +1,16 @@ +function foo ( x ) { + effect( x ); + if ( x > 0 ) foo( x - 1 ); +} + +function bar ( x ) { + effect( x ); + if ( x > 0 ) baz( x ); +} + +function baz ( x ) { + bar( x - 1 ); +} + +foo( 10 ); +bar( 10 ); diff --git a/test/form/self-calling-function/_config.js b/test/form/self-calling-function/_config.js new file mode 100644 index 0000000..3acb040 --- /dev/null +++ b/test/form/self-calling-function/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'discards a self-calling function without side-effects' +}; diff --git a/test/form/self-calling-function/_expected/amd.js b/test/form/self-calling-function/_expected/amd.js new file mode 100644 index 0000000..ec759b1 --- /dev/null +++ b/test/form/self-calling-function/_expected/amd.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + + +}); \ No newline at end of file diff --git a/test/form/self-calling-function/_expected/cjs.js b/test/form/self-calling-function/_expected/cjs.js new file mode 100644 index 0000000..eb109ab --- /dev/null +++ b/test/form/self-calling-function/_expected/cjs.js @@ -0,0 +1,2 @@ +'use strict'; + diff --git a/test/form/self-calling-function/_expected/es.js b/test/form/self-calling-function/_expected/es.js new file mode 100644 index 0000000..e69de29 diff --git a/test/form/self-calling-function/_expected/iife.js b/test/form/self-calling-function/_expected/iife.js new file mode 100644 index 0000000..f3d1016 --- /dev/null +++ b/test/form/self-calling-function/_expected/iife.js @@ -0,0 +1,6 @@ +(function () { + 'use strict'; + + + +}()); \ No newline at end of file diff --git a/test/form/self-calling-function/_expected/umd.js b/test/form/self-calling-function/_expected/umd.js new file mode 100644 index 0000000..d561e69 --- /dev/null +++ b/test/form/self-calling-function/_expected/umd.js @@ -0,0 +1,9 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + + +}))); \ No newline at end of file diff --git a/test/form/self-calling-function/main.js b/test/form/self-calling-function/main.js new file mode 100644 index 0000000..76ff633 --- /dev/null +++ b/test/form/self-calling-function/main.js @@ -0,0 +1,14 @@ +function foo ( x ) { + if ( x > 0 ) foo( x - 1 ); +} + +function bar ( x ) { + if ( x > 0 ) baz( x ); +} + +function baz ( x ) { + bar( x - 1 ); +} + +foo( 10 ); +bar( 10 ); From 2e32f237774599848a6324c19971673a8447ec84 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 7 Sep 2016 21:34:12 -0400 Subject: [PATCH 207/331] fix double var declaration bug (#716) --- src/ast/nodes/VariableDeclarator.js | 2 ++ src/ast/scopes/Scope.js | 11 +++++++++- .../duplicated-var-declarations/_config.js | 1 - .../_expected/amd.js | 17 +++++++++++++++ .../_expected/cjs.js | 15 +++++++++++++ .../_expected/es.js | 13 ++++++++++++ .../_expected/iife.js | 18 ++++++++++++++++ .../_expected/umd.js | 21 +++++++++++++++++++ 8 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 test/form/duplicated-var-declarations/_expected/amd.js create mode 100644 test/form/duplicated-var-declarations/_expected/cjs.js create mode 100644 test/form/duplicated-var-declarations/_expected/es.js create mode 100644 test/form/duplicated-var-declarations/_expected/iife.js create mode 100644 test/form/duplicated-var-declarations/_expected/umd.js diff --git a/src/ast/nodes/VariableDeclarator.js b/src/ast/nodes/VariableDeclarator.js index 61ca51b..dc35bff 100644 --- a/src/ast/nodes/VariableDeclarator.js +++ b/src/ast/nodes/VariableDeclarator.js @@ -11,12 +11,14 @@ class DeclaratorProxy { this.isReassigned = false; this.exportName = null; + this.duplicates = []; this.possibleValues = new Set( init ? [ init ] : null ); } activate () { this.activated = true; this.declarator.activate(); + this.duplicates.forEach( dupe => dupe.activate() ); } addReference () { diff --git a/src/ast/scopes/Scope.js b/src/ast/scopes/Scope.js index c77e6d2..25512b7 100644 --- a/src/ast/scopes/Scope.js +++ b/src/ast/scopes/Scope.js @@ -1,3 +1,5 @@ +import getLocation from '../../utils/getLocation.js'; +import error from '../../utils/error.js'; import { blank, keys } from '../../utils/object.js'; import { UNKNOWN } from '../values.js'; @@ -49,7 +51,14 @@ export default class Scope { if ( isVar && this.isBlockScope ) { this.parent.addDeclaration( name, declaration, isVar, isParam ); } else { - this.declarations[ name ] = isParam ? new Parameter( name ) : declaration; + const existingDeclaration = this.declarations[ name ]; + + if ( existingDeclaration && existingDeclaration.duplicates ) { + // TODO warn/throw on duplicates? + existingDeclaration.duplicates.push( declaration ); + } else { + this.declarations[ name ] = isParam ? new Parameter( name ) : declaration; + } } } diff --git a/test/form/duplicated-var-declarations/_config.js b/test/form/duplicated-var-declarations/_config.js index 1dd69da..4c3038c 100644 --- a/test/form/duplicated-var-declarations/_config.js +++ b/test/form/duplicated-var-declarations/_config.js @@ -1,4 +1,3 @@ module.exports = { - skip: true, description: 'does not remove duplicated var declarations (#716)' }; diff --git a/test/form/duplicated-var-declarations/_expected/amd.js b/test/form/duplicated-var-declarations/_expected/amd.js new file mode 100644 index 0000000..b43e2a4 --- /dev/null +++ b/test/form/duplicated-var-declarations/_expected/amd.js @@ -0,0 +1,17 @@ +define(function () { 'use strict'; + + var a = 1; + var b = 2; + + assert.equal( a, 1 ); + assert.equal( b, 2 ); + + var a = 3; + var b = 4; + var c = 5; + + assert.equal( a, 3 ); + assert.equal( b, 4 ); + assert.equal( c, 5 ); + +}); diff --git a/test/form/duplicated-var-declarations/_expected/cjs.js b/test/form/duplicated-var-declarations/_expected/cjs.js new file mode 100644 index 0000000..e47b61a --- /dev/null +++ b/test/form/duplicated-var-declarations/_expected/cjs.js @@ -0,0 +1,15 @@ +'use strict'; + +var a = 1; +var b = 2; + +assert.equal( a, 1 ); +assert.equal( b, 2 ); + +var a = 3; +var b = 4; +var c = 5; + +assert.equal( a, 3 ); +assert.equal( b, 4 ); +assert.equal( c, 5 ); diff --git a/test/form/duplicated-var-declarations/_expected/es.js b/test/form/duplicated-var-declarations/_expected/es.js new file mode 100644 index 0000000..cacf6d2 --- /dev/null +++ b/test/form/duplicated-var-declarations/_expected/es.js @@ -0,0 +1,13 @@ +var a = 1; +var b = 2; + +assert.equal( a, 1 ); +assert.equal( b, 2 ); + +var a = 3; +var b = 4; +var c = 5; + +assert.equal( a, 3 ); +assert.equal( b, 4 ); +assert.equal( c, 5 ); diff --git a/test/form/duplicated-var-declarations/_expected/iife.js b/test/form/duplicated-var-declarations/_expected/iife.js new file mode 100644 index 0000000..106066a --- /dev/null +++ b/test/form/duplicated-var-declarations/_expected/iife.js @@ -0,0 +1,18 @@ +(function () { + 'use strict'; + + var a = 1; + var b = 2; + + assert.equal( a, 1 ); + assert.equal( b, 2 ); + + var a = 3; + var b = 4; + var c = 5; + + assert.equal( a, 3 ); + assert.equal( b, 4 ); + assert.equal( c, 5 ); + +}()); diff --git a/test/form/duplicated-var-declarations/_expected/umd.js b/test/form/duplicated-var-declarations/_expected/umd.js new file mode 100644 index 0000000..4574799 --- /dev/null +++ b/test/form/duplicated-var-declarations/_expected/umd.js @@ -0,0 +1,21 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + var a = 1; + var b = 2; + + assert.equal( a, 1 ); + assert.equal( b, 2 ); + + var a = 3; + var b = 4; + var c = 5; + + assert.equal( a, 3 ); + assert.equal( b, 4 ); + assert.equal( c, 5 ); + +}))); From ef676b4081a670d51d61ee8ef29009389e1915bc Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Thu, 8 Sep 2016 09:12:57 -0400 Subject: [PATCH 208/331] disregard effects in dead branches --- src/ast/nodes/ConditionalExpression.js | 12 +++++------ src/ast/nodes/IfStatement.js | 26 ++++------------------- test/form/side-effect-q/_config.js | 3 +++ test/form/side-effect-q/_expected/amd.js | 5 +++++ test/form/side-effect-q/_expected/cjs.js | 2 ++ test/form/side-effect-q/_expected/es.js | 0 test/form/side-effect-q/_expected/iife.js | 6 ++++++ test/form/side-effect-q/_expected/umd.js | 9 ++++++++ test/form/side-effect-q/main.js | 5 +++++ 9 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 test/form/side-effect-q/_config.js create mode 100644 test/form/side-effect-q/_expected/amd.js create mode 100644 test/form/side-effect-q/_expected/cjs.js create mode 100644 test/form/side-effect-q/_expected/es.js create mode 100644 test/form/side-effect-q/_expected/iife.js create mode 100644 test/form/side-effect-q/_expected/umd.js create mode 100644 test/form/side-effect-q/main.js diff --git a/src/ast/nodes/ConditionalExpression.js b/src/ast/nodes/ConditionalExpression.js index 6a6c803..c5e336d 100644 --- a/src/ast/nodes/ConditionalExpression.js +++ b/src/ast/nodes/ConditionalExpression.js @@ -4,13 +4,13 @@ import { UNKNOWN } from '../values.js'; export default class ConditionalExpression extends Node { initialise ( scope ) { if ( this.module.bundle.treeshake ) { - const testValue = this.test.getValue(); + this.testValue = this.test.getValue(); - if ( testValue === UNKNOWN ) { + if ( this.testValue === UNKNOWN ) { super.initialise( scope ); } - else if ( testValue ) { + else if ( this.testValue ) { this.consequent.initialise( scope ); this.alternate = null; } else if ( this.alternate ) { @@ -47,13 +47,11 @@ export default class ConditionalExpression extends Node { } else { - const testValue = this.test.getValue(); - - if ( testValue === UNKNOWN ) { + if ( this.testValue === UNKNOWN ) { super.render( code, es ); } - else if ( testValue ) { + else if ( this.testValue ) { code.remove( this.start, this.consequent.start ); code.remove( this.consequent.end, this.end ); } else { diff --git a/src/ast/nodes/IfStatement.js b/src/ast/nodes/IfStatement.js index baccbd5..1a5c184 100644 --- a/src/ast/nodes/IfStatement.js +++ b/src/ast/nodes/IfStatement.js @@ -3,26 +3,6 @@ import { UNKNOWN } from '../values.js'; // TODO DRY this out export default class IfStatement extends Node { - bind ( scope ) { - if ( this.module.bundle.treeshake ) { - if ( this.testValue === UNKNOWN ) { - super.bind( scope ); - } - - else if ( this.testValue ) { - this.consequent.bind( scope ); - this.alternate = null; - } else if ( this.alternate ) { - this.alternate.bind( scope ); - this.consequent = null; - } - } - - else { - super.bind( scope ); - } - } - initialise ( scope ) { this.testValue = this.test.getValue(); @@ -33,8 +13,10 @@ export default class IfStatement extends Node { else if ( this.testValue ) { this.consequent.initialise( scope ); - } else if ( this.alternate ) { - this.alternate.initialise( scope ); + this.alternate = null; + } else { + if ( this.alternate ) this.alternate.initialise( scope ); + this.consequent = null; } } diff --git a/test/form/side-effect-q/_config.js b/test/form/side-effect-q/_config.js new file mode 100644 index 0000000..944a58a --- /dev/null +++ b/test/form/side-effect-q/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'discards effects in conditional expressions with known test values' +}; diff --git a/test/form/side-effect-q/_expected/amd.js b/test/form/side-effect-q/_expected/amd.js new file mode 100644 index 0000000..ec759b1 --- /dev/null +++ b/test/form/side-effect-q/_expected/amd.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + + +}); \ No newline at end of file diff --git a/test/form/side-effect-q/_expected/cjs.js b/test/form/side-effect-q/_expected/cjs.js new file mode 100644 index 0000000..eb109ab --- /dev/null +++ b/test/form/side-effect-q/_expected/cjs.js @@ -0,0 +1,2 @@ +'use strict'; + diff --git a/test/form/side-effect-q/_expected/es.js b/test/form/side-effect-q/_expected/es.js new file mode 100644 index 0000000..e69de29 diff --git a/test/form/side-effect-q/_expected/iife.js b/test/form/side-effect-q/_expected/iife.js new file mode 100644 index 0000000..f3d1016 --- /dev/null +++ b/test/form/side-effect-q/_expected/iife.js @@ -0,0 +1,6 @@ +(function () { + 'use strict'; + + + +}()); \ No newline at end of file diff --git a/test/form/side-effect-q/_expected/umd.js b/test/form/side-effect-q/_expected/umd.js new file mode 100644 index 0000000..d561e69 --- /dev/null +++ b/test/form/side-effect-q/_expected/umd.js @@ -0,0 +1,9 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + + +}))); \ No newline at end of file diff --git a/test/form/side-effect-q/main.js b/test/form/side-effect-q/main.js new file mode 100644 index 0000000..2272edb --- /dev/null +++ b/test/form/side-effect-q/main.js @@ -0,0 +1,5 @@ +var x = true ? foo () : bar(); + +function foo () { + return 'should be removed, because x is unused'; +} From 95106fa770b19cff7b4f574079ea6cbde6b01721 Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Thu, 8 Sep 2016 08:56:11 -0700 Subject: [PATCH 209/331] Remove unused imports to fix linting. --- src/ast/scopes/Scope.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ast/scopes/Scope.js b/src/ast/scopes/Scope.js index 25512b7..7bb1671 100644 --- a/src/ast/scopes/Scope.js +++ b/src/ast/scopes/Scope.js @@ -1,5 +1,3 @@ -import getLocation from '../../utils/getLocation.js'; -import error from '../../utils/error.js'; import { blank, keys } from '../../utils/object.js'; import { UNKNOWN } from '../values.js'; From bd01c0acb40d5b135c6a7d11513e285fb57105f7 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Thu, 8 Sep 2016 23:01:03 -0400 Subject: [PATCH 210/331] correctly rename children of conditional expressions --- src/ast/nodes/ConditionalExpression.js | 2 ++ src/ast/scopes/Scope.js | 2 -- .../function/rename-conditional-expression-children/_config.js | 3 +++ test/function/rename-conditional-expression-children/foo.js | 2 ++ test/function/rename-conditional-expression-children/main.js | 3 +++ 5 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 test/function/rename-conditional-expression-children/_config.js create mode 100644 test/function/rename-conditional-expression-children/foo.js create mode 100644 test/function/rename-conditional-expression-children/main.js diff --git a/src/ast/nodes/ConditionalExpression.js b/src/ast/nodes/ConditionalExpression.js index c5e336d..9c7b444 100644 --- a/src/ast/nodes/ConditionalExpression.js +++ b/src/ast/nodes/ConditionalExpression.js @@ -54,9 +54,11 @@ export default class ConditionalExpression extends Node { else if ( this.testValue ) { code.remove( this.start, this.consequent.start ); code.remove( this.consequent.end, this.end ); + this.consequent.render( code, es ); } else { code.remove( this.start, this.alternate.start ); code.remove( this.alternate.end, this.end ); + this.alternate.render( code, es ); } } } diff --git a/src/ast/scopes/Scope.js b/src/ast/scopes/Scope.js index 25512b7..7bb1671 100644 --- a/src/ast/scopes/Scope.js +++ b/src/ast/scopes/Scope.js @@ -1,5 +1,3 @@ -import getLocation from '../../utils/getLocation.js'; -import error from '../../utils/error.js'; import { blank, keys } from '../../utils/object.js'; import { UNKNOWN } from '../values.js'; diff --git a/test/function/rename-conditional-expression-children/_config.js b/test/function/rename-conditional-expression-children/_config.js new file mode 100644 index 0000000..7c052c5 --- /dev/null +++ b/test/function/rename-conditional-expression-children/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'correctly renders children of ConditionalExpressions' +}; diff --git a/test/function/rename-conditional-expression-children/foo.js b/test/function/rename-conditional-expression-children/foo.js new file mode 100644 index 0000000..7fe4a4d --- /dev/null +++ b/test/function/rename-conditional-expression-children/foo.js @@ -0,0 +1,2 @@ +export const bar = 42; +export const baz = 43; diff --git a/test/function/rename-conditional-expression-children/main.js b/test/function/rename-conditional-expression-children/main.js new file mode 100644 index 0000000..16bfa0f --- /dev/null +++ b/test/function/rename-conditional-expression-children/main.js @@ -0,0 +1,3 @@ +import * as foo from './foo.js'; + +assert.equal( true ? foo.bar : foo.baz, 42 ); From 316f6041ab7abb4d23bbae353ba3661de2169663 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 08:11:12 -0400 Subject: [PATCH 211/331] always treat literals as leaf nodes --- src/ast/keys.js | 3 ++- test/test.js | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ast/keys.js b/src/ast/keys.js index 99d14ea..194ccf7 100644 --- a/src/ast/keys.js +++ b/src/ast/keys.js @@ -1,3 +1,4 @@ export default { - Program: [ 'body' ] + Program: [ 'body' ], + Literal: [] }; diff --git a/test/test.js b/test/test.js index 9697e6e..ca11679 100644 --- a/test/test.js +++ b/test/test.js @@ -93,6 +93,15 @@ describe( 'rollup', function () { assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, context, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); }); }); + + it( 'treats Literals as leaf nodes, even if first literal encountered is null', () => { + // this test has to be up here, otherwise the bug doesn't have + // an opportunity to present itself + return rollup.rollup({ + entry: 'x', + plugins: [ loader({ x: `var a = null; a = 'a string';` }) ] + }); + }); }); describe( 'bundle.write()', () => { From 06d167b60dc5775c1f44d1422dffe100b6ff629f Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 08:59:22 -0400 Subject: [PATCH 212/331] failing test (skipped for now) --- test/form/side-effect-r/_config.js | 4 ++++ test/form/side-effect-r/main.js | 7 +++++++ 2 files changed, 11 insertions(+) create mode 100644 test/form/side-effect-r/_config.js create mode 100644 test/form/side-effect-r/main.js diff --git a/test/form/side-effect-r/_config.js b/test/form/side-effect-r/_config.js new file mode 100644 index 0000000..2c3f470 --- /dev/null +++ b/test/form/side-effect-r/_config.js @@ -0,0 +1,4 @@ +module.exports = { + skip: true, + description: 'discards unused function expression assigned to a variable that calls itself and a global' +}; diff --git a/test/form/side-effect-r/main.js b/test/form/side-effect-r/main.js new file mode 100644 index 0000000..716ee31 --- /dev/null +++ b/test/form/side-effect-r/main.js @@ -0,0 +1,7 @@ +var foo = function foo() { + if ( whatever ) { + foo(); + } else { + bar(); + } +}; From b05ceb24788aaec77919cb866efbc9c73186983c Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 09:20:10 -0400 Subject: [PATCH 213/331] doh --- src/Module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Module.js b/src/Module.js index fc3ebd1..1c65807 100644 --- a/src/Module.js +++ b/src/Module.js @@ -70,7 +70,7 @@ export default class Module { } this.declarations = blank(); - this.type === 'Module'; // TODO only necessary so that Scope knows this should be treated as a function scope... messy + this.type = 'Module'; // TODO only necessary so that Scope knows this should be treated as a function scope... messy this.scope = new ModuleScope( this ); this.analyse(); From 9fd72a655f67350a773afd34139c75293bdc54c9 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 09:30:14 -0400 Subject: [PATCH 214/331] -> v0.35.0 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3739a73..d598c9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # rollup changelog +## 0.35.0 + +* Rewrite analysis/tree-shaking code ([#902](https://github.com/rollup/rollup/pull/902)) +* Include conditional mutations of global objects ([#901](https://github.com/rollup/rollup/issues/901)) +* Only reify namespaces if necessary ([#898](https://github.com/rollup/rollup/issues/898)) +* Track mutations of aliased globals ([#893](https://github.com/rollup/rollup/issues/893)) +* Include duplicated var declarations ([#716](https://github.com/rollup/rollup/issues/716)) + ## 0.34.13 * Pass `{ format }` through to `transformBundle` ([#867](https://github.com/rollup/rollup/issues/867)) diff --git a/package.json b/package.json index 394a4ae..6f5fb1a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.34.13", + "version": "0.35.0", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 928f7f4f9ab4c8185a0c53c83471419c2077fdc4 Mon Sep 17 00:00:00 2001 From: npmcdn-to-unpkg-bot Date: Sat, 10 Sep 2016 16:25:00 +0100 Subject: [PATCH 215/331] Replace npmcdn.com with unpkg.com --- test/form/paths-function/_config.js | 2 +- test/form/paths-function/_expected/amd.js | 2 +- test/form/paths-function/_expected/cjs.js | 2 +- test/form/paths-function/_expected/es.js | 2 +- test/form/paths-function/_expected/umd.js | 4 ++-- test/form/paths/_config.js | 2 +- test/form/paths/_expected/amd.js | 2 +- test/form/paths/_expected/cjs.js | 2 +- test/form/paths/_expected/es.js | 2 +- test/form/paths/_expected/umd.js | 4 ++-- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/test/form/paths-function/_config.js b/test/form/paths-function/_config.js index d4f6a0d..2d1f055 100644 --- a/test/form/paths-function/_config.js +++ b/test/form/paths-function/_config.js @@ -1,6 +1,6 @@ module.exports = { description: 'external paths (#754)', options: { - paths: id => `https://npmcdn.com/${id}` + paths: id => `https://unpkg.com/${id}` } }; diff --git a/test/form/paths-function/_expected/amd.js b/test/form/paths-function/_expected/amd.js index fe2d243..0893293 100644 --- a/test/form/paths-function/_expected/amd.js +++ b/test/form/paths-function/_expected/amd.js @@ -1,4 +1,4 @@ -define(['https://npmcdn.com/foo'], function (foo) { 'use strict'; +define(['https://unpkg.com/foo'], function (foo) { 'use strict'; foo = 'default' in foo ? foo['default'] : foo; diff --git a/test/form/paths-function/_expected/cjs.js b/test/form/paths-function/_expected/cjs.js index 864ce43..4bb0804 100644 --- a/test/form/paths-function/_expected/cjs.js +++ b/test/form/paths-function/_expected/cjs.js @@ -2,6 +2,6 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -var foo = _interopDefault(require('https://npmcdn.com/foo')); +var foo = _interopDefault(require('https://unpkg.com/foo')); assert.equal( foo, 42 ); diff --git a/test/form/paths-function/_expected/es.js b/test/form/paths-function/_expected/es.js index 1c4fe57..74bfea3 100644 --- a/test/form/paths-function/_expected/es.js +++ b/test/form/paths-function/_expected/es.js @@ -1,3 +1,3 @@ -import foo from 'https://npmcdn.com/foo'; +import foo from 'https://unpkg.com/foo'; assert.equal( foo, 42 ); diff --git a/test/form/paths-function/_expected/umd.js b/test/form/paths-function/_expected/umd.js index 8da109e..e86e892 100644 --- a/test/form/paths-function/_expected/umd.js +++ b/test/form/paths-function/_expected/umd.js @@ -1,6 +1,6 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('https://npmcdn.com/foo')) : - typeof define === 'function' && define.amd ? define(['https://npmcdn.com/foo'], factory) : + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('https://unpkg.com/foo')) : + typeof define === 'function' && define.amd ? define(['https://unpkg.com/foo'], factory) : (factory(global.foo)); }(this, (function (foo) { 'use strict'; diff --git a/test/form/paths/_config.js b/test/form/paths/_config.js index c9b4ca3..1d6ed03 100644 --- a/test/form/paths/_config.js +++ b/test/form/paths/_config.js @@ -2,7 +2,7 @@ module.exports = { description: 'external paths (#754)', options: { paths: { - foo: 'https://npmcdn.com/foo' + foo: 'https://unpkg.com/foo' } } }; diff --git a/test/form/paths/_expected/amd.js b/test/form/paths/_expected/amd.js index fe2d243..0893293 100644 --- a/test/form/paths/_expected/amd.js +++ b/test/form/paths/_expected/amd.js @@ -1,4 +1,4 @@ -define(['https://npmcdn.com/foo'], function (foo) { 'use strict'; +define(['https://unpkg.com/foo'], function (foo) { 'use strict'; foo = 'default' in foo ? foo['default'] : foo; diff --git a/test/form/paths/_expected/cjs.js b/test/form/paths/_expected/cjs.js index 864ce43..4bb0804 100644 --- a/test/form/paths/_expected/cjs.js +++ b/test/form/paths/_expected/cjs.js @@ -2,6 +2,6 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -var foo = _interopDefault(require('https://npmcdn.com/foo')); +var foo = _interopDefault(require('https://unpkg.com/foo')); assert.equal( foo, 42 ); diff --git a/test/form/paths/_expected/es.js b/test/form/paths/_expected/es.js index 1c4fe57..74bfea3 100644 --- a/test/form/paths/_expected/es.js +++ b/test/form/paths/_expected/es.js @@ -1,3 +1,3 @@ -import foo from 'https://npmcdn.com/foo'; +import foo from 'https://unpkg.com/foo'; assert.equal( foo, 42 ); diff --git a/test/form/paths/_expected/umd.js b/test/form/paths/_expected/umd.js index 8da109e..e86e892 100644 --- a/test/form/paths/_expected/umd.js +++ b/test/form/paths/_expected/umd.js @@ -1,6 +1,6 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('https://npmcdn.com/foo')) : - typeof define === 'function' && define.amd ? define(['https://npmcdn.com/foo'], factory) : + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('https://unpkg.com/foo')) : + typeof define === 'function' && define.amd ? define(['https://unpkg.com/foo'], factory) : (factory(global.foo)); }(this, (function (foo) { 'use strict'; From e8179c2013b7cfb4b1c7cba3b2fe441f7597ad97 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 12:21:29 -0400 Subject: [PATCH 216/331] include dependencies in bundle.modules (closes #903) --- src/Module.js | 1 + test/function/module-tree/_config.js | 37 +++++++++++++++++++++++++ test/function/module-tree/bar.js | 1 + test/function/module-tree/foo.js | 1 + test/function/module-tree/main.js | 2 ++ test/function/module-tree/nested/baz.js | 1 + test/function/module-tree/nested/qux.js | 1 + 7 files changed, 44 insertions(+) create mode 100644 test/function/module-tree/_config.js create mode 100644 test/function/module-tree/bar.js create mode 100644 test/function/module-tree/foo.js create mode 100644 test/function/module-tree/main.js create mode 100644 test/function/module-tree/nested/baz.js create mode 100644 test/function/module-tree/nested/qux.js diff --git a/src/Module.js b/src/Module.js index 1c65807..74f7b74 100644 --- a/src/Module.js +++ b/src/Module.js @@ -315,6 +315,7 @@ export default class Module { toJSON () { return { id: this.id, + dependencies: this.dependencies.map( module => module.id ), code: this.code, originalCode: this.originalCode, ast: this.astClone, diff --git a/test/function/module-tree/_config.js b/test/function/module-tree/_config.js new file mode 100644 index 0000000..97827df --- /dev/null +++ b/test/function/module-tree/_config.js @@ -0,0 +1,37 @@ +const path = require( 'path' ); +const assert = require( 'assert' ); + +module.exports = { + description: 'bundle.modules includes dependencies (#903)', + bundle ( bundle ) { + const modules = bundle.modules.map( module => { + return { + id: path.relative( __dirname, module.id ), + dependencies: module.dependencies.map( id => path.relative( __dirname, id ) ) + }; + }); + + assert.deepEqual( modules, [ + { + id: 'nested/qux.js', + dependencies: [] + }, + { + id: 'nested/baz.js', + dependencies: [ 'nested/qux.js' ] + }, + { + id: 'bar.js', + dependencies: [ 'nested/baz.js' ] + }, + { + id: 'foo.js', + dependencies: [ 'bar.js' ] + }, + { + id: 'main.js', + dependencies: [ 'foo.js', 'bar.js' ] + } + ]); + } +}; diff --git a/test/function/module-tree/bar.js b/test/function/module-tree/bar.js new file mode 100644 index 0000000..76340f6 --- /dev/null +++ b/test/function/module-tree/bar.js @@ -0,0 +1 @@ +import './nested/baz.js'; diff --git a/test/function/module-tree/foo.js b/test/function/module-tree/foo.js new file mode 100644 index 0000000..1df02c2 --- /dev/null +++ b/test/function/module-tree/foo.js @@ -0,0 +1 @@ +import './bar.js'; diff --git a/test/function/module-tree/main.js b/test/function/module-tree/main.js new file mode 100644 index 0000000..f257022 --- /dev/null +++ b/test/function/module-tree/main.js @@ -0,0 +1,2 @@ +import './foo.js'; +import './bar.js'; diff --git a/test/function/module-tree/nested/baz.js b/test/function/module-tree/nested/baz.js new file mode 100644 index 0000000..0ff2bf9 --- /dev/null +++ b/test/function/module-tree/nested/baz.js @@ -0,0 +1 @@ +import qux from './qux.js'; diff --git a/test/function/module-tree/nested/qux.js b/test/function/module-tree/nested/qux.js new file mode 100644 index 0000000..6d70fec --- /dev/null +++ b/test/function/module-tree/nested/qux.js @@ -0,0 +1 @@ +export default 'whatever'; From 7819d7b68822e7a767e227480b08598492b14bf9 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 12:26:31 -0400 Subject: [PATCH 217/331] update to acorn 4 --- package.json | 2 +- test/function/double-default-export/_config.js | 3 ++- test/function/double-named-export/_config.js | 3 ++- test/function/double-named-reexport/_config.js | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 6f5fb1a..230039c 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ }, "homepage": "https://github.com/rollup/rollup", "devDependencies": { - "acorn": "^3.2.0", + "acorn": "^4.0.1", "buble": "^0.12.5", "chalk": "^1.1.3", "codecov.io": "^0.1.6", diff --git a/test/function/double-default-export/_config.js b/test/function/double-default-export/_config.js index 26e86e7..d5f5254 100644 --- a/test/function/double-default-export/_config.js +++ b/test/function/double-default-export/_config.js @@ -1,8 +1,9 @@ +const path = require( 'path' ); const assert = require( 'assert' ); module.exports = { description: 'throws on double default exports', error: err => { - assert.equal( err.message, 'A module can only have one default export' ); + assert.equal( err.message, `Duplicate export 'default' (2:7) in ${path.resolve(__dirname, 'foo.js')}` ); } }; diff --git a/test/function/double-named-export/_config.js b/test/function/double-named-export/_config.js index 577b421..169ce76 100644 --- a/test/function/double-named-export/_config.js +++ b/test/function/double-named-export/_config.js @@ -1,8 +1,9 @@ +const path = require( 'path' ); const assert = require( 'assert' ); module.exports = { description: 'throws on duplicate named exports', error: err => { - assert.equal( err.message, `A module cannot have multiple exports with the same name ('foo')` ); + assert.equal( err.message, `Duplicate export 'foo' (3:9) in ${path.resolve(__dirname, 'foo.js')}` ); } }; diff --git a/test/function/double-named-reexport/_config.js b/test/function/double-named-reexport/_config.js index 577b421..169ce76 100644 --- a/test/function/double-named-reexport/_config.js +++ b/test/function/double-named-reexport/_config.js @@ -1,8 +1,9 @@ +const path = require( 'path' ); const assert = require( 'assert' ); module.exports = { description: 'throws on duplicate named exports', error: err => { - assert.equal( err.message, `A module cannot have multiple exports with the same name ('foo')` ); + assert.equal( err.message, `Duplicate export 'foo' (3:9) in ${path.resolve(__dirname, 'foo.js')}` ); } }; From e723cc5c468317341ce7c44c695e3dceec3522d9 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 12:29:34 -0400 Subject: [PATCH 218/331] only transpile acorn 4 down to node 4 support level --- rollup.config.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index f55dc7c..a8ac2c8 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -22,11 +22,7 @@ export default { entry: 'src/rollup.js', plugins: [ buble({ - include: [ 'node_modules/acorn/**' ] - }), - - buble({ - include: [ 'src/**' ], + include: [ 'src/**', 'node_modules/acorn/**' ], target: { node: 4 } From 4817eada3e656f4b166084cf0744245bee705a42 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 10 Sep 2016 20:01:38 +0300 Subject: [PATCH 219/331] Fix test on windows --- test/function/module-tree/_config.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/function/module-tree/_config.js b/test/function/module-tree/_config.js index 97827df..efb1a20 100644 --- a/test/function/module-tree/_config.js +++ b/test/function/module-tree/_config.js @@ -13,16 +13,16 @@ module.exports = { assert.deepEqual( modules, [ { - id: 'nested/qux.js', + id: path.normalize('nested/qux.js'), dependencies: [] }, { - id: 'nested/baz.js', - dependencies: [ 'nested/qux.js' ] + id: path.normalize('nested/baz.js'), + dependencies: [ path.normalize('nested/qux.js') ] }, { id: 'bar.js', - dependencies: [ 'nested/baz.js' ] + dependencies: [ path.normalize('nested/baz.js') ] }, { id: 'foo.js', From c1b7092b0dc292905012ac5d3a915c8b5dad5b4e Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 10 Sep 2016 20:02:33 +0300 Subject: [PATCH 220/331] Fix codestyle --- test/function/module-tree/_config.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/function/module-tree/_config.js b/test/function/module-tree/_config.js index efb1a20..553ab2b 100644 --- a/test/function/module-tree/_config.js +++ b/test/function/module-tree/_config.js @@ -13,16 +13,16 @@ module.exports = { assert.deepEqual( modules, [ { - id: path.normalize('nested/qux.js'), + id: path.normalize( 'nested/qux.js' ), dependencies: [] }, { - id: path.normalize('nested/baz.js'), - dependencies: [ path.normalize('nested/qux.js') ] + id: path.normalize( 'nested/baz.js' ), + dependencies: [ path.normalize( 'nested/qux.js' ) ] }, { id: 'bar.js', - dependencies: [ path.normalize('nested/baz.js') ] + dependencies: [ path.normalize( 'nested/baz.js' ) ] }, { id: 'foo.js', From 16da86e93c7047bea39212cbb761bf4f836ca7f4 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 13:12:22 -0400 Subject: [PATCH 221/331] deconflict-classes --- src/ast/nodes/ClassDeclaration.js | 6 ++++-- test/function/deconflicts-classes/_config.js | 4 ++++ test/function/deconflicts-classes/a.js | 2 ++ test/function/deconflicts-classes/b.js | 2 ++ test/function/deconflicts-classes/main.js | 4 ++++ 5 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 test/function/deconflicts-classes/_config.js create mode 100644 test/function/deconflicts-classes/a.js create mode 100644 test/function/deconflicts-classes/b.js create mode 100644 test/function/deconflicts-classes/main.js diff --git a/src/ast/nodes/ClassDeclaration.js b/src/ast/nodes/ClassDeclaration.js index ed773da..f67c87d 100644 --- a/src/ast/nodes/ClassDeclaration.js +++ b/src/ast/nodes/ClassDeclaration.js @@ -18,7 +18,7 @@ export default class ClassDeclaration extends Node { } getName () { - return this.id.name; + return this.name; } hasEffects () { @@ -26,7 +26,9 @@ export default class ClassDeclaration extends Node { } initialise ( scope ) { - scope.addDeclaration( this.id.name, this, false, false ); + this.name = this.id.name; + + scope.addDeclaration( this.name, this, false, false ); super.initialise( scope ); } diff --git a/test/function/deconflicts-classes/_config.js b/test/function/deconflicts-classes/_config.js new file mode 100644 index 0000000..d2e030b --- /dev/null +++ b/test/function/deconflicts-classes/_config.js @@ -0,0 +1,4 @@ +module.exports = { + solo: true, + description: 'deconflicts top-level classes' +}; diff --git a/test/function/deconflicts-classes/a.js b/test/function/deconflicts-classes/a.js new file mode 100644 index 0000000..8f88528 --- /dev/null +++ b/test/function/deconflicts-classes/a.js @@ -0,0 +1,2 @@ +var Foo = function Foo () {}; +export { Foo }; diff --git a/test/function/deconflicts-classes/b.js b/test/function/deconflicts-classes/b.js new file mode 100644 index 0000000..6f6f410 --- /dev/null +++ b/test/function/deconflicts-classes/b.js @@ -0,0 +1,2 @@ +class Foo {}; +export { Foo }; diff --git a/test/function/deconflicts-classes/main.js b/test/function/deconflicts-classes/main.js new file mode 100644 index 0000000..89ff7de --- /dev/null +++ b/test/function/deconflicts-classes/main.js @@ -0,0 +1,4 @@ +import { Foo as A } from './a.js'; +import { Foo as B } from './b.js'; + +assert.notEqual( A, B ); From db8fcc4273167df7dd1118f567540a24a61a82cf Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 13:19:12 -0400 Subject: [PATCH 222/331] -> v0.35.1 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d598c9d..4f4626f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # rollup changelog +## 0.35.1 + +* Rewrite deconflicted class identifiers ([#915](https://github.com/rollup/rollup/pull/915)) +* Include `dependencies` in `bundle.modules` objects ([#903](https://github.com/rollup/rollup/issues/903)) +* Update to Acorn 4 ([#914](https://github.com/rollup/rollup/pull/914)) + ## 0.35.0 * Rewrite analysis/tree-shaking code ([#902](https://github.com/rollup/rollup/pull/902)) diff --git a/package.json b/package.json index 230039c..0ee877b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.0", + "version": "0.35.1", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From a6dd89b25d8c1d404ad4e6fc60e2699685670c51 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 13:24:20 -0400 Subject: [PATCH 223/331] -> v0.35.2 --- CHANGELOG.md | 4 ++++ package.json | 2 +- test/function/deconflicts-classes/_config.js | 1 - 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f4626f..5ac7487 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.2 + +* Fix broken build caused by out of date locally installed dependencies + ## 0.35.1 * Rewrite deconflicted class identifiers ([#915](https://github.com/rollup/rollup/pull/915)) diff --git a/package.json b/package.json index 0ee877b..ad9d319 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.1", + "version": "0.35.2", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", diff --git a/test/function/deconflicts-classes/_config.js b/test/function/deconflicts-classes/_config.js index d2e030b..ee66bd1 100644 --- a/test/function/deconflicts-classes/_config.js +++ b/test/function/deconflicts-classes/_config.js @@ -1,4 +1,3 @@ module.exports = { - solo: true, description: 'deconflicts top-level classes' }; From 81979770505e4d4844f500da398a873e710bc6f3 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 10 Sep 2016 21:01:24 +0300 Subject: [PATCH 224/331] Add performance labels --- src/Bundle.js | 27 +++++++++++++++++++++++++++ src/Module.js | 11 +++++++++++ src/rollup.js | 11 +++++++++++ src/utils/flushTime.js | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 src/utils/flushTime.js diff --git a/src/Bundle.js b/src/Bundle.js index 881907a..40a9211 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -1,3 +1,4 @@ +import { timeStart, timeEnd } from './utils/flushTime.js'; import { decode } from 'sourcemap-codec'; import { Bundle as MagicStringBundle } from 'magic-string'; import first from './utils/first.js'; @@ -102,12 +103,19 @@ export default class Bundle { // Phase 2 – binding. We link references to their declarations // to generate a complete picture of the bundle + + timeStart( 'phase 2' ); + this.modules.forEach( module => module.bindImportSpecifiers() ); this.modules.forEach( module => module.bindReferences() ); + timeEnd( 'phase 2' ); + // Phase 3 – marking. We 'run' each statement to see which ones // need to be included in the generated bundle + timeStart( 'phase 3' ); + // mark all export statements entryModule.getExports().forEach( name => { const declaration = entryModule.traceExport( name ); @@ -146,11 +154,18 @@ export default class Bundle { } } + timeEnd( 'phase 3' ); + // Phase 4 – final preparation. We order the modules with an // enhanced topological sort that accounts for cycles, then // ensure that names are deconflicted throughout the bundle + + timeStart( 'phase 4' ); + this.orderedModules = this.sort(); this.deconflict(); + + timeEnd( 'phase 4' ); }); } @@ -332,6 +347,8 @@ export default class Bundle { let magicString = new MagicStringBundle({ separator: '\n\n' }); const usedModules = []; + timeStart( 'render modules' ); + this.orderedModules.forEach( module => { const source = module.render( format === 'es' ); @@ -341,6 +358,8 @@ export default class Bundle { } }); + timeEnd( 'render modules' ); + let intro = [ options.intro ] .concat( this.plugins.map( plugin => plugin.intro && plugin.intro() ) @@ -355,8 +374,12 @@ export default class Bundle { const finalise = finalisers[ format ]; if ( !finalise ) throw new Error( `You must specify an output type - valid options are ${keys( finalisers ).join( ', ' )}` ); + timeStart( 'render format' ); + magicString = finalise( this, magicString.trim(), { exportMode, indentString, intro }, options ); + timeEnd( 'render format' ); + const banner = [ options.banner ] .concat( this.plugins.map( plugin => plugin.banner ) ) .map( callIfFunction ) @@ -380,6 +403,8 @@ export default class Bundle { .replace( new RegExp( `\\/\\/#\\s+${SOURCEMAPPING_URL}=.+\\n?`, 'g' ), '' ); if ( options.sourceMap ) { + timeStart( 'sourceMap' ); + let file = options.sourceMapFile || options.dest; if ( file ) file = resolve( typeof process !== 'undefined' ? process.cwd() : '', file ); @@ -394,6 +419,8 @@ export default class Bundle { } map.sources = map.sources.map( normalize ); + + timeEnd( 'sourceMap' ); } return { code, map }; diff --git a/src/Module.js b/src/Module.js index 1c65807..dc0b051 100644 --- a/src/Module.js +++ b/src/Module.js @@ -1,3 +1,4 @@ +import { timeStart, timeEnd } from './utils/flushTime.js'; import { parse } from 'acorn/src/index.js'; import MagicString from 'magic-string'; import { assign, blank, deepClone, keys } from './utils/object.js'; @@ -34,9 +35,14 @@ export default class Module { this.sourceMapChain = sourceMapChain; this.comments = []; + + timeStart( 'ast' ); + this.ast = ast || tryParse( code, this.comments, bundle.acornOptions, id ); // TODO what happens to comments if AST is provided? this.astClone = deepClone( this.ast ); + timeEnd( 'ast' ); + this.bundle = bundle; this.id = id; this.excludeFromSourcemap = /\0/.test( id ); @@ -72,8 +78,13 @@ export default class Module { this.declarations = blank(); this.type = 'Module'; // TODO only necessary so that Scope knows this should be treated as a function scope... messy this.scope = new ModuleScope( this ); + + timeStart( 'analyse' ); + this.analyse(); + timeEnd( 'analyse' ); + this.strongDependencies = []; } diff --git a/src/rollup.js b/src/rollup.js index 4c1a076..e0db03e 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -1,3 +1,4 @@ +import { timeStart, timeEnd, flushTime } from './utils/flushTime.js'; import { basename } from './utils/path.js'; import { writeFile } from './utils/fs.js'; import { assign, keys } from './utils/object.js'; @@ -54,10 +55,18 @@ export function rollup ( options ) { const bundle = new Bundle( options ); + timeStart( '--BUILD--' ); + return bundle.build().then( () => { + timeEnd( '--BUILD--' ); + function generate ( options ) { + timeStart( '--GENERATE--' ) + const rendered = bundle.render( options ); + timeEnd( '--GENERATE--' ); + bundle.plugins.forEach( plugin => { if ( plugin.ongenerate ) { plugin.ongenerate( assign({ @@ -66,6 +75,8 @@ export function rollup ( options ) { } }); + flushTime(); + return rendered; } diff --git a/src/utils/flushTime.js b/src/utils/flushTime.js new file mode 100644 index 0000000..e54e1b2 --- /dev/null +++ b/src/utils/flushTime.js @@ -0,0 +1,35 @@ +const DEBUG = false; +const map = new Map; + +export function timeStart( label ) { + if ( !map.has( label ) ) { + map.set( label, { + time: 0 + }); + } + map.get( label ).start = process.hrtime(); +} + +export function timeEnd( label ) { + if ( map.has( label ) ) { + const item = map.get( label ); + item.time += toMilliseconds( process.hrtime( item.start ) ); + } +} + +export function flushTime( log = defaultLog ) { + for ( const item of map.entries() ) { + log( item[0], item[1].time ); + } + map.clear(); +} + +function toMilliseconds( time ) { + return time[0] * 1e+3 + Math.floor( time[1] * 1e-6 ); +} + +function defaultLog( label, time ) { + if ( DEBUG ) { + console.info( '%dms: %s', time, label ); + } +} From 50d263203ee04f0ff4e91257d65ae9d5b3f7b754 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 10 Sep 2016 21:04:52 +0300 Subject: [PATCH 225/331] Fix lint --- src/rollup.js | 2 +- src/utils/flushTime.js | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/rollup.js b/src/rollup.js index e0db03e..2ab5b51 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -61,7 +61,7 @@ export function rollup ( options ) { timeEnd( '--BUILD--' ); function generate ( options ) { - timeStart( '--GENERATE--' ) + timeStart( '--GENERATE--' ); const rendered = bundle.render( options ); diff --git a/src/utils/flushTime.js b/src/utils/flushTime.js index e54e1b2..fb4d331 100644 --- a/src/utils/flushTime.js +++ b/src/utils/flushTime.js @@ -1,7 +1,7 @@ const DEBUG = false; const map = new Map; -export function timeStart( label ) { +export function timeStart ( label ) { if ( !map.has( label ) ) { map.set( label, { time: 0 @@ -10,26 +10,28 @@ export function timeStart( label ) { map.get( label ).start = process.hrtime(); } -export function timeEnd( label ) { +export function timeEnd ( label ) { if ( map.has( label ) ) { const item = map.get( label ); item.time += toMilliseconds( process.hrtime( item.start ) ); } } -export function flushTime( log = defaultLog ) { +export function flushTime ( log = defaultLog ) { for ( const item of map.entries() ) { log( item[0], item[1].time ); } map.clear(); } -function toMilliseconds( time ) { +function toMilliseconds ( time ) { return time[0] * 1e+3 + Math.floor( time[1] * 1e-6 ); } -function defaultLog( label, time ) { +function defaultLog ( label, time ) { if ( DEBUG ) { + /* eslint-disable no-console */ console.info( '%dms: %s', time, label ); + /* eslint-enable no-console */ } } From 8446b06e8d13ce742085af88c21032e3eab5c91f Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 14:43:06 -0400 Subject: [PATCH 226/331] render identifiers inside template literals --- src/ast/nodes/TemplateLiteral.js | 3 ++- test/function/identifiers-in-template-literals/_config.js | 3 +++ test/function/identifiers-in-template-literals/a.js | 7 +++++++ test/function/identifiers-in-template-literals/b.js | 7 +++++++ test/function/identifiers-in-template-literals/main.js | 5 +++++ 5 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 test/function/identifiers-in-template-literals/_config.js create mode 100644 test/function/identifiers-in-template-literals/a.js create mode 100644 test/function/identifiers-in-template-literals/b.js create mode 100644 test/function/identifiers-in-template-literals/main.js diff --git a/src/ast/nodes/TemplateLiteral.js b/src/ast/nodes/TemplateLiteral.js index 057ce12..b25ef48 100644 --- a/src/ast/nodes/TemplateLiteral.js +++ b/src/ast/nodes/TemplateLiteral.js @@ -1,7 +1,8 @@ import Node from '../Node.js'; export default class TemplateLiteral extends Node { - render ( code ) { + render ( code, es ) { code.indentExclusionRanges.push([ this.start, this.end ]); + super.render( code, es ); } } diff --git a/test/function/identifiers-in-template-literals/_config.js b/test/function/identifiers-in-template-literals/_config.js new file mode 100644 index 0000000..8b031cd --- /dev/null +++ b/test/function/identifiers-in-template-literals/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'identifiers in template literals are rendered correctly' +}; diff --git a/test/function/identifiers-in-template-literals/a.js b/test/function/identifiers-in-template-literals/a.js new file mode 100644 index 0000000..26a1db8 --- /dev/null +++ b/test/function/identifiers-in-template-literals/a.js @@ -0,0 +1,7 @@ +function x ( keypath ) { + return 'a'; +} + +export default function a () { + return x(); +} diff --git a/test/function/identifiers-in-template-literals/b.js b/test/function/identifiers-in-template-literals/b.js new file mode 100644 index 0000000..7511028 --- /dev/null +++ b/test/function/identifiers-in-template-literals/b.js @@ -0,0 +1,7 @@ +function x ( name ) { + return 'b'; +} + +export default function b () { + return `${x()}`; +} diff --git a/test/function/identifiers-in-template-literals/main.js b/test/function/identifiers-in-template-literals/main.js new file mode 100644 index 0000000..eedb4fb --- /dev/null +++ b/test/function/identifiers-in-template-literals/main.js @@ -0,0 +1,5 @@ +import a from './a.js'; +import b from './b.js'; + +assert.equal( a(), 'a' ); +assert.equal( b(), 'b' ); From c00399bf20ba60d522c9d7d299b0975eda007c97 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 14:44:07 -0400 Subject: [PATCH 227/331] -> v0.35.3 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ac7487..009ae46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.3 + +* Render identifiers inside template literals + ## 0.35.2 * Fix broken build caused by out of date locally installed dependencies diff --git a/package.json b/package.json index ad9d319..de10926 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.2", + "version": "0.35.3", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 56d64da1a4170b5974e7d962f2403736d958cf39 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 14:47:06 -0400 Subject: [PATCH 228/331] build self with 0.35 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index de10926..bcb8ff7 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "mocha": "^3.0.0", "remap-istanbul": "^0.6.4", "require-relative": "^0.8.7", - "rollup": "^0.34.2", + "rollup": "^0.35.3", "rollup-plugin-buble": "^0.12.1", "rollup-plugin-commonjs": "^3.0.0", "rollup-plugin-json": "^2.0.0", From b82375c2734a1da91f0d793723bdfa0f28e8a931 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 16:04:28 -0400 Subject: [PATCH 229/331] preserve effects in for-of loop (#870) --- src/ast/nodes/ForInStatement.js | 15 ++++++++++++ src/ast/nodes/ForOfStatement.js | 15 ++++++++++++ src/ast/nodes/index.js | 4 ++++ test/form/effect-in-for-of-loop/_config.js | 3 +++ .../effect-in-for-of-loop/_expected/amd.js | 19 +++++++++++++++ .../effect-in-for-of-loop/_expected/cjs.js | 17 ++++++++++++++ .../effect-in-for-of-loop/_expected/es.js | 15 ++++++++++++ .../effect-in-for-of-loop/_expected/iife.js | 20 ++++++++++++++++ .../effect-in-for-of-loop/_expected/umd.js | 23 +++++++++++++++++++ test/form/effect-in-for-of-loop/main.js | 23 +++++++++++++++++++ 10 files changed, 154 insertions(+) create mode 100644 src/ast/nodes/ForInStatement.js create mode 100644 src/ast/nodes/ForOfStatement.js create mode 100644 test/form/effect-in-for-of-loop/_config.js create mode 100644 test/form/effect-in-for-of-loop/_expected/amd.js create mode 100644 test/form/effect-in-for-of-loop/_expected/cjs.js create mode 100644 test/form/effect-in-for-of-loop/_expected/es.js create mode 100644 test/form/effect-in-for-of-loop/_expected/iife.js create mode 100644 test/form/effect-in-for-of-loop/_expected/umd.js create mode 100644 test/form/effect-in-for-of-loop/main.js diff --git a/src/ast/nodes/ForInStatement.js b/src/ast/nodes/ForInStatement.js new file mode 100644 index 0000000..002dd0a --- /dev/null +++ b/src/ast/nodes/ForInStatement.js @@ -0,0 +1,15 @@ +import Node from '../Node.js'; +import { STRING } from '../values.js'; + +export default class ForInStatement extends Node { + initialise ( scope ) { + super.initialise( scope ); + + // special case + if ( this.left.type === 'VariableDeclaration' ) { + for ( const proxy of this.left.declarations[0].proxies.values() ) { + proxy.possibleValues.add( STRING ); + } + } + } +} diff --git a/src/ast/nodes/ForOfStatement.js b/src/ast/nodes/ForOfStatement.js new file mode 100644 index 0000000..201d491 --- /dev/null +++ b/src/ast/nodes/ForOfStatement.js @@ -0,0 +1,15 @@ +import Node from '../Node.js'; +import { UNKNOWN } from '../values.js'; + +export default class ForOfStatement extends Node { + initialise ( scope ) { + super.initialise( scope ); + + // special case + if ( this.left.type === 'VariableDeclaration' ) { + for ( const proxy of this.left.declarations[0].proxies.values() ) { + proxy.possibleValues.add( UNKNOWN ); + } + } + } +} diff --git a/src/ast/nodes/index.js b/src/ast/nodes/index.js index c276a34..3cca1ad 100644 --- a/src/ast/nodes/index.js +++ b/src/ast/nodes/index.js @@ -11,6 +11,8 @@ import ExportAllDeclaration from './ExportAllDeclaration.js'; import ExportDefaultDeclaration from './ExportDefaultDeclaration.js'; import ExportNamedDeclaration from './ExportNamedDeclaration.js'; import ExpressionStatement from './ExpressionStatement.js'; +import ForInStatement from './ForInStatement.js'; +import ForOfStatement from './ForOfStatement.js'; import FunctionDeclaration from './FunctionDeclaration.js'; import FunctionExpression from './FunctionExpression.js'; import Identifier from './Identifier.js'; @@ -43,6 +45,8 @@ export default { ExportDefaultDeclaration, ExportNamedDeclaration, ExpressionStatement, + ForInStatement, + ForOfStatement, FunctionDeclaration, FunctionExpression, Identifier, diff --git a/test/form/effect-in-for-of-loop/_config.js b/test/form/effect-in-for-of-loop/_config.js new file mode 100644 index 0000000..79abe74 --- /dev/null +++ b/test/form/effect-in-for-of-loop/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'includes effects in for-of loop (#870)' +} diff --git a/test/form/effect-in-for-of-loop/_expected/amd.js b/test/form/effect-in-for-of-loop/_expected/amd.js new file mode 100644 index 0000000..57223a0 --- /dev/null +++ b/test/form/effect-in-for-of-loop/_expected/amd.js @@ -0,0 +1,19 @@ +define(function () { 'use strict'; + + const items = [{}, {}, {}]; + + function x () { + for ( const item of items.children ) { + item.foo = 'bar'; + } + } + + x(); + + assert.deepEqual( items, [ + { foo: 'bar' }, + { foo: 'bar' }, + { foo: 'bar' } + ]); + +}); diff --git a/test/form/effect-in-for-of-loop/_expected/cjs.js b/test/form/effect-in-for-of-loop/_expected/cjs.js new file mode 100644 index 0000000..fd94a9d --- /dev/null +++ b/test/form/effect-in-for-of-loop/_expected/cjs.js @@ -0,0 +1,17 @@ +'use strict'; + +const items = [{}, {}, {}]; + +function x () { + for ( const item of items.children ) { + item.foo = 'bar'; + } +} + +x(); + +assert.deepEqual( items, [ + { foo: 'bar' }, + { foo: 'bar' }, + { foo: 'bar' } +]); diff --git a/test/form/effect-in-for-of-loop/_expected/es.js b/test/form/effect-in-for-of-loop/_expected/es.js new file mode 100644 index 0000000..cabffc4 --- /dev/null +++ b/test/form/effect-in-for-of-loop/_expected/es.js @@ -0,0 +1,15 @@ +const items = [{}, {}, {}]; + +function x () { + for ( const item of items.children ) { + item.foo = 'bar'; + } +} + +x(); + +assert.deepEqual( items, [ + { foo: 'bar' }, + { foo: 'bar' }, + { foo: 'bar' } +]); diff --git a/test/form/effect-in-for-of-loop/_expected/iife.js b/test/form/effect-in-for-of-loop/_expected/iife.js new file mode 100644 index 0000000..96e91ea --- /dev/null +++ b/test/form/effect-in-for-of-loop/_expected/iife.js @@ -0,0 +1,20 @@ +(function () { + 'use strict'; + + const items = [{}, {}, {}]; + + function x () { + for ( const item of items.children ) { + item.foo = 'bar'; + } + } + + x(); + + assert.deepEqual( items, [ + { foo: 'bar' }, + { foo: 'bar' }, + { foo: 'bar' } + ]); + +}()); diff --git a/test/form/effect-in-for-of-loop/_expected/umd.js b/test/form/effect-in-for-of-loop/_expected/umd.js new file mode 100644 index 0000000..83a6d30 --- /dev/null +++ b/test/form/effect-in-for-of-loop/_expected/umd.js @@ -0,0 +1,23 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + const items = [{}, {}, {}]; + + function x () { + for ( const item of items.children ) { + item.foo = 'bar'; + } + } + + x(); + + assert.deepEqual( items, [ + { foo: 'bar' }, + { foo: 'bar' }, + { foo: 'bar' } + ]); + +}))); diff --git a/test/form/effect-in-for-of-loop/main.js b/test/form/effect-in-for-of-loop/main.js new file mode 100644 index 0000000..401dcf2 --- /dev/null +++ b/test/form/effect-in-for-of-loop/main.js @@ -0,0 +1,23 @@ +const items = [{}, {}, {}]; + +function x () { + for ( const item of items.children ) { + item.foo = 'bar'; + } +} + +x(); + +function y () { + for ( const item of items.children ) { + // do nothing + } +} + +y(); + +assert.deepEqual( items, [ + { foo: 'bar' }, + { foo: 'bar' }, + { foo: 'bar' } +]); From 6da374cea2ad72b3a6f729d0e89a532170cf0858 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 16:49:37 -0400 Subject: [PATCH 230/331] preserve effects in for-of and for-in statements. fixes #870 --- src/ast/nodes/ExpressionStatement.js | 15 +------ src/ast/nodes/ForInStatement.js | 13 ++---- src/ast/nodes/ForOfStatement.js | 13 ++---- src/ast/nodes/IfStatement.js | 4 +- src/ast/nodes/ThrowStatement.js | 7 ++++ src/ast/nodes/index.js | 2 + src/ast/nodes/shared/Statement.js | 16 ++++++++ src/ast/nodes/shared/assignTo.js | 29 +++++++++++++ .../_config.js | 3 ++ .../_expected/amd.js | 28 +++++++++++++ .../_expected/cjs.js | 26 ++++++++++++ .../_expected/es.js | 24 +++++++++++ .../_expected/iife.js | 29 +++++++++++++ .../_expected/umd.js | 32 +++++++++++++++ .../main.js | 41 +++++++++++++++++++ .../effect-in-for-of-loop/_expected/amd.js | 17 ++++---- .../effect-in-for-of-loop/_expected/cjs.js | 17 ++++---- .../effect-in-for-of-loop/_expected/es.js | 17 ++++---- .../effect-in-for-of-loop/_expected/iife.js | 17 ++++---- .../effect-in-for-of-loop/_expected/umd.js | 17 ++++---- test/form/effect-in-for-of-loop/main.js | 28 +++++++------ 21 files changed, 309 insertions(+), 86 deletions(-) create mode 100644 src/ast/nodes/ThrowStatement.js create mode 100644 src/ast/nodes/shared/Statement.js create mode 100644 src/ast/nodes/shared/assignTo.js create mode 100644 test/form/effect-in-for-of-loop-in-functions/_config.js create mode 100644 test/form/effect-in-for-of-loop-in-functions/_expected/amd.js create mode 100644 test/form/effect-in-for-of-loop-in-functions/_expected/cjs.js create mode 100644 test/form/effect-in-for-of-loop-in-functions/_expected/es.js create mode 100644 test/form/effect-in-for-of-loop-in-functions/_expected/iife.js create mode 100644 test/form/effect-in-for-of-loop-in-functions/_expected/umd.js create mode 100644 test/form/effect-in-for-of-loop-in-functions/main.js diff --git a/src/ast/nodes/ExpressionStatement.js b/src/ast/nodes/ExpressionStatement.js index c5c3255..237441a 100644 --- a/src/ast/nodes/ExpressionStatement.js +++ b/src/ast/nodes/ExpressionStatement.js @@ -1,16 +1,5 @@ -import Node from '../Node.js'; +import Statement from './shared/Statement.js'; -export default class ExpressionStatement extends Node { - render ( code, es ) { - if ( !this.module.bundle.treeshake || this.shouldInclude ) { - super.render( code, es ); - } else { - code.remove( this.leadingCommentStart || this.start, this.next || this.end ); - } - } +export default class ExpressionStatement extends Statement { - run ( scope ) { - this.shouldInclude = true; - super.run( scope ); - } } diff --git a/src/ast/nodes/ForInStatement.js b/src/ast/nodes/ForInStatement.js index 002dd0a..a59bfd2 100644 --- a/src/ast/nodes/ForInStatement.js +++ b/src/ast/nodes/ForInStatement.js @@ -1,15 +1,10 @@ -import Node from '../Node.js'; +import Statement from './shared/Statement.js'; +import assignTo from './shared/assignTo.js'; import { STRING } from '../values.js'; -export default class ForInStatement extends Node { +export default class ForInStatement extends Statement { initialise ( scope ) { super.initialise( scope ); - - // special case - if ( this.left.type === 'VariableDeclaration' ) { - for ( const proxy of this.left.declarations[0].proxies.values() ) { - proxy.possibleValues.add( STRING ); - } - } + assignTo( this.left, scope, STRING ); } } diff --git a/src/ast/nodes/ForOfStatement.js b/src/ast/nodes/ForOfStatement.js index 201d491..9e663a0 100644 --- a/src/ast/nodes/ForOfStatement.js +++ b/src/ast/nodes/ForOfStatement.js @@ -1,15 +1,10 @@ -import Node from '../Node.js'; +import Statement from './shared/Statement.js'; +import assignTo from './shared/assignTo.js'; import { UNKNOWN } from '../values.js'; -export default class ForOfStatement extends Node { +export default class ForOfStatement extends Statement { initialise ( scope ) { super.initialise( scope ); - - // special case - if ( this.left.type === 'VariableDeclaration' ) { - for ( const proxy of this.left.declarations[0].proxies.values() ) { - proxy.possibleValues.add( UNKNOWN ); - } - } + assignTo( this.left, scope, UNKNOWN ); } } diff --git a/src/ast/nodes/IfStatement.js b/src/ast/nodes/IfStatement.js index 1a5c184..9e6f0fc 100644 --- a/src/ast/nodes/IfStatement.js +++ b/src/ast/nodes/IfStatement.js @@ -1,8 +1,8 @@ -import Node from '../Node.js'; +import Statement from './shared/Statement.js'; import { UNKNOWN } from '../values.js'; // TODO DRY this out -export default class IfStatement extends Node { +export default class IfStatement extends Statement { initialise ( scope ) { this.testValue = this.test.getValue(); diff --git a/src/ast/nodes/ThrowStatement.js b/src/ast/nodes/ThrowStatement.js new file mode 100644 index 0000000..4e9047b --- /dev/null +++ b/src/ast/nodes/ThrowStatement.js @@ -0,0 +1,7 @@ +import Node from '../Node.js'; + +export default class ThrowStatement extends Node { + hasEffects ( scope ) { + return scope.findLexicalBoundary().isModuleScope; // TODO should this just be `true`? probably... + } +} diff --git a/src/ast/nodes/index.js b/src/ast/nodes/index.js index 3cca1ad..b5babe0 100644 --- a/src/ast/nodes/index.js +++ b/src/ast/nodes/index.js @@ -26,6 +26,7 @@ import ParenthesizedExpression from './ParenthesizedExpression.js'; import ReturnStatement from './ReturnStatement.js'; import TemplateLiteral from './TemplateLiteral.js'; import ThisExpression from './ThisExpression.js'; +import ThrowStatement from './ThrowStatement.js'; import UnaryExpression from './UnaryExpression.js'; import UpdateExpression from './UpdateExpression.js'; import VariableDeclarator from './VariableDeclarator.js'; @@ -60,6 +61,7 @@ export default { ReturnStatement, TemplateLiteral, ThisExpression, + ThrowStatement, UnaryExpression, UpdateExpression, VariableDeclarator, diff --git a/src/ast/nodes/shared/Statement.js b/src/ast/nodes/shared/Statement.js new file mode 100644 index 0000000..5667652 --- /dev/null +++ b/src/ast/nodes/shared/Statement.js @@ -0,0 +1,16 @@ +import Node from '../../Node.js'; + +export default class Statement extends Node { + render ( code, es ) { + if ( !this.module.bundle.treeshake || this.shouldInclude ) { + super.render( code, es ); + } else { + code.remove( this.leadingCommentStart || this.start, this.next || this.end ); + } + } + + run ( scope ) { + this.shouldInclude = true; + super.run( scope ); + } +} diff --git a/src/ast/nodes/shared/assignTo.js b/src/ast/nodes/shared/assignTo.js new file mode 100644 index 0000000..03512e1 --- /dev/null +++ b/src/ast/nodes/shared/assignTo.js @@ -0,0 +1,29 @@ +import extractNames from '../../utils/extractNames.js'; + +export default function assignToForLoopLeft ( node, scope, value ) { + if ( node.type === 'VariableDeclaration' ) { + for ( const proxy of node.declarations[0].proxies.values() ) { + proxy.possibleValues.add( value ); + } + } + + else { + while ( node.type === 'ParenthesizedExpression' ) node = node.expression; + + if ( node.type === 'MemberExpression' ) { + // apparently this is legal JavaScript? Though I don't know what + // kind of monster would write `for ( foo.bar of thing ) {...}` + + // for now, do nothing, as I'm not sure anything needs to happen... + } + + else { + for ( const name of extractNames( node ) ) { + const declaration = scope.findDeclaration( name ); + if ( declaration.possibleValues ) { + declaration.possibleValues.add( value ); + } + } + } + } +} diff --git a/test/form/effect-in-for-of-loop-in-functions/_config.js b/test/form/effect-in-for-of-loop-in-functions/_config.js new file mode 100644 index 0000000..79abe74 --- /dev/null +++ b/test/form/effect-in-for-of-loop-in-functions/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'includes effects in for-of loop (#870)' +} diff --git a/test/form/effect-in-for-of-loop-in-functions/_expected/amd.js b/test/form/effect-in-for-of-loop-in-functions/_expected/amd.js new file mode 100644 index 0000000..a7c1b48 --- /dev/null +++ b/test/form/effect-in-for-of-loop-in-functions/_expected/amd.js @@ -0,0 +1,28 @@ +define(function () { 'use strict'; + + const items = [{}, {}, {}]; + + function a () { + for ( const item of items.children ) { + item.foo = 'a'; + } + } + + a(); + + function c () { + let item; + for ( item of items.children ) { + item.bar = 'c'; + } + } + + c(); + + assert.deepEqual( items, [ + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } + ]); + +}); diff --git a/test/form/effect-in-for-of-loop-in-functions/_expected/cjs.js b/test/form/effect-in-for-of-loop-in-functions/_expected/cjs.js new file mode 100644 index 0000000..51c5f3b --- /dev/null +++ b/test/form/effect-in-for-of-loop-in-functions/_expected/cjs.js @@ -0,0 +1,26 @@ +'use strict'; + +const items = [{}, {}, {}]; + +function a () { + for ( const item of items.children ) { + item.foo = 'a'; + } +} + +a(); + +function c () { + let item; + for ( item of items.children ) { + item.bar = 'c'; + } +} + +c(); + +assert.deepEqual( items, [ + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } +]); diff --git a/test/form/effect-in-for-of-loop-in-functions/_expected/es.js b/test/form/effect-in-for-of-loop-in-functions/_expected/es.js new file mode 100644 index 0000000..0aafee1 --- /dev/null +++ b/test/form/effect-in-for-of-loop-in-functions/_expected/es.js @@ -0,0 +1,24 @@ +const items = [{}, {}, {}]; + +function a () { + for ( const item of items.children ) { + item.foo = 'a'; + } +} + +a(); + +function c () { + let item; + for ( item of items.children ) { + item.bar = 'c'; + } +} + +c(); + +assert.deepEqual( items, [ + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } +]); diff --git a/test/form/effect-in-for-of-loop-in-functions/_expected/iife.js b/test/form/effect-in-for-of-loop-in-functions/_expected/iife.js new file mode 100644 index 0000000..406ab3a --- /dev/null +++ b/test/form/effect-in-for-of-loop-in-functions/_expected/iife.js @@ -0,0 +1,29 @@ +(function () { + 'use strict'; + + const items = [{}, {}, {}]; + + function a () { + for ( const item of items.children ) { + item.foo = 'a'; + } + } + + a(); + + function c () { + let item; + for ( item of items.children ) { + item.bar = 'c'; + } + } + + c(); + + assert.deepEqual( items, [ + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } + ]); + +}()); diff --git a/test/form/effect-in-for-of-loop-in-functions/_expected/umd.js b/test/form/effect-in-for-of-loop-in-functions/_expected/umd.js new file mode 100644 index 0000000..33518c0 --- /dev/null +++ b/test/form/effect-in-for-of-loop-in-functions/_expected/umd.js @@ -0,0 +1,32 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + const items = [{}, {}, {}]; + + function a () { + for ( const item of items.children ) { + item.foo = 'a'; + } + } + + a(); + + function c () { + let item; + for ( item of items.children ) { + item.bar = 'c'; + } + } + + c(); + + assert.deepEqual( items, [ + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } + ]); + +}))); diff --git a/test/form/effect-in-for-of-loop-in-functions/main.js b/test/form/effect-in-for-of-loop-in-functions/main.js new file mode 100644 index 0000000..7ba1241 --- /dev/null +++ b/test/form/effect-in-for-of-loop-in-functions/main.js @@ -0,0 +1,41 @@ +const items = [{}, {}, {}]; + +function a () { + for ( const item of items.children ) { + item.foo = 'a'; + } +} + +a(); + +function b () { + for ( const item of items.children ) { + // do nothing + } +} + +b(); + +function c () { + let item; + for ( item of items.children ) { + item.bar = 'c'; + } +} + +c(); + +function d () { + let item; + for ( item of items.children ) { + // do nothing + } +} + +d(); + +assert.deepEqual( items, [ + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } +]); diff --git a/test/form/effect-in-for-of-loop/_expected/amd.js b/test/form/effect-in-for-of-loop/_expected/amd.js index 57223a0..c252e26 100644 --- a/test/form/effect-in-for-of-loop/_expected/amd.js +++ b/test/form/effect-in-for-of-loop/_expected/amd.js @@ -2,18 +2,19 @@ define(function () { 'use strict'; const items = [{}, {}, {}]; - function x () { - for ( const item of items.children ) { - item.foo = 'bar'; - } + for ( const a of items.children ) { + a.foo = 'a'; } - x(); + let c; + for ( c of items.children ) { + c.bar = 'c'; + } assert.deepEqual( items, [ - { foo: 'bar' }, - { foo: 'bar' }, - { foo: 'bar' } + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } ]); }); diff --git a/test/form/effect-in-for-of-loop/_expected/cjs.js b/test/form/effect-in-for-of-loop/_expected/cjs.js index fd94a9d..197b73e 100644 --- a/test/form/effect-in-for-of-loop/_expected/cjs.js +++ b/test/form/effect-in-for-of-loop/_expected/cjs.js @@ -2,16 +2,17 @@ const items = [{}, {}, {}]; -function x () { - for ( const item of items.children ) { - item.foo = 'bar'; - } +for ( const a of items.children ) { + a.foo = 'a'; } -x(); +let c; +for ( c of items.children ) { + c.bar = 'c'; +} assert.deepEqual( items, [ - { foo: 'bar' }, - { foo: 'bar' }, - { foo: 'bar' } + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } ]); diff --git a/test/form/effect-in-for-of-loop/_expected/es.js b/test/form/effect-in-for-of-loop/_expected/es.js index cabffc4..3869419 100644 --- a/test/form/effect-in-for-of-loop/_expected/es.js +++ b/test/form/effect-in-for-of-loop/_expected/es.js @@ -1,15 +1,16 @@ const items = [{}, {}, {}]; -function x () { - for ( const item of items.children ) { - item.foo = 'bar'; - } +for ( const a of items.children ) { + a.foo = 'a'; } -x(); +let c; +for ( c of items.children ) { + c.bar = 'c'; +} assert.deepEqual( items, [ - { foo: 'bar' }, - { foo: 'bar' }, - { foo: 'bar' } + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } ]); diff --git a/test/form/effect-in-for-of-loop/_expected/iife.js b/test/form/effect-in-for-of-loop/_expected/iife.js index 96e91ea..7ca26c8 100644 --- a/test/form/effect-in-for-of-loop/_expected/iife.js +++ b/test/form/effect-in-for-of-loop/_expected/iife.js @@ -3,18 +3,19 @@ const items = [{}, {}, {}]; - function x () { - for ( const item of items.children ) { - item.foo = 'bar'; - } + for ( const a of items.children ) { + a.foo = 'a'; } - x(); + let c; + for ( c of items.children ) { + c.bar = 'c'; + } assert.deepEqual( items, [ - { foo: 'bar' }, - { foo: 'bar' }, - { foo: 'bar' } + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } ]); }()); diff --git a/test/form/effect-in-for-of-loop/_expected/umd.js b/test/form/effect-in-for-of-loop/_expected/umd.js index 83a6d30..08ef206 100644 --- a/test/form/effect-in-for-of-loop/_expected/umd.js +++ b/test/form/effect-in-for-of-loop/_expected/umd.js @@ -6,18 +6,19 @@ const items = [{}, {}, {}]; - function x () { - for ( const item of items.children ) { - item.foo = 'bar'; - } + for ( const a of items.children ) { + a.foo = 'a'; } - x(); + let c; + for ( c of items.children ) { + c.bar = 'c'; + } assert.deepEqual( items, [ - { foo: 'bar' }, - { foo: 'bar' }, - { foo: 'bar' } + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } ]); }))); diff --git a/test/form/effect-in-for-of-loop/main.js b/test/form/effect-in-for-of-loop/main.js index 401dcf2..122bf0f 100644 --- a/test/form/effect-in-for-of-loop/main.js +++ b/test/form/effect-in-for-of-loop/main.js @@ -1,23 +1,25 @@ const items = [{}, {}, {}]; -function x () { - for ( const item of items.children ) { - item.foo = 'bar'; - } +for ( const a of items.children ) { + a.foo = 'a'; } -x(); +for ( const b of items.children ) { + // do nothing +} -function y () { - for ( const item of items.children ) { - // do nothing - } +let c; +for ( c of items.children ) { + c.bar = 'c'; } -y(); +let d; +for ( d of items.children ) { + // do nothing +} assert.deepEqual( items, [ - { foo: 'bar' }, - { foo: 'bar' }, - { foo: 'bar' } + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' }, + { foo: 'a', bar: 'c' } ]); From 9d9cfccd32f85bd19dc53c5c0164d120687f2db6 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 18:32:43 -0400 Subject: [PATCH 231/331] remove empty statements --- src/ast/nodes/ArrowFunctionExpression.js | 29 +++++++++-------- src/ast/nodes/AssignmentExpression.js | 4 ++- src/ast/nodes/BlockStatement.js | 32 +++---------------- src/ast/nodes/EmptyStatement.js | 7 ++++ src/ast/nodes/ForInStatement.js | 5 +-- src/ast/nodes/ForOfStatement.js | 5 +-- src/ast/nodes/ForStatement.js | 31 ++++++++++++++++++ src/ast/nodes/FunctionDeclaration.js | 4 +-- src/ast/nodes/FunctionExpression.js | 4 +-- src/ast/nodes/index.js | 11 ++++++- test/form/empty-block-statement/_config.js | 3 ++ .../empty-block-statement/_expected/amd.js | 6 ++++ .../empty-block-statement/_expected/cjs.js | 4 +++ .../empty-block-statement/_expected/es.js | 2 ++ .../empty-block-statement/_expected/iife.js | 7 ++++ .../empty-block-statement/_expected/umd.js | 10 ++++++ test/form/empty-block-statement/main.js | 5 +++ test/form/empty-do-while-statement/_config.js | 3 ++ .../empty-do-while-statement/_expected/amd.js | 6 ++++ .../empty-do-while-statement/_expected/cjs.js | 4 +++ .../empty-do-while-statement/_expected/es.js | 2 ++ .../_expected/iife.js | 7 ++++ .../empty-do-while-statement/_expected/umd.js | 10 ++++++ test/form/empty-do-while-statement/main.js | 6 ++++ test/form/empty-for-in-statement/_config.js | 3 ++ .../empty-for-in-statement/_expected/amd.js | 6 ++++ .../empty-for-in-statement/_expected/cjs.js | 4 +++ .../empty-for-in-statement/_expected/es.js | 2 ++ .../empty-for-in-statement/_expected/iife.js | 7 ++++ .../empty-for-in-statement/_expected/umd.js | 10 ++++++ test/form/empty-for-in-statement/main.js | 5 +++ test/form/empty-for-of-statement/_config.js | 3 ++ .../empty-for-of-statement/_expected/amd.js | 6 ++++ .../empty-for-of-statement/_expected/cjs.js | 4 +++ .../empty-for-of-statement/_expected/es.js | 2 ++ .../empty-for-of-statement/_expected/iife.js | 7 ++++ .../empty-for-of-statement/_expected/umd.js | 10 ++++++ test/form/empty-for-of-statement/main.js | 5 +++ test/form/empty-for-statement/_config.js | 3 ++ .../form/empty-for-statement/_expected/amd.js | 6 ++++ .../form/empty-for-statement/_expected/cjs.js | 4 +++ test/form/empty-for-statement/_expected/es.js | 2 ++ .../empty-for-statement/_expected/iife.js | 7 ++++ .../form/empty-for-statement/_expected/umd.js | 10 ++++++ test/form/empty-for-statement/main.js | 5 +++ test/form/empty-if-statement/_config.js | 3 ++ test/form/empty-if-statement/_expected/amd.js | 6 ++++ test/form/empty-if-statement/_expected/cjs.js | 4 +++ test/form/empty-if-statement/_expected/es.js | 2 ++ .../form/empty-if-statement/_expected/iife.js | 7 ++++ test/form/empty-if-statement/_expected/umd.js | 10 ++++++ test/form/empty-if-statement/main.js | 5 +++ test/form/empty-statement/_config.js | 3 ++ test/form/empty-statement/_expected/amd.js | 7 ++++ test/form/empty-statement/_expected/cjs.js | 5 +++ test/form/empty-statement/_expected/es.js | 3 ++ test/form/empty-statement/_expected/iife.js | 8 +++++ test/form/empty-statement/_expected/umd.js | 11 +++++++ test/form/empty-statement/main.js | 4 +++ test/form/empty-switch-statement/_config.js | 3 ++ .../empty-switch-statement/_expected/amd.js | 6 ++++ .../empty-switch-statement/_expected/cjs.js | 4 +++ .../empty-switch-statement/_expected/es.js | 2 ++ .../empty-switch-statement/_expected/iife.js | 7 ++++ .../empty-switch-statement/_expected/umd.js | 10 ++++++ test/form/empty-switch-statement/main.js | 11 +++++++ .../form/empty-try-catch-statement/_config.js | 3 ++ .../_expected/amd.js | 6 ++++ .../_expected/cjs.js | 4 +++ .../empty-try-catch-statement/_expected/es.js | 2 ++ .../_expected/iife.js | 7 ++++ .../_expected/umd.js | 10 ++++++ test/form/empty-try-catch-statement/main.js | 9 ++++++ test/form/empty-while-statement/_config.js | 3 ++ .../empty-while-statement/_expected/amd.js | 6 ++++ .../empty-while-statement/_expected/cjs.js | 4 +++ .../empty-while-statement/_expected/es.js | 2 ++ .../empty-while-statement/_expected/iife.js | 7 ++++ .../empty-while-statement/_expected/umd.js | 10 ++++++ test/form/empty-while-statement/main.js | 6 ++++ .../_expected/amd.js | 4 +-- .../_expected/cjs.js | 4 +-- .../_expected/es.js | 4 +-- .../_expected/iife.js | 4 +-- .../_expected/umd.js | 4 +-- .../_expected/amd.js | 2 +- .../_expected/cjs.js | 2 +- .../_expected/es.js | 2 +- .../_expected/iife.js | 2 +- .../_expected/umd.js | 4 +-- 90 files changed, 484 insertions(+), 66 deletions(-) create mode 100644 src/ast/nodes/EmptyStatement.js create mode 100644 src/ast/nodes/ForStatement.js create mode 100644 test/form/empty-block-statement/_config.js create mode 100644 test/form/empty-block-statement/_expected/amd.js create mode 100644 test/form/empty-block-statement/_expected/cjs.js create mode 100644 test/form/empty-block-statement/_expected/es.js create mode 100644 test/form/empty-block-statement/_expected/iife.js create mode 100644 test/form/empty-block-statement/_expected/umd.js create mode 100644 test/form/empty-block-statement/main.js create mode 100644 test/form/empty-do-while-statement/_config.js create mode 100644 test/form/empty-do-while-statement/_expected/amd.js create mode 100644 test/form/empty-do-while-statement/_expected/cjs.js create mode 100644 test/form/empty-do-while-statement/_expected/es.js create mode 100644 test/form/empty-do-while-statement/_expected/iife.js create mode 100644 test/form/empty-do-while-statement/_expected/umd.js create mode 100644 test/form/empty-do-while-statement/main.js create mode 100644 test/form/empty-for-in-statement/_config.js create mode 100644 test/form/empty-for-in-statement/_expected/amd.js create mode 100644 test/form/empty-for-in-statement/_expected/cjs.js create mode 100644 test/form/empty-for-in-statement/_expected/es.js create mode 100644 test/form/empty-for-in-statement/_expected/iife.js create mode 100644 test/form/empty-for-in-statement/_expected/umd.js create mode 100644 test/form/empty-for-in-statement/main.js create mode 100644 test/form/empty-for-of-statement/_config.js create mode 100644 test/form/empty-for-of-statement/_expected/amd.js create mode 100644 test/form/empty-for-of-statement/_expected/cjs.js create mode 100644 test/form/empty-for-of-statement/_expected/es.js create mode 100644 test/form/empty-for-of-statement/_expected/iife.js create mode 100644 test/form/empty-for-of-statement/_expected/umd.js create mode 100644 test/form/empty-for-of-statement/main.js create mode 100644 test/form/empty-for-statement/_config.js create mode 100644 test/form/empty-for-statement/_expected/amd.js create mode 100644 test/form/empty-for-statement/_expected/cjs.js create mode 100644 test/form/empty-for-statement/_expected/es.js create mode 100644 test/form/empty-for-statement/_expected/iife.js create mode 100644 test/form/empty-for-statement/_expected/umd.js create mode 100644 test/form/empty-for-statement/main.js create mode 100644 test/form/empty-if-statement/_config.js create mode 100644 test/form/empty-if-statement/_expected/amd.js create mode 100644 test/form/empty-if-statement/_expected/cjs.js create mode 100644 test/form/empty-if-statement/_expected/es.js create mode 100644 test/form/empty-if-statement/_expected/iife.js create mode 100644 test/form/empty-if-statement/_expected/umd.js create mode 100644 test/form/empty-if-statement/main.js create mode 100644 test/form/empty-statement/_config.js create mode 100644 test/form/empty-statement/_expected/amd.js create mode 100644 test/form/empty-statement/_expected/cjs.js create mode 100644 test/form/empty-statement/_expected/es.js create mode 100644 test/form/empty-statement/_expected/iife.js create mode 100644 test/form/empty-statement/_expected/umd.js create mode 100644 test/form/empty-statement/main.js create mode 100644 test/form/empty-switch-statement/_config.js create mode 100644 test/form/empty-switch-statement/_expected/amd.js create mode 100644 test/form/empty-switch-statement/_expected/cjs.js create mode 100644 test/form/empty-switch-statement/_expected/es.js create mode 100644 test/form/empty-switch-statement/_expected/iife.js create mode 100644 test/form/empty-switch-statement/_expected/umd.js create mode 100644 test/form/empty-switch-statement/main.js create mode 100644 test/form/empty-try-catch-statement/_config.js create mode 100644 test/form/empty-try-catch-statement/_expected/amd.js create mode 100644 test/form/empty-try-catch-statement/_expected/cjs.js create mode 100644 test/form/empty-try-catch-statement/_expected/es.js create mode 100644 test/form/empty-try-catch-statement/_expected/iife.js create mode 100644 test/form/empty-try-catch-statement/_expected/umd.js create mode 100644 test/form/empty-try-catch-statement/main.js create mode 100644 test/form/empty-while-statement/_config.js create mode 100644 test/form/empty-while-statement/_expected/amd.js create mode 100644 test/form/empty-while-statement/_expected/cjs.js create mode 100644 test/form/empty-while-statement/_expected/es.js create mode 100644 test/form/empty-while-statement/_expected/iife.js create mode 100644 test/form/empty-while-statement/_expected/umd.js create mode 100644 test/form/empty-while-statement/main.js diff --git a/src/ast/nodes/ArrowFunctionExpression.js b/src/ast/nodes/ArrowFunctionExpression.js index 2071965..257c7a3 100644 --- a/src/ast/nodes/ArrowFunctionExpression.js +++ b/src/ast/nodes/ArrowFunctionExpression.js @@ -3,8 +3,22 @@ import Scope from '../scopes/Scope.js'; import extractNames from '../utils/extractNames.js'; export default class ArrowFunctionExpression extends Node { + bind ( scope ) { + super.bind( this.scope || scope ); + } + + findScope ( functionScope ) { + return this.scope || this.parent.findScope( functionScope ); + } + + hasEffects () { + return false; + } + initialise ( scope ) { - if ( this.body.type !== 'BlockStatement' ) { + if ( this.body.type === 'BlockStatement' ) { + this.body.createScope( scope ); + } else { this.scope = new Scope({ parent: scope, isBlockScope: false, @@ -18,18 +32,7 @@ export default class ArrowFunctionExpression extends Node { } } + scope = this.scope || this.body.scope; super.initialise( scope ); } - - bind ( scope ) { - super.bind( this.scope || scope ); - } - - findScope ( functionScope ) { - return this.scope || this.parent.findScope( functionScope ); - } - - hasEffects () { - return false; - } } diff --git a/src/ast/nodes/AssignmentExpression.js b/src/ast/nodes/AssignmentExpression.js index b8dc0e2..f1fbcf3 100644 --- a/src/ast/nodes/AssignmentExpression.js +++ b/src/ast/nodes/AssignmentExpression.js @@ -35,11 +35,13 @@ export default class AssignmentExpression extends Node { } initialise ( scope ) { + this.scope = scope; + this.module.bundle.dependentExpressions.push( this ); super.initialise( scope ); } isUsedByBundle () { - return isUsedByBundle( this.findScope(), this.subject ); + return isUsedByBundle( this.scope, this.subject ); } } diff --git a/src/ast/nodes/BlockStatement.js b/src/ast/nodes/BlockStatement.js index ea341d5..78e6e67 100644 --- a/src/ast/nodes/BlockStatement.js +++ b/src/ast/nodes/BlockStatement.js @@ -1,8 +1,8 @@ -import Node from '../Node.js'; +import Statement from './shared/Statement.js'; import Scope from '../scopes/Scope.js'; import extractNames from '../utils/extractNames.js'; -export default class BlockStatement extends Node { +export default class BlockStatement extends Statement { bind () { for ( const node of this.body ) { node.bind( this.scope ); @@ -14,9 +14,9 @@ export default class BlockStatement extends Node { this.isFunctionBlock = this.parentIsFunction || this.parent.type === 'Module'; this.scope = new Scope({ + parent, isBlockScope: !this.isFunctionBlock, isLexicalBoundary: this.isFunctionBlock && this.parent.type !== 'ArrowFunctionExpression', - parent: parent || this.parent.findScope( false ), // TODO always supply parent owner: this // TODO is this used anywhere? }); @@ -35,14 +35,8 @@ export default class BlockStatement extends Node { return functionScope && !this.isFunctionBlock ? this.parent.findScope( functionScope ) : this.scope; } - hasEffects () { - for ( const node of this.body ) { - if ( node.hasEffects( this.scope ) ) return true; - } - } - - initialise () { - if ( !this.scope ) this.createScope(); // scope can be created early in some cases, e.g for (let i... ) + initialise ( scope ) { + if ( !this.scope ) this.createScope( scope ); // scope can be created early in some cases, e.g for (let i... ) let lastNode; for ( const node of this.body ) { @@ -52,20 +46,4 @@ export default class BlockStatement extends Node { lastNode = node; } } - - render ( code, es ) { - for ( const node of this.body ) { - node.render( code, es ); - } - } - - run () { - if ( this.ran ) return; - this.ran = true; - - for ( const node of this.body ) { - // TODO only include non-top-level statements if necessary - node.run( this.scope ); - } - } } diff --git a/src/ast/nodes/EmptyStatement.js b/src/ast/nodes/EmptyStatement.js new file mode 100644 index 0000000..27830c4 --- /dev/null +++ b/src/ast/nodes/EmptyStatement.js @@ -0,0 +1,7 @@ +import Statement from './shared/Statement.js'; + +export default class EmptyStatement extends Statement { + render ( code ) { + code.remove( this.start, this.end ); + } +} diff --git a/src/ast/nodes/ForInStatement.js b/src/ast/nodes/ForInStatement.js index a59bfd2..0838aa1 100644 --- a/src/ast/nodes/ForInStatement.js +++ b/src/ast/nodes/ForInStatement.js @@ -4,7 +4,8 @@ import { STRING } from '../values.js'; export default class ForInStatement extends Statement { initialise ( scope ) { - super.initialise( scope ); - assignTo( this.left, scope, STRING ); + this.body.createScope( scope ); + super.initialise( this.body.scope ); + assignTo( this.left, this.body.scope, STRING ); } } diff --git a/src/ast/nodes/ForOfStatement.js b/src/ast/nodes/ForOfStatement.js index 9e663a0..e761433 100644 --- a/src/ast/nodes/ForOfStatement.js +++ b/src/ast/nodes/ForOfStatement.js @@ -4,7 +4,8 @@ import { UNKNOWN } from '../values.js'; export default class ForOfStatement extends Statement { initialise ( scope ) { - super.initialise( scope ); - assignTo( this.left, scope, UNKNOWN ); + this.body.createScope( scope ); + super.initialise( this.body.scope ); + assignTo( this.left, this.body.scope, UNKNOWN ); } } diff --git a/src/ast/nodes/ForStatement.js b/src/ast/nodes/ForStatement.js new file mode 100644 index 0000000..bd5a57f --- /dev/null +++ b/src/ast/nodes/ForStatement.js @@ -0,0 +1,31 @@ +import Statement from './shared/Statement.js'; + +export default class ForStatement extends Statement { + bind () { + const scope = this.body.scope; + + this.init.bind( scope ); + this.test.bind( scope ); + this.update.bind( scope ); + this.body.bind( scope ); + } + + hasEffects () { + return super.hasEffects( this.body.scope ); + } + + initialise ( scope ) { + this.body.createScope( scope ); + scope = this.body.scope; + + // can't use super, because we need to control the order + this.init.initialise( scope ); + this.test.initialise( scope ); + this.update.initialise( scope ); + this.body.initialise( scope ); + } + + run ( scope ) { + super.run( scope ); + } +} diff --git a/src/ast/nodes/FunctionDeclaration.js b/src/ast/nodes/FunctionDeclaration.js index 96cba0c..dffed95 100644 --- a/src/ast/nodes/FunctionDeclaration.js +++ b/src/ast/nodes/FunctionDeclaration.js @@ -36,11 +36,11 @@ export default class FunctionDeclaration extends Node { this.name = this.id.name; // may be overridden by bundle.deconflict scope.addDeclaration( this.name, this, false, false ); - this.body.createScope(); + this.body.createScope( scope ); this.id.initialise( scope ); this.params.forEach( param => param.initialise( this.body.scope ) ); - this.body.initialise( scope ); + this.body.initialise(); } render ( code, es ) { diff --git a/src/ast/nodes/FunctionExpression.js b/src/ast/nodes/FunctionExpression.js index 56c87ee..4d170af 100644 --- a/src/ast/nodes/FunctionExpression.js +++ b/src/ast/nodes/FunctionExpression.js @@ -11,8 +11,8 @@ export default class FunctionExpression extends Node { return false; } - initialise () { - this.body.createScope(); // TODO we'll also need to do this for For[Of|In]Statement + initialise ( scope ) { + this.body.createScope( scope ); if ( this.id ) this.id.initialise( this.body.scope ); this.params.forEach( param => param.initialise( this.body.scope ) ); diff --git a/src/ast/nodes/index.js b/src/ast/nodes/index.js index b5babe0..94d2f4c 100644 --- a/src/ast/nodes/index.js +++ b/src/ast/nodes/index.js @@ -7,10 +7,12 @@ import CallExpression from './CallExpression.js'; import ClassDeclaration from './ClassDeclaration.js'; import ClassExpression from './ClassExpression.js'; import ConditionalExpression from './ConditionalExpression.js'; +import EmptyStatement from './EmptyStatement.js'; import ExportAllDeclaration from './ExportAllDeclaration.js'; import ExportDefaultDeclaration from './ExportDefaultDeclaration.js'; import ExportNamedDeclaration from './ExportNamedDeclaration.js'; import ExpressionStatement from './ExpressionStatement.js'; +import ForStatement from './ForStatement.js'; import ForInStatement from './ForInStatement.js'; import ForOfStatement from './ForOfStatement.js'; import FunctionDeclaration from './FunctionDeclaration.js'; @@ -24,6 +26,7 @@ import NewExpression from './NewExpression.js'; import ObjectExpression from './ObjectExpression.js'; import ParenthesizedExpression from './ParenthesizedExpression.js'; import ReturnStatement from './ReturnStatement.js'; +import Statement from './shared/Statement.js'; import TemplateLiteral from './TemplateLiteral.js'; import ThisExpression from './ThisExpression.js'; import ThrowStatement from './ThrowStatement.js'; @@ -42,10 +45,13 @@ export default { ClassDeclaration, ClassExpression, ConditionalExpression, + DoWhileStatement: Statement, + EmptyStatement, ExportAllDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration, ExpressionStatement, + ForStatement, ForInStatement, ForOfStatement, FunctionDeclaration, @@ -59,11 +65,14 @@ export default { ObjectExpression, ParenthesizedExpression, ReturnStatement, + SwitchStatement: Statement, TemplateLiteral, ThisExpression, ThrowStatement, + TryStatement: Statement, UnaryExpression, UpdateExpression, VariableDeclarator, - VariableDeclaration + VariableDeclaration, + WhileStatement: Statement }; diff --git a/test/form/empty-block-statement/_config.js b/test/form/empty-block-statement/_config.js new file mode 100644 index 0000000..283b0b6 --- /dev/null +++ b/test/form/empty-block-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'removes an empty block statement' +}; diff --git a/test/form/empty-block-statement/_expected/amd.js b/test/form/empty-block-statement/_expected/amd.js new file mode 100644 index 0000000..6036f28 --- /dev/null +++ b/test/form/empty-block-statement/_expected/amd.js @@ -0,0 +1,6 @@ +define(function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}); diff --git a/test/form/empty-block-statement/_expected/cjs.js b/test/form/empty-block-statement/_expected/cjs.js new file mode 100644 index 0000000..33f9de0 --- /dev/null +++ b/test/form/empty-block-statement/_expected/cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log( 1 ); +console.log( 2 ); diff --git a/test/form/empty-block-statement/_expected/es.js b/test/form/empty-block-statement/_expected/es.js new file mode 100644 index 0000000..472e544 --- /dev/null +++ b/test/form/empty-block-statement/_expected/es.js @@ -0,0 +1,2 @@ +console.log( 1 ); +console.log( 2 ); diff --git a/test/form/empty-block-statement/_expected/iife.js b/test/form/empty-block-statement/_expected/iife.js new file mode 100644 index 0000000..08a84a9 --- /dev/null +++ b/test/form/empty-block-statement/_expected/iife.js @@ -0,0 +1,7 @@ +(function () { + 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}()); diff --git a/test/form/empty-block-statement/_expected/umd.js b/test/form/empty-block-statement/_expected/umd.js new file mode 100644 index 0000000..0aae43f --- /dev/null +++ b/test/form/empty-block-statement/_expected/umd.js @@ -0,0 +1,10 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}))); diff --git a/test/form/empty-block-statement/main.js b/test/form/empty-block-statement/main.js new file mode 100644 index 0000000..edca010 --- /dev/null +++ b/test/form/empty-block-statement/main.js @@ -0,0 +1,5 @@ +console.log( 1 ); +{ + // empty +} +console.log( 2 ); diff --git a/test/form/empty-do-while-statement/_config.js b/test/form/empty-do-while-statement/_config.js new file mode 100644 index 0000000..00672ed --- /dev/null +++ b/test/form/empty-do-while-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'removes an empty do-while statement' +}; diff --git a/test/form/empty-do-while-statement/_expected/amd.js b/test/form/empty-do-while-statement/_expected/amd.js new file mode 100644 index 0000000..e44e556 --- /dev/null +++ b/test/form/empty-do-while-statement/_expected/amd.js @@ -0,0 +1,6 @@ +define(function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}); \ No newline at end of file diff --git a/test/form/empty-do-while-statement/_expected/cjs.js b/test/form/empty-do-while-statement/_expected/cjs.js new file mode 100644 index 0000000..1afb143 --- /dev/null +++ b/test/form/empty-do-while-statement/_expected/cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-do-while-statement/_expected/es.js b/test/form/empty-do-while-statement/_expected/es.js new file mode 100644 index 0000000..f97f3d0 --- /dev/null +++ b/test/form/empty-do-while-statement/_expected/es.js @@ -0,0 +1,2 @@ +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-do-while-statement/_expected/iife.js b/test/form/empty-do-while-statement/_expected/iife.js new file mode 100644 index 0000000..39aedbf --- /dev/null +++ b/test/form/empty-do-while-statement/_expected/iife.js @@ -0,0 +1,7 @@ +(function () { + 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}()); \ No newline at end of file diff --git a/test/form/empty-do-while-statement/_expected/umd.js b/test/form/empty-do-while-statement/_expected/umd.js new file mode 100644 index 0000000..0445193 --- /dev/null +++ b/test/form/empty-do-while-statement/_expected/umd.js @@ -0,0 +1,10 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}))); \ No newline at end of file diff --git a/test/form/empty-do-while-statement/main.js b/test/form/empty-do-while-statement/main.js new file mode 100644 index 0000000..8b04429 --- /dev/null +++ b/test/form/empty-do-while-statement/main.js @@ -0,0 +1,6 @@ +console.log( 1 ); +var condition = true; +do { + condition = false; +} while ( condition ); +console.log( 2 ); diff --git a/test/form/empty-for-in-statement/_config.js b/test/form/empty-for-in-statement/_config.js new file mode 100644 index 0000000..b95837c --- /dev/null +++ b/test/form/empty-for-in-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'removes an empty for-in statement' +}; diff --git a/test/form/empty-for-in-statement/_expected/amd.js b/test/form/empty-for-in-statement/_expected/amd.js new file mode 100644 index 0000000..e44e556 --- /dev/null +++ b/test/form/empty-for-in-statement/_expected/amd.js @@ -0,0 +1,6 @@ +define(function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}); \ No newline at end of file diff --git a/test/form/empty-for-in-statement/_expected/cjs.js b/test/form/empty-for-in-statement/_expected/cjs.js new file mode 100644 index 0000000..1afb143 --- /dev/null +++ b/test/form/empty-for-in-statement/_expected/cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-for-in-statement/_expected/es.js b/test/form/empty-for-in-statement/_expected/es.js new file mode 100644 index 0000000..f97f3d0 --- /dev/null +++ b/test/form/empty-for-in-statement/_expected/es.js @@ -0,0 +1,2 @@ +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-for-in-statement/_expected/iife.js b/test/form/empty-for-in-statement/_expected/iife.js new file mode 100644 index 0000000..39aedbf --- /dev/null +++ b/test/form/empty-for-in-statement/_expected/iife.js @@ -0,0 +1,7 @@ +(function () { + 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}()); \ No newline at end of file diff --git a/test/form/empty-for-in-statement/_expected/umd.js b/test/form/empty-for-in-statement/_expected/umd.js new file mode 100644 index 0000000..0445193 --- /dev/null +++ b/test/form/empty-for-in-statement/_expected/umd.js @@ -0,0 +1,10 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}))); \ No newline at end of file diff --git a/test/form/empty-for-in-statement/main.js b/test/form/empty-for-in-statement/main.js new file mode 100644 index 0000000..cb706f7 --- /dev/null +++ b/test/form/empty-for-in-statement/main.js @@ -0,0 +1,5 @@ +console.log( 1 ); +for ( const i in whatever ) { + // do nothing +} +console.log( 2 ); diff --git a/test/form/empty-for-of-statement/_config.js b/test/form/empty-for-of-statement/_config.js new file mode 100644 index 0000000..4a7bd91 --- /dev/null +++ b/test/form/empty-for-of-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'removes an empty for-of statement' +}; diff --git a/test/form/empty-for-of-statement/_expected/amd.js b/test/form/empty-for-of-statement/_expected/amd.js new file mode 100644 index 0000000..e44e556 --- /dev/null +++ b/test/form/empty-for-of-statement/_expected/amd.js @@ -0,0 +1,6 @@ +define(function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}); \ No newline at end of file diff --git a/test/form/empty-for-of-statement/_expected/cjs.js b/test/form/empty-for-of-statement/_expected/cjs.js new file mode 100644 index 0000000..1afb143 --- /dev/null +++ b/test/form/empty-for-of-statement/_expected/cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-for-of-statement/_expected/es.js b/test/form/empty-for-of-statement/_expected/es.js new file mode 100644 index 0000000..f97f3d0 --- /dev/null +++ b/test/form/empty-for-of-statement/_expected/es.js @@ -0,0 +1,2 @@ +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-for-of-statement/_expected/iife.js b/test/form/empty-for-of-statement/_expected/iife.js new file mode 100644 index 0000000..39aedbf --- /dev/null +++ b/test/form/empty-for-of-statement/_expected/iife.js @@ -0,0 +1,7 @@ +(function () { + 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}()); \ No newline at end of file diff --git a/test/form/empty-for-of-statement/_expected/umd.js b/test/form/empty-for-of-statement/_expected/umd.js new file mode 100644 index 0000000..0445193 --- /dev/null +++ b/test/form/empty-for-of-statement/_expected/umd.js @@ -0,0 +1,10 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}))); \ No newline at end of file diff --git a/test/form/empty-for-of-statement/main.js b/test/form/empty-for-of-statement/main.js new file mode 100644 index 0000000..e591dde --- /dev/null +++ b/test/form/empty-for-of-statement/main.js @@ -0,0 +1,5 @@ +console.log( 1 ); +for ( const i of whatever ) { + // do nothing +} +console.log( 2 ); diff --git a/test/form/empty-for-statement/_config.js b/test/form/empty-for-statement/_config.js new file mode 100644 index 0000000..f448ddf --- /dev/null +++ b/test/form/empty-for-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'removes an empty for statement' +}; diff --git a/test/form/empty-for-statement/_expected/amd.js b/test/form/empty-for-statement/_expected/amd.js new file mode 100644 index 0000000..6036f28 --- /dev/null +++ b/test/form/empty-for-statement/_expected/amd.js @@ -0,0 +1,6 @@ +define(function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}); diff --git a/test/form/empty-for-statement/_expected/cjs.js b/test/form/empty-for-statement/_expected/cjs.js new file mode 100644 index 0000000..33f9de0 --- /dev/null +++ b/test/form/empty-for-statement/_expected/cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log( 1 ); +console.log( 2 ); diff --git a/test/form/empty-for-statement/_expected/es.js b/test/form/empty-for-statement/_expected/es.js new file mode 100644 index 0000000..472e544 --- /dev/null +++ b/test/form/empty-for-statement/_expected/es.js @@ -0,0 +1,2 @@ +console.log( 1 ); +console.log( 2 ); diff --git a/test/form/empty-for-statement/_expected/iife.js b/test/form/empty-for-statement/_expected/iife.js new file mode 100644 index 0000000..08a84a9 --- /dev/null +++ b/test/form/empty-for-statement/_expected/iife.js @@ -0,0 +1,7 @@ +(function () { + 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}()); diff --git a/test/form/empty-for-statement/_expected/umd.js b/test/form/empty-for-statement/_expected/umd.js new file mode 100644 index 0000000..0aae43f --- /dev/null +++ b/test/form/empty-for-statement/_expected/umd.js @@ -0,0 +1,10 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}))); diff --git a/test/form/empty-for-statement/main.js b/test/form/empty-for-statement/main.js new file mode 100644 index 0000000..3b5d176 --- /dev/null +++ b/test/form/empty-for-statement/main.js @@ -0,0 +1,5 @@ +console.log( 1 ); +for ( let i = 0; i < 10; i += 1 ) { + // do nothing +} +console.log( 2 ); diff --git a/test/form/empty-if-statement/_config.js b/test/form/empty-if-statement/_config.js new file mode 100644 index 0000000..abea889 --- /dev/null +++ b/test/form/empty-if-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'removes an empty if statement' +}; diff --git a/test/form/empty-if-statement/_expected/amd.js b/test/form/empty-if-statement/_expected/amd.js new file mode 100644 index 0000000..e44e556 --- /dev/null +++ b/test/form/empty-if-statement/_expected/amd.js @@ -0,0 +1,6 @@ +define(function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}); \ No newline at end of file diff --git a/test/form/empty-if-statement/_expected/cjs.js b/test/form/empty-if-statement/_expected/cjs.js new file mode 100644 index 0000000..1afb143 --- /dev/null +++ b/test/form/empty-if-statement/_expected/cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-if-statement/_expected/es.js b/test/form/empty-if-statement/_expected/es.js new file mode 100644 index 0000000..f97f3d0 --- /dev/null +++ b/test/form/empty-if-statement/_expected/es.js @@ -0,0 +1,2 @@ +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-if-statement/_expected/iife.js b/test/form/empty-if-statement/_expected/iife.js new file mode 100644 index 0000000..39aedbf --- /dev/null +++ b/test/form/empty-if-statement/_expected/iife.js @@ -0,0 +1,7 @@ +(function () { + 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}()); \ No newline at end of file diff --git a/test/form/empty-if-statement/_expected/umd.js b/test/form/empty-if-statement/_expected/umd.js new file mode 100644 index 0000000..0445193 --- /dev/null +++ b/test/form/empty-if-statement/_expected/umd.js @@ -0,0 +1,10 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}))); \ No newline at end of file diff --git a/test/form/empty-if-statement/main.js b/test/form/empty-if-statement/main.js new file mode 100644 index 0000000..6db9dc1 --- /dev/null +++ b/test/form/empty-if-statement/main.js @@ -0,0 +1,5 @@ +console.log( 1 ); +if ( nothing ) { + // empty +} +console.log( 2 ); diff --git a/test/form/empty-statement/_config.js b/test/form/empty-statement/_config.js new file mode 100644 index 0000000..76e4fa3 --- /dev/null +++ b/test/form/empty-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'removes an empty statement' +}; diff --git a/test/form/empty-statement/_expected/amd.js b/test/form/empty-statement/_expected/amd.js new file mode 100644 index 0000000..d7ee383 --- /dev/null +++ b/test/form/empty-statement/_expected/amd.js @@ -0,0 +1,7 @@ +define(function () { 'use strict'; + + console.log( 1 ); + + console.log( 2 ); + +}); diff --git a/test/form/empty-statement/_expected/cjs.js b/test/form/empty-statement/_expected/cjs.js new file mode 100644 index 0000000..2ad8cd2 --- /dev/null +++ b/test/form/empty-statement/_expected/cjs.js @@ -0,0 +1,5 @@ +'use strict'; + +console.log( 1 ); + +console.log( 2 ); diff --git a/test/form/empty-statement/_expected/es.js b/test/form/empty-statement/_expected/es.js new file mode 100644 index 0000000..b149085 --- /dev/null +++ b/test/form/empty-statement/_expected/es.js @@ -0,0 +1,3 @@ +console.log( 1 ); + +console.log( 2 ); diff --git a/test/form/empty-statement/_expected/iife.js b/test/form/empty-statement/_expected/iife.js new file mode 100644 index 0000000..c9dbff5 --- /dev/null +++ b/test/form/empty-statement/_expected/iife.js @@ -0,0 +1,8 @@ +(function () { + 'use strict'; + + console.log( 1 ); + + console.log( 2 ); + +}()); diff --git a/test/form/empty-statement/_expected/umd.js b/test/form/empty-statement/_expected/umd.js new file mode 100644 index 0000000..e97ebff --- /dev/null +++ b/test/form/empty-statement/_expected/umd.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log( 1 ); + + console.log( 2 ); + +}))); diff --git a/test/form/empty-statement/main.js b/test/form/empty-statement/main.js new file mode 100644 index 0000000..43f7037 --- /dev/null +++ b/test/form/empty-statement/main.js @@ -0,0 +1,4 @@ +; +console.log( 1 );; +; +console.log( 2 );; diff --git a/test/form/empty-switch-statement/_config.js b/test/form/empty-switch-statement/_config.js new file mode 100644 index 0000000..29c0517 --- /dev/null +++ b/test/form/empty-switch-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'removes an empty switch statement' +}; diff --git a/test/form/empty-switch-statement/_expected/amd.js b/test/form/empty-switch-statement/_expected/amd.js new file mode 100644 index 0000000..e44e556 --- /dev/null +++ b/test/form/empty-switch-statement/_expected/amd.js @@ -0,0 +1,6 @@ +define(function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}); \ No newline at end of file diff --git a/test/form/empty-switch-statement/_expected/cjs.js b/test/form/empty-switch-statement/_expected/cjs.js new file mode 100644 index 0000000..1afb143 --- /dev/null +++ b/test/form/empty-switch-statement/_expected/cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-switch-statement/_expected/es.js b/test/form/empty-switch-statement/_expected/es.js new file mode 100644 index 0000000..f97f3d0 --- /dev/null +++ b/test/form/empty-switch-statement/_expected/es.js @@ -0,0 +1,2 @@ +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-switch-statement/_expected/iife.js b/test/form/empty-switch-statement/_expected/iife.js new file mode 100644 index 0000000..39aedbf --- /dev/null +++ b/test/form/empty-switch-statement/_expected/iife.js @@ -0,0 +1,7 @@ +(function () { + 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}()); \ No newline at end of file diff --git a/test/form/empty-switch-statement/_expected/umd.js b/test/form/empty-switch-statement/_expected/umd.js new file mode 100644 index 0000000..0445193 --- /dev/null +++ b/test/form/empty-switch-statement/_expected/umd.js @@ -0,0 +1,10 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}))); \ No newline at end of file diff --git a/test/form/empty-switch-statement/main.js b/test/form/empty-switch-statement/main.js new file mode 100644 index 0000000..58da4d4 --- /dev/null +++ b/test/form/empty-switch-statement/main.js @@ -0,0 +1,11 @@ +console.log( 1 ); +var result; +switch ( whatever ) { + case foo: + result = 'foo'; + break; + + default: + result = 'default'; +} +console.log( 2 ); diff --git a/test/form/empty-try-catch-statement/_config.js b/test/form/empty-try-catch-statement/_config.js new file mode 100644 index 0000000..70bf652 --- /dev/null +++ b/test/form/empty-try-catch-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'removes an empty try-catch-finally statement' +}; diff --git a/test/form/empty-try-catch-statement/_expected/amd.js b/test/form/empty-try-catch-statement/_expected/amd.js new file mode 100644 index 0000000..e44e556 --- /dev/null +++ b/test/form/empty-try-catch-statement/_expected/amd.js @@ -0,0 +1,6 @@ +define(function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}); \ No newline at end of file diff --git a/test/form/empty-try-catch-statement/_expected/cjs.js b/test/form/empty-try-catch-statement/_expected/cjs.js new file mode 100644 index 0000000..1afb143 --- /dev/null +++ b/test/form/empty-try-catch-statement/_expected/cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-try-catch-statement/_expected/es.js b/test/form/empty-try-catch-statement/_expected/es.js new file mode 100644 index 0000000..f97f3d0 --- /dev/null +++ b/test/form/empty-try-catch-statement/_expected/es.js @@ -0,0 +1,2 @@ +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-try-catch-statement/_expected/iife.js b/test/form/empty-try-catch-statement/_expected/iife.js new file mode 100644 index 0000000..39aedbf --- /dev/null +++ b/test/form/empty-try-catch-statement/_expected/iife.js @@ -0,0 +1,7 @@ +(function () { + 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}()); \ No newline at end of file diff --git a/test/form/empty-try-catch-statement/_expected/umd.js b/test/form/empty-try-catch-statement/_expected/umd.js new file mode 100644 index 0000000..0445193 --- /dev/null +++ b/test/form/empty-try-catch-statement/_expected/umd.js @@ -0,0 +1,10 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}))); \ No newline at end of file diff --git a/test/form/empty-try-catch-statement/main.js b/test/form/empty-try-catch-statement/main.js new file mode 100644 index 0000000..52ed8c1 --- /dev/null +++ b/test/form/empty-try-catch-statement/main.js @@ -0,0 +1,9 @@ +console.log( 1 ); +try { + // do nothing +} catch ( err ) { + // do nothing +} finally { + // do nothing +} +console.log( 2 ); diff --git a/test/form/empty-while-statement/_config.js b/test/form/empty-while-statement/_config.js new file mode 100644 index 0000000..8db2e7f --- /dev/null +++ b/test/form/empty-while-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'removes an empty while statement' +}; diff --git a/test/form/empty-while-statement/_expected/amd.js b/test/form/empty-while-statement/_expected/amd.js new file mode 100644 index 0000000..e44e556 --- /dev/null +++ b/test/form/empty-while-statement/_expected/amd.js @@ -0,0 +1,6 @@ +define(function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}); \ No newline at end of file diff --git a/test/form/empty-while-statement/_expected/cjs.js b/test/form/empty-while-statement/_expected/cjs.js new file mode 100644 index 0000000..1afb143 --- /dev/null +++ b/test/form/empty-while-statement/_expected/cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-while-statement/_expected/es.js b/test/form/empty-while-statement/_expected/es.js new file mode 100644 index 0000000..f97f3d0 --- /dev/null +++ b/test/form/empty-while-statement/_expected/es.js @@ -0,0 +1,2 @@ +console.log( 1 ); +console.log( 2 ); \ No newline at end of file diff --git a/test/form/empty-while-statement/_expected/iife.js b/test/form/empty-while-statement/_expected/iife.js new file mode 100644 index 0000000..39aedbf --- /dev/null +++ b/test/form/empty-while-statement/_expected/iife.js @@ -0,0 +1,7 @@ +(function () { + 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}()); \ No newline at end of file diff --git a/test/form/empty-while-statement/_expected/umd.js b/test/form/empty-while-statement/_expected/umd.js new file mode 100644 index 0000000..0445193 --- /dev/null +++ b/test/form/empty-while-statement/_expected/umd.js @@ -0,0 +1,10 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log( 1 ); + console.log( 2 ); + +}))); \ No newline at end of file diff --git a/test/form/empty-while-statement/main.js b/test/form/empty-while-statement/main.js new file mode 100644 index 0000000..c499a7f --- /dev/null +++ b/test/form/empty-while-statement/main.js @@ -0,0 +1,6 @@ +console.log( 1 ); +var condition = true; +while ( condition ) { + condition = false; +} +console.log( 2 ); diff --git a/test/form/erroneous-nested-member-expression/_expected/amd.js b/test/form/erroneous-nested-member-expression/_expected/amd.js index 6499b90..4b402c7 100644 --- a/test/form/erroneous-nested-member-expression/_expected/amd.js +++ b/test/form/erroneous-nested-member-expression/_expected/amd.js @@ -6,8 +6,8 @@ define(function () { 'use strict'; console.log('har?'); } }; - }; + } yar.har(); -}); \ No newline at end of file +}); diff --git a/test/form/erroneous-nested-member-expression/_expected/cjs.js b/test/form/erroneous-nested-member-expression/_expected/cjs.js index aa4b949..01c96f9 100644 --- a/test/form/erroneous-nested-member-expression/_expected/cjs.js +++ b/test/form/erroneous-nested-member-expression/_expected/cjs.js @@ -6,6 +6,6 @@ function yar() { console.log('har?'); } }; -}; +} -yar.har(); \ No newline at end of file +yar.har(); diff --git a/test/form/erroneous-nested-member-expression/_expected/es.js b/test/form/erroneous-nested-member-expression/_expected/es.js index 34c4e2e..ee4eace 100644 --- a/test/form/erroneous-nested-member-expression/_expected/es.js +++ b/test/form/erroneous-nested-member-expression/_expected/es.js @@ -4,6 +4,6 @@ function yar() { console.log('har?'); } }; -}; +} -yar.har(); \ No newline at end of file +yar.har(); diff --git a/test/form/erroneous-nested-member-expression/_expected/iife.js b/test/form/erroneous-nested-member-expression/_expected/iife.js index 4233cfe..8a8d65e 100644 --- a/test/form/erroneous-nested-member-expression/_expected/iife.js +++ b/test/form/erroneous-nested-member-expression/_expected/iife.js @@ -7,8 +7,8 @@ console.log('har?'); } }; - }; + } yar.har(); -}()); \ No newline at end of file +}()); diff --git a/test/form/erroneous-nested-member-expression/_expected/umd.js b/test/form/erroneous-nested-member-expression/_expected/umd.js index 2a8dba1..94dee16 100644 --- a/test/form/erroneous-nested-member-expression/_expected/umd.js +++ b/test/form/erroneous-nested-member-expression/_expected/umd.js @@ -10,8 +10,8 @@ console.log('har?'); } }; - }; + } yar.har(); -}))); \ No newline at end of file +}))); diff --git a/test/form/spacing-after-function-with-semicolon/_expected/amd.js b/test/form/spacing-after-function-with-semicolon/_expected/amd.js index 37f42f3..4db965c 100644 --- a/test/form/spacing-after-function-with-semicolon/_expected/amd.js +++ b/test/form/spacing-after-function-with-semicolon/_expected/amd.js @@ -1,6 +1,6 @@ define(function () { 'use strict'; - function x () { return 'x' }; + function x () { return 'x' } assert.equal( x(), 'x' ); diff --git a/test/form/spacing-after-function-with-semicolon/_expected/cjs.js b/test/form/spacing-after-function-with-semicolon/_expected/cjs.js index 503ea73..bac28c1 100644 --- a/test/form/spacing-after-function-with-semicolon/_expected/cjs.js +++ b/test/form/spacing-after-function-with-semicolon/_expected/cjs.js @@ -1,5 +1,5 @@ 'use strict'; -function x () { return 'x' }; +function x () { return 'x' } assert.equal( x(), 'x' ); diff --git a/test/form/spacing-after-function-with-semicolon/_expected/es.js b/test/form/spacing-after-function-with-semicolon/_expected/es.js index 3b3f5e7..f5b5029 100644 --- a/test/form/spacing-after-function-with-semicolon/_expected/es.js +++ b/test/form/spacing-after-function-with-semicolon/_expected/es.js @@ -1,3 +1,3 @@ -function x () { return 'x' }; +function x () { return 'x' } assert.equal( x(), 'x' ); diff --git a/test/form/spacing-after-function-with-semicolon/_expected/iife.js b/test/form/spacing-after-function-with-semicolon/_expected/iife.js index 7ff78ec..f8d6992 100644 --- a/test/form/spacing-after-function-with-semicolon/_expected/iife.js +++ b/test/form/spacing-after-function-with-semicolon/_expected/iife.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - function x () { return 'x' }; + function x () { return 'x' } assert.equal( x(), 'x' ); diff --git a/test/form/spacing-after-function-with-semicolon/_expected/umd.js b/test/form/spacing-after-function-with-semicolon/_expected/umd.js index 8b7954a..75d31a1 100644 --- a/test/form/spacing-after-function-with-semicolon/_expected/umd.js +++ b/test/form/spacing-after-function-with-semicolon/_expected/umd.js @@ -4,8 +4,8 @@ (factory()); }(this, (function () { 'use strict'; - function x () { return 'x' }; + function x () { return 'x' } assert.equal( x(), 'x' ); -}))); \ No newline at end of file +}))); From 4379d486f8b0523cbbcef00996ddd6ea43e8312b Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 18:42:14 -0400 Subject: [PATCH 232/331] -> v0.35.4 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 009ae46..d2fcbc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.35.4 + +* Preserve effects in for-of and for-in loops ([#870](https://github.com/rollup/rollup/issues/870)) +* Remove empty statements ([#918](https://github.com/rollup/rollup/pull/918)) + ## 0.35.3 * Render identifiers inside template literals diff --git a/package.json b/package.json index bcb8ff7..097202f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.3", + "version": "0.35.4", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From eba7a70350ac22973421eb7a45a9187ad3d264c2 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 19:20:53 -0400 Subject: [PATCH 233/331] =?UTF-8?q?allow=20empty=20for=20loop=20heads=20?= =?UTF-8?q?=E2=80=93=20fixes=20#919?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ast/nodes/ForStatement.js | 15 +++------------ test/form/for-loop-with-empty-head/_config.js | 3 +++ .../for-loop-with-empty-head/_expected/amd.js | 7 +++++++ .../for-loop-with-empty-head/_expected/cjs.js | 5 +++++ .../form/for-loop-with-empty-head/_expected/es.js | 3 +++ .../for-loop-with-empty-head/_expected/iife.js | 8 ++++++++ .../for-loop-with-empty-head/_expected/umd.js | 11 +++++++++++ test/form/for-loop-with-empty-head/main.js | 3 +++ 8 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 test/form/for-loop-with-empty-head/_config.js create mode 100644 test/form/for-loop-with-empty-head/_expected/amd.js create mode 100644 test/form/for-loop-with-empty-head/_expected/cjs.js create mode 100644 test/form/for-loop-with-empty-head/_expected/es.js create mode 100644 test/form/for-loop-with-empty-head/_expected/iife.js create mode 100644 test/form/for-loop-with-empty-head/_expected/umd.js create mode 100644 test/form/for-loop-with-empty-head/main.js diff --git a/src/ast/nodes/ForStatement.js b/src/ast/nodes/ForStatement.js index bd5a57f..1d61b02 100644 --- a/src/ast/nodes/ForStatement.js +++ b/src/ast/nodes/ForStatement.js @@ -1,15 +1,6 @@ import Statement from './shared/Statement.js'; export default class ForStatement extends Statement { - bind () { - const scope = this.body.scope; - - this.init.bind( scope ); - this.test.bind( scope ); - this.update.bind( scope ); - this.body.bind( scope ); - } - hasEffects () { return super.hasEffects( this.body.scope ); } @@ -19,9 +10,9 @@ export default class ForStatement extends Statement { scope = this.body.scope; // can't use super, because we need to control the order - this.init.initialise( scope ); - this.test.initialise( scope ); - this.update.initialise( scope ); + if ( this.init ) this.init.initialise( scope ); + if ( this.test ) this.test.initialise( scope ); + if ( this.update ) this.update.initialise( scope ); this.body.initialise( scope ); } diff --git a/test/form/for-loop-with-empty-head/_config.js b/test/form/for-loop-with-empty-head/_config.js new file mode 100644 index 0000000..3fc4a67 --- /dev/null +++ b/test/form/for-loop-with-empty-head/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'handles for loop with empty head' +}; diff --git a/test/form/for-loop-with-empty-head/_expected/amd.js b/test/form/for-loop-with-empty-head/_expected/amd.js new file mode 100644 index 0000000..a07e3e0 --- /dev/null +++ b/test/form/for-loop-with-empty-head/_expected/amd.js @@ -0,0 +1,7 @@ +define(function () { 'use strict'; + + for ( ; ; ) { + console.log( 42 ); + } + +}); \ No newline at end of file diff --git a/test/form/for-loop-with-empty-head/_expected/cjs.js b/test/form/for-loop-with-empty-head/_expected/cjs.js new file mode 100644 index 0000000..f94dff7 --- /dev/null +++ b/test/form/for-loop-with-empty-head/_expected/cjs.js @@ -0,0 +1,5 @@ +'use strict'; + +for ( ; ; ) { + console.log( 42 ); +} \ No newline at end of file diff --git a/test/form/for-loop-with-empty-head/_expected/es.js b/test/form/for-loop-with-empty-head/_expected/es.js new file mode 100644 index 0000000..1690f25 --- /dev/null +++ b/test/form/for-loop-with-empty-head/_expected/es.js @@ -0,0 +1,3 @@ +for ( ; ; ) { + console.log( 42 ); +} \ No newline at end of file diff --git a/test/form/for-loop-with-empty-head/_expected/iife.js b/test/form/for-loop-with-empty-head/_expected/iife.js new file mode 100644 index 0000000..2217234 --- /dev/null +++ b/test/form/for-loop-with-empty-head/_expected/iife.js @@ -0,0 +1,8 @@ +(function () { + 'use strict'; + + for ( ; ; ) { + console.log( 42 ); + } + +}()); \ No newline at end of file diff --git a/test/form/for-loop-with-empty-head/_expected/umd.js b/test/form/for-loop-with-empty-head/_expected/umd.js new file mode 100644 index 0000000..3e90731 --- /dev/null +++ b/test/form/for-loop-with-empty-head/_expected/umd.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + for ( ; ; ) { + console.log( 42 ); + } + +}))); \ No newline at end of file diff --git a/test/form/for-loop-with-empty-head/main.js b/test/form/for-loop-with-empty-head/main.js new file mode 100644 index 0000000..5e492f8 --- /dev/null +++ b/test/form/for-loop-with-empty-head/main.js @@ -0,0 +1,3 @@ +for ( ; ; ) { + console.log( 42 ); +} From 7afadff2683b845fa90d0c6d302c834dbe361749 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 19:44:28 -0400 Subject: [PATCH 234/331] handle body-less for loops etc --- src/ast/Node.js | 8 +++-- src/ast/nodes/ArrowFunctionExpression.js | 4 +-- src/ast/nodes/ForInStatement.js | 17 +++++++++-- src/ast/nodes/ForOfStatement.js | 17 +++++++++-- src/ast/nodes/ForStatement.js | 29 ++++++++++--------- test/form/body-less-for-loops/_config.js | 3 ++ .../form/body-less-for-loops/_expected/amd.js | 16 ++++++++++ .../form/body-less-for-loops/_expected/cjs.js | 14 +++++++++ test/form/body-less-for-loops/_expected/es.js | 12 ++++++++ .../body-less-for-loops/_expected/iife.js | 17 +++++++++++ .../form/body-less-for-loops/_expected/umd.js | 20 +++++++++++++ test/form/body-less-for-loops/main.js | 12 ++++++++ 12 files changed, 144 insertions(+), 25 deletions(-) create mode 100644 test/form/body-less-for-loops/_config.js create mode 100644 test/form/body-less-for-loops/_expected/amd.js create mode 100644 test/form/body-less-for-loops/_expected/cjs.js create mode 100644 test/form/body-less-for-loops/_expected/es.js create mode 100644 test/form/body-less-for-loops/_expected/iife.js create mode 100644 test/form/body-less-for-loops/_expected/umd.js create mode 100644 test/form/body-less-for-loops/main.js diff --git a/src/ast/Node.js b/src/ast/Node.js index 0343f28..4f65871 100644 --- a/src/ast/Node.js +++ b/src/ast/Node.js @@ -3,7 +3,7 @@ import getLocation from '../utils/getLocation.js'; export default class Node { bind ( scope ) { - this.eachChild( child => child.bind( scope ) ); + this.eachChild( child => child.bind( this.scope || scope ) ); } eachChild ( callback ) { @@ -43,6 +43,8 @@ export default class Node { } hasEffects ( scope ) { + if ( this.scope ) scope = this.scope; + for ( const key of this.keys ) { const value = this[ key ]; @@ -61,7 +63,7 @@ export default class Node { } initialise ( scope ) { - this.eachChild( child => child.initialise( scope ) ); + this.eachChild( child => child.initialise( this.scope || scope ) ); } locate () { @@ -82,7 +84,7 @@ export default class Node { this.ran = true; this.eachChild( child => { - child.run( scope ); + child.run( this.scope || scope ); }); } diff --git a/src/ast/nodes/ArrowFunctionExpression.js b/src/ast/nodes/ArrowFunctionExpression.js index 257c7a3..8d9a3d2 100644 --- a/src/ast/nodes/ArrowFunctionExpression.js +++ b/src/ast/nodes/ArrowFunctionExpression.js @@ -18,6 +18,7 @@ export default class ArrowFunctionExpression extends Node { initialise ( scope ) { if ( this.body.type === 'BlockStatement' ) { this.body.createScope( scope ); + this.scope = this.body.scope; } else { this.scope = new Scope({ parent: scope, @@ -32,7 +33,6 @@ export default class ArrowFunctionExpression extends Node { } } - scope = this.scope || this.body.scope; - super.initialise( scope ); + super.initialise( this.scope ); } } diff --git a/src/ast/nodes/ForInStatement.js b/src/ast/nodes/ForInStatement.js index 0838aa1..1872b96 100644 --- a/src/ast/nodes/ForInStatement.js +++ b/src/ast/nodes/ForInStatement.js @@ -1,11 +1,22 @@ import Statement from './shared/Statement.js'; import assignTo from './shared/assignTo.js'; +import Scope from '../scopes/Scope.js'; import { STRING } from '../values.js'; export default class ForInStatement extends Statement { initialise ( scope ) { - this.body.createScope( scope ); - super.initialise( this.body.scope ); - assignTo( this.left, this.body.scope, STRING ); + if ( this.body.type === 'BlockStatement' ) { + this.body.createScope( scope ); + this.scope = this.body.scope; + } else { + this.scope = new Scope({ + parent: scope, + isBlockScope: true, + isLexicalBoundary: false + }); + } + + super.initialise( this.scope ); + assignTo( this.left, this.scope, STRING ); } } diff --git a/src/ast/nodes/ForOfStatement.js b/src/ast/nodes/ForOfStatement.js index e761433..a5225f8 100644 --- a/src/ast/nodes/ForOfStatement.js +++ b/src/ast/nodes/ForOfStatement.js @@ -1,11 +1,22 @@ import Statement from './shared/Statement.js'; import assignTo from './shared/assignTo.js'; +import Scope from '../scopes/Scope.js'; import { UNKNOWN } from '../values.js'; export default class ForOfStatement extends Statement { initialise ( scope ) { - this.body.createScope( scope ); - super.initialise( this.body.scope ); - assignTo( this.left, this.body.scope, UNKNOWN ); + if ( this.body.type === 'BlockStatement' ) { + this.body.createScope( scope ); + this.scope = this.body.scope; + } else { + this.scope = new Scope({ + parent: scope, + isBlockScope: true, + isLexicalBoundary: false + }); + } + + super.initialise( this.scope ); + assignTo( this.left, this.scope, UNKNOWN ); } } diff --git a/src/ast/nodes/ForStatement.js b/src/ast/nodes/ForStatement.js index 1d61b02..11e98e5 100644 --- a/src/ast/nodes/ForStatement.js +++ b/src/ast/nodes/ForStatement.js @@ -1,22 +1,23 @@ import Statement from './shared/Statement.js'; +import Scope from '../scopes/Scope.js'; export default class ForStatement extends Statement { - hasEffects () { - return super.hasEffects( this.body.scope ); - } - initialise ( scope ) { - this.body.createScope( scope ); - scope = this.body.scope; + if ( this.body.type === 'BlockStatement' ) { + this.body.createScope( scope ); + this.scope = this.body.scope; + } else { + this.scope = new Scope({ + parent: scope, + isBlockScope: true, + isLexicalBoundary: false + }); + } // can't use super, because we need to control the order - if ( this.init ) this.init.initialise( scope ); - if ( this.test ) this.test.initialise( scope ); - if ( this.update ) this.update.initialise( scope ); - this.body.initialise( scope ); - } - - run ( scope ) { - super.run( scope ); + if ( this.init ) this.init.initialise( this.scope ); + if ( this.test ) this.test.initialise( this.scope ); + if ( this.update ) this.update.initialise( this.scope ); + this.body.initialise( this.scope ); } } diff --git a/test/form/body-less-for-loops/_config.js b/test/form/body-less-for-loops/_config.js new file mode 100644 index 0000000..a748fa0 --- /dev/null +++ b/test/form/body-less-for-loops/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'supports body-less for loops' +}; diff --git a/test/form/body-less-for-loops/_expected/amd.js b/test/form/body-less-for-loops/_expected/amd.js new file mode 100644 index 0000000..464893d --- /dev/null +++ b/test/form/body-less-for-loops/_expected/amd.js @@ -0,0 +1,16 @@ +define(function () { 'use strict'; + + for ( let i = 0; i < 10; i += 1 ) console.log( i ); + for ( const letter of array ) console.log( letter ); + for ( const index in array ) console.log( index ); + + let i; + for ( i = 0; i < 10; i += 1 ) console.log( i ); + + let letter; + for ( letter of array ) console.log( letter ); + + let index; + for ( index in array ) console.log( index ); + +}); \ No newline at end of file diff --git a/test/form/body-less-for-loops/_expected/cjs.js b/test/form/body-less-for-loops/_expected/cjs.js new file mode 100644 index 0000000..f2e4fde --- /dev/null +++ b/test/form/body-less-for-loops/_expected/cjs.js @@ -0,0 +1,14 @@ +'use strict'; + +for ( let i = 0; i < 10; i += 1 ) console.log( i ); +for ( const letter of array ) console.log( letter ); +for ( const index in array ) console.log( index ); + +let i; +for ( i = 0; i < 10; i += 1 ) console.log( i ); + +let letter; +for ( letter of array ) console.log( letter ); + +let index; +for ( index in array ) console.log( index ); \ No newline at end of file diff --git a/test/form/body-less-for-loops/_expected/es.js b/test/form/body-less-for-loops/_expected/es.js new file mode 100644 index 0000000..63ee4e5 --- /dev/null +++ b/test/form/body-less-for-loops/_expected/es.js @@ -0,0 +1,12 @@ +for ( let i = 0; i < 10; i += 1 ) console.log( i ); +for ( const letter of array ) console.log( letter ); +for ( const index in array ) console.log( index ); + +let i; +for ( i = 0; i < 10; i += 1 ) console.log( i ); + +let letter; +for ( letter of array ) console.log( letter ); + +let index; +for ( index in array ) console.log( index ); \ No newline at end of file diff --git a/test/form/body-less-for-loops/_expected/iife.js b/test/form/body-less-for-loops/_expected/iife.js new file mode 100644 index 0000000..2214bd4 --- /dev/null +++ b/test/form/body-less-for-loops/_expected/iife.js @@ -0,0 +1,17 @@ +(function () { + 'use strict'; + + for ( let i = 0; i < 10; i += 1 ) console.log( i ); + for ( const letter of array ) console.log( letter ); + for ( const index in array ) console.log( index ); + + let i; + for ( i = 0; i < 10; i += 1 ) console.log( i ); + + let letter; + for ( letter of array ) console.log( letter ); + + let index; + for ( index in array ) console.log( index ); + +}()); \ No newline at end of file diff --git a/test/form/body-less-for-loops/_expected/umd.js b/test/form/body-less-for-loops/_expected/umd.js new file mode 100644 index 0000000..9840021 --- /dev/null +++ b/test/form/body-less-for-loops/_expected/umd.js @@ -0,0 +1,20 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + for ( let i = 0; i < 10; i += 1 ) console.log( i ); + for ( const letter of array ) console.log( letter ); + for ( const index in array ) console.log( index ); + + let i; + for ( i = 0; i < 10; i += 1 ) console.log( i ); + + let letter; + for ( letter of array ) console.log( letter ); + + let index; + for ( index in array ) console.log( index ); + +}))); \ No newline at end of file diff --git a/test/form/body-less-for-loops/main.js b/test/form/body-less-for-loops/main.js new file mode 100644 index 0000000..3aa7b7e --- /dev/null +++ b/test/form/body-less-for-loops/main.js @@ -0,0 +1,12 @@ +for ( let i = 0; i < 10; i += 1 ) console.log( i ); +for ( const letter of array ) console.log( letter ); +for ( const index in array ) console.log( index ); + +let i; +for ( i = 0; i < 10; i += 1 ) console.log( i ); + +let letter; +for ( letter of array ) console.log( letter ); + +let index; +for ( index in array ) console.log( index ); From e297468b6a68a17e7c60d25450a67fec9c5ef6ac Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 19:46:29 -0400 Subject: [PATCH 235/331] temporarily revert to 0.34 for build --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 097202f..928a68c 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "mocha": "^3.0.0", "remap-istanbul": "^0.6.4", "require-relative": "^0.8.7", - "rollup": "^0.35.3", + "rollup": "^0.34.0", "rollup-plugin-buble": "^0.12.1", "rollup-plugin-commonjs": "^3.0.0", "rollup-plugin-json": "^2.0.0", From 3ecde8cd093ace63cbecc477827de566d728bd19 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 19:51:27 -0400 Subject: [PATCH 236/331] -> v0.35.5 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2fcbc6..e46c0a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.5 + +* Allow empty for loop heads ([#919](https://github.com/rollup/rollup/issues/919)) + ## 0.35.4 * Preserve effects in for-of and for-in loops ([#870](https://github.com/rollup/rollup/issues/870)) diff --git a/package.json b/package.json index 928a68c..5a2c977 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.4", + "version": "0.35.5", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 55c23a3f23a8047b1dfee8186373949fbcb9bde8 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 20:05:31 -0400 Subject: [PATCH 237/331] browser friendly flushTime --- src/utils/flushTime.js | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/utils/flushTime.js b/src/utils/flushTime.js index fb4d331..000fbb9 100644 --- a/src/utils/flushTime.js +++ b/src/utils/flushTime.js @@ -1,19 +1,35 @@ const DEBUG = false; const map = new Map; +let time; + +if ( typeof process === 'undefined' ) { + time = function time ( previous ) { + const now = window.performance.now(); + return previous ? previous - now : now; + }; +} else { + time = function time ( previous ) { + const hrtime = process.hrtime( previous ); + if ( previous ) { + return hrtime[0] * 1e3 + hrtime[1] / 1e6; + } + }; +} + export function timeStart ( label ) { if ( !map.has( label ) ) { map.set( label, { time: 0 }); } - map.get( label ).start = process.hrtime(); + map.get( label ).start = time(); } export function timeEnd ( label ) { if ( map.has( label ) ) { const item = map.get( label ); - item.time += toMilliseconds( process.hrtime( item.start ) ); + item.time += time( item.start ); } } @@ -24,10 +40,6 @@ export function flushTime ( log = defaultLog ) { map.clear(); } -function toMilliseconds ( time ) { - return time[0] * 1e+3 + Math.floor( time[1] * 1e-6 ); -} - function defaultLog ( label, time ) { if ( DEBUG ) { /* eslint-disable no-console */ From 17f52787cb03072b1eb926d57d7f4f8df5a469f5 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 20:07:00 -0400 Subject: [PATCH 238/331] -> v0.35.6 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e46c0a5..b82ff51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.6 + +* Fix browser build + ## 0.35.5 * Allow empty for loop heads ([#919](https://github.com/rollup/rollup/issues/919)) diff --git a/package.json b/package.json index 5a2c977..b852ddf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.5", + "version": "0.35.6", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From ae82c520e6e9a3eddb130ab876b400b6ecb697f6 Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 10 Sep 2016 17:38:39 -0700 Subject: [PATCH 239/331] Fixed "process.hrtime() only accepts an Array tuple." error --- src/utils/flushTime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/flushTime.js b/src/utils/flushTime.js index 000fbb9..8261189 100644 --- a/src/utils/flushTime.js +++ b/src/utils/flushTime.js @@ -10,8 +10,8 @@ if ( typeof process === 'undefined' ) { }; } else { time = function time ( previous ) { - const hrtime = process.hrtime( previous ); if ( previous ) { + const hrtime = process.hrtime( previous ); return hrtime[0] * 1e3 + hrtime[1] / 1e6; } }; From 10808f733b5389ddeaa97e3b2ea3215cb7b8037e Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 10 Sep 2016 17:59:17 -0700 Subject: [PATCH 240/331] Made flushTime actually work again --- src/utils/flushTime.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/utils/flushTime.js b/src/utils/flushTime.js index 8261189..c6c95e3 100644 --- a/src/utils/flushTime.js +++ b/src/utils/flushTime.js @@ -1,20 +1,25 @@ const DEBUG = false; const map = new Map; -let time; +let time, toMilliseconds; if ( typeof process === 'undefined' ) { time = function time ( previous ) { const now = window.performance.now(); return previous ? previous - now : now; }; + + toMilliseconds = function toMilliseconds ( time ) { + return time; + } } else { time = function time ( previous ) { - if ( previous ) { - const hrtime = process.hrtime( previous ); - return hrtime[0] * 1e3 + hrtime[1] / 1e6; - } + return previous === undefined ? process.hrtime() : process.hrtime( previous ); }; + + toMilliseconds = function toMilliseconds ( time ) { + return time[0] * 1e3 + time[1] / 1e6; + } } export function timeStart ( label ) { @@ -29,7 +34,7 @@ export function timeStart ( label ) { export function timeEnd ( label ) { if ( map.has( label ) ) { const item = map.get( label ); - item.time += time( item.start ); + item.time += toMilliseconds( time( item.start ) ); } } From d31c75bc70ddf134331411e7278aef55310464b0 Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 10 Sep 2016 18:02:32 -0700 Subject: [PATCH 241/331] Pass linting --- src/utils/flushTime.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/utils/flushTime.js b/src/utils/flushTime.js index c6c95e3..c94ac73 100644 --- a/src/utils/flushTime.js +++ b/src/utils/flushTime.js @@ -1,7 +1,8 @@ const DEBUG = false; const map = new Map; -let time, toMilliseconds; +let time; +let toMilliseconds; if ( typeof process === 'undefined' ) { time = function time ( previous ) { @@ -11,7 +12,7 @@ if ( typeof process === 'undefined' ) { toMilliseconds = function toMilliseconds ( time ) { return time; - } + }; } else { time = function time ( previous ) { return previous === undefined ? process.hrtime() : process.hrtime( previous ); @@ -19,7 +20,7 @@ if ( typeof process === 'undefined' ) { toMilliseconds = function toMilliseconds ( time ) { return time[0] * 1e3 + time[1] / 1e6; - } + }; } export function timeStart ( label ) { From b09f0831675f6d4237e83ec6fc16e07afa517cba Mon Sep 17 00:00:00 2001 From: Permutator Date: Sat, 10 Sep 2016 18:17:30 -0700 Subject: [PATCH 242/331] Use timeStartHelper and timeEndHelper instead of time and toMilliseconds --- src/utils/flushTime.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/utils/flushTime.js b/src/utils/flushTime.js index c94ac73..683e28c 100644 --- a/src/utils/flushTime.js +++ b/src/utils/flushTime.js @@ -1,25 +1,25 @@ const DEBUG = false; const map = new Map; -let time; -let toMilliseconds; +let timeStartHelper; +let timeEndHelper; if ( typeof process === 'undefined' ) { - time = function time ( previous ) { - const now = window.performance.now(); - return previous ? previous - now : now; + timeStartHelper = function timeStartHelper () { + return window.performance.now(); }; - toMilliseconds = function toMilliseconds ( time ) { - return time; + timeEndHelper = function timeEndHelper ( previous ) { + return window.performance.now() - previous; }; } else { - time = function time ( previous ) { - return previous === undefined ? process.hrtime() : process.hrtime( previous ); + timeStartHelper = function timeStartHelper () { + return process.hrtime(); }; - toMilliseconds = function toMilliseconds ( time ) { - return time[0] * 1e3 + time[1] / 1e6; + timeEndHelper = function timeEndHelper ( previous ) { + const hrtime = process.hrtime( previous ); + return hrtime[0] * 1e3 + hrtime[1] / 1e6; }; } @@ -29,13 +29,13 @@ export function timeStart ( label ) { time: 0 }); } - map.get( label ).start = time(); + map.get( label ).start = timeStartHelper(); } export function timeEnd ( label ) { if ( map.has( label ) ) { const item = map.get( label ); - item.time += toMilliseconds( time( item.start ) ); + item.time += timeEndHelper( item.start ); } } From 1f63f405516a99082d428c75aaad94ee8960f33e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 10 Sep 2016 21:22:38 -0400 Subject: [PATCH 243/331] -> v0.35.7 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b82ff51..2680013 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.7 + +* Refactor `flushTime.js` ([#922](https://github.com/rollup/rollup/pull/922)) + ## 0.35.6 * Fix browser build diff --git a/package.json b/package.json index b852ddf..c688e6b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.6", + "version": "0.35.7", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 610ff331e4dc4ee569df164405d615531124d018 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 11 Sep 2016 11:18:57 +0300 Subject: [PATCH 244/331] Trim debug numbers --- src/utils/flushTime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/flushTime.js b/src/utils/flushTime.js index 683e28c..9f32e45 100644 --- a/src/utils/flushTime.js +++ b/src/utils/flushTime.js @@ -19,7 +19,7 @@ if ( typeof process === 'undefined' ) { timeEndHelper = function timeEndHelper ( previous ) { const hrtime = process.hrtime( previous ); - return hrtime[0] * 1e3 + hrtime[1] / 1e6; + return hrtime[0] * 1e3 + Math.floor( hrtime[1] / 1e6 ); }; } From a7161689e467452621b9b2fa453d87646a94da06 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sun, 11 Sep 2016 11:05:27 -0700 Subject: [PATCH 245/331] Correctly deshadow re-assigned module functions Fixes #910. --- src/ast/scopes/ModuleScope.js | 13 +++++++------ .../namespacing-in-sub-functions/_config.js | 8 ++++++++ test/function/namespacing-in-sub-functions/main.js | 11 +++++++++++ .../namespacing-in-sub-functions/problematicFunc.js | 5 +++++ 4 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 test/function/namespacing-in-sub-functions/_config.js create mode 100644 test/function/namespacing-in-sub-functions/main.js create mode 100644 test/function/namespacing-in-sub-functions/problematicFunc.js diff --git a/src/ast/scopes/ModuleScope.js b/src/ast/scopes/ModuleScope.js index f451d20..cdc2c93 100644 --- a/src/ast/scopes/ModuleScope.js +++ b/src/ast/scopes/ModuleScope.js @@ -19,14 +19,15 @@ export default class ModuleScope extends Scope { forOwn( this.module.imports, specifier => { if ( specifier.module.isExternal ) return; - if ( specifier.name === '*' ) { - specifier.module.getExports().forEach( name => { - names.set( name, true ); - }); - } else { + specifier.module.getExports().forEach( name => { + names.set(name); + }); + if ( specifier.name !== '*' ) { const declaration = specifier.module.traceExport( specifier.name ); const name = declaration.getName( true ); - if ( name !== specifier.name ) names.set( declaration.getName( true ) ); + if ( name !== specifier.name ) { + names.set(declaration.getName( true )); + } } }); diff --git a/test/function/namespacing-in-sub-functions/_config.js b/test/function/namespacing-in-sub-functions/_config.js new file mode 100644 index 0000000..025b117 --- /dev/null +++ b/test/function/namespacing-in-sub-functions/_config.js @@ -0,0 +1,8 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'correctly namespaces sub-functions (#910)', + exports: function ( exports ) { + assert.equal( exports, 'foobar' ); + } +}; diff --git a/test/function/namespacing-in-sub-functions/main.js b/test/function/namespacing-in-sub-functions/main.js new file mode 100644 index 0000000..ac9d9da --- /dev/null +++ b/test/function/namespacing-in-sub-functions/main.js @@ -0,0 +1,11 @@ +import { problematicFunc as otherFunc } from './problematicFunc'; +function innerFunc() { + function problematicFunc () { + return otherFunc(); + } + return problematicFunc(); +} + +var res = innerFunc(); + +export default res; \ No newline at end of file diff --git a/test/function/namespacing-in-sub-functions/problematicFunc.js b/test/function/namespacing-in-sub-functions/problematicFunc.js new file mode 100644 index 0000000..1fbecc0 --- /dev/null +++ b/test/function/namespacing-in-sub-functions/problematicFunc.js @@ -0,0 +1,5 @@ +function problematicFunc() { + return 'foobar'; +} + +export { problematicFunc }; \ No newline at end of file From e7925e29d1f55f9bf09fe9c548f1bebc7ccfd52a Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 11 Sep 2016 14:35:04 -0400 Subject: [PATCH 246/331] -> v0.35.8 --- CHANGELOG.md | 4 ++++ package.json | 2 +- src/ast/scopes/ModuleScope.js | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2680013..a6f3f90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.8 + +* Correctly deshadow re-assigned module functions ([#910](https://github.com/rollup/rollup/issues/910)) + ## 0.35.7 * Refactor `flushTime.js` ([#922](https://github.com/rollup/rollup/pull/922)) diff --git a/package.json b/package.json index c688e6b..d49fd0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.7", + "version": "0.35.8", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", diff --git a/src/ast/scopes/ModuleScope.js b/src/ast/scopes/ModuleScope.js index cdc2c93..051fcb4 100644 --- a/src/ast/scopes/ModuleScope.js +++ b/src/ast/scopes/ModuleScope.js @@ -26,7 +26,7 @@ export default class ModuleScope extends Scope { const declaration = specifier.module.traceExport( specifier.name ); const name = declaration.getName( true ); if ( name !== specifier.name ) { - names.set(declaration.getName( true )); + names.set( declaration.getName( true ) ); } } }); From 0727c3284f1419b3d65786f03b326bd1dffbfa7e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 11 Sep 2016 14:43:30 -0400 Subject: [PATCH 247/331] support 0.12 --- rollup.config.js | 2 +- test/function/deconflicts-classes/_config.js | 3 ++- test/function/identifiers-in-template-literals/_config.js | 3 ++- .../function/rename-conditional-expression-children/_config.js | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index a8ac2c8..cc0b9ba 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -24,7 +24,7 @@ export default { buble({ include: [ 'src/**', 'node_modules/acorn/**' ], target: { - node: 4 + node: '0.12' } }), diff --git a/test/function/deconflicts-classes/_config.js b/test/function/deconflicts-classes/_config.js index ee66bd1..633aacc 100644 --- a/test/function/deconflicts-classes/_config.js +++ b/test/function/deconflicts-classes/_config.js @@ -1,3 +1,4 @@ module.exports = { - description: 'deconflicts top-level classes' + description: 'deconflicts top-level classes', + buble: true }; diff --git a/test/function/identifiers-in-template-literals/_config.js b/test/function/identifiers-in-template-literals/_config.js index 8b031cd..51b503d 100644 --- a/test/function/identifiers-in-template-literals/_config.js +++ b/test/function/identifiers-in-template-literals/_config.js @@ -1,3 +1,4 @@ module.exports = { - description: 'identifiers in template literals are rendered correctly' + description: 'identifiers in template literals are rendered correctly', + buble: true }; diff --git a/test/function/rename-conditional-expression-children/_config.js b/test/function/rename-conditional-expression-children/_config.js index 7c052c5..d159c95 100644 --- a/test/function/rename-conditional-expression-children/_config.js +++ b/test/function/rename-conditional-expression-children/_config.js @@ -1,3 +1,4 @@ module.exports = { - description: 'correctly renders children of ConditionalExpressions' + description: 'correctly renders children of ConditionalExpressions', + buble: true }; From b76f7b03ce98d0f9349d215b0adf27957f60185e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 11 Sep 2016 14:44:00 -0400 Subject: [PATCH 248/331] put 0.12 back in the build matrix --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 956a81b..83d1bca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ sudo: false language: node_js node_js: + - "0.12" - "4" - "6" env: diff --git a/appveyor.yml b/appveyor.yml index 8ab6c7d..a4389cb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,6 +10,7 @@ init: environment: matrix: # node.js + - nodejs_version: 0.12 - nodejs_version: 4 - nodejs_version: 6 From a1478d744577c4cf1d94ab7da4e120f147f3141c Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 11 Sep 2016 18:57:27 -0400 Subject: [PATCH 249/331] -> v0.35.9 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6f3f90..f097310 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.9 + +* Support Node 0.12 ([#909](https://github.com/rollup/rollup/issues/909)) + ## 0.35.8 * Correctly deshadow re-assigned module functions ([#910](https://github.com/rollup/rollup/issues/910)) diff --git a/package.json b/package.json index d49fd0a..6060ec6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.8", + "version": "0.35.9", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From d980cf37de5f58db13e50294b1e83b15dbf7ba56 Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Mon, 12 Sep 2016 21:46:54 -0700 Subject: [PATCH 250/331] Only remove EmptyStatement nodes directly inside blocks. When used as part of another statement, such as an `IfStatement`, they can be semantically meaningful. Fixes #931 --- src/ast/nodes/EmptyStatement.js | 4 +++- test/form/empty-statement-consequent/_config.js | 3 +++ test/form/empty-statement-consequent/_expected/amd.js | 6 ++++++ test/form/empty-statement-consequent/_expected/cjs.js | 4 ++++ test/form/empty-statement-consequent/_expected/es.js | 2 ++ test/form/empty-statement-consequent/_expected/iife.js | 7 +++++++ test/form/empty-statement-consequent/_expected/umd.js | 10 ++++++++++ test/form/empty-statement-consequent/main.js | 2 ++ 8 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/form/empty-statement-consequent/_config.js create mode 100644 test/form/empty-statement-consequent/_expected/amd.js create mode 100644 test/form/empty-statement-consequent/_expected/cjs.js create mode 100644 test/form/empty-statement-consequent/_expected/es.js create mode 100644 test/form/empty-statement-consequent/_expected/iife.js create mode 100644 test/form/empty-statement-consequent/_expected/umd.js create mode 100644 test/form/empty-statement-consequent/main.js diff --git a/src/ast/nodes/EmptyStatement.js b/src/ast/nodes/EmptyStatement.js index 27830c4..5f7309c 100644 --- a/src/ast/nodes/EmptyStatement.js +++ b/src/ast/nodes/EmptyStatement.js @@ -2,6 +2,8 @@ import Statement from './shared/Statement.js'; export default class EmptyStatement extends Statement { render ( code ) { - code.remove( this.start, this.end ); + if ( this.parent.type === 'BlockStatement' || this.parent.type === 'Program' ) { + code.remove( this.start, this.end ); + } } } diff --git a/test/form/empty-statement-consequent/_config.js b/test/form/empty-statement-consequent/_config.js new file mode 100644 index 0000000..dc10538 --- /dev/null +++ b/test/form/empty-statement-consequent/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'preserves empty statements used as the consequent of conditionals' +}; diff --git a/test/form/empty-statement-consequent/_expected/amd.js b/test/form/empty-statement-consequent/_expected/amd.js new file mode 100644 index 0000000..9114028 --- /dev/null +++ b/test/form/empty-statement-consequent/_expected/amd.js @@ -0,0 +1,6 @@ +define(function () { 'use strict'; + + if ( a === 0 ); + else a++; + +}); \ No newline at end of file diff --git a/test/form/empty-statement-consequent/_expected/cjs.js b/test/form/empty-statement-consequent/_expected/cjs.js new file mode 100644 index 0000000..9b5e04a --- /dev/null +++ b/test/form/empty-statement-consequent/_expected/cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +if ( a === 0 ); +else a++; \ No newline at end of file diff --git a/test/form/empty-statement-consequent/_expected/es.js b/test/form/empty-statement-consequent/_expected/es.js new file mode 100644 index 0000000..04006b3 --- /dev/null +++ b/test/form/empty-statement-consequent/_expected/es.js @@ -0,0 +1,2 @@ +if ( a === 0 ); +else a++; \ No newline at end of file diff --git a/test/form/empty-statement-consequent/_expected/iife.js b/test/form/empty-statement-consequent/_expected/iife.js new file mode 100644 index 0000000..45b92d8 --- /dev/null +++ b/test/form/empty-statement-consequent/_expected/iife.js @@ -0,0 +1,7 @@ +(function () { + 'use strict'; + + if ( a === 0 ); + else a++; + +}()); \ No newline at end of file diff --git a/test/form/empty-statement-consequent/_expected/umd.js b/test/form/empty-statement-consequent/_expected/umd.js new file mode 100644 index 0000000..08026c7 --- /dev/null +++ b/test/form/empty-statement-consequent/_expected/umd.js @@ -0,0 +1,10 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + if ( a === 0 ); + else a++; + +}))); \ No newline at end of file diff --git a/test/form/empty-statement-consequent/main.js b/test/form/empty-statement-consequent/main.js new file mode 100644 index 0000000..b6b36cf --- /dev/null +++ b/test/form/empty-statement-consequent/main.js @@ -0,0 +1,2 @@ +if ( a === 0 ); +else a++; From 8545d85a9ee99b2a0651ce5997e647f998ec90cf Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Mon, 12 Sep 2016 22:50:31 -0700 Subject: [PATCH 251/331] Correctly deshadow star imports when conflicting --- src/Bundle.js | 9 +++++++++ test/form/namespace-optimization-b/_expected/amd.js | 6 +++--- test/form/namespace-optimization-b/_expected/cjs.js | 6 +++--- test/form/namespace-optimization-b/_expected/es.js | 6 +++--- test/form/namespace-optimization-b/_expected/iife.js | 6 +++--- test/form/namespace-optimization-b/_expected/umd.js | 6 +++--- test/function/namespacing-collisions-2/Material.js | 3 +++ test/function/namespacing-collisions-2/MaterialAgain.js | 3 +++ test/function/namespacing-collisions-2/Something.js | 6 ++++++ test/function/namespacing-collisions-2/SomethingAgain.js | 6 ++++++ test/function/namespacing-collisions-2/_config.js | 8 ++++++++ test/function/namespacing-collisions-2/main.js | 7 +++++++ test/function/namespacing-collisions/Material.js | 3 +++ test/function/namespacing-collisions/Something.js | 6 ++++++ test/function/namespacing-collisions/_config.js | 8 ++++++++ test/function/namespacing-collisions/main.js | 5 +++++ 16 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 test/function/namespacing-collisions-2/Material.js create mode 100644 test/function/namespacing-collisions-2/MaterialAgain.js create mode 100644 test/function/namespacing-collisions-2/Something.js create mode 100644 test/function/namespacing-collisions-2/SomethingAgain.js create mode 100644 test/function/namespacing-collisions-2/_config.js create mode 100644 test/function/namespacing-collisions-2/main.js create mode 100644 test/function/namespacing-collisions/Material.js create mode 100644 test/function/namespacing-collisions/Something.js create mode 100644 test/function/namespacing-collisions/_config.js create mode 100644 test/function/namespacing-collisions/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 40a9211..d3ec8b5 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -208,6 +208,15 @@ export default class Bundle { declaration.name = getSafeName( declaration.name ); }); + // special case - for `import * as Foo`, we need to make sure that Foo + // gets its own variable because it will eventually be rendered as + // `var Foo = Object.freeze(...)` + forOwn( module.imports, ( importee, importeeName ) => { + if ( importee.name === '*' ) { + delete module.imports[ importeeName ]; + module.imports[ getSafeName(importeeName) ] = importee; + } + }); }); this.scope.deshadow( toDeshadow ); diff --git a/test/form/namespace-optimization-b/_expected/amd.js b/test/form/namespace-optimization-b/_expected/amd.js index 30c5406..45db05f 100644 --- a/test/form/namespace-optimization-b/_expected/amd.js +++ b/test/form/namespace-optimization-b/_expected/amd.js @@ -1,12 +1,12 @@ define(function () { 'use strict'; - function foo () { + function foo$1 () { console.log( 'foo' ); } function a () { - foo(); - foo(); + foo$1(); + foo$1(); var a; if ( a.b ) { diff --git a/test/form/namespace-optimization-b/_expected/cjs.js b/test/form/namespace-optimization-b/_expected/cjs.js index 3ee6869..5891df9 100644 --- a/test/form/namespace-optimization-b/_expected/cjs.js +++ b/test/form/namespace-optimization-b/_expected/cjs.js @@ -1,12 +1,12 @@ 'use strict'; -function foo () { +function foo$1 () { console.log( 'foo' ); } function a () { - foo(); - foo(); + foo$1(); + foo$1(); var a; if ( a.b ) { diff --git a/test/form/namespace-optimization-b/_expected/es.js b/test/form/namespace-optimization-b/_expected/es.js index 8346d0d..c63d076 100644 --- a/test/form/namespace-optimization-b/_expected/es.js +++ b/test/form/namespace-optimization-b/_expected/es.js @@ -1,10 +1,10 @@ -function foo () { +function foo$1 () { console.log( 'foo' ); } function a () { - foo(); - foo(); + foo$1(); + foo$1(); var a; if ( a.b ) { diff --git a/test/form/namespace-optimization-b/_expected/iife.js b/test/form/namespace-optimization-b/_expected/iife.js index 6aeb1cd..bfc4c08 100644 --- a/test/form/namespace-optimization-b/_expected/iife.js +++ b/test/form/namespace-optimization-b/_expected/iife.js @@ -1,13 +1,13 @@ (function () { 'use strict'; - function foo () { + function foo$1 () { console.log( 'foo' ); } function a () { - foo(); - foo(); + foo$1(); + foo$1(); var a; if ( a.b ) { diff --git a/test/form/namespace-optimization-b/_expected/umd.js b/test/form/namespace-optimization-b/_expected/umd.js index f7fbbdf..a95eafd 100644 --- a/test/form/namespace-optimization-b/_expected/umd.js +++ b/test/form/namespace-optimization-b/_expected/umd.js @@ -4,13 +4,13 @@ (factory()); }(this, (function () { 'use strict'; - function foo () { + function foo$1 () { console.log( 'foo' ); } function a () { - foo(); - foo(); + foo$1(); + foo$1(); var a; if ( a.b ) { diff --git a/test/function/namespacing-collisions-2/Material.js b/test/function/namespacing-collisions-2/Material.js new file mode 100644 index 0000000..b6d1881 --- /dev/null +++ b/test/function/namespacing-collisions-2/Material.js @@ -0,0 +1,3 @@ +export function Material() { + return 'Material'; +} diff --git a/test/function/namespacing-collisions-2/MaterialAgain.js b/test/function/namespacing-collisions-2/MaterialAgain.js new file mode 100644 index 0000000..170cfff --- /dev/null +++ b/test/function/namespacing-collisions-2/MaterialAgain.js @@ -0,0 +1,3 @@ +export function MaterialAgain() { + return 'MaterialAgain'; +} diff --git a/test/function/namespacing-collisions-2/Something.js b/test/function/namespacing-collisions-2/Something.js new file mode 100644 index 0000000..64cbdca --- /dev/null +++ b/test/function/namespacing-collisions-2/Something.js @@ -0,0 +1,6 @@ +import * as Material from './Material'; + +export function Something() { + console.log(Material); + return 'Something'; +} \ No newline at end of file diff --git a/test/function/namespacing-collisions-2/SomethingAgain.js b/test/function/namespacing-collisions-2/SomethingAgain.js new file mode 100644 index 0000000..1efaca7 --- /dev/null +++ b/test/function/namespacing-collisions-2/SomethingAgain.js @@ -0,0 +1,6 @@ +import * as Material from './MaterialAgain'; + +export function SomethingAgain() { + console.log(Material); + return 'SomethingAgain'; +} \ No newline at end of file diff --git a/test/function/namespacing-collisions-2/_config.js b/test/function/namespacing-collisions-2/_config.js new file mode 100644 index 0000000..4684296 --- /dev/null +++ b/test/function/namespacing-collisions-2/_config.js @@ -0,0 +1,8 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'correctly namespaces when using * exports, take two (#910)', + exports: function ( exports ) { + assert.deepEqual( exports, ['Material', 'MaterialAgain', 'Something', 'SomethingAgain'] ); + } +}; diff --git a/test/function/namespacing-collisions-2/main.js b/test/function/namespacing-collisions-2/main.js new file mode 100644 index 0000000..c69a6e4 --- /dev/null +++ b/test/function/namespacing-collisions-2/main.js @@ -0,0 +1,7 @@ +import { Something } from './Something'; +import { SomethingAgain } from './SomethingAgain'; +import { Material } from './Material'; +import { MaterialAgain } from './MaterialAgain'; + +var result = [Material(), MaterialAgain(), Something(), SomethingAgain()] +export default result; diff --git a/test/function/namespacing-collisions/Material.js b/test/function/namespacing-collisions/Material.js new file mode 100644 index 0000000..b6d1881 --- /dev/null +++ b/test/function/namespacing-collisions/Material.js @@ -0,0 +1,3 @@ +export function Material() { + return 'Material'; +} diff --git a/test/function/namespacing-collisions/Something.js b/test/function/namespacing-collisions/Something.js new file mode 100644 index 0000000..64cbdca --- /dev/null +++ b/test/function/namespacing-collisions/Something.js @@ -0,0 +1,6 @@ +import * as Material from './Material'; + +export function Something() { + console.log(Material); + return 'Something'; +} \ No newline at end of file diff --git a/test/function/namespacing-collisions/_config.js b/test/function/namespacing-collisions/_config.js new file mode 100644 index 0000000..02c772f --- /dev/null +++ b/test/function/namespacing-collisions/_config.js @@ -0,0 +1,8 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'correctly namespaces when using * exports (#910)', + exports: function ( exports ) { + assert.deepEqual( exports, [ 'Material', 'Something' ] ); + } +}; diff --git a/test/function/namespacing-collisions/main.js b/test/function/namespacing-collisions/main.js new file mode 100644 index 0000000..8746123 --- /dev/null +++ b/test/function/namespacing-collisions/main.js @@ -0,0 +1,5 @@ +import { Something } from './Something'; +import { Material } from './Material'; + +var result = [Material(), Something()] +export default result; \ No newline at end of file From 5b68b14052806364878975dc976eda1b7ea35cab Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Tue, 13 Sep 2016 09:57:34 -0700 Subject: [PATCH 252/331] -> v0.35.10 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f097310..32f446e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.10 + +* Only remove EmptyStatement nodes directly inside blocks ([#913](https://github.com/rollup/rollup/issues/931)) + ## 0.35.9 * Support Node 0.12 ([#909](https://github.com/rollup/rollup/issues/909)) diff --git a/package.json b/package.json index 6060ec6..17351f7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.9", + "version": "0.35.10", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From bed6f0650da4f54ab8b8f7b4e3d64d99a12c922c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 15 Sep 2016 12:06:03 -0400 Subject: [PATCH 253/331] only deconflict reified namespaces --- src/Bundle.js | 15 ++++++--------- .../namespace-optimization-b/_expected/amd.js | 8 ++++---- .../namespace-optimization-b/_expected/cjs.js | 8 ++++---- .../form/namespace-optimization-b/_expected/es.js | 8 ++++---- .../namespace-optimization-b/_expected/iife.js | 8 ++++---- .../namespace-optimization-b/_expected/umd.js | 8 ++++---- 6 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index d3ec8b5..2716102 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -208,15 +208,12 @@ export default class Bundle { declaration.name = getSafeName( declaration.name ); }); - // special case - for `import * as Foo`, we need to make sure that Foo - // gets its own variable because it will eventually be rendered as - // `var Foo = Object.freeze(...)` - forOwn( module.imports, ( importee, importeeName ) => { - if ( importee.name === '*' ) { - delete module.imports[ importeeName ]; - module.imports[ getSafeName(importeeName) ] = importee; - } - }); + + // deconflict reified namespaces + const namespace = module.namespace(); + if ( namespace.needsNamespaceBlock ) { + namespace.name = getSafeName( namespace.name ); + } }); this.scope.deshadow( toDeshadow ); diff --git a/test/form/namespace-optimization-b/_expected/amd.js b/test/form/namespace-optimization-b/_expected/amd.js index 45db05f..e2582cc 100644 --- a/test/form/namespace-optimization-b/_expected/amd.js +++ b/test/form/namespace-optimization-b/_expected/amd.js @@ -1,12 +1,12 @@ define(function () { 'use strict'; - function foo$1 () { + function foo () { console.log( 'foo' ); } function a () { - foo$1(); - foo$1(); + foo(); + foo(); var a; if ( a.b ) { @@ -16,4 +16,4 @@ define(function () { 'use strict'; a(); -}); \ No newline at end of file +}); diff --git a/test/form/namespace-optimization-b/_expected/cjs.js b/test/form/namespace-optimization-b/_expected/cjs.js index 5891df9..a826df2 100644 --- a/test/form/namespace-optimization-b/_expected/cjs.js +++ b/test/form/namespace-optimization-b/_expected/cjs.js @@ -1,12 +1,12 @@ 'use strict'; -function foo$1 () { +function foo () { console.log( 'foo' ); } function a () { - foo$1(); - foo$1(); + foo(); + foo(); var a; if ( a.b ) { @@ -14,4 +14,4 @@ function a () { } } -a(); \ No newline at end of file +a(); diff --git a/test/form/namespace-optimization-b/_expected/es.js b/test/form/namespace-optimization-b/_expected/es.js index c63d076..85c15d8 100644 --- a/test/form/namespace-optimization-b/_expected/es.js +++ b/test/form/namespace-optimization-b/_expected/es.js @@ -1,10 +1,10 @@ -function foo$1 () { +function foo () { console.log( 'foo' ); } function a () { - foo$1(); - foo$1(); + foo(); + foo(); var a; if ( a.b ) { @@ -12,4 +12,4 @@ function a () { } } -a(); \ No newline at end of file +a(); diff --git a/test/form/namespace-optimization-b/_expected/iife.js b/test/form/namespace-optimization-b/_expected/iife.js index bfc4c08..6c497f5 100644 --- a/test/form/namespace-optimization-b/_expected/iife.js +++ b/test/form/namespace-optimization-b/_expected/iife.js @@ -1,13 +1,13 @@ (function () { 'use strict'; - function foo$1 () { + function foo () { console.log( 'foo' ); } function a () { - foo$1(); - foo$1(); + foo(); + foo(); var a; if ( a.b ) { @@ -17,4 +17,4 @@ a(); -}()); \ No newline at end of file +}()); diff --git a/test/form/namespace-optimization-b/_expected/umd.js b/test/form/namespace-optimization-b/_expected/umd.js index a95eafd..7a2c4b0 100644 --- a/test/form/namespace-optimization-b/_expected/umd.js +++ b/test/form/namespace-optimization-b/_expected/umd.js @@ -4,13 +4,13 @@ (factory()); }(this, (function () { 'use strict'; - function foo$1 () { + function foo () { console.log( 'foo' ); } function a () { - foo$1(); - foo$1(); + foo(); + foo(); var a; if ( a.b ) { @@ -20,4 +20,4 @@ a(); -}))); \ No newline at end of file +}))); From 5d5eb24b15562bb1a41a3e8c98e15ba02353896c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 15 Sep 2016 12:08:56 -0400 Subject: [PATCH 254/331] -> v0.35.11 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32f446e..05c057e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.11 + +* Deconflict reified namespaces with other declarations ([#910](https://github.com/rollup/rollup/issues/910)) + ## 0.35.10 * Only remove EmptyStatement nodes directly inside blocks ([#913](https://github.com/rollup/rollup/issues/931)) diff --git a/package.json b/package.json index 17351f7..af215c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.10", + "version": "0.35.11", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 211fa097a929a049584a520196d182a3128316a6 Mon Sep 17 00:00:00 2001 From: Emil Ajdyna Date: Fri, 16 Sep 2016 11:41:02 +0200 Subject: [PATCH 255/331] add: interop option --- LICENSE.md | 2 +- src/finalisers/amd.js | 2 +- src/finalisers/iife.js | 2 +- src/finalisers/shared/getInteropBlock.js | 4 ++-- src/finalisers/umd.js | 2 +- src/rollup.js | 1 + test/form/interop-false/_config.js | 7 +++++++ test/form/interop-false/_expected/amd.js | 8 ++++++++ test/form/interop-false/_expected/cjs.js | 10 ++++++++++ test/form/interop-false/_expected/es.js | 6 ++++++ test/form/interop-false/_expected/iife.js | 9 +++++++++ test/form/interop-false/_expected/umd.js | 12 ++++++++++++ test/form/interop-false/main.js | 3 +++ test/test.js | 2 +- 14 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 test/form/interop-false/_config.js create mode 100644 test/form/interop-false/_expected/amd.js create mode 100644 test/form/interop-false/_expected/cjs.js create mode 100644 test/form/interop-false/_expected/es.js create mode 100644 test/form/interop-false/_expected/iife.js create mode 100644 test/form/interop-false/_expected/umd.js create mode 100644 test/form/interop-false/main.js diff --git a/LICENSE.md b/LICENSE.md index ae037ce..ec3180a 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 [these people](https://github.com/rollup/rollup/graphs/contributors) +Copyright (c) 2016 [these people](https://github.com/rollup/rollup/graphs/contributors) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/finalisers/amd.js b/src/finalisers/amd.js index 456dd86..96626e2 100644 --- a/src/finalisers/amd.js +++ b/src/finalisers/amd.js @@ -20,7 +20,7 @@ export default function amd ( bundle, magicString, { exportMode, indentString, i const wrapperStart = `define(${params}function (${args.join( ', ' )}) {${useStrict}\n\n`; // var foo__default = 'default' in foo ? foo['default'] : foo; - const interopBlock = getInteropBlock( bundle ); + const interopBlock = getInteropBlock( bundle, options ); if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' ); if ( intro ) magicString.prepend( intro ); diff --git a/src/finalisers/iife.js b/src/finalisers/iife.js index 612f70f..8120594 100644 --- a/src/finalisers/iife.js +++ b/src/finalisers/iife.js @@ -49,7 +49,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString, } // var foo__default = 'default' in foo ? foo['default'] : foo; - const interopBlock = getInteropBlock( bundle ); + const interopBlock = getInteropBlock( bundle, options ); if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' ); if ( intro ) magicString.prepend( intro ); diff --git a/src/finalisers/shared/getInteropBlock.js b/src/finalisers/shared/getInteropBlock.js index 67a26d7..6ecdba0 100644 --- a/src/finalisers/shared/getInteropBlock.js +++ b/src/finalisers/shared/getInteropBlock.js @@ -1,7 +1,7 @@ -export default function getInteropBlock ( bundle ) { +export default function getInteropBlock ( bundle, options ) { return bundle.externalModules .map( module => { - if ( !module.declarations.default ) return null; + if ( !module.declarations.default || options.interop === false ) return null; if ( module.exportsNamespace ) { return `${bundle.varOrConst} ${module.name}__default = ${module.name}['default'];`; diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index a36db02..f2be2a2 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -66,7 +66,7 @@ export default function umd ( bundle, magicString, { exportMode, indentString, i `.replace( /^\t\t/gm, '' ).replace( /^\t/gm, magicString.getIndentString() ); // var foo__default = 'default' in foo ? foo['default'] : foo; - const interopBlock = getInteropBlock( bundle ); + const interopBlock = getInteropBlock( bundle, options ); if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' ); if ( intro ) magicString.prepend( intro ); diff --git a/src/rollup.js b/src/rollup.js index 2ab5b51..be39d0b 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -22,6 +22,7 @@ const ALLOWED_KEYS = [ 'format', 'globals', 'indent', + 'interop', 'intro', 'moduleId', 'moduleName', diff --git a/test/form/interop-false/_config.js b/test/form/interop-false/_config.js new file mode 100644 index 0000000..0076e3a --- /dev/null +++ b/test/form/interop-false/_config.js @@ -0,0 +1,7 @@ +module.exports = { + description: 'getInterop with interop: false', + options: { + moduleName: 'foo', + interop: false + } +}; diff --git a/test/form/interop-false/_expected/amd.js b/test/form/interop-false/_expected/amd.js new file mode 100644 index 0000000..3ee81e0 --- /dev/null +++ b/test/form/interop-false/_expected/amd.js @@ -0,0 +1,8 @@ +define(['core/view'], function (View) { 'use strict'; + + /*eslint import/no-unresolved: 0*/ + var main = View.extend({}); + + return main; + +}); \ No newline at end of file diff --git a/test/form/interop-false/_expected/cjs.js b/test/form/interop-false/_expected/cjs.js new file mode 100644 index 0000000..4813a5d --- /dev/null +++ b/test/form/interop-false/_expected/cjs.js @@ -0,0 +1,10 @@ +'use strict'; + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var View = _interopDefault(require('core/view')); + +/*eslint import/no-unresolved: 0*/ +var main = View.extend({}); + +module.exports = main; \ No newline at end of file diff --git a/test/form/interop-false/_expected/es.js b/test/form/interop-false/_expected/es.js new file mode 100644 index 0000000..d404c44 --- /dev/null +++ b/test/form/interop-false/_expected/es.js @@ -0,0 +1,6 @@ +import View from 'core/view'; + +/*eslint import/no-unresolved: 0*/ +var main = View.extend({}); + +export default main; \ No newline at end of file diff --git a/test/form/interop-false/_expected/iife.js b/test/form/interop-false/_expected/iife.js new file mode 100644 index 0000000..fe0202b --- /dev/null +++ b/test/form/interop-false/_expected/iife.js @@ -0,0 +1,9 @@ +var foo = (function (View) { + 'use strict'; + + /*eslint import/no-unresolved: 0*/ + var main = View.extend({}); + + return main; + +}(View)); \ No newline at end of file diff --git a/test/form/interop-false/_expected/umd.js b/test/form/interop-false/_expected/umd.js new file mode 100644 index 0000000..2f376e3 --- /dev/null +++ b/test/form/interop-false/_expected/umd.js @@ -0,0 +1,12 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('core/view')) : + typeof define === 'function' && define.amd ? define(['core/view'], factory) : + (global.foo = factory(global.View)); +}(this, (function (View) { 'use strict'; + + /*eslint import/no-unresolved: 0*/ + var main = View.extend({}); + + return main; + +}))); \ No newline at end of file diff --git a/test/form/interop-false/main.js b/test/form/interop-false/main.js new file mode 100644 index 0000000..8d67d61 --- /dev/null +++ b/test/form/interop-false/main.js @@ -0,0 +1,3 @@ +/*eslint import/no-unresolved: 0*/ +import View from 'core/view'; +export default View.extend({}); \ No newline at end of file diff --git a/test/test.js b/test/test.js index ca11679..5876435 100644 --- a/test/test.js +++ b/test/test.js @@ -90,7 +90,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( () => { throw new Error( 'Missing expected error' ); }, err => { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, context, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, context, dest, entry, exports, external, footer, format, globals, indent, interop, intro, moduleId, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); }); }); From 303333b31019ad92d7bda54ad2a558e126ed9d6e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 17 Sep 2016 22:59:14 -0400 Subject: [PATCH 256/331] enable interop option in CJS bundles --- src/finalisers/cjs.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index 0ffbce8..5af4df7 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -8,11 +8,12 @@ export default function cjs ( bundle, magicString, { exportMode, intro }, option let needsInterop = false; const varOrConst = bundle.varOrConst; + const interop = options.interop !== false; // TODO handle empty imports, once they're supported const importBlock = bundle.externalModules .map( module => { - if ( module.declarations.default ) { + if ( interop && module.declarations.default ) { if ( module.exportsNamespace ) { return `${varOrConst} ${module.name} = require('${module.path}');` + `\n${varOrConst} ${module.name}__default = ${module.name}['default'];`; From a2487a455545fd08e80462899cdd511d03f8114a Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 17 Sep 2016 22:59:22 -0400 Subject: [PATCH 257/331] remove eslint comment --- test/form/interop-false/_expected/amd.js | 3 +-- test/form/interop-false/_expected/cjs.js | 7 ++----- test/form/interop-false/_expected/es.js | 3 +-- test/form/interop-false/_expected/iife.js | 3 +-- test/form/interop-false/_expected/umd.js | 3 +-- test/form/interop-false/main.js | 3 +-- 6 files changed, 7 insertions(+), 15 deletions(-) diff --git a/test/form/interop-false/_expected/amd.js b/test/form/interop-false/_expected/amd.js index 3ee81e0..9245883 100644 --- a/test/form/interop-false/_expected/amd.js +++ b/test/form/interop-false/_expected/amd.js @@ -1,8 +1,7 @@ define(['core/view'], function (View) { 'use strict'; - /*eslint import/no-unresolved: 0*/ var main = View.extend({}); return main; -}); \ No newline at end of file +}); diff --git a/test/form/interop-false/_expected/cjs.js b/test/form/interop-false/_expected/cjs.js index 4813a5d..8396bc7 100644 --- a/test/form/interop-false/_expected/cjs.js +++ b/test/form/interop-false/_expected/cjs.js @@ -1,10 +1,7 @@ 'use strict'; -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } +var View = require('core/view'); -var View = _interopDefault(require('core/view')); - -/*eslint import/no-unresolved: 0*/ var main = View.extend({}); -module.exports = main; \ No newline at end of file +module.exports = main; diff --git a/test/form/interop-false/_expected/es.js b/test/form/interop-false/_expected/es.js index d404c44..d5e775e 100644 --- a/test/form/interop-false/_expected/es.js +++ b/test/form/interop-false/_expected/es.js @@ -1,6 +1,5 @@ import View from 'core/view'; -/*eslint import/no-unresolved: 0*/ var main = View.extend({}); -export default main; \ No newline at end of file +export default main; diff --git a/test/form/interop-false/_expected/iife.js b/test/form/interop-false/_expected/iife.js index fe0202b..d94c432 100644 --- a/test/form/interop-false/_expected/iife.js +++ b/test/form/interop-false/_expected/iife.js @@ -1,9 +1,8 @@ var foo = (function (View) { 'use strict'; - /*eslint import/no-unresolved: 0*/ var main = View.extend({}); return main; -}(View)); \ No newline at end of file +}(View)); diff --git a/test/form/interop-false/_expected/umd.js b/test/form/interop-false/_expected/umd.js index 2f376e3..5c9be13 100644 --- a/test/form/interop-false/_expected/umd.js +++ b/test/form/interop-false/_expected/umd.js @@ -4,9 +4,8 @@ (global.foo = factory(global.View)); }(this, (function (View) { 'use strict'; - /*eslint import/no-unresolved: 0*/ var main = View.extend({}); return main; -}))); \ No newline at end of file +}))); diff --git a/test/form/interop-false/main.js b/test/form/interop-false/main.js index 8d67d61..a6b1040 100644 --- a/test/form/interop-false/main.js +++ b/test/form/interop-false/main.js @@ -1,3 +1,2 @@ -/*eslint import/no-unresolved: 0*/ import View from 'core/view'; -export default View.extend({}); \ No newline at end of file +export default View.extend({}); From 05e12b7b3e27217cad810acf05e08de0e9d37dc6 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 17 Sep 2016 23:12:08 -0400 Subject: [PATCH 258/331] -> v0.35.12 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05c057e..0548e8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.12 + +* Add `interop: false` option to disable unwrapping of external imports ([#939](https://github.com/rollup/rollup/issues/939)) + ## 0.35.11 * Deconflict reified namespaces with other declarations ([#910](https://github.com/rollup/rollup/issues/910)) diff --git a/package.json b/package.json index af215c5..c78a456 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.11", + "version": "0.35.12", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From b26917bff6c808d020a87ebc9f3230af0c5f96ce Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 09:53:00 -0400 Subject: [PATCH 259/331] include superclass when including a class declaration (#932) --- src/ast/nodes/ClassDeclaration.js | 3 +++ test/function/includes-superclass/_config.js | 3 +++ test/function/includes-superclass/base.js | 5 +++++ test/function/includes-superclass/main.js | 6 ++++++ test/function/includes-superclass/thing.js | 7 +++++++ 5 files changed, 24 insertions(+) create mode 100644 test/function/includes-superclass/_config.js create mode 100644 test/function/includes-superclass/base.js create mode 100644 test/function/includes-superclass/main.js create mode 100644 test/function/includes-superclass/thing.js diff --git a/src/ast/nodes/ClassDeclaration.js b/src/ast/nodes/ClassDeclaration.js index f67c87d..f1a1daa 100644 --- a/src/ast/nodes/ClassDeclaration.js +++ b/src/ast/nodes/ClassDeclaration.js @@ -6,6 +6,7 @@ export default class ClassDeclaration extends Node { if ( this.activated ) return; this.activated = true; + if ( this.superClass ) this.superClass.run( this.scope ); this.body.run(); } @@ -26,6 +27,8 @@ export default class ClassDeclaration extends Node { } initialise ( scope ) { + this.scope = scope; + this.name = this.id.name; scope.addDeclaration( this.name, this, false, false ); diff --git a/test/function/includes-superclass/_config.js b/test/function/includes-superclass/_config.js new file mode 100644 index 0000000..7baf385 --- /dev/null +++ b/test/function/includes-superclass/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'includes superclass (#932)' +}; diff --git a/test/function/includes-superclass/base.js b/test/function/includes-superclass/base.js new file mode 100644 index 0000000..c374794 --- /dev/null +++ b/test/function/includes-superclass/base.js @@ -0,0 +1,5 @@ +export class Base { + foo () { + return true; + } +} diff --git a/test/function/includes-superclass/main.js b/test/function/includes-superclass/main.js new file mode 100644 index 0000000..bfb78e8 --- /dev/null +++ b/test/function/includes-superclass/main.js @@ -0,0 +1,6 @@ +import { Thing } from './thing'; + +const thing = new Thing(); + +assert.ok( thing.foo() ); +assert.ok( thing.bar() ); diff --git a/test/function/includes-superclass/thing.js b/test/function/includes-superclass/thing.js new file mode 100644 index 0000000..97b3be8 --- /dev/null +++ b/test/function/includes-superclass/thing.js @@ -0,0 +1,7 @@ +import { Base } from './base.js'; + +export class Thing extends Base { + bar () { + return true; + } +} From 036eae5ab116d5aa343953b2db64d3572d1af317 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 09:56:41 -0400 Subject: [PATCH 260/331] transpile test for 0.12 --- test/function/includes-superclass/_config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/function/includes-superclass/_config.js b/test/function/includes-superclass/_config.js index 7baf385..e226472 100644 --- a/test/function/includes-superclass/_config.js +++ b/test/function/includes-superclass/_config.js @@ -1,3 +1,4 @@ module.exports = { - description: 'includes superclass (#932)' + description: 'includes superclass (#932)', + buble: true }; From b5a34d60bac0e9a2d65df4d900b4d785b77db332 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 10:02:35 -0400 Subject: [PATCH 261/331] -> v0.35.13 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0548e8f..c13bc94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.13 + +* Include superclasses when including their subclasses ([#932](https://github.com/rollup/rollup/issues/932)) + ## 0.35.12 * Add `interop: false` option to disable unwrapping of external imports ([#939](https://github.com/rollup/rollup/issues/939)) diff --git a/package.json b/package.json index c78a456..0bb95d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.12", + "version": "0.35.13", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 819d619aa14d27e0d59e2bcd3ed93f2dccff8833 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 10:50:08 -0400 Subject: [PATCH 262/331] include all ancestors of expression with effects, up to function boundary - fixes #930 --- src/Bundle.js | 4 +++- src/ast/nodes/UpdateExpression.js | 4 +++- test/function/if-statement-with-assignment/_config.js | 3 +++ test/function/if-statement-with-assignment/main.js | 4 ++++ test/function/if-statement-with-update/_config.js | 3 +++ test/function/if-statement-with-update/main.js | 4 ++++ 6 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/function/if-statement-with-assignment/_config.js create mode 100644 test/function/if-statement-with-assignment/main.js create mode 100644 test/function/if-statement-with-update/_config.js create mode 100644 test/function/if-statement-with-update/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 2716102..d56f4a5 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -141,7 +141,9 @@ export default class Bundle { let i = this.dependentExpressions.length; while ( i-- ) { const expression = this.dependentExpressions[i]; - const statement = expression.findParent( /ExpressionStatement/ ); + + let statement = expression; + while ( statement.parent && !/Function/.test( statement.parent.type ) ) statement = statement.parent; if ( !statement || statement.ran ) { this.dependentExpressions.splice( i, 1 ); diff --git a/src/ast/nodes/UpdateExpression.js b/src/ast/nodes/UpdateExpression.js index c5b9263..656da69 100644 --- a/src/ast/nodes/UpdateExpression.js +++ b/src/ast/nodes/UpdateExpression.js @@ -28,11 +28,13 @@ export default class UpdateExpression extends Node { } initialise ( scope ) { + this.scope = scope; + this.module.bundle.dependentExpressions.push( this ); super.initialise( scope ); } isUsedByBundle () { - return isUsedByBundle( this.findScope(), this.subject ); + return isUsedByBundle( this.scope, this.subject ); } } diff --git a/test/function/if-statement-with-assignment/_config.js b/test/function/if-statement-with-assignment/_config.js new file mode 100644 index 0000000..6c573d5 --- /dev/null +++ b/test/function/if-statement-with-assignment/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'update assignments to names are preserved (#930)' +}; diff --git a/test/function/if-statement-with-assignment/main.js b/test/function/if-statement-with-assignment/main.js new file mode 100644 index 0000000..612436b --- /dev/null +++ b/test/function/if-statement-with-assignment/main.js @@ -0,0 +1,4 @@ +var result = 0; +if ( Math.random() <= 1 ) result += 1; + +assert.equal( result, 1 ); diff --git a/test/function/if-statement-with-update/_config.js b/test/function/if-statement-with-update/_config.js new file mode 100644 index 0000000..8601e12 --- /dev/null +++ b/test/function/if-statement-with-update/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'updates to names are preserved (#930)' +}; diff --git a/test/function/if-statement-with-update/main.js b/test/function/if-statement-with-update/main.js new file mode 100644 index 0000000..9239794 --- /dev/null +++ b/test/function/if-statement-with-update/main.js @@ -0,0 +1,4 @@ +var result = 0; +if ( Math.random() <= 1 ) ++result; + +assert.equal( result, 1 ); From f143b01c6206366a1a7a702d79b514ffcaedd696 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 11:28:34 -0400 Subject: [PATCH 263/331] beef up test --- test/function/if-statement-with-assignment/main.js | 4 +++- test/function/if-statement-with-update/main.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/test/function/if-statement-with-assignment/main.js b/test/function/if-statement-with-assignment/main.js index 612436b..e885c22 100644 --- a/test/function/if-statement-with-assignment/main.js +++ b/test/function/if-statement-with-assignment/main.js @@ -1,4 +1,6 @@ var result = 0; -if ( Math.random() <= 1 ) result += 1; +if ( Math.random() <= 1 ) { + if ( Math.random() <= 1 ) result += 1; +} assert.equal( result, 1 ); diff --git a/test/function/if-statement-with-update/main.js b/test/function/if-statement-with-update/main.js index 9239794..7ab3055 100644 --- a/test/function/if-statement-with-update/main.js +++ b/test/function/if-statement-with-update/main.js @@ -1,4 +1,6 @@ var result = 0; -if ( Math.random() <= 1 ) ++result; +if ( Math.random() <= 1 ) { + if ( Math.random() <= 1 ) ++result; +} assert.equal( result, 1 ); From 42ed5c24ba44f4f59c5da9c811f29d5692799880 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 11:39:47 -0400 Subject: [PATCH 264/331] -> v0.35.14 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c13bc94..62d02b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.35.14 + +* Include all parent statements of expression with effects, up to function boundary ([#930](https://github.com/rollup/rollup/issues/930)) + ## 0.35.13 * Include superclasses when including their subclasses ([#932](https://github.com/rollup/rollup/issues/932)) diff --git a/package.json b/package.json index 0bb95d3..ec1c88e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.13", + "version": "0.35.14", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 3a7322499035b0d030e38f7a4fca8eb38cc3a94c Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 12:24:17 -0400 Subject: [PATCH 265/331] =?UTF-8?q?ensure=20bundle=20ends=20with=20newline?= =?UTF-8?q?=20=E2=80=93=20fixes=20#958?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Bundle.js | 1 + src/rollup.js | 2 +- test/test.js | 10 ++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Bundle.js b/src/Bundle.js index d56f4a5..a4e8c53 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -431,6 +431,7 @@ export default class Bundle { timeEnd( 'sourceMap' ); } + if ( code[ code.length - 1 ] !== '\n' ) code += '\n'; return { code, map }; } diff --git a/src/rollup.js b/src/rollup.js index be39d0b..0868960 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -108,7 +108,7 @@ export function rollup ( options ) { promises.push( writeFile( dest + '.map', map.toString() ) ); } - code += `\n//# ${SOURCEMAPPING_URL}=${url}\n`; + code += `//# ${SOURCEMAPPING_URL}=${url}\n`; } promises.push( writeFile( dest, code ) ); diff --git a/test/test.js b/test/test.js index 5876435..52cc00e 100644 --- a/test/test.js +++ b/test/test.js @@ -102,6 +102,16 @@ describe( 'rollup', function () { plugins: [ loader({ x: `var a = null; a = 'a string';` }) ] }); }); + + it( 'includes a newline at the end of the bundle', () => { + return rollup.rollup({ + entry: 'x', + plugins: [ loader({ x: `console.log( 42 );` }) ] + }).then( bundle => { + const { code } = bundle.generate({ format: 'iife' }); + assert.ok( code[ code.length - 1 ] === '\n' ); + }); + }); }); describe( 'bundle.write()', () => { From 0cd5ea35e606f0c6f4208d211e552b6bec1acd18 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 13:30:42 -0400 Subject: [PATCH 266/331] add issue and pull request templates --- .github/ISSUE_TEMPLATE.md | 18 ++++++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 8 ++++++++ 2 files changed, 26 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..8349819 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,18 @@ + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..6ff5a20 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,8 @@ + From e152bb95c588a13ce05b0434572bcad6c54728c9 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 15:03:20 -0400 Subject: [PATCH 267/331] warn on missing unused imports in deshadowing phase, rather than throwing - fixes #928 --- src/ast/scopes/ModuleScope.js | 5 +++++ .../warn-on-unused-missing-imports/_config.js | 12 ++++++++++++ test/function/warn-on-unused-missing-imports/foo.js | 1 + test/function/warn-on-unused-missing-imports/main.js | 3 +++ 4 files changed, 21 insertions(+) create mode 100644 test/function/warn-on-unused-missing-imports/_config.js create mode 100644 test/function/warn-on-unused-missing-imports/foo.js create mode 100644 test/function/warn-on-unused-missing-imports/main.js diff --git a/src/ast/scopes/ModuleScope.js b/src/ast/scopes/ModuleScope.js index 051fcb4..5a18d6f 100644 --- a/src/ast/scopes/ModuleScope.js +++ b/src/ast/scopes/ModuleScope.js @@ -22,8 +22,13 @@ export default class ModuleScope extends Scope { specifier.module.getExports().forEach( name => { names.set(name); }); + if ( specifier.name !== '*' ) { const declaration = specifier.module.traceExport( specifier.name ); + if ( !declaration ) { + this.module.bundle.onwarn( `Non-existent export '${specifier.name}' is imported from ${specifier.module.id} by ${this.module.id}` ); + return; + } const name = declaration.getName( true ); if ( name !== specifier.name ) { names.set( declaration.getName( true ) ); diff --git a/test/function/warn-on-unused-missing-imports/_config.js b/test/function/warn-on-unused-missing-imports/_config.js new file mode 100644 index 0000000..16d69c1 --- /dev/null +++ b/test/function/warn-on-unused-missing-imports/_config.js @@ -0,0 +1,12 @@ +const path = require( 'path' ); +const assert = require( 'assert' ); + +module.exports = { + solo: true, + description: 'warns on missing (but unused) imports', + warnings: warnings => { + assert.deepEqual( warnings, [ + `Non-existent export 'b' is imported from ${path.resolve(__dirname, 'foo.js')} by ${path.resolve(__dirname, 'main.js')}` + ]); + } +}; diff --git a/test/function/warn-on-unused-missing-imports/foo.js b/test/function/warn-on-unused-missing-imports/foo.js new file mode 100644 index 0000000..71becd3 --- /dev/null +++ b/test/function/warn-on-unused-missing-imports/foo.js @@ -0,0 +1 @@ +export const a = 42; diff --git a/test/function/warn-on-unused-missing-imports/main.js b/test/function/warn-on-unused-missing-imports/main.js new file mode 100644 index 0000000..7eaceb9 --- /dev/null +++ b/test/function/warn-on-unused-missing-imports/main.js @@ -0,0 +1,3 @@ +import { a, b } from './foo.js'; + +assert.equal( a, 42 ); From fa08af7689c7688f859f17478966abb4315ec803 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 15:24:15 -0400 Subject: [PATCH 268/331] argh 0.12 --- test/function/warn-on-unused-missing-imports/foo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/function/warn-on-unused-missing-imports/foo.js b/test/function/warn-on-unused-missing-imports/foo.js index 71becd3..18e60c8 100644 --- a/test/function/warn-on-unused-missing-imports/foo.js +++ b/test/function/warn-on-unused-missing-imports/foo.js @@ -1 +1 @@ -export const a = 42; +export var a = 42; From 1a15b811185b2123b35d8edfb3a7a4c792733729 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 15:34:31 -0400 Subject: [PATCH 269/331] remove link markdown and squashing bullet point --- .github/ISSUE_TEMPLATE.md | 4 ++-- .github/PULL_REQUEST_TEMPLATE.md | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 8349819..4e2b499 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,10 +1,10 @@ From 5001d2b2cb38d689913a013739091618d0aebe37 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 15:38:55 -0400 Subject: [PATCH 270/331] -> v0.35.15 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62d02b5..aa4f31b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # rollup changelog +## 0.35.15 + +* Warn on missing unused imports in deshadowing phase ([#928](https://github.com/rollup/rollup/issues/928)) +* Always add a newline to the end of bundles ([#958](https://github.com/rollup/rollup/issues/958)) + ## 0.35.14 * Include all parent statements of expression with effects, up to function boundary ([#930](https://github.com/rollup/rollup/issues/930)) diff --git a/package.json b/package.json index ec1c88e..84ae321 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.14", + "version": "0.35.15", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 609cf2b3c6ef3e788fb7c40e2671675b3513d5f1 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 15:40:29 -0400 Subject: [PATCH 271/331] oops, reinstate all tests --- test/function/warn-on-unused-missing-imports/_config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/function/warn-on-unused-missing-imports/_config.js b/test/function/warn-on-unused-missing-imports/_config.js index 16d69c1..1fca512 100644 --- a/test/function/warn-on-unused-missing-imports/_config.js +++ b/test/function/warn-on-unused-missing-imports/_config.js @@ -2,7 +2,6 @@ const path = require( 'path' ); const assert = require( 'assert' ); module.exports = { - solo: true, description: 'warns on missing (but unused) imports', warnings: warnings => { assert.deepEqual( warnings, [ From e36a57527b490a748a6e13e7952c8a8d382fa774 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 17:45:09 -0400 Subject: [PATCH 272/331] prevent {export foo as default} from creating a live binding (#860) --- src/Module.js | 8 ++- src/ast/nodes/ExportNamedDeclaration.js | 67 ++++++++++++++++++++-- test/function/export-as-default/_config.js | 1 - 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/Module.js b/src/Module.js index 6e58131..3abdd4c 100644 --- a/src/Module.js +++ b/src/Module.js @@ -170,7 +170,13 @@ export default class Module { throw new Error( `A module cannot have multiple exports with the same name ('${exportedName}')` ); } - this.exports[ exportedName ] = { localName }; + // `export { default as foo }` – special case. We want importers + // to use the UnboundDefaultExport proxy, not the original declaration + if ( exportedName === 'default' ) { + this.exports[ exportedName ] = { localName: 'default' }; + } else { + this.exports[ exportedName ] = { localName }; + } }); } else { this.bundle.onwarn( `Module ${this.id} has an empty export declaration` ); diff --git a/src/ast/nodes/ExportNamedDeclaration.js b/src/ast/nodes/ExportNamedDeclaration.js index b815dd6..3f9ba4e 100644 --- a/src/ast/nodes/ExportNamedDeclaration.js +++ b/src/ast/nodes/ExportNamedDeclaration.js @@ -1,17 +1,59 @@ +import { find } from '../../utils/array.js'; import Node from '../Node.js'; +class UnboundDefaultExport { + constructor ( original ) { + this.original = original; + this.name = original.name; + } + + activate () { + if ( this.activated ) return; + this.activated = true; + + this.original.activate(); + } + + addReference ( reference ) { + this.name = reference.name; + this.original.addReference( reference ); + } + + bind ( scope ) { + this.original.bind( scope ); + } + + gatherPossibleValues ( values ) { + this.original.gatherPossibleValues( values ); + } + + getName ( es ) { + if ( this.original && !this.original.isReassigned ) { + return this.original.getName( es ); + } + + return this.name; + } +} + export default class ExportNamedDeclaration extends Node { initialise ( scope ) { + this.scope = scope; this.isExportDeclaration = true; - if ( this.declaration ) { - this.declaration.initialise( scope ); + + // special case – `export { foo as default }` should not create a live binding + const defaultExport = find( this.specifiers, specifier => specifier.exported.name === 'default' ); + if ( defaultExport ) { + const declaration = this.scope.findDeclaration( defaultExport.local.name ); + this.defaultExport = new UnboundDefaultExport( declaration ); + scope.declarations.default = this.defaultExport; } + + if ( this.declaration ) this.declaration.initialise( scope ); } bind ( scope ) { - if ( this.declaration ) { - this.declaration.bind( scope ); - } + if ( this.declaration ) this.declaration.bind( scope ); } render ( code, es ) { @@ -19,7 +61,20 @@ export default class ExportNamedDeclaration extends Node { code.remove( this.start, this.declaration.start ); this.declaration.render( code, es ); } else { - code.remove( this.leadingCommentStart || this.start, this.next || this.end ); + const start = this.leadingCommentStart || this.start; + const end = this.next || this.end; + + if ( this.defaultExport ) { + const name = this.defaultExport.getName( es ); + const originalName = this.defaultExport.original.getName( es ); + + if ( name !== originalName ) { + code.overwrite( start, end, `var ${name} = ${originalName};` ); + return; + } + } + + code.remove( start, end ); } } } diff --git a/test/function/export-as-default/_config.js b/test/function/export-as-default/_config.js index 0f4773a..d5de425 100644 --- a/test/function/export-as-default/_config.js +++ b/test/function/export-as-default/_config.js @@ -1,6 +1,5 @@ var assert = require( 'assert' ); module.exports = { - solo: true, description: 'export { foo as default } does not create a live binding' }; From ef3c8d54522f477d729e383987a8d811e26471e8 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 17:47:58 -0400 Subject: [PATCH 273/331] let -> var --- test/function/export-as-default/foo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/function/export-as-default/foo.js b/test/function/export-as-default/foo.js index 2e5b275..3c54230 100644 --- a/test/function/export-as-default/foo.js +++ b/test/function/export-as-default/foo.js @@ -1,3 +1,3 @@ -let foo = 1; +var foo = 1; export { foo as default }; foo = 2; From 152afb9732975188c7f4bf716c143da549afd432 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 18 Sep 2016 17:57:25 -0400 Subject: [PATCH 274/331] -> v0.36.0 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa4f31b..a25081a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.36.0 + +* `export { foo as default }` no longer creates a live binding ([#860](https://github.com/rollup/rollup/issues/860)) + ## 0.35.15 * Warn on missing unused imports in deshadowing phase ([#928](https://github.com/rollup/rollup/issues/928)) diff --git a/package.json b/package.json index 84ae321..ba2eeba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.35.15", + "version": "0.36.0", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 7f61f5c75402785d956c9de6d838bc7bd580161c Mon Sep 17 00:00:00 2001 From: Permutator Date: Mon, 19 Sep 2016 12:57:20 -0700 Subject: [PATCH 275/331] Added failing test for inclusion of internally used default export --- .../includes-internally-used-default-export/_config.js | 3 +++ .../includes-internally-used-default-export/main.js | 3 +++ .../includes-internally-used-default-export/module.js | 7 +++++++ 3 files changed, 13 insertions(+) create mode 100644 test/function/includes-internally-used-default-export/_config.js create mode 100644 test/function/includes-internally-used-default-export/main.js create mode 100644 test/function/includes-internally-used-default-export/module.js diff --git a/test/function/includes-internally-used-default-export/_config.js b/test/function/includes-internally-used-default-export/_config.js new file mode 100644 index 0000000..3eab340 --- /dev/null +++ b/test/function/includes-internally-used-default-export/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'includes default exports that are only used internally' +}; diff --git a/test/function/includes-internally-used-default-export/main.js b/test/function/includes-internally-used-default-export/main.js new file mode 100644 index 0000000..c196b10 --- /dev/null +++ b/test/function/includes-internally-used-default-export/main.js @@ -0,0 +1,3 @@ +import { b } from './module.js'; + +assert.equal(b(), 15); diff --git a/test/function/includes-internally-used-default-export/module.js b/test/function/includes-internally-used-default-export/module.js new file mode 100644 index 0000000..8f3524b --- /dev/null +++ b/test/function/includes-internally-used-default-export/module.js @@ -0,0 +1,7 @@ +export default function a() { + return 5; +} + +export function b() { + return a() + 10; +} From 33934791dde9389a85547520b199223e8d60ec4d Mon Sep 17 00:00:00 2001 From: Permutator Date: Mon, 19 Sep 2016 12:58:23 -0700 Subject: [PATCH 276/331] Default exports that are only used internally now included --- src/ast/nodes/ExportDefaultDeclaration.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/nodes/ExportDefaultDeclaration.js b/src/ast/nodes/ExportDefaultDeclaration.js index 716ffcf..30e402c 100644 --- a/src/ast/nodes/ExportDefaultDeclaration.js +++ b/src/ast/nodes/ExportDefaultDeclaration.js @@ -49,7 +49,7 @@ export default class ExportDefaultDeclaration extends Node { const treeshake = this.module.bundle.treeshake; const name = this.getName( es ); - if ( this.shouldInclude ) { + if ( this.shouldInclude || this.declaration.activated ) { if ( this.activated ) { if ( functionOrClassDeclaration.test( this.declaration.type ) ) { if ( this.declaration.id ) { From 1d51b06592cc334029b1eb9fade62130e5040848 Mon Sep 17 00:00:00 2001 From: Permutator Date: Mon, 19 Sep 2016 13:09:26 -0700 Subject: [PATCH 277/331] Whoops, tabs, not spaces --- .../includes-internally-used-default-export/module.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/function/includes-internally-used-default-export/module.js b/test/function/includes-internally-used-default-export/module.js index 8f3524b..ba2c4ee 100644 --- a/test/function/includes-internally-used-default-export/module.js +++ b/test/function/includes-internally-used-default-export/module.js @@ -1,7 +1,7 @@ export default function a() { - return 5; + return 5; } export function b() { - return a() + 10; + return a() + 10; } From a3e7b07e850c991a69681cf8f089cf31fb0f464c Mon Sep 17 00:00:00 2001 From: Federico Brigante Date: Tue, 20 Sep 2016 09:34:07 +0700 Subject: [PATCH 278/331] Avoid exports:auto warning on format:es --- src/Bundle.js | 2 +- src/utils/getExportMode.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index a4e8c53..2f4b0f9 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -350,7 +350,7 @@ export default class Bundle { const format = options.format || 'es'; // Determine export mode - 'default', 'named', 'none' - const exportMode = getExportMode( this, options.exports, options.moduleName ); + const exportMode = getExportMode( this, options ); let magicString = new MagicStringBundle({ separator: '\n\n' }); const usedModules = []; diff --git a/src/utils/getExportMode.js b/src/utils/getExportMode.js index f37ff1e..a3d00a0 100644 --- a/src/utils/getExportMode.js +++ b/src/utils/getExportMode.js @@ -4,7 +4,7 @@ function badExports ( option, keys ) { throw new Error( `'${option}' was specified for options.exports, but entry module has following exports: ${keys.join(', ')}` ); } -export default function getExportMode ( bundle, exportMode, moduleName ) { +export default function getExportMode ( bundle, {exports: exportMode, moduleName, format} ) { const exportKeys = keys( bundle.entryModule.exports ) .concat( keys( bundle.entryModule.reexports ) ) .concat( bundle.entryModule.exportAllSources ); // not keys, but makes our job easier this way @@ -23,7 +23,7 @@ export default function getExportMode ( bundle, exportMode, moduleName ) { } else if ( exportKeys.length === 1 && exportKeys[0] === 'default' ) { exportMode = 'default'; } else { - if ( bundle.entryModule.exports.default ) { + if ( bundle.entryModule.exports.default && format !== 'es') { bundle.onwarn( `Using named and default exports together. Consumers of your bundle will have to use ${moduleName || 'bundle'}['default'] to access the default export, which may not be what you want. Use \`exports: 'named'\` to disable this warning. See https://github.com/rollup/rollup/wiki/JavaScript-API#exports for more information` ); } exportMode = 'named'; From d9193654dcb2bde76e15c8699240a9659ee237c6 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Thu, 22 Sep 2016 09:59:26 -0700 Subject: [PATCH 279/331] Remove redundant check. --- src/ast/nodes/ExportDefaultDeclaration.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/nodes/ExportDefaultDeclaration.js b/src/ast/nodes/ExportDefaultDeclaration.js index 30e402c..ab4a776 100644 --- a/src/ast/nodes/ExportDefaultDeclaration.js +++ b/src/ast/nodes/ExportDefaultDeclaration.js @@ -76,7 +76,7 @@ export default class ExportDefaultDeclaration extends Node { super.render( code, es ); } else { if ( treeshake ) { - if ( functionOrClassDeclaration.test( this.declaration.type ) && !this.declaration.activated ) { + if ( functionOrClassDeclaration.test( this.declaration.type ) ) { code.remove( this.leadingCommentStart || this.start, this.next || this.end ); } else { const hasEffects = this.declaration.hasEffects( this.module.scope ); From 2c80dc7d72c0f883b63ee8ee62c8c949aa4d04b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Segersv=C3=A4rd?= Date: Fri, 23 Sep 2016 17:07:46 +0200 Subject: [PATCH 280/331] Fix #973 --- src/ast/nodes/IfStatement.js | 27 +++++++++-- .../_config.js | 3 ++ .../if-statement-with-false-condition/main.js | 47 +++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 test/function/if-statement-with-false-condition/_config.js create mode 100644 test/function/if-statement-with-false-condition/main.js diff --git a/src/ast/nodes/IfStatement.js b/src/ast/nodes/IfStatement.js index 9e6f0fc..fe83a78 100644 --- a/src/ast/nodes/IfStatement.js +++ b/src/ast/nodes/IfStatement.js @@ -1,6 +1,16 @@ import Statement from './shared/Statement.js'; import { UNKNOWN } from '../values.js'; +// Statement types which may contain if-statements as direct children. +const statementsWithIfStatements = new Set([ + 'DoWhileStatement', + 'ForInStatement', + 'ForOfStatement', + 'ForStatement', + 'IfStatement', + 'WhileStatement' +]); + // TODO DRY this out export default class IfStatement extends Statement { initialise ( scope ) { @@ -14,7 +24,9 @@ export default class IfStatement extends Statement { else if ( this.testValue ) { this.consequent.initialise( scope ); this.alternate = null; - } else { + } + + else { if ( this.alternate ) this.alternate.initialise( scope ); this.consequent = null; } @@ -41,9 +53,18 @@ export default class IfStatement extends Statement { code.remove( this.start, this.consequent.start ); code.remove( this.consequent.end, this.end ); this.consequent.render( code, es ); - } else { + } + + else { code.remove( this.start, this.alternate ? this.alternate.start : this.next || this.end ); - if ( this.alternate ) this.alternate.render( code, es ); + + if ( this.alternate ) { + this.alternate.render( code, es ); + } + + else if ( statementsWithIfStatements.has( this.parent.type ) ) { + code.insertRight( this.start, '{}' ); + } } } } diff --git a/test/function/if-statement-with-false-condition/_config.js b/test/function/if-statement-with-false-condition/_config.js new file mode 100644 index 0000000..b7eda7a --- /dev/null +++ b/test/function/if-statement-with-false-condition/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'if statements with false condition do not break render (#973)' +}; diff --git a/test/function/if-statement-with-false-condition/main.js b/test/function/if-statement-with-false-condition/main.js new file mode 100644 index 0000000..59bf4fd --- /dev/null +++ b/test/function/if-statement-with-false-condition/main.js @@ -0,0 +1,47 @@ +export function whileIf(x) { + while (x) + if (false) + // replaced with {} + x = 0; +} + +export function whileBlockIf(x) { + while (x) { + if (false) + // removed + x = 0; + } +} + +export function ifWhile(x) { + if (x) + while (false) + // not optimized + x = 0; +} + +export function ifFalseElse(x) { + if (false) { + // removed + } else { + // kept + } +} + +export function elseIfFalse(x) { + if (x) { + // kept + } else if (false) { + // replaced with {} + } +} + +export function elseIfFalseElse(x) { + if (x) { + // kept + } else if (false) { + // removed + } else { + // kept + } +} From b65657fd38d6db746298c2d7ffc44dbbdc64aff3 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Fri, 23 Sep 2016 14:27:45 -0700 Subject: [PATCH 281/331] Add failing test case for #977. --- test/form/unused-called-import/_config.js | 3 +++ test/form/unused-called-import/_expected/amd.js | 7 +++++++ test/form/unused-called-import/_expected/cjs.js | 5 +++++ test/form/unused-called-import/_expected/es.js | 3 +++ test/form/unused-called-import/_expected/iife.js | 8 ++++++++ test/form/unused-called-import/_expected/umd.js | 11 +++++++++++ test/form/unused-called-import/dead.js | 1 + test/form/unused-called-import/foo.js | 5 +++++ test/form/unused-called-import/main.js | 2 ++ 9 files changed, 45 insertions(+) create mode 100644 test/form/unused-called-import/_config.js create mode 100644 test/form/unused-called-import/_expected/amd.js create mode 100644 test/form/unused-called-import/_expected/cjs.js create mode 100644 test/form/unused-called-import/_expected/es.js create mode 100644 test/form/unused-called-import/_expected/iife.js create mode 100644 test/form/unused-called-import/_expected/umd.js create mode 100644 test/form/unused-called-import/dead.js create mode 100644 test/form/unused-called-import/foo.js create mode 100644 test/form/unused-called-import/main.js diff --git a/test/form/unused-called-import/_config.js b/test/form/unused-called-import/_config.js new file mode 100644 index 0000000..0f1029d --- /dev/null +++ b/test/form/unused-called-import/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'does not include called-in-unused-code import' +}; diff --git a/test/form/unused-called-import/_expected/amd.js b/test/form/unused-called-import/_expected/amd.js new file mode 100644 index 0000000..98fec0b --- /dev/null +++ b/test/form/unused-called-import/_expected/amd.js @@ -0,0 +1,7 @@ +define(function () { 'use strict'; + + var foo = function() { return 'foo'; } + + assert.equal( foo(), 'foo' ); + +}); diff --git a/test/form/unused-called-import/_expected/cjs.js b/test/form/unused-called-import/_expected/cjs.js new file mode 100644 index 0000000..084a719 --- /dev/null +++ b/test/form/unused-called-import/_expected/cjs.js @@ -0,0 +1,5 @@ +'use strict'; + +var foo = function() { return 'foo'; } + +assert.equal( foo(), 'foo' ); diff --git a/test/form/unused-called-import/_expected/es.js b/test/form/unused-called-import/_expected/es.js new file mode 100644 index 0000000..7d15eea --- /dev/null +++ b/test/form/unused-called-import/_expected/es.js @@ -0,0 +1,3 @@ +var foo = function() { return 'foo'; } + +assert.equal( foo(), 'foo' ); diff --git a/test/form/unused-called-import/_expected/iife.js b/test/form/unused-called-import/_expected/iife.js new file mode 100644 index 0000000..f7fa135 --- /dev/null +++ b/test/form/unused-called-import/_expected/iife.js @@ -0,0 +1,8 @@ +(function () { + 'use strict'; + + var foo = function() { return 'foo'; } + + assert.equal( foo(), 'foo' ); + +}()); diff --git a/test/form/unused-called-import/_expected/umd.js b/test/form/unused-called-import/_expected/umd.js new file mode 100644 index 0000000..3cd2a2b --- /dev/null +++ b/test/form/unused-called-import/_expected/umd.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + var foo = function() { return 'foo'; } + + assert.equal( foo(), 'foo' ); + +}))); diff --git a/test/form/unused-called-import/dead.js b/test/form/unused-called-import/dead.js new file mode 100644 index 0000000..56a0ceb --- /dev/null +++ b/test/form/unused-called-import/dead.js @@ -0,0 +1 @@ +export default function() { return 'dead'; } diff --git a/test/form/unused-called-import/foo.js b/test/form/unused-called-import/foo.js new file mode 100644 index 0000000..e19ff25 --- /dev/null +++ b/test/form/unused-called-import/foo.js @@ -0,0 +1,5 @@ +import dead from './dead'; + +export default function() { return 'foo'; } + +export function foodead() { return 'foo' + dead(); } diff --git a/test/form/unused-called-import/main.js b/test/form/unused-called-import/main.js new file mode 100644 index 0000000..3e476bb --- /dev/null +++ b/test/form/unused-called-import/main.js @@ -0,0 +1,2 @@ +import foo from './foo'; +assert.equal( foo(), 'foo' ); From ad22e33dcd09aa806003c6ff6b9efc9c33b0d830 Mon Sep 17 00:00:00 2001 From: Denis Bardadym Date: Sat, 24 Sep 2016 23:54:11 +0300 Subject: [PATCH 282/331] Do not skip non empty block statements --- src/ast/nodes/BlockStatement.js | 10 ++++++++++ test/form/non-empty-block-statement/_config.js | 3 +++ .../form/non-empty-block-statement/_expected/amd.js | 9 +++++++++ .../form/non-empty-block-statement/_expected/cjs.js | 7 +++++++ test/form/non-empty-block-statement/_expected/es.js | 5 +++++ .../non-empty-block-statement/_expected/iife.js | 10 ++++++++++ .../form/non-empty-block-statement/_expected/umd.js | 13 +++++++++++++ test/form/non-empty-block-statement/main.js | 5 +++++ 8 files changed, 62 insertions(+) create mode 100644 test/form/non-empty-block-statement/_config.js create mode 100644 test/form/non-empty-block-statement/_expected/amd.js create mode 100644 test/form/non-empty-block-statement/_expected/cjs.js create mode 100644 test/form/non-empty-block-statement/_expected/es.js create mode 100644 test/form/non-empty-block-statement/_expected/iife.js create mode 100644 test/form/non-empty-block-statement/_expected/umd.js create mode 100644 test/form/non-empty-block-statement/main.js diff --git a/src/ast/nodes/BlockStatement.js b/src/ast/nodes/BlockStatement.js index 78e6e67..d83d321 100644 --- a/src/ast/nodes/BlockStatement.js +++ b/src/ast/nodes/BlockStatement.js @@ -46,4 +46,14 @@ export default class BlockStatement extends Statement { lastNode = node; } } + + render ( code, es ) { + if (this.body.length) { + for ( const node of this.body ) { + node.render( code, es ); + } + } else { + Statement.prototype.render.call(this, code, es); + } + } } diff --git a/test/form/non-empty-block-statement/_config.js b/test/form/non-empty-block-statement/_config.js new file mode 100644 index 0000000..283b0b6 --- /dev/null +++ b/test/form/non-empty-block-statement/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'removes an empty block statement' +}; diff --git a/test/form/non-empty-block-statement/_expected/amd.js b/test/form/non-empty-block-statement/_expected/amd.js new file mode 100644 index 0000000..aaad1ff --- /dev/null +++ b/test/form/non-empty-block-statement/_expected/amd.js @@ -0,0 +1,9 @@ +define(function () { 'use strict'; + + console.log( 1 ); + { + var tmp = 10; + } + console.log( tmp ); + +}); diff --git a/test/form/non-empty-block-statement/_expected/cjs.js b/test/form/non-empty-block-statement/_expected/cjs.js new file mode 100644 index 0000000..ef9e375 --- /dev/null +++ b/test/form/non-empty-block-statement/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +console.log( 1 ); +{ + var tmp = 10; +} +console.log( tmp ); diff --git a/test/form/non-empty-block-statement/_expected/es.js b/test/form/non-empty-block-statement/_expected/es.js new file mode 100644 index 0000000..9f19ab6 --- /dev/null +++ b/test/form/non-empty-block-statement/_expected/es.js @@ -0,0 +1,5 @@ +console.log( 1 ); +{ + var tmp = 10; +} +console.log( tmp ); diff --git a/test/form/non-empty-block-statement/_expected/iife.js b/test/form/non-empty-block-statement/_expected/iife.js new file mode 100644 index 0000000..611fa6e --- /dev/null +++ b/test/form/non-empty-block-statement/_expected/iife.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + console.log( 1 ); + { + var tmp = 10; + } + console.log( tmp ); + +}()); diff --git a/test/form/non-empty-block-statement/_expected/umd.js b/test/form/non-empty-block-statement/_expected/umd.js new file mode 100644 index 0000000..9015af2 --- /dev/null +++ b/test/form/non-empty-block-statement/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log( 1 ); + { + var tmp = 10; + } + console.log( tmp ); + +}))); diff --git a/test/form/non-empty-block-statement/main.js b/test/form/non-empty-block-statement/main.js new file mode 100644 index 0000000..9f19ab6 --- /dev/null +++ b/test/form/non-empty-block-statement/main.js @@ -0,0 +1,5 @@ +console.log( 1 ); +{ + var tmp = 10; +} +console.log( tmp ); From fb12be58143032f3c05e369a2ac163c4052b4484 Mon Sep 17 00:00:00 2001 From: Denis Bardadym Date: Sun, 25 Sep 2016 22:48:11 +0300 Subject: [PATCH 283/331] Update _config.js --- test/form/non-empty-block-statement/_config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/form/non-empty-block-statement/_config.js b/test/form/non-empty-block-statement/_config.js index 283b0b6..92803d7 100644 --- a/test/form/non-empty-block-statement/_config.js +++ b/test/form/non-empty-block-statement/_config.js @@ -1,3 +1,3 @@ module.exports = { - description: 'removes an empty block statement' + description: 'do not remove non an empty block statement' }; From 4cff28b3a2cb5f27a86059baa1e35344400d144b Mon Sep 17 00:00:00 2001 From: 1111hui <26634873@qq.com> Date: Mon, 26 Sep 2016 11:07:58 +0800 Subject: [PATCH 284/331] ADD: fallback for Object.freeze --- src/Declaration.js | 2 +- test/form/prefer-const/_expected/amd.js | 2 +- test/form/prefer-const/_expected/cjs.js | 2 +- test/form/prefer-const/_expected/es.js | 2 +- test/form/prefer-const/_expected/iife.js | 2 +- test/form/prefer-const/_expected/umd.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Declaration.js b/src/Declaration.js index 8d0934e..2e75793 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -86,7 +86,7 @@ export class SyntheticNamespaceDeclaration { return `${indentString}${name}: ${original.getName( es )}`; }); - return `${this.module.bundle.varOrConst} ${this.getName( es )} = Object.freeze({\n${members.join( ',\n' )}\n});\n\n`; + return `${this.module.bundle.varOrConst} ${this.getName( es )} = (Object.freeze || Object)({\n${members.join( ',\n' )}\n});\n\n`; } } diff --git a/test/form/prefer-const/_expected/amd.js b/test/form/prefer-const/_expected/amd.js index a89dacd..2e0b570 100644 --- a/test/form/prefer-const/_expected/amd.js +++ b/test/form/prefer-const/_expected/amd.js @@ -4,7 +4,7 @@ define(['external', 'other', 'another'], function (external, other, another) { ' const b = 2; - const namespace = Object.freeze({ + const namespace = (Object.freeze || Object)({ a: a, b: b }); diff --git a/test/form/prefer-const/_expected/cjs.js b/test/form/prefer-const/_expected/cjs.js index 5c2e4da..692b290 100644 --- a/test/form/prefer-const/_expected/cjs.js +++ b/test/form/prefer-const/_expected/cjs.js @@ -8,7 +8,7 @@ const a = 1; const b = 2; -const namespace = Object.freeze({ +const namespace = (Object.freeze || Object)({ a: a, b: b }); diff --git a/test/form/prefer-const/_expected/es.js b/test/form/prefer-const/_expected/es.js index 8f5a5c9..2545ae4 100644 --- a/test/form/prefer-const/_expected/es.js +++ b/test/form/prefer-const/_expected/es.js @@ -6,7 +6,7 @@ const a = 1; const b = 2; -const namespace = Object.freeze({ +const namespace = (Object.freeze || Object)({ a: a, b: b }); diff --git a/test/form/prefer-const/_expected/iife.js b/test/form/prefer-const/_expected/iife.js index 9c66729..2aea939 100644 --- a/test/form/prefer-const/_expected/iife.js +++ b/test/form/prefer-const/_expected/iife.js @@ -5,7 +5,7 @@ const myBundle = (function (external,other,another) { const b = 2; - const namespace = Object.freeze({ + const namespace = (Object.freeze || Object)({ a: a, b: b }); diff --git a/test/form/prefer-const/_expected/umd.js b/test/form/prefer-const/_expected/umd.js index 0ec9750..19a0747 100644 --- a/test/form/prefer-const/_expected/umd.js +++ b/test/form/prefer-const/_expected/umd.js @@ -8,7 +8,7 @@ const b = 2; - const namespace = Object.freeze({ + const namespace = (Object.freeze || Object)({ a: a, b: b }); From 82f2149a1818f5754db9c361e0f604d412bf27fe Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 26 Sep 2016 09:49:32 -0700 Subject: [PATCH 285/331] Add another failing test case. --- .../form/unused-called-with-side-effects/_config.js | 3 +++ .../_expected/amd.js | 9 +++++++++ .../_expected/cjs.js | 7 +++++++ .../unused-called-with-side-effects/_expected/es.js | 5 +++++ .../_expected/iife.js | 10 ++++++++++ .../_expected/umd.js | 13 +++++++++++++ test/form/unused-called-with-side-effects/main.js | 13 +++++++++++++ 7 files changed, 60 insertions(+) create mode 100644 test/form/unused-called-with-side-effects/_config.js create mode 100644 test/form/unused-called-with-side-effects/_expected/amd.js create mode 100644 test/form/unused-called-with-side-effects/_expected/cjs.js create mode 100644 test/form/unused-called-with-side-effects/_expected/es.js create mode 100644 test/form/unused-called-with-side-effects/_expected/iife.js create mode 100644 test/form/unused-called-with-side-effects/_expected/umd.js create mode 100644 test/form/unused-called-with-side-effects/main.js diff --git a/test/form/unused-called-with-side-effects/_config.js b/test/form/unused-called-with-side-effects/_config.js new file mode 100644 index 0000000..0f1029d --- /dev/null +++ b/test/form/unused-called-with-side-effects/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'does not include called-in-unused-code import' +}; diff --git a/test/form/unused-called-with-side-effects/_expected/amd.js b/test/form/unused-called-with-side-effects/_expected/amd.js new file mode 100644 index 0000000..8be9631 --- /dev/null +++ b/test/form/unused-called-with-side-effects/_expected/amd.js @@ -0,0 +1,9 @@ +define(function () { 'use strict'; + + function foo() { + return 'foo' + } + + assert.equal( foo(), 'foo' ); + +}); diff --git a/test/form/unused-called-with-side-effects/_expected/cjs.js b/test/form/unused-called-with-side-effects/_expected/cjs.js new file mode 100644 index 0000000..9cd0d53 --- /dev/null +++ b/test/form/unused-called-with-side-effects/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +function foo() { + return 'foo' +} + +assert.equal( foo(), 'foo' ); diff --git a/test/form/unused-called-with-side-effects/_expected/es.js b/test/form/unused-called-with-side-effects/_expected/es.js new file mode 100644 index 0000000..1ea92fc --- /dev/null +++ b/test/form/unused-called-with-side-effects/_expected/es.js @@ -0,0 +1,5 @@ +function foo() { + return 'foo' +} + +assert.equal( foo(), 'foo' ); diff --git a/test/form/unused-called-with-side-effects/_expected/iife.js b/test/form/unused-called-with-side-effects/_expected/iife.js new file mode 100644 index 0000000..ccdb513 --- /dev/null +++ b/test/form/unused-called-with-side-effects/_expected/iife.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + function foo() { + return 'foo' + } + + assert.equal( foo(), 'foo' ); + +}()); diff --git a/test/form/unused-called-with-side-effects/_expected/umd.js b/test/form/unused-called-with-side-effects/_expected/umd.js new file mode 100644 index 0000000..e3ea51f --- /dev/null +++ b/test/form/unused-called-with-side-effects/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + function foo() { + return 'foo' + } + + assert.equal( foo(), 'foo' ); + +}))); diff --git a/test/form/unused-called-with-side-effects/main.js b/test/form/unused-called-with-side-effects/main.js new file mode 100644 index 0000000..25de8d8 --- /dev/null +++ b/test/form/unused-called-with-side-effects/main.js @@ -0,0 +1,13 @@ +function foo() { + return 'foo' +} + +function bar() { + dead(); +} + +function dead() { + console.log('dead'); +} + +assert.equal( foo(), 'foo' ); From daaaeafc759120697f953caf4478277f405add5b Mon Sep 17 00:00:00 2001 From: Vladimir Smyshlyaev Date: Tue, 27 Sep 2016 13:25:22 +0300 Subject: [PATCH 286/331] Cut options validation into method --- src/rollup.js | 18 +++++++++++------- src/utils/validateKeys.js | 6 +----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/rollup.js b/src/rollup.js index 0868960..0773d43 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -39,20 +39,24 @@ const ALLOWED_KEYS = [ 'useStrict' ]; -export function rollup ( options ) { +function checkOptions ( options ) { if ( !options || !options.entry ) { - return Promise.reject( new Error( 'You must supply options.entry to rollup' ) ); + return new Error( 'You must supply options.entry to rollup' ); } if ( options.transform || options.load || options.resolveId || options.resolveExternal ) { - return Promise.reject( new Error( 'The `transform`, `load`, `resolveId` and `resolveExternal` options are deprecated in favour of a unified plugin API. See https://github.com/rollup/rollup/wiki/Plugins for details' ) ); + return new Error( 'The `transform`, `load`, `resolveId` and `resolveExternal` options are deprecated in favour of a unified plugin API. See https://github.com/rollup/rollup/wiki/Plugins for details' ); } - const error = validateKeys( options, ALLOWED_KEYS ); + const error = validateKeys( keys(options), ALLOWED_KEYS ); + if ( error ) return error; - if ( error ) { - return Promise.reject( error ); - } + return null; +} + +export function rollup ( options ) { + const error = checkOptions ( options ); + if ( error ) return Promise.reject( error ); const bundle = new Bundle( options ); diff --git a/src/utils/validateKeys.js b/src/utils/validateKeys.js index 3ff51cd..d717b0a 100644 --- a/src/utils/validateKeys.js +++ b/src/utils/validateKeys.js @@ -1,8 +1,4 @@ -import { keys } from './object.js'; - -export default function validateKeys ( object, allowedKeys ) { - const actualKeys = keys( object ); - +export default function validateKeys ( actualKeys, allowedKeys ) { let i = actualKeys.length; while ( i-- ) { From 5becfeb86af3c9090bbf2a5bdc7619698e8d3fda Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 28 Sep 2016 08:48:57 -0400 Subject: [PATCH 287/331] -> v0.36.1 --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a25081a..e8bb569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # rollup changelog +## 0.36.1 + +* Include naked block statements ([#981](https://github.com/rollup/rollup/issues/981)) +* Correctly include falsy alternate statements in optimised if blocks ([#973](https://github.com/rollup/rollup/issues/973)) +* Prevent omission of default exports that are only used by the exporting module ([#967](https://github.com/rollup/rollup/pull/967)) +* Prevent warning on `auto` exports with ES output ([#966](https://github.com/rollup/rollup/pull/966)) + ## 0.36.0 * `export { foo as default }` no longer creates a live binding ([#860](https://github.com/rollup/rollup/issues/860)) diff --git a/package.json b/package.json index ba2eeba..844253f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.36.0", + "version": "0.36.1", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 0812aa52d457dcc2b226a9046954a63b5c8beaa0 Mon Sep 17 00:00:00 2001 From: Vladimir Smyshlyaev Date: Thu, 29 Sep 2016 12:35:19 +0300 Subject: [PATCH 288/331] refactor: reduce options mutations with reduce --- src/Bundle.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 2f4b0f9..b4dda83 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -31,11 +31,10 @@ export default class Bundle { this.plugins = ensureArray( options.plugins ); - this.plugins.forEach( plugin => { - if ( plugin.options ) { - options = plugin.options( options ) || options; - } - }); + options = this.plugins.reduce( ( acc, plugin ) => { + if ( plugin.options ) return plugin.options( acc ) || acc; + return acc; + }, options); this.entry = options.entry; this.entryId = null; From 6bfa47747c3f45a73fcb8761f3589c7fc52808c8 Mon Sep 17 00:00:00 2001 From: jlengstorf Date: Thu, 29 Sep 2016 12:46:01 -0700 Subject: [PATCH 289/331] docs(tutorial): added a reference to the tutorial series To help folks who are less comfortable with CLI help dialogs. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c5de896..a181aa5 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ Rollup can be used via a [JavaScript API](https://github.com/rollup/rollup/wiki/JavaScript-API) or a [Command Line Interface](https://github.com/rollup/rollup/wiki/Command-Line-Interface). Install with `npm install -g rollup` and run `rollup --help` to get started. +If the command line's not your jam, there's also a [step-by-step tutorial video series](https://code.lengstorf.com/learn-rollup-js/) (with accompanying written walkthrough). + [Dive into the wiki](https://github.com/rollup/rollup/wiki) when you're ready to learn more about Rollup and ES6 modules. From ed35cef98f86591086ce1a4610d4c7734023f592 Mon Sep 17 00:00:00 2001 From: Daniel K Date: Sat, 1 Oct 2016 22:15:24 +0200 Subject: [PATCH 290/331] Add module id when warning about top level this Hard to fix the problem when not knowing which module actually has it. --- src/ast/nodes/ThisExpression.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/nodes/ThisExpression.js b/src/ast/nodes/ThisExpression.js index e614194..baba840 100644 --- a/src/ast/nodes/ThisExpression.js +++ b/src/ast/nodes/ThisExpression.js @@ -7,7 +7,7 @@ export default class ThisExpression extends Node { if ( lexicalBoundary.isModuleScope ) { this.alias = this.module.bundle.context; if ( this.alias === 'undefined' ) { - this.module.bundle.onwarn( 'The `this` keyword is equivalent to `undefined` at the top level of an ES module, and has been rewritten' ); + this.module.bundle.onwarn( `The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten (in ${this.module.id})` ); } } } From 8cb47862a24584757e6047ca93de90b56e4d3fe0 Mon Sep 17 00:00:00 2001 From: Daniel K Date: Mon, 3 Oct 2016 20:42:38 +0200 Subject: [PATCH 291/331] Fix warn-on-top-level-this test --- test/function/warn-on-top-level-this/_config.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/function/warn-on-top-level-this/_config.js b/test/function/warn-on-top-level-this/_config.js index c667044..fd8f9a0 100644 --- a/test/function/warn-on-top-level-this/_config.js +++ b/test/function/warn-on-top-level-this/_config.js @@ -3,9 +3,10 @@ const assert = require( 'assert' ); module.exports = { description: 'warns on top-level this (#770)', warnings: warnings => { - assert.deepEqual( warnings, [ - 'The `this` keyword is equivalent to `undefined` at the top level of an ES module, and has been rewritten' - ]); + const message = `The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten`; + assert.equal(warnings.length, 1); + assert.equal(warnings[0].indexOf(message), 0); + assert(warnings[0].match(/\(in.*warn-on-top-level-this.*\)/)); }, runtimeError: err => { assert.equal( err.message, `Cannot set property 'foo' of undefined` ); From b164a463637d95a9cde493f1f1fcbc1b74f188d7 Mon Sep 17 00:00:00 2001 From: Daniel K Date: Tue, 4 Oct 2016 10:48:33 +0200 Subject: [PATCH 292/331] Include line & column number in warning message --- src/ast/nodes/ThisExpression.js | 5 ++++- test/function/warn-on-top-level-this/_config.js | 1 + test/function/warn-on-top-level-this/main.js | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ast/nodes/ThisExpression.js b/src/ast/nodes/ThisExpression.js index baba840..15de769 100644 --- a/src/ast/nodes/ThisExpression.js +++ b/src/ast/nodes/ThisExpression.js @@ -1,4 +1,5 @@ import Node from '../Node.js'; +import getLocation from '../../utils/getLocation.js'; export default class ThisExpression extends Node { initialise ( scope ) { @@ -7,7 +8,9 @@ export default class ThisExpression extends Node { if ( lexicalBoundary.isModuleScope ) { this.alias = this.module.bundle.context; if ( this.alias === 'undefined' ) { - this.module.bundle.onwarn( `The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten (in ${this.module.id})` ); + const location = getLocation(this.module.code, this.module.ast.end); + const detail = `${this.module.id}, line: ${location.line}, column: ${location.column}`; + this.module.bundle.onwarn( `The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten (in ${detail})`); } } } diff --git a/test/function/warn-on-top-level-this/_config.js b/test/function/warn-on-top-level-this/_config.js index fd8f9a0..53fe344 100644 --- a/test/function/warn-on-top-level-this/_config.js +++ b/test/function/warn-on-top-level-this/_config.js @@ -7,6 +7,7 @@ module.exports = { assert.equal(warnings.length, 1); assert.equal(warnings[0].indexOf(message), 0); assert(warnings[0].match(/\(in.*warn-on-top-level-this.*\)/)); + assert(warnings[0].match(/line: 4, column: 0/)); }, runtimeError: err => { assert.equal( err.message, `Cannot set property 'foo' of undefined` ); diff --git a/test/function/warn-on-top-level-this/main.js b/test/function/warn-on-top-level-this/main.js index 3853449..e3ca378 100644 --- a/test/function/warn-on-top-level-this/main.js +++ b/test/function/warn-on-top-level-this/main.js @@ -1 +1,3 @@ +const someVariableJustToCheckOnCorrectLineNumber = true; // eslint-disable-line + this.foo = 'bar'; From 77b8d4589fe4821da1f66706ca2c7642a3a4f0ac Mon Sep 17 00:00:00 2001 From: Michel Gotta Date: Tue, 4 Oct 2016 17:14:15 +0200 Subject: [PATCH 293/331] Fixed link to David DM badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c5de896..76a4ba0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ alt="license"> - dependency status From 4fdf3fb9a2508c3775bd0fcbdb87ec28097f68f5 Mon Sep 17 00:00:00 2001 From: Nikhil Tilwalli Date: Wed, 5 Oct 2016 22:37:39 -0400 Subject: [PATCH 294/331] Add support for module-specific context with 'moduleContext' option --- browser/path.js | 6 ++++ src/Bundle.js | 29 ++++++++++++++++++- src/ast/nodes/ThisExpression.js | 20 ++++++++++++- src/rollup.js | 1 + src/utils/path.js | 2 +- test/form/custom-module-context/_config.js | 8 +++++ .../custom-module-context/_expected/amd.js | 5 ++++ .../custom-module-context/_expected/cjs.js | 3 ++ .../custom-module-context/_expected/es.js | 1 + .../custom-module-context/_expected/iife.js | 6 ++++ .../custom-module-context/_expected/umd.js | 9 ++++++ test/form/custom-module-context/main.js | 1 + test/test.js | 2 +- 13 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 test/form/custom-module-context/_config.js create mode 100644 test/form/custom-module-context/_expected/amd.js create mode 100644 test/form/custom-module-context/_expected/cjs.js create mode 100644 test/form/custom-module-context/_expected/es.js create mode 100644 test/form/custom-module-context/_expected/iife.js create mode 100644 test/form/custom-module-context/_expected/umd.js create mode 100644 test/form/custom-module-context/main.js diff --git a/browser/path.js b/browser/path.js index 279ba66..84efd9d 100644 --- a/browser/path.js +++ b/browser/path.js @@ -78,3 +78,9 @@ export function resolve ( ...paths ) { return resolvedParts.join( '/' ); // TODO windows... } + +export function join ( ...parts ) { + const separator = '/'; + const replaceExp = new RegExp(separator+'{1,}', 'g'); + return parts.join(separator).replace(replaceExp, separator); +} diff --git a/src/Bundle.js b/src/Bundle.js index 2f4b0f9..7b06181 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -17,7 +17,7 @@ import transformBundle from './utils/transformBundle.js'; import collapseSourcemaps from './utils/collapseSourcemaps.js'; import SOURCEMAPPING_URL from './utils/sourceMappingURL.js'; import callIfFunction from './utils/callIfFunction.js'; -import { dirname, isRelative, isAbsolute, normalize, relative, resolve } from './utils/path.js'; +import { dirname, isRelative, isAbsolute, normalize, relative, resolve, join } from './utils/path.js'; import BundleScope from './ast/scopes/BundleScope.js'; export default class Bundle { @@ -72,6 +72,33 @@ export default class Bundle { this.externalModules = []; this.context = String( options.context ); + if (options.moduleContext) { + if (typeof options.moduleContext === 'object') { + const moduleContext = {}; + for (const key in options.moduleContext) { + let resolvedKey; + if (isAbsolute(key)) { + resolvedKey = normalize(key); + } else { + const useWorkingDir = key.substring(0, 2) === `./` ? true : false; + let absoluteKey; + if (useWorkingDir) { + absoluteKey = join(process.cwd(), key.substring(2)); + } else { + absoluteKey = join(dirname(options.entry), key); + } + + resolvedKey = normalize(absoluteKey); + } + + moduleContext[resolvedKey] = options.moduleContext[key]; + } + + this.moduleContext = moduleContext; + } else { + throw new Error('options.moduleContext must be an object'); + } + } if ( typeof options.external === 'function' ) { this.isExternal = options.external; diff --git a/src/ast/nodes/ThisExpression.js b/src/ast/nodes/ThisExpression.js index e614194..b6b8f68 100644 --- a/src/ast/nodes/ThisExpression.js +++ b/src/ast/nodes/ThisExpression.js @@ -1,11 +1,29 @@ import Node from '../Node.js'; +import {normalize} from '../../utils/path'; + +function getContext (module) { + let context = module.bundle.context; + const moduleContext = module.bundle.moduleContext; + if (moduleContext) { + const moduleId = normalize(module.id); + const candidates = Object.keys(moduleContext) + .map(relPath => moduleId.indexOf(relPath) >= 0 ? moduleContext[relPath] : undefined) + .filter(context => !!context); + + if (candidates.length) { + context = String( candidates[candidates.length - 1] ); + } + } + + return context; +} export default class ThisExpression extends Node { initialise ( scope ) { const lexicalBoundary = scope.findLexicalBoundary(); if ( lexicalBoundary.isModuleScope ) { - this.alias = this.module.bundle.context; + this.alias = getContext(this.module); if ( this.alias === 'undefined' ) { this.module.bundle.onwarn( 'The `this` keyword is equivalent to `undefined` at the top level of an ES module, and has been rewritten' ); } diff --git a/src/rollup.js b/src/rollup.js index 0773d43..f99e991 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -24,6 +24,7 @@ const ALLOWED_KEYS = [ 'indent', 'interop', 'intro', + 'moduleContext', 'moduleId', 'moduleName', 'noConflict', diff --git a/src/utils/path.js b/src/utils/path.js index d2ce64d..1f8af19 100644 --- a/src/utils/path.js +++ b/src/utils/path.js @@ -13,4 +13,4 @@ export function normalize ( path ) { return path.replace( /\\/g, '/' ); } -export { basename, dirname, extname, relative, resolve } from 'path'; +export { basename, dirname, extname, relative, resolve, join} from 'path'; diff --git a/test/form/custom-module-context/_config.js b/test/form/custom-module-context/_config.js new file mode 100644 index 0000000..3aa508d --- /dev/null +++ b/test/form/custom-module-context/_config.js @@ -0,0 +1,8 @@ +module.exports = { + description: 'allows custom module-specific context', + options: { + moduleContext: { + 'main.js': 'lolwut' + } + } +}; diff --git a/test/form/custom-module-context/_expected/amd.js b/test/form/custom-module-context/_expected/amd.js new file mode 100644 index 0000000..a160d17 --- /dev/null +++ b/test/form/custom-module-context/_expected/amd.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + lolwut.prop = '???'; + +}); diff --git a/test/form/custom-module-context/_expected/cjs.js b/test/form/custom-module-context/_expected/cjs.js new file mode 100644 index 0000000..f42cf3c --- /dev/null +++ b/test/form/custom-module-context/_expected/cjs.js @@ -0,0 +1,3 @@ +'use strict'; + +lolwut.prop = '???'; diff --git a/test/form/custom-module-context/_expected/es.js b/test/form/custom-module-context/_expected/es.js new file mode 100644 index 0000000..fa83c3d --- /dev/null +++ b/test/form/custom-module-context/_expected/es.js @@ -0,0 +1 @@ +lolwut.prop = '???'; diff --git a/test/form/custom-module-context/_expected/iife.js b/test/form/custom-module-context/_expected/iife.js new file mode 100644 index 0000000..a41619e --- /dev/null +++ b/test/form/custom-module-context/_expected/iife.js @@ -0,0 +1,6 @@ +(function () { + 'use strict'; + + lolwut.prop = '???'; + +}()); diff --git a/test/form/custom-module-context/_expected/umd.js b/test/form/custom-module-context/_expected/umd.js new file mode 100644 index 0000000..a73a22c --- /dev/null +++ b/test/form/custom-module-context/_expected/umd.js @@ -0,0 +1,9 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + lolwut.prop = '???'; + +}))); diff --git a/test/form/custom-module-context/main.js b/test/form/custom-module-context/main.js new file mode 100644 index 0000000..169f08b --- /dev/null +++ b/test/form/custom-module-context/main.js @@ -0,0 +1 @@ +this.prop = '???'; diff --git a/test/test.js b/test/test.js index 52cc00e..aa2bbbb 100644 --- a/test/test.js +++ b/test/test.js @@ -90,7 +90,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( () => { throw new Error( 'Missing expected error' ); }, err => { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, context, dest, entry, exports, external, footer, format, globals, indent, interop, intro, moduleId, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, context, dest, entry, exports, external, footer, format, globals, indent, interop, intro, moduleContext, moduleId, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); }); }); From 78515c3fb1666e5233fd312064b0bda877cf1d3e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 09:35:12 -0400 Subject: [PATCH 295/331] better error for missing export (#1033) --- src/Module.js | 3 ++- src/utils/relativeId.js | 4 ++++ test/function/import-of-unexported-fails/_config.js | 2 +- test/test.js | 2 ++ 4 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 src/utils/relativeId.js diff --git a/src/Module.js b/src/Module.js index 3abdd4c..41386f5 100644 --- a/src/Module.js +++ b/src/Module.js @@ -6,6 +6,7 @@ import { basename, extname } from './utils/path.js'; import getLocation from './utils/getLocation.js'; import makeLegalIdentifier from './utils/makeLegalIdentifier.js'; import SOURCEMAPPING_URL from './utils/sourceMappingURL.js'; +import relativeId from './utils/relativeId.js'; import { SyntheticNamespaceDeclaration } from './Declaration.js'; import extractNames from './ast/utils/extractNames.js'; import enhance from './ast/enhance.js'; @@ -357,7 +358,7 @@ export default class Module { const declaration = otherModule.traceExport( importDeclaration.name ); - if ( !declaration ) throw new Error( `Module ${otherModule.id} does not export ${importDeclaration.name} (imported by ${this.id})` ); + if ( !declaration ) throw new Error( `'${importDeclaration.name}' is not exported by ${relativeId( otherModule.id )} (imported by ${relativeId( this.id )}). For help fixing this error see https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module` ); return declaration; } diff --git a/src/utils/relativeId.js b/src/utils/relativeId.js new file mode 100644 index 0000000..e26bd02 --- /dev/null +++ b/src/utils/relativeId.js @@ -0,0 +1,4 @@ +export default function relativeId ( id ) { + if ( typeof process === 'undefined' ) return id; + return id.replace( process.cwd(), '' ).replace( /^[\/\\]/, '' ); +} diff --git a/test/function/import-of-unexported-fails/_config.js b/test/function/import-of-unexported-fails/_config.js index 3027ba9..10d11a6 100644 --- a/test/function/import-of-unexported-fails/_config.js +++ b/test/function/import-of-unexported-fails/_config.js @@ -3,6 +3,6 @@ var assert = require( 'assert' ); module.exports = { description: 'marking an imported, but unexported, identifier should throw', error: function ( err ) { - assert.ok( /Module .+empty\.js does not export default \(imported by .+main\.js\)/.test( err.message ) ); + assert.equal( err.message, `'default' is not exported by empty.js (imported by main.js). For help fixing this error see https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module` ); } }; diff --git a/test/test.js b/test/test.js index 52cc00e..965cafd 100644 --- a/test/test.js +++ b/test/test.js @@ -186,6 +186,8 @@ describe( 'rollup', function () { const config = loadConfig( FUNCTION + '/' + dir + '/_config.js' ); ( config.skip ? it.skip : config.solo ? it.only : it )( dir, () => { + process.chdir( FUNCTION + '/' + dir ); + const warnings = []; const captureWarning = msg => warnings.push( msg ); From 9751849e7fac41ce0cb20ecb16ccb1a755882a98 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 12:23:58 -0400 Subject: [PATCH 296/331] beef up test --- test/form/custom-module-context/_config.js | 2 +- test/form/custom-module-context/_expected/amd.js | 2 ++ test/form/custom-module-context/_expected/cjs.js | 2 ++ test/form/custom-module-context/_expected/es.js | 2 ++ test/form/custom-module-context/_expected/iife.js | 2 ++ test/form/custom-module-context/_expected/umd.js | 2 ++ test/form/custom-module-context/foo.js | 1 + test/form/custom-module-context/main.js | 1 + 8 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 test/form/custom-module-context/foo.js diff --git a/test/form/custom-module-context/_config.js b/test/form/custom-module-context/_config.js index 3aa508d..f5d68d2 100644 --- a/test/form/custom-module-context/_config.js +++ b/test/form/custom-module-context/_config.js @@ -3,6 +3,6 @@ module.exports = { options: { moduleContext: { 'main.js': 'lolwut' - } + } } }; diff --git a/test/form/custom-module-context/_expected/amd.js b/test/form/custom-module-context/_expected/amd.js index a160d17..9274799 100644 --- a/test/form/custom-module-context/_expected/amd.js +++ b/test/form/custom-module-context/_expected/amd.js @@ -1,5 +1,7 @@ define(function () { 'use strict'; + undefined.prop = 'nope'; + lolwut.prop = '???'; }); diff --git a/test/form/custom-module-context/_expected/cjs.js b/test/form/custom-module-context/_expected/cjs.js index f42cf3c..35a5b08 100644 --- a/test/form/custom-module-context/_expected/cjs.js +++ b/test/form/custom-module-context/_expected/cjs.js @@ -1,3 +1,5 @@ 'use strict'; +undefined.prop = 'nope'; + lolwut.prop = '???'; diff --git a/test/form/custom-module-context/_expected/es.js b/test/form/custom-module-context/_expected/es.js index fa83c3d..a6903e0 100644 --- a/test/form/custom-module-context/_expected/es.js +++ b/test/form/custom-module-context/_expected/es.js @@ -1 +1,3 @@ +undefined.prop = 'nope'; + lolwut.prop = '???'; diff --git a/test/form/custom-module-context/_expected/iife.js b/test/form/custom-module-context/_expected/iife.js index a41619e..7926fe6 100644 --- a/test/form/custom-module-context/_expected/iife.js +++ b/test/form/custom-module-context/_expected/iife.js @@ -1,6 +1,8 @@ (function () { 'use strict'; + undefined.prop = 'nope'; + lolwut.prop = '???'; }()); diff --git a/test/form/custom-module-context/_expected/umd.js b/test/form/custom-module-context/_expected/umd.js index a73a22c..22fa605 100644 --- a/test/form/custom-module-context/_expected/umd.js +++ b/test/form/custom-module-context/_expected/umd.js @@ -4,6 +4,8 @@ (factory()); }(this, (function () { 'use strict'; + undefined.prop = 'nope'; + lolwut.prop = '???'; }))); diff --git a/test/form/custom-module-context/foo.js b/test/form/custom-module-context/foo.js new file mode 100644 index 0000000..a5a991d --- /dev/null +++ b/test/form/custom-module-context/foo.js @@ -0,0 +1 @@ +this.prop = 'nope'; diff --git a/test/form/custom-module-context/main.js b/test/form/custom-module-context/main.js index 169f08b..1323b68 100644 --- a/test/form/custom-module-context/main.js +++ b/test/form/custom-module-context/main.js @@ -1 +1,2 @@ +import './foo.js'; this.prop = '???'; From 559ef0f343ff9c8c1e8b86ad2779860d8262fd69 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 12:24:26 -0400 Subject: [PATCH 297/331] add test of function moduleContext option --- test/form/custom-module-context-function/_config.js | 8 ++++++++ .../custom-module-context-function/_expected/amd.js | 7 +++++++ .../custom-module-context-function/_expected/cjs.js | 5 +++++ .../custom-module-context-function/_expected/es.js | 3 +++ .../custom-module-context-function/_expected/iife.js | 8 ++++++++ .../custom-module-context-function/_expected/umd.js | 11 +++++++++++ test/form/custom-module-context-function/foo.js | 1 + test/form/custom-module-context-function/main.js | 2 ++ test/test.js | 2 ++ 9 files changed, 47 insertions(+) create mode 100644 test/form/custom-module-context-function/_config.js create mode 100644 test/form/custom-module-context-function/_expected/amd.js create mode 100644 test/form/custom-module-context-function/_expected/cjs.js create mode 100644 test/form/custom-module-context-function/_expected/es.js create mode 100644 test/form/custom-module-context-function/_expected/iife.js create mode 100644 test/form/custom-module-context-function/_expected/umd.js create mode 100644 test/form/custom-module-context-function/foo.js create mode 100644 test/form/custom-module-context-function/main.js diff --git a/test/form/custom-module-context-function/_config.js b/test/form/custom-module-context-function/_config.js new file mode 100644 index 0000000..c15118e --- /dev/null +++ b/test/form/custom-module-context-function/_config.js @@ -0,0 +1,8 @@ +module.exports = { + description: 'allows custom module-specific context with a function option', + options: { + moduleContext ( id ) { + return /main\.js$/.test( id ) ? 'lolwut' : 'undefined'; + } + } +}; diff --git a/test/form/custom-module-context-function/_expected/amd.js b/test/form/custom-module-context-function/_expected/amd.js new file mode 100644 index 0000000..9274799 --- /dev/null +++ b/test/form/custom-module-context-function/_expected/amd.js @@ -0,0 +1,7 @@ +define(function () { 'use strict'; + + undefined.prop = 'nope'; + + lolwut.prop = '???'; + +}); diff --git a/test/form/custom-module-context-function/_expected/cjs.js b/test/form/custom-module-context-function/_expected/cjs.js new file mode 100644 index 0000000..35a5b08 --- /dev/null +++ b/test/form/custom-module-context-function/_expected/cjs.js @@ -0,0 +1,5 @@ +'use strict'; + +undefined.prop = 'nope'; + +lolwut.prop = '???'; diff --git a/test/form/custom-module-context-function/_expected/es.js b/test/form/custom-module-context-function/_expected/es.js new file mode 100644 index 0000000..a6903e0 --- /dev/null +++ b/test/form/custom-module-context-function/_expected/es.js @@ -0,0 +1,3 @@ +undefined.prop = 'nope'; + +lolwut.prop = '???'; diff --git a/test/form/custom-module-context-function/_expected/iife.js b/test/form/custom-module-context-function/_expected/iife.js new file mode 100644 index 0000000..7926fe6 --- /dev/null +++ b/test/form/custom-module-context-function/_expected/iife.js @@ -0,0 +1,8 @@ +(function () { + 'use strict'; + + undefined.prop = 'nope'; + + lolwut.prop = '???'; + +}()); diff --git a/test/form/custom-module-context-function/_expected/umd.js b/test/form/custom-module-context-function/_expected/umd.js new file mode 100644 index 0000000..22fa605 --- /dev/null +++ b/test/form/custom-module-context-function/_expected/umd.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + undefined.prop = 'nope'; + + lolwut.prop = '???'; + +}))); diff --git a/test/form/custom-module-context-function/foo.js b/test/form/custom-module-context-function/foo.js new file mode 100644 index 0000000..a5a991d --- /dev/null +++ b/test/form/custom-module-context-function/foo.js @@ -0,0 +1 @@ +this.prop = 'nope'; diff --git a/test/form/custom-module-context-function/main.js b/test/form/custom-module-context-function/main.js new file mode 100644 index 0000000..1323b68 --- /dev/null +++ b/test/form/custom-module-context-function/main.js @@ -0,0 +1,2 @@ +import './foo.js'; +this.prop = '???'; diff --git a/test/test.js b/test/test.js index aa2bbbb..f6b36c6 100644 --- a/test/test.js +++ b/test/test.js @@ -316,6 +316,8 @@ describe( 'rollup', function () { PROFILES.forEach( profile => { it( 'generates ' + profile.format, () => { + process.chdir( FORM + '/' + dir ); + return createBundle().then( bundle => { const options = extend( {}, config.options, { dest: FORM + '/' + dir + '/_actual/' + profile.format + '.js', From 2929f1a771bf24fbcea3bccd89d4c084323cee2c Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 12:25:08 -0400 Subject: [PATCH 298/331] support function moduleContext option --- browser/path.js | 6 ------ src/Bundle.js | 35 ++++++++++----------------------- src/Module.js | 1 + src/ast/nodes/ThisExpression.js | 19 +----------------- src/utils/path.js | 2 +- 5 files changed, 13 insertions(+), 50 deletions(-) diff --git a/browser/path.js b/browser/path.js index 84efd9d..279ba66 100644 --- a/browser/path.js +++ b/browser/path.js @@ -78,9 +78,3 @@ export function resolve ( ...paths ) { return resolvedParts.join( '/' ); // TODO windows... } - -export function join ( ...parts ) { - const separator = '/'; - const replaceExp = new RegExp(separator+'{1,}', 'g'); - return parts.join(separator).replace(replaceExp, separator); -} diff --git a/src/Bundle.js b/src/Bundle.js index 7b06181..66deba6 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -72,32 +72,17 @@ export default class Bundle { this.externalModules = []; this.context = String( options.context ); - if (options.moduleContext) { - if (typeof options.moduleContext === 'object') { - const moduleContext = {}; - for (const key in options.moduleContext) { - let resolvedKey; - if (isAbsolute(key)) { - resolvedKey = normalize(key); - } else { - const useWorkingDir = key.substring(0, 2) === `./` ? true : false; - let absoluteKey; - if (useWorkingDir) { - absoluteKey = join(process.cwd(), key.substring(2)); - } else { - absoluteKey = join(dirname(options.entry), key); - } - - resolvedKey = normalize(absoluteKey); - } - - moduleContext[resolvedKey] = options.moduleContext[key]; - } - this.moduleContext = moduleContext; - } else { - throw new Error('options.moduleContext must be an object'); - } + if ( typeof options.moduleContext === 'function' ) { + this.getModuleContext = id => options.moduleContext( id ) || this.context; + } else if ( typeof options.moduleContext === 'object' ) { + const moduleContext = new Map(); + Object.keys( options.moduleContext ).forEach( key => { + moduleContext.set( resolve( key ), options.moduleContext[ key ] ); + }); + this.getModuleContext = id => moduleContext.get( id ) || this.context; + } else { + this.getModuleContext = () => this.context; } if ( typeof options.external === 'function' ) { diff --git a/src/Module.js b/src/Module.js index 3abdd4c..0cb02db 100644 --- a/src/Module.js +++ b/src/Module.js @@ -46,6 +46,7 @@ export default class Module { this.bundle = bundle; this.id = id; this.excludeFromSourcemap = /\0/.test( id ); + this.context = bundle.getModuleContext( id ); // all dependencies this.sources = []; diff --git a/src/ast/nodes/ThisExpression.js b/src/ast/nodes/ThisExpression.js index b6b8f68..5d295fe 100644 --- a/src/ast/nodes/ThisExpression.js +++ b/src/ast/nodes/ThisExpression.js @@ -1,29 +1,12 @@ import Node from '../Node.js'; import {normalize} from '../../utils/path'; -function getContext (module) { - let context = module.bundle.context; - const moduleContext = module.bundle.moduleContext; - if (moduleContext) { - const moduleId = normalize(module.id); - const candidates = Object.keys(moduleContext) - .map(relPath => moduleId.indexOf(relPath) >= 0 ? moduleContext[relPath] : undefined) - .filter(context => !!context); - - if (candidates.length) { - context = String( candidates[candidates.length - 1] ); - } - } - - return context; -} - export default class ThisExpression extends Node { initialise ( scope ) { const lexicalBoundary = scope.findLexicalBoundary(); if ( lexicalBoundary.isModuleScope ) { - this.alias = getContext(this.module); + this.alias = this.module.context; if ( this.alias === 'undefined' ) { this.module.bundle.onwarn( 'The `this` keyword is equivalent to `undefined` at the top level of an ES module, and has been rewritten' ); } diff --git a/src/utils/path.js b/src/utils/path.js index 1f8af19..d2ce64d 100644 --- a/src/utils/path.js +++ b/src/utils/path.js @@ -13,4 +13,4 @@ export function normalize ( path ) { return path.replace( /\\/g, '/' ); } -export { basename, dirname, extname, relative, resolve, join} from 'path'; +export { basename, dirname, extname, relative, resolve } from 'path'; From be952fef124613ae484d654f7ac41c3ed22510b5 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 14:12:05 -0400 Subject: [PATCH 299/331] automatic semicolon insertion (fixes #1004, #1009). fight me --- src/ast/Node.js | 6 ++++++ src/ast/nodes/ExpressionStatement.js | 5 ++++- src/ast/nodes/VariableDeclaration.js | 15 +++++++++++---- .../adds-semicolons-if-necessary-b/_config.js | 3 +++ .../adds-semicolons-if-necessary-b/foo.js | 1 + .../adds-semicolons-if-necessary-b/main.js | 3 +++ .../adds-semicolons-if-necessary/_config.js | 3 +++ test/function/adds-semicolons-if-necessary/foo.js | 3 +++ .../function/adds-semicolons-if-necessary/main.js | 7 +++++++ 9 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 test/function/adds-semicolons-if-necessary-b/_config.js create mode 100644 test/function/adds-semicolons-if-necessary-b/foo.js create mode 100644 test/function/adds-semicolons-if-necessary-b/main.js create mode 100644 test/function/adds-semicolons-if-necessary/_config.js create mode 100644 test/function/adds-semicolons-if-necessary/foo.js create mode 100644 test/function/adds-semicolons-if-necessary/main.js diff --git a/src/ast/Node.js b/src/ast/Node.js index 4f65871..6a80ede 100644 --- a/src/ast/Node.js +++ b/src/ast/Node.js @@ -66,6 +66,12 @@ export default class Node { this.eachChild( child => child.initialise( this.scope || scope ) ); } + insertSemicolon ( code ) { + if ( code.original[ this.end - 1 ] !== ';' ) { + code.insertLeft( this.end, ';' ); + } + } + locate () { // useful for debugging const location = getLocation( this.module.code, this.start ); diff --git a/src/ast/nodes/ExpressionStatement.js b/src/ast/nodes/ExpressionStatement.js index 237441a..7198541 100644 --- a/src/ast/nodes/ExpressionStatement.js +++ b/src/ast/nodes/ExpressionStatement.js @@ -1,5 +1,8 @@ import Statement from './shared/Statement.js'; export default class ExpressionStatement extends Statement { - + render ( code, es ) { + super.render( code, es ); + if ( this.shouldInclude ) this.insertSemicolon( code ); + } } diff --git a/src/ast/nodes/VariableDeclaration.js b/src/ast/nodes/VariableDeclaration.js index e1be1a0..77f4433 100644 --- a/src/ast/nodes/VariableDeclaration.js +++ b/src/ast/nodes/VariableDeclaration.js @@ -14,7 +14,7 @@ function getSeparator ( code, start ) { return `;\n${lineStart}`; } -const forStatement = /^For(?:Of|In)Statement/; +const forStatement = /^For(?:Of|In)?Statement/; export default class VariableDeclaration extends Node { initialise ( scope ) { @@ -92,9 +92,16 @@ export default class VariableDeclaration extends Node { if ( treeshake && empty ) { code.remove( this.leadingCommentStart || this.start, this.next || this.end ); - } else if ( this.end > c ) { - const hasSemicolon = code.original[ this.end - 1 ] === ';'; - code.overwrite( c, this.end, hasSemicolon ? ';' : '' ); + } else { + // always include a semi-colon (https://github.com/rollup/rollup/pull/1013), + // unless it's a var declaration in a loop head + const needsSemicolon = !forStatement.test( this.parent.type ); + + if ( this.end > c ) { + code.overwrite( c, this.end, needsSemicolon ? ';' : '' ); + } else if ( needsSemicolon ) { + this.insertSemicolon( code ); + } } } } diff --git a/test/function/adds-semicolons-if-necessary-b/_config.js b/test/function/adds-semicolons-if-necessary-b/_config.js new file mode 100644 index 0000000..bb17123 --- /dev/null +++ b/test/function/adds-semicolons-if-necessary-b/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'adds semi-colons if necessary' +}; diff --git a/test/function/adds-semicolons-if-necessary-b/foo.js b/test/function/adds-semicolons-if-necessary-b/foo.js new file mode 100644 index 0000000..b2602d2 --- /dev/null +++ b/test/function/adds-semicolons-if-necessary-b/foo.js @@ -0,0 +1 @@ +assert.ok( true ) diff --git a/test/function/adds-semicolons-if-necessary-b/main.js b/test/function/adds-semicolons-if-necessary-b/main.js new file mode 100644 index 0000000..c6ddba4 --- /dev/null +++ b/test/function/adds-semicolons-if-necessary-b/main.js @@ -0,0 +1,3 @@ +import './foo.js'; + +(function bar() {})(); diff --git a/test/function/adds-semicolons-if-necessary/_config.js b/test/function/adds-semicolons-if-necessary/_config.js new file mode 100644 index 0000000..bb17123 --- /dev/null +++ b/test/function/adds-semicolons-if-necessary/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'adds semi-colons if necessary' +}; diff --git a/test/function/adds-semicolons-if-necessary/foo.js b/test/function/adds-semicolons-if-necessary/foo.js new file mode 100644 index 0000000..14d0105 --- /dev/null +++ b/test/function/adds-semicolons-if-necessary/foo.js @@ -0,0 +1,3 @@ +export var foo = function () { + return 42; +} diff --git a/test/function/adds-semicolons-if-necessary/main.js b/test/function/adds-semicolons-if-necessary/main.js new file mode 100644 index 0000000..2a031e5 --- /dev/null +++ b/test/function/adds-semicolons-if-necessary/main.js @@ -0,0 +1,7 @@ +import { foo } from './foo.js'; + +(function bar() { + assert.ok( true ); +})(); + +assert.equal( foo(), 42 ); From e8858ef1371c6bf9e7a50d7dfb9ed090d751c9a5 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 14:15:06 -0400 Subject: [PATCH 300/331] update tests --- .../assignment-to-exports-class-declaration/_expected/amd.js | 2 +- .../assignment-to-exports-class-declaration/_expected/cjs.js | 2 +- .../assignment-to-exports-class-declaration/_expected/es.js | 2 +- .../assignment-to-exports-class-declaration/_expected/iife.js | 2 +- .../assignment-to-exports-class-declaration/_expected/umd.js | 2 +- test/form/side-effect-m/_expected/amd.js | 2 +- test/form/side-effect-m/_expected/cjs.js | 2 +- test/form/side-effect-m/_expected/es.js | 2 +- test/form/side-effect-m/_expected/iife.js | 2 +- test/form/side-effect-m/_expected/umd.js | 2 +- test/form/side-effect-p/_expected/amd.js | 4 ++-- test/form/side-effect-p/_expected/cjs.js | 4 ++-- test/form/side-effect-p/_expected/es.js | 4 ++-- test/form/side-effect-p/_expected/iife.js | 4 ++-- test/form/side-effect-p/_expected/umd.js | 4 ++-- test/form/this-is-undefined/_expected/amd.js | 2 +- test/form/this-is-undefined/_expected/cjs.js | 2 +- test/form/this-is-undefined/_expected/es.js | 2 +- test/form/this-is-undefined/_expected/iife.js | 2 +- test/form/this-is-undefined/_expected/umd.js | 2 +- 20 files changed, 25 insertions(+), 25 deletions(-) diff --git a/test/form/assignment-to-exports-class-declaration/_expected/amd.js b/test/form/assignment-to-exports-class-declaration/_expected/amd.js index bdbdbe5..b6e6ac9 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/amd.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/amd.js @@ -1,6 +1,6 @@ define(['exports'], function (exports) { 'use strict'; - exports.Foo = class Foo {} + exports.Foo = class Foo {}; exports.Foo = lol( exports.Foo ); Object.defineProperty(exports, '__esModule', { value: true }); diff --git a/test/form/assignment-to-exports-class-declaration/_expected/cjs.js b/test/form/assignment-to-exports-class-declaration/_expected/cjs.js index 03bdfb8..d291984 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/cjs.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/cjs.js @@ -2,5 +2,5 @@ Object.defineProperty(exports, '__esModule', { value: true }); -exports.Foo = class Foo {} +exports.Foo = class Foo {}; exports.Foo = lol( exports.Foo ); diff --git a/test/form/assignment-to-exports-class-declaration/_expected/es.js b/test/form/assignment-to-exports-class-declaration/_expected/es.js index 2631630..d4297e6 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/es.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/es.js @@ -1,4 +1,4 @@ -let Foo = class Foo {} +let Foo = class Foo {}; Foo = lol( Foo ); export { Foo }; diff --git a/test/form/assignment-to-exports-class-declaration/_expected/iife.js b/test/form/assignment-to-exports-class-declaration/_expected/iife.js index fa37538..09261c7 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/iife.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/iife.js @@ -1,7 +1,7 @@ (function (exports) { 'use strict'; - exports.Foo = class Foo {} + exports.Foo = class Foo {}; exports.Foo = lol( exports.Foo ); }((this.myModule = this.myModule || {}))); diff --git a/test/form/assignment-to-exports-class-declaration/_expected/umd.js b/test/form/assignment-to-exports-class-declaration/_expected/umd.js index 6de079e..33b2140 100644 --- a/test/form/assignment-to-exports-class-declaration/_expected/umd.js +++ b/test/form/assignment-to-exports-class-declaration/_expected/umd.js @@ -4,7 +4,7 @@ (factory((global.myModule = global.myModule || {}))); }(this, (function (exports) { 'use strict'; - exports.Foo = class Foo {} + exports.Foo = class Foo {}; exports.Foo = lol( exports.Foo ); Object.defineProperty(exports, '__esModule', { value: true }); diff --git a/test/form/side-effect-m/_expected/amd.js b/test/form/side-effect-m/_expected/amd.js index 8c7787a..af4a5b5 100644 --- a/test/form/side-effect-m/_expected/amd.js +++ b/test/form/side-effect-m/_expected/amd.js @@ -10,7 +10,7 @@ define(function () { 'use strict'; var foo = odd( 12 ); function even ( n ) { - alert( counter++ ) + alert( counter++ ); return n === 0 || odd( n - 1 ); } diff --git a/test/form/side-effect-m/_expected/cjs.js b/test/form/side-effect-m/_expected/cjs.js index 43eacf4..1e7377f 100644 --- a/test/form/side-effect-m/_expected/cjs.js +++ b/test/form/side-effect-m/_expected/cjs.js @@ -10,7 +10,7 @@ var counter = 0; var foo = odd( 12 ); function even ( n ) { - alert( counter++ ) + alert( counter++ ); return n === 0 || odd( n - 1 ); } diff --git a/test/form/side-effect-m/_expected/es.js b/test/form/side-effect-m/_expected/es.js index 61bbbbf..d4df0da 100644 --- a/test/form/side-effect-m/_expected/es.js +++ b/test/form/side-effect-m/_expected/es.js @@ -8,7 +8,7 @@ var counter = 0; var foo = odd( 12 ); function even ( n ) { - alert( counter++ ) + alert( counter++ ); return n === 0 || odd( n - 1 ); } diff --git a/test/form/side-effect-m/_expected/iife.js b/test/form/side-effect-m/_expected/iife.js index d4be68e..0d378a8 100644 --- a/test/form/side-effect-m/_expected/iife.js +++ b/test/form/side-effect-m/_expected/iife.js @@ -11,7 +11,7 @@ var foo = odd( 12 ); function even ( n ) { - alert( counter++ ) + alert( counter++ ); return n === 0 || odd( n - 1 ); } diff --git a/test/form/side-effect-m/_expected/umd.js b/test/form/side-effect-m/_expected/umd.js index b0419fe..38f9417 100644 --- a/test/form/side-effect-m/_expected/umd.js +++ b/test/form/side-effect-m/_expected/umd.js @@ -14,7 +14,7 @@ var foo = odd( 12 ); function even ( n ) { - alert( counter++ ) + alert( counter++ ); return n === 0 || odd( n - 1 ); } diff --git a/test/form/side-effect-p/_expected/amd.js b/test/form/side-effect-p/_expected/amd.js index 35e8591..7a76cb7 100644 --- a/test/form/side-effect-p/_expected/amd.js +++ b/test/form/side-effect-p/_expected/amd.js @@ -5,7 +5,7 @@ define(function () { 'use strict'; const hs = document.documentElement.style; if ( bool ) { - hs.color = "#222" + hs.color = "#222"; } -}); \ No newline at end of file +}); diff --git a/test/form/side-effect-p/_expected/cjs.js b/test/form/side-effect-p/_expected/cjs.js index 08dc383..9553e7d 100644 --- a/test/form/side-effect-p/_expected/cjs.js +++ b/test/form/side-effect-p/_expected/cjs.js @@ -5,5 +5,5 @@ var bool = true; const hs = document.documentElement.style; if ( bool ) { - hs.color = "#222" -} \ No newline at end of file + hs.color = "#222"; +} diff --git a/test/form/side-effect-p/_expected/es.js b/test/form/side-effect-p/_expected/es.js index 8e80199..c6eddb2 100644 --- a/test/form/side-effect-p/_expected/es.js +++ b/test/form/side-effect-p/_expected/es.js @@ -3,5 +3,5 @@ var bool = true; const hs = document.documentElement.style; if ( bool ) { - hs.color = "#222" -} \ No newline at end of file + hs.color = "#222"; +} diff --git a/test/form/side-effect-p/_expected/iife.js b/test/form/side-effect-p/_expected/iife.js index 4ea2e35..7ab23ea 100644 --- a/test/form/side-effect-p/_expected/iife.js +++ b/test/form/side-effect-p/_expected/iife.js @@ -6,7 +6,7 @@ const hs = document.documentElement.style; if ( bool ) { - hs.color = "#222" + hs.color = "#222"; } -}()); \ No newline at end of file +}()); diff --git a/test/form/side-effect-p/_expected/umd.js b/test/form/side-effect-p/_expected/umd.js index f99ce83..57553d3 100644 --- a/test/form/side-effect-p/_expected/umd.js +++ b/test/form/side-effect-p/_expected/umd.js @@ -9,7 +9,7 @@ const hs = document.documentElement.style; if ( bool ) { - hs.color = "#222" + hs.color = "#222"; } -}))); \ No newline at end of file +}))); diff --git a/test/form/this-is-undefined/_expected/amd.js b/test/form/this-is-undefined/_expected/amd.js index 4452e03..c90e975 100644 --- a/test/form/this-is-undefined/_expected/amd.js +++ b/test/form/this-is-undefined/_expected/amd.js @@ -10,7 +10,7 @@ define(function () { 'use strict'; const bar = () => { // ...unless it's an arrow function assert.strictEqual( undefined, undefined ); - } + }; foo.call( fooContext ); bar.call( {} ); diff --git a/test/form/this-is-undefined/_expected/cjs.js b/test/form/this-is-undefined/_expected/cjs.js index bfa1110..c99ffc5 100644 --- a/test/form/this-is-undefined/_expected/cjs.js +++ b/test/form/this-is-undefined/_expected/cjs.js @@ -10,7 +10,7 @@ function foo () { const bar = () => { // ...unless it's an arrow function assert.strictEqual( undefined, undefined ); -} +}; foo.call( fooContext ); bar.call( {} ); diff --git a/test/form/this-is-undefined/_expected/es.js b/test/form/this-is-undefined/_expected/es.js index f5bd3ba..686db33 100644 --- a/test/form/this-is-undefined/_expected/es.js +++ b/test/form/this-is-undefined/_expected/es.js @@ -8,7 +8,7 @@ function foo () { const bar = () => { // ...unless it's an arrow function assert.strictEqual( undefined, undefined ); -} +}; foo.call( fooContext ); bar.call( {} ); diff --git a/test/form/this-is-undefined/_expected/iife.js b/test/form/this-is-undefined/_expected/iife.js index 890862c..f82edce 100644 --- a/test/form/this-is-undefined/_expected/iife.js +++ b/test/form/this-is-undefined/_expected/iife.js @@ -11,7 +11,7 @@ const bar = () => { // ...unless it's an arrow function assert.strictEqual( undefined, undefined ); - } + }; foo.call( fooContext ); bar.call( {} ); diff --git a/test/form/this-is-undefined/_expected/umd.js b/test/form/this-is-undefined/_expected/umd.js index b7f3efa..996e798 100644 --- a/test/form/this-is-undefined/_expected/umd.js +++ b/test/form/this-is-undefined/_expected/umd.js @@ -14,7 +14,7 @@ const bar = () => { // ...unless it's an arrow function assert.strictEqual( undefined, undefined ); - } + }; foo.call( fooContext ); bar.call( {} ); From 70c38bfaffabbcde550585fa6b35972beec3fcc3 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 14:20:54 -0400 Subject: [PATCH 301/331] linting --- src/Bundle.js | 2 +- src/ast/nodes/ThisExpression.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 66deba6..7aeeec8 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -17,7 +17,7 @@ import transformBundle from './utils/transformBundle.js'; import collapseSourcemaps from './utils/collapseSourcemaps.js'; import SOURCEMAPPING_URL from './utils/sourceMappingURL.js'; import callIfFunction from './utils/callIfFunction.js'; -import { dirname, isRelative, isAbsolute, normalize, relative, resolve, join } from './utils/path.js'; +import { dirname, isRelative, isAbsolute, normalize, relative, resolve } from './utils/path.js'; import BundleScope from './ast/scopes/BundleScope.js'; export default class Bundle { diff --git a/src/ast/nodes/ThisExpression.js b/src/ast/nodes/ThisExpression.js index 5d295fe..7cb1de6 100644 --- a/src/ast/nodes/ThisExpression.js +++ b/src/ast/nodes/ThisExpression.js @@ -1,5 +1,4 @@ import Node from '../Node.js'; -import {normalize} from '../../utils/path'; export default class ThisExpression extends Node { initialise ( scope ) { From 40643bf543f3df399619c3b81c3aff0c7be3e657 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 14:26:58 -0400 Subject: [PATCH 302/331] include default exports in ASI --- src/ast/nodes/ExportDefaultDeclaration.js | 2 ++ .../removes-existing-sourcemap-comments/_expected/amd.js | 2 +- .../removes-existing-sourcemap-comments/_expected/cjs.js | 2 +- .../removes-existing-sourcemap-comments/_expected/es.js | 2 +- .../removes-existing-sourcemap-comments/_expected/iife.js | 2 +- .../removes-existing-sourcemap-comments/_expected/umd.js | 2 +- test/function/adds-semicolons-if-necessary-c/_config.js | 3 +++ test/function/adds-semicolons-if-necessary-c/foo.js | 3 +++ test/function/adds-semicolons-if-necessary-c/main.js | 7 +++++++ 9 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 test/function/adds-semicolons-if-necessary-c/_config.js create mode 100644 test/function/adds-semicolons-if-necessary-c/foo.js create mode 100644 test/function/adds-semicolons-if-necessary-c/main.js diff --git a/src/ast/nodes/ExportDefaultDeclaration.js b/src/ast/nodes/ExportDefaultDeclaration.js index ab4a776..81ae1c9 100644 --- a/src/ast/nodes/ExportDefaultDeclaration.js +++ b/src/ast/nodes/ExportDefaultDeclaration.js @@ -67,6 +67,8 @@ export default class ExportDefaultDeclaration extends Node { } else { code.overwrite( this.start, this.declaration.start, `${this.module.bundle.varOrConst} ${name} = ` ); } + + this.insertSemicolon( code ); } } else { // remove `var foo` from `var foo = bar()`, if `foo` is unused diff --git a/test/form/removes-existing-sourcemap-comments/_expected/amd.js b/test/form/removes-existing-sourcemap-comments/_expected/amd.js index 99bdf35..b89e399 100644 --- a/test/form/removes-existing-sourcemap-comments/_expected/amd.js +++ b/test/form/removes-existing-sourcemap-comments/_expected/amd.js @@ -2,7 +2,7 @@ define(function () { 'use strict'; var foo = function () { return 42; - } + }; console.log( foo() ); diff --git a/test/form/removes-existing-sourcemap-comments/_expected/cjs.js b/test/form/removes-existing-sourcemap-comments/_expected/cjs.js index 8735c93..1152d76 100644 --- a/test/form/removes-existing-sourcemap-comments/_expected/cjs.js +++ b/test/form/removes-existing-sourcemap-comments/_expected/cjs.js @@ -2,6 +2,6 @@ var foo = function () { return 42; -} +}; console.log( foo() ); diff --git a/test/form/removes-existing-sourcemap-comments/_expected/es.js b/test/form/removes-existing-sourcemap-comments/_expected/es.js index 2a09cfb..0ef1000 100644 --- a/test/form/removes-existing-sourcemap-comments/_expected/es.js +++ b/test/form/removes-existing-sourcemap-comments/_expected/es.js @@ -1,5 +1,5 @@ var foo = function () { return 42; -} +}; console.log( foo() ); diff --git a/test/form/removes-existing-sourcemap-comments/_expected/iife.js b/test/form/removes-existing-sourcemap-comments/_expected/iife.js index 6381613..cac12fb 100644 --- a/test/form/removes-existing-sourcemap-comments/_expected/iife.js +++ b/test/form/removes-existing-sourcemap-comments/_expected/iife.js @@ -3,7 +3,7 @@ var foo = function () { return 42; - } + }; console.log( foo() ); diff --git a/test/form/removes-existing-sourcemap-comments/_expected/umd.js b/test/form/removes-existing-sourcemap-comments/_expected/umd.js index b291566..9a6706d 100644 --- a/test/form/removes-existing-sourcemap-comments/_expected/umd.js +++ b/test/form/removes-existing-sourcemap-comments/_expected/umd.js @@ -6,7 +6,7 @@ var foo = function () { return 42; - } + }; console.log( foo() ); diff --git a/test/function/adds-semicolons-if-necessary-c/_config.js b/test/function/adds-semicolons-if-necessary-c/_config.js new file mode 100644 index 0000000..bb17123 --- /dev/null +++ b/test/function/adds-semicolons-if-necessary-c/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'adds semi-colons if necessary' +}; diff --git a/test/function/adds-semicolons-if-necessary-c/foo.js b/test/function/adds-semicolons-if-necessary-c/foo.js new file mode 100644 index 0000000..7dc8833 --- /dev/null +++ b/test/function/adds-semicolons-if-necessary-c/foo.js @@ -0,0 +1,3 @@ +export default function () { + return 42; +} diff --git a/test/function/adds-semicolons-if-necessary-c/main.js b/test/function/adds-semicolons-if-necessary-c/main.js new file mode 100644 index 0000000..ae0bdb2 --- /dev/null +++ b/test/function/adds-semicolons-if-necessary-c/main.js @@ -0,0 +1,7 @@ +import foo from './foo.js'; + +(function bar() { + assert.ok( true ); +})(); + +assert.equal( foo(), 42 ); From 40400224431729bec1970a32c0b78bb694094ccf Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 15:08:49 -0400 Subject: [PATCH 303/331] tweak message --- src/ast/nodes/ThisExpression.js | 8 +++++--- test/function/warn-on-top-level-this/_config.js | 9 ++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ast/nodes/ThisExpression.js b/src/ast/nodes/ThisExpression.js index 65bb5b4..16aed87 100644 --- a/src/ast/nodes/ThisExpression.js +++ b/src/ast/nodes/ThisExpression.js @@ -1,6 +1,8 @@ import Node from '../Node.js'; import getLocation from '../../utils/getLocation.js'; +const warning = `The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten. See https://github.com/rollup/rollup/wiki/Troubleshooting#this-is-undefined for more information`; + export default class ThisExpression extends Node { initialise ( scope ) { const lexicalBoundary = scope.findLexicalBoundary(); @@ -8,9 +10,9 @@ export default class ThisExpression extends Node { if ( lexicalBoundary.isModuleScope ) { this.alias = this.module.context; if ( this.alias === 'undefined' ) { - const location = getLocation(this.module.code, this.module.ast.end); - const detail = `${this.module.id}, line: ${location.line}, column: ${location.column}`; - this.module.bundle.onwarn( `The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten (in ${detail})`); + const { line, column } = getLocation( this.module.code, this.start ); + const detail = `${this.module.id} (${line}:${column + 1})`; // use one-based column number convention + this.module.bundle.onwarn( `${detail} ${warning}` ); } } } diff --git a/test/function/warn-on-top-level-this/_config.js b/test/function/warn-on-top-level-this/_config.js index 53fe344..9976ec1 100644 --- a/test/function/warn-on-top-level-this/_config.js +++ b/test/function/warn-on-top-level-this/_config.js @@ -1,13 +1,12 @@ const assert = require( 'assert' ); module.exports = { + solo: true, description: 'warns on top-level this (#770)', warnings: warnings => { - const message = `The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten`; - assert.equal(warnings.length, 1); - assert.equal(warnings[0].indexOf(message), 0); - assert(warnings[0].match(/\(in.*warn-on-top-level-this.*\)/)); - assert(warnings[0].match(/line: 4, column: 0/)); + assert.deepEqual( warnings, [ + `main.js (3:1) The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten. See https://github.com/rollup/rollup/wiki/Troubleshooting#this-is-undefined for more information` + ]); }, runtimeError: err => { assert.equal( err.message, `Cannot set property 'foo' of undefined` ); From 4eae8da80d89d3f33833daeefe19b9c346c98e62 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 15:13:07 -0400 Subject: [PATCH 304/331] use relative ID for more readable message --- src/ast/nodes/ThisExpression.js | 3 ++- test/function/warn-on-top-level-this/_config.js | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/nodes/ThisExpression.js b/src/ast/nodes/ThisExpression.js index 16aed87..ae35173 100644 --- a/src/ast/nodes/ThisExpression.js +++ b/src/ast/nodes/ThisExpression.js @@ -1,5 +1,6 @@ import Node from '../Node.js'; import getLocation from '../../utils/getLocation.js'; +import relativeId from '../../utils/relativeId.js'; const warning = `The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten. See https://github.com/rollup/rollup/wiki/Troubleshooting#this-is-undefined for more information`; @@ -11,7 +12,7 @@ export default class ThisExpression extends Node { this.alias = this.module.context; if ( this.alias === 'undefined' ) { const { line, column } = getLocation( this.module.code, this.start ); - const detail = `${this.module.id} (${line}:${column + 1})`; // use one-based column number convention + const detail = `${relativeId( this.module.id )} (${line}:${column + 1})`; // use one-based column number convention this.module.bundle.onwarn( `${detail} ${warning}` ); } } diff --git a/test/function/warn-on-top-level-this/_config.js b/test/function/warn-on-top-level-this/_config.js index 9976ec1..99c3f2c 100644 --- a/test/function/warn-on-top-level-this/_config.js +++ b/test/function/warn-on-top-level-this/_config.js @@ -1,7 +1,6 @@ const assert = require( 'assert' ); module.exports = { - solo: true, description: 'warns on top-level this (#770)', warnings: warnings => { assert.deepEqual( warnings, [ From 49149f9be570e99640784388377dba34c3558a41 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 15:19:39 -0400 Subject: [PATCH 305/331] -> v0.36.2 --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8bb569..9313c38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # rollup changelog +## 0.36.2 + +* Insert semicolons where necessary to fix broken code ([#1004](https://github.com/rollup/rollup/issues/1004)) +* Include module ID and location when warning about top-level `this` ([#1012](https://github.com/rollup/rollup/pull/1012)) +* More informative error for missing exports ([#1033](https://github.com/rollup/rollup/issues/1033)) +* `options.moduleContext` for per-module context overrides ([#1023](https://github.com/rollup/rollup/pull/1023)) + ## 0.36.1 * Include naked block statements ([#981](https://github.com/rollup/rollup/issues/981)) diff --git a/package.json b/package.json index 844253f..642f25f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.36.1", + "version": "0.36.2", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From a1666103b14867c3b5b45e17ccb64067406fe225 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 15:59:19 -0400 Subject: [PATCH 306/331] put Object.freeze fallback behind legacy option --- src/Bundle.js | 3 ++- src/Declaration.js | 5 +++-- src/Module.js | 4 ++-- src/rollup.js | 1 + test/form/legacy/_config.js | 6 ++++++ test/form/legacy/_expected/amd.js | 13 +++++++++++++ test/form/legacy/_expected/cjs.js | 11 +++++++++++ test/form/legacy/_expected/es.js | 9 +++++++++ test/form/legacy/_expected/iife.js | 14 ++++++++++++++ test/form/legacy/_expected/umd.js | 17 +++++++++++++++++ test/form/legacy/main.js | 4 ++++ test/form/legacy/namespace.js | 1 + test/form/prefer-const/_expected/amd.js | 2 +- test/form/prefer-const/_expected/cjs.js | 2 +- test/form/prefer-const/_expected/es.js | 2 +- test/form/prefer-const/_expected/iife.js | 2 +- test/form/prefer-const/_expected/umd.js | 2 +- test/test.js | 2 +- 18 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 test/form/legacy/_config.js create mode 100644 test/form/legacy/_expected/amd.js create mode 100644 test/form/legacy/_expected/cjs.js create mode 100644 test/form/legacy/_expected/es.js create mode 100644 test/form/legacy/_expected/iife.js create mode 100644 test/form/legacy/_expected/umd.js create mode 100644 test/form/legacy/main.js create mode 100644 test/form/legacy/namespace.js diff --git a/src/Bundle.js b/src/Bundle.js index 7aeeec8..f1643f2 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -95,6 +95,7 @@ export default class Bundle { this.onwarn = options.onwarn || makeOnwarn(); this.varOrConst = options.preferConst ? 'const' : 'var'; + this.legacy = options.legacy; this.acornOptions = options.acorn || {}; this.dependentExpressions = []; @@ -370,7 +371,7 @@ export default class Bundle { timeStart( 'render modules' ); this.orderedModules.forEach( module => { - const source = module.render( format === 'es' ); + const source = module.render( format === 'es', this.legacy ); if ( source.toString().length ) { magicString.addSource( source ); diff --git a/src/Declaration.js b/src/Declaration.js index 2e75793..b550cec 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -75,7 +75,7 @@ export class SyntheticNamespaceDeclaration { return this.name; } - renderBlock ( es, indentString ) { + renderBlock ( es, legacy, indentString ) { const members = keys( this.originals ).map( name => { const original = this.originals[ name ]; @@ -86,7 +86,8 @@ export class SyntheticNamespaceDeclaration { return `${indentString}${name}: ${original.getName( es )}`; }); - return `${this.module.bundle.varOrConst} ${this.getName( es )} = (Object.freeze || Object)({\n${members.join( ',\n' )}\n});\n\n`; + const callee = legacy ? `(Object.freeze || Object)` : `Object.freeze`; + return `${this.module.bundle.varOrConst} ${this.getName( es )} = ${callee}({\n${members.join( ',\n' )}\n});\n\n`; } } diff --git a/src/Module.js b/src/Module.js index 83fbba9..81a097c 100644 --- a/src/Module.js +++ b/src/Module.js @@ -309,7 +309,7 @@ export default class Module { return this.declarations['*']; } - render ( es ) { + render ( es, legacy ) { const magicString = this.magicString.clone(); for ( const node of this.ast.body ) { @@ -317,7 +317,7 @@ export default class Module { } if ( this.namespace().needsNamespaceBlock ) { - magicString.append( '\n\n' + this.namespace().renderBlock( es, '\t' ) ); // TODO use correct indentation + magicString.append( '\n\n' + this.namespace().renderBlock( es, legacy, '\t' ) ); // TODO use correct indentation } return magicString.trim(); diff --git a/src/rollup.js b/src/rollup.js index f99e991..cf79500 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -24,6 +24,7 @@ const ALLOWED_KEYS = [ 'indent', 'interop', 'intro', + 'legacy', 'moduleContext', 'moduleId', 'moduleName', diff --git a/test/form/legacy/_config.js b/test/form/legacy/_config.js new file mode 100644 index 0000000..2bdf641 --- /dev/null +++ b/test/form/legacy/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'supports environments without Object.freeze', + options: { + legacy: true + } +}; diff --git a/test/form/legacy/_expected/amd.js b/test/form/legacy/_expected/amd.js new file mode 100644 index 0000000..3ba37d0 --- /dev/null +++ b/test/form/legacy/_expected/amd.js @@ -0,0 +1,13 @@ +define(function () { 'use strict'; + + const foo = 42; + + + var namespace = (Object.freeze || Object)({ + foo: foo + }); + + const x = 'foo'; + assert.equal( namespace[x], 42 ); + +}); diff --git a/test/form/legacy/_expected/cjs.js b/test/form/legacy/_expected/cjs.js new file mode 100644 index 0000000..33c3402 --- /dev/null +++ b/test/form/legacy/_expected/cjs.js @@ -0,0 +1,11 @@ +'use strict'; + +const foo = 42; + + +var namespace = (Object.freeze || Object)({ + foo: foo +}); + +const x = 'foo'; +assert.equal( namespace[x], 42 ); diff --git a/test/form/legacy/_expected/es.js b/test/form/legacy/_expected/es.js new file mode 100644 index 0000000..be10260 --- /dev/null +++ b/test/form/legacy/_expected/es.js @@ -0,0 +1,9 @@ +const foo = 42; + + +var namespace = (Object.freeze || Object)({ + foo: foo +}); + +const x = 'foo'; +assert.equal( namespace[x], 42 ); diff --git a/test/form/legacy/_expected/iife.js b/test/form/legacy/_expected/iife.js new file mode 100644 index 0000000..095ddd0 --- /dev/null +++ b/test/form/legacy/_expected/iife.js @@ -0,0 +1,14 @@ +(function () { + 'use strict'; + + const foo = 42; + + + var namespace = (Object.freeze || Object)({ + foo: foo + }); + + const x = 'foo'; + assert.equal( namespace[x], 42 ); + +}()); diff --git a/test/form/legacy/_expected/umd.js b/test/form/legacy/_expected/umd.js new file mode 100644 index 0000000..f3d0fa9 --- /dev/null +++ b/test/form/legacy/_expected/umd.js @@ -0,0 +1,17 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + const foo = 42; + + + var namespace = (Object.freeze || Object)({ + foo: foo + }); + + const x = 'foo'; + assert.equal( namespace[x], 42 ); + +}))); diff --git a/test/form/legacy/main.js b/test/form/legacy/main.js new file mode 100644 index 0000000..321f9b3 --- /dev/null +++ b/test/form/legacy/main.js @@ -0,0 +1,4 @@ +import * as namespace from './namespace.js'; + +const x = 'foo'; +assert.equal( namespace[x], 42 ); diff --git a/test/form/legacy/namespace.js b/test/form/legacy/namespace.js new file mode 100644 index 0000000..9d7381d --- /dev/null +++ b/test/form/legacy/namespace.js @@ -0,0 +1 @@ +export const foo = 42; diff --git a/test/form/prefer-const/_expected/amd.js b/test/form/prefer-const/_expected/amd.js index 2e0b570..a89dacd 100644 --- a/test/form/prefer-const/_expected/amd.js +++ b/test/form/prefer-const/_expected/amd.js @@ -4,7 +4,7 @@ define(['external', 'other', 'another'], function (external, other, another) { ' const b = 2; - const namespace = (Object.freeze || Object)({ + const namespace = Object.freeze({ a: a, b: b }); diff --git a/test/form/prefer-const/_expected/cjs.js b/test/form/prefer-const/_expected/cjs.js index 692b290..5c2e4da 100644 --- a/test/form/prefer-const/_expected/cjs.js +++ b/test/form/prefer-const/_expected/cjs.js @@ -8,7 +8,7 @@ const a = 1; const b = 2; -const namespace = (Object.freeze || Object)({ +const namespace = Object.freeze({ a: a, b: b }); diff --git a/test/form/prefer-const/_expected/es.js b/test/form/prefer-const/_expected/es.js index 2545ae4..8f5a5c9 100644 --- a/test/form/prefer-const/_expected/es.js +++ b/test/form/prefer-const/_expected/es.js @@ -6,7 +6,7 @@ const a = 1; const b = 2; -const namespace = (Object.freeze || Object)({ +const namespace = Object.freeze({ a: a, b: b }); diff --git a/test/form/prefer-const/_expected/iife.js b/test/form/prefer-const/_expected/iife.js index 2aea939..9c66729 100644 --- a/test/form/prefer-const/_expected/iife.js +++ b/test/form/prefer-const/_expected/iife.js @@ -5,7 +5,7 @@ const myBundle = (function (external,other,another) { const b = 2; - const namespace = (Object.freeze || Object)({ + const namespace = Object.freeze({ a: a, b: b }); diff --git a/test/form/prefer-const/_expected/umd.js b/test/form/prefer-const/_expected/umd.js index 19a0747..0ec9750 100644 --- a/test/form/prefer-const/_expected/umd.js +++ b/test/form/prefer-const/_expected/umd.js @@ -8,7 +8,7 @@ const b = 2; - const namespace = (Object.freeze || Object)({ + const namespace = Object.freeze({ a: a, b: b }); diff --git a/test/test.js b/test/test.js index 4ea2867..8b2b66f 100644 --- a/test/test.js +++ b/test/test.js @@ -90,7 +90,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( () => { throw new Error( 'Missing expected error' ); }, err => { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, context, dest, entry, exports, external, footer, format, globals, indent, interop, intro, moduleContext, moduleId, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, banner, cache, context, dest, entry, exports, external, footer, format, globals, indent, interop, intro, legacy, moduleContext, moduleId, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, sourceMap, sourceMapFile, targets, treeshake, useStrict' ); }); }); From 5344665d7256c7192cb69068635ff0d3f6c6cd8b Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 16:02:54 -0400 Subject: [PATCH 307/331] -> v0.36.3 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9313c38..24e644b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.36.3 + +* Add `legacy` option for IE8 support ([#989](https://github.com/rollup/rollup/pull/989)) + ## 0.36.2 * Insert semicolons where necessary to fix broken code ([#1004](https://github.com/rollup/rollup/issues/1004)) diff --git a/package.json b/package.json index 642f25f..47b3db8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.36.2", + "version": "0.36.3", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From f4489515e444f918c5aa35efac31c7200c5cb372 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 9 Oct 2016 20:05:21 -0400 Subject: [PATCH 308/331] fix behaviour of export * in relation to defaults - fixes #1028 --- src/Module.js | 23 ++++++++++++++----- .../default-not-reexported/_config.js | 8 +++++++ test/function/default-not-reexported/bar.js | 2 ++ test/function/default-not-reexported/foo.js | 1 + test/function/default-not-reexported/main.js | 3 +++ 5 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 test/function/default-not-reexported/_config.js create mode 100644 test/function/default-not-reexported/bar.js create mode 100644 test/function/default-not-reexported/foo.js create mode 100644 test/function/default-not-reexported/main.js diff --git a/src/Module.js b/src/Module.js index 81a097c..c3a9fa6 100644 --- a/src/Module.js +++ b/src/Module.js @@ -6,6 +6,7 @@ import { basename, extname } from './utils/path.js'; import getLocation from './utils/getLocation.js'; import makeLegalIdentifier from './utils/makeLegalIdentifier.js'; import SOURCEMAPPING_URL from './utils/sourceMappingURL.js'; +import error from './utils/error.js'; import relativeId from './utils/relativeId.js'; import { SyntheticNamespaceDeclaration } from './Declaration.js'; import extractNames from './ast/utils/extractNames.js'; @@ -205,7 +206,7 @@ export default class Module { const isNamespace = specifier.type === 'ImportNamespaceSpecifier'; const name = isDefault ? 'default' : isNamespace ? '*' : specifier.imported.name; - this.imports[ localName ] = { source, name, module: null }; + this.imports[ localName ] = { source, specifier, name, module: null }; }); } @@ -359,7 +360,14 @@ export default class Module { const declaration = otherModule.traceExport( importDeclaration.name ); - if ( !declaration ) throw new Error( `'${importDeclaration.name}' is not exported by ${relativeId( otherModule.id )} (imported by ${relativeId( this.id )}). For help fixing this error see https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module` ); + if ( !declaration ) { + error({ + message: `'${importDeclaration.name}' is not exported by ${relativeId( otherModule.id )} (imported by ${relativeId( this.id )}). For help fixing this error see https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module`, + file: this.id, + loc: getLocation( this.code, importDeclaration.specifier.start ) + }); + } + return declaration; } @@ -373,10 +381,11 @@ export default class Module { const declaration = reexportDeclaration.module.traceExport( reexportDeclaration.localName ); if ( !declaration ) { - const err = new Error( `'${reexportDeclaration.localName}' is not exported by '${reexportDeclaration.module.id}' (imported by '${this.id}')` ); - err.file = this.id; - err.loc = getLocation( this.code, reexportDeclaration.start ); - throw err; + error({ + message: `'${reexportDeclaration.localName}' is not exported by '${reexportDeclaration.module.id}' (imported by '${this.id}')`, + file: this.id, + loc: getLocation( this.code, reexportDeclaration.start ) + }); } return declaration; @@ -390,6 +399,8 @@ export default class Module { return declaration || this.bundle.scope.findDeclaration( name ); } + if ( name === 'default' ) return; + for ( let i = 0; i < this.exportAllModules.length; i += 1 ) { const module = this.exportAllModules[i]; const declaration = module.traceExport( name ); diff --git a/test/function/default-not-reexported/_config.js b/test/function/default-not-reexported/_config.js new file mode 100644 index 0000000..4280924 --- /dev/null +++ b/test/function/default-not-reexported/_config.js @@ -0,0 +1,8 @@ +const assert = require( 'assert' ); + +module.exports = { + description: 'default export is not re-exported with export *', + error ( error ) { + assert.equal( error.message, `'default' is not exported by foo.js (imported by main.js). For help fixing this error see https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module` ); + } +}; diff --git a/test/function/default-not-reexported/bar.js b/test/function/default-not-reexported/bar.js new file mode 100644 index 0000000..f3f6547 --- /dev/null +++ b/test/function/default-not-reexported/bar.js @@ -0,0 +1,2 @@ +export const named = 42; +export default 'should not be re-exported'; diff --git a/test/function/default-not-reexported/foo.js b/test/function/default-not-reexported/foo.js new file mode 100644 index 0000000..a8e4f7c --- /dev/null +++ b/test/function/default-not-reexported/foo.js @@ -0,0 +1 @@ +export * from './bar.js'; diff --git a/test/function/default-not-reexported/main.js b/test/function/default-not-reexported/main.js new file mode 100644 index 0000000..6aa8dfa --- /dev/null +++ b/test/function/default-not-reexported/main.js @@ -0,0 +1,3 @@ +import def from './foo.js'; + +console.log( def ); From 54124770cd94a0a9e6095031e8e835f080c7b64b Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 12 Oct 2016 09:26:01 -0400 Subject: [PATCH 309/331] fix missing namespace member warnings (closes #1045) --- src/ast/nodes/MemberExpression.js | 14 ++++++++++++-- test/function/namespace-missing-export/_config.js | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/ast/nodes/MemberExpression.js b/src/ast/nodes/MemberExpression.js index ea373cd..eca57a2 100644 --- a/src/ast/nodes/MemberExpression.js +++ b/src/ast/nodes/MemberExpression.js @@ -1,3 +1,5 @@ +import getLocation from '../../utils/getLocation.js'; +import relativeId from '../../utils/relativeId.js'; import isReference from '../utils/isReference.js'; import Node from '../Node.js'; import { UNKNOWN } from '../values.js'; @@ -26,12 +28,16 @@ export default class MemberExpression extends Node { let declaration = scope.findDeclaration( keypath.root.name ); while ( declaration.isNamespace && keypath.parts.length ) { + const exporterId = declaration.module.id; + const part = keypath.parts[0]; declaration = declaration.module.traceExport( part.name ); if ( !declaration ) { - this.module.bundle.onwarn( `Export '${part.name}' is not defined by '${this.module.id}'` ); - break; + const { line, column } = getLocation( this.module.code, this.start ); + this.module.bundle.onwarn( `${relativeId( this.module.id )} (${line}:${column}) '${part.name}' is not exported by '${relativeId( exporterId )}'. See https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module` ); + this.replacement = 'undefined'; + return; } keypath.parts.shift(); @@ -64,6 +70,10 @@ export default class MemberExpression extends Node { if ( name !== this.name ) code.overwrite( this.start, this.end, name, true ); } + else if ( this.replacement ) { + code.overwrite( this.start, this.end, this.replacement, true ); + } + super.render( code, es ); } diff --git a/test/function/namespace-missing-export/_config.js b/test/function/namespace-missing-export/_config.js index 7835ef4..6ecf3b9 100644 --- a/test/function/namespace-missing-export/_config.js +++ b/test/function/namespace-missing-export/_config.js @@ -3,7 +3,7 @@ var assert = require( 'assert' ); module.exports = { options: { onwarn: function ( msg ) { - assert.ok( /Export 'foo' is not defined by/.test( msg ) ); + assert.equal( msg, `main.js (3:21) 'foo' is not exported by 'empty.js'. See https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module` ); } } }; From c6089e75843ce898be96d36c370c68442b6511df Mon Sep 17 00:00:00 2001 From: chge Date: Sun, 16 Oct 2016 23:58:07 +0300 Subject: [PATCH 310/331] Quote names in module definition if legacy option is set --- src/Declaration.js | 3 +++ test/form/legacy/_expected/amd.js | 2 +- test/form/legacy/_expected/cjs.js | 2 +- test/form/legacy/_expected/es.js | 2 +- test/form/legacy/_expected/iife.js | 2 +- test/form/legacy/_expected/umd.js | 2 +- 6 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Declaration.js b/src/Declaration.js index b550cec..eb64e00 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -82,6 +82,9 @@ export class SyntheticNamespaceDeclaration { if ( original.isReassigned ) { return `${indentString}get ${name} () { return ${original.getName( es )}; }`; } + if (legacy) { + name = `'${name}'`; + } return `${indentString}${name}: ${original.getName( es )}`; }); diff --git a/test/form/legacy/_expected/amd.js b/test/form/legacy/_expected/amd.js index 3ba37d0..7e9566f 100644 --- a/test/form/legacy/_expected/amd.js +++ b/test/form/legacy/_expected/amd.js @@ -4,7 +4,7 @@ define(function () { 'use strict'; var namespace = (Object.freeze || Object)({ - foo: foo + 'foo': foo }); const x = 'foo'; diff --git a/test/form/legacy/_expected/cjs.js b/test/form/legacy/_expected/cjs.js index 33c3402..77b77d1 100644 --- a/test/form/legacy/_expected/cjs.js +++ b/test/form/legacy/_expected/cjs.js @@ -4,7 +4,7 @@ const foo = 42; var namespace = (Object.freeze || Object)({ - foo: foo + 'foo': foo }); const x = 'foo'; diff --git a/test/form/legacy/_expected/es.js b/test/form/legacy/_expected/es.js index be10260..df7b6ff 100644 --- a/test/form/legacy/_expected/es.js +++ b/test/form/legacy/_expected/es.js @@ -2,7 +2,7 @@ const foo = 42; var namespace = (Object.freeze || Object)({ - foo: foo + 'foo': foo }); const x = 'foo'; diff --git a/test/form/legacy/_expected/iife.js b/test/form/legacy/_expected/iife.js index 095ddd0..79e6a2a 100644 --- a/test/form/legacy/_expected/iife.js +++ b/test/form/legacy/_expected/iife.js @@ -5,7 +5,7 @@ var namespace = (Object.freeze || Object)({ - foo: foo + 'foo': foo }); const x = 'foo'; diff --git a/test/form/legacy/_expected/umd.js b/test/form/legacy/_expected/umd.js index f3d0fa9..2774375 100644 --- a/test/form/legacy/_expected/umd.js +++ b/test/form/legacy/_expected/umd.js @@ -8,7 +8,7 @@ var namespace = (Object.freeze || Object)({ - foo: foo + 'foo': foo }); const x = 'foo'; From e20a332c57b903d6bf63ab08d79bff7b6dc39aaa Mon Sep 17 00:00:00 2001 From: kzc Date: Tue, 18 Oct 2016 08:51:16 -0400 Subject: [PATCH 311/331] fix TypeError in arrow function without braces returning a function (#1032) --- src/ast/nodes/shared/callHasEffects.js | 2 +- .../braceless-arrow-function-returning-function/_config.js | 3 +++ .../braceless-arrow-function-returning-function/main.js | 7 +++++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 test/function/braceless-arrow-function-returning-function/_config.js create mode 100644 test/function/braceless-arrow-function-returning-function/main.js diff --git a/src/ast/nodes/shared/callHasEffects.js b/src/ast/nodes/shared/callHasEffects.js index cf8d964..8fa026d 100644 --- a/src/ast/nodes/shared/callHasEffects.js +++ b/src/ast/nodes/shared/callHasEffects.js @@ -11,7 +11,7 @@ function fnHasEffects ( fn ) { // handle body-less arrow functions const scope = fn.body.scope || fn.scope; - const body = fn.body.body || [ fn.body ]; + const body = Array.isArray(fn.body.body) && fn.body.body || [ fn.body ]; for ( const node of body ) { if ( node.hasEffects( scope ) ) { diff --git a/test/function/braceless-arrow-function-returning-function/_config.js b/test/function/braceless-arrow-function-returning-function/_config.js new file mode 100644 index 0000000..03ddb4d --- /dev/null +++ b/test/function/braceless-arrow-function-returning-function/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'arrow function without braces returning a function (#1032)' +}; diff --git a/test/function/braceless-arrow-function-returning-function/main.js b/test/function/braceless-arrow-function-returning-function/main.js new file mode 100644 index 0000000..637a0ee --- /dev/null +++ b/test/function/braceless-arrow-function-returning-function/main.js @@ -0,0 +1,7 @@ +const f = (a) => (b) => { return a * b } +function ff (a) { return f(a) } +assert.equal( ff(2)(3), 6 ); + +const g = (a) => { return (b) => { return a - b } } +function gg (a) { return g(a) } +assert.equal( gg(2)(3), -1 ); From 0006ea1e1c7e9b0e41d178ab3959cd0a27259c54 Mon Sep 17 00:00:00 2001 From: kzc Date: Tue, 18 Oct 2016 09:02:44 -0400 Subject: [PATCH 312/331] use buble for test to resolve node 0.12 failure --- .../braceless-arrow-function-returning-function/_config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/function/braceless-arrow-function-returning-function/_config.js b/test/function/braceless-arrow-function-returning-function/_config.js index 03ddb4d..3204f3c 100644 --- a/test/function/braceless-arrow-function-returning-function/_config.js +++ b/test/function/braceless-arrow-function-returning-function/_config.js @@ -1,3 +1,4 @@ module.exports = { - description: 'arrow function without braces returning a function (#1032)' + description: 'arrow function without braces returning a function (#1032)', + buble: true }; From d5997f36c355038e8608f06ae4768beee28c0143 Mon Sep 17 00:00:00 2001 From: 1111hui <26634873@qq.com> Date: Thu, 20 Oct 2016 11:55:46 +0800 Subject: [PATCH 313/331] FIX: test for legacy; remove Object.define for legacy --- bin/src/index.js | 1 + bin/src/runRollup.js | 1 + src/finalisers/amd.js | 2 +- src/finalisers/cjs.js | 2 +- src/finalisers/umd.js | 2 +- test/form/legacy/_config.js | 3 ++- test/form/legacy/_expected/amd.js | 17 ++++++++++++----- test/form/legacy/_expected/cjs.js | 15 +++++++++++---- test/form/legacy/_expected/es.js | 14 ++++++++++---- test/form/legacy/_expected/iife.js | 19 +++++++++++++------ test/form/legacy/_expected/umd.js | 23 +++++++++++++++-------- test/form/legacy/main.js | 6 ++++-- test/form/legacy/namespace.js | 3 ++- 13 files changed, 74 insertions(+), 34 deletions(-) diff --git a/bin/src/index.js b/bin/src/index.js index 1b8f1e6..cbc8123 100644 --- a/bin/src/index.js +++ b/bin/src/index.js @@ -16,6 +16,7 @@ const command = minimist( process.argv.slice( 2 ), { g: 'globals', h: 'help', i: 'input', + l: 'legacy', m: 'sourcemap', n: 'name', o: 'output', diff --git a/bin/src/runRollup.js b/bin/src/runRollup.js index 53a6231..84cd3da 100644 --- a/bin/src/runRollup.js +++ b/bin/src/runRollup.js @@ -105,6 +105,7 @@ const equivalents = { indent: 'indent', input: 'entry', intro: 'intro', + legacy: 'legacy', name: 'moduleName', output: 'dest', outro: 'outro', diff --git a/src/finalisers/amd.js b/src/finalisers/amd.js index 96626e2..64adffd 100644 --- a/src/finalisers/amd.js +++ b/src/finalisers/amd.js @@ -27,7 +27,7 @@ export default function amd ( bundle, magicString, { exportMode, indentString, i const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); - if ( exportMode === 'named' ) magicString.append( `\n\n${esModuleExport}` ); + if ( exportMode === 'named' && options.legacy !== true ) magicString.append( `\n\n${esModuleExport}` ); if ( options.outro ) magicString.append( `\n${options.outro}` ); return magicString diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index 5af4df7..e89ef32 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -3,7 +3,7 @@ import esModuleExport from './shared/esModuleExport.js'; export default function cjs ( bundle, magicString, { exportMode, intro }, options ) { intro = ( options.useStrict === false ? intro : `'use strict';\n\n${intro}` ) + - ( exportMode === 'named' ? `${esModuleExport}\n\n` : '' ); + ( exportMode === 'named' && options.legacy !== true ? `${esModuleExport}\n\n` : '' ); let needsInterop = false; diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index f2be2a2..67b9860 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -73,7 +73,7 @@ export default function umd ( bundle, magicString, { exportMode, indentString, i const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); - if ( exportMode === 'named' ) magicString.append( `\n\n${esModuleExport}` ); + if ( exportMode === 'named' && options.legacy !== true ) magicString.append( `\n\n${esModuleExport}` ); if ( options.outro ) magicString.append( `\n${options.outro}` ); return magicString diff --git a/test/form/legacy/_config.js b/test/form/legacy/_config.js index 2bdf641..8ccc71d 100644 --- a/test/form/legacy/_config.js +++ b/test/form/legacy/_config.js @@ -1,6 +1,7 @@ module.exports = { - description: 'supports environments without Object.freeze', + description: 'supports environments without Object.freeze, Object.defined', options: { + moduleName: 'myBundle', legacy: true } }; diff --git a/test/form/legacy/_expected/amd.js b/test/form/legacy/_expected/amd.js index 3ba37d0..c1b004a 100644 --- a/test/form/legacy/_expected/amd.js +++ b/test/form/legacy/_expected/amd.js @@ -1,13 +1,20 @@ -define(function () { 'use strict'; +define(['exports'], function (exports) { 'use strict'; - const foo = 42; + const foo = 1; + const bar = 2; var namespace = (Object.freeze || Object)({ - foo: foo + foo: foo, + bar: bar }); - const x = 'foo'; - assert.equal( namespace[x], 42 ); + console.log( Object.keys( namespace ) ); + + const a = 1; + const b = 2; + + exports.a = a; + exports.b = b; }); diff --git a/test/form/legacy/_expected/cjs.js b/test/form/legacy/_expected/cjs.js index 33c3402..f904af3 100644 --- a/test/form/legacy/_expected/cjs.js +++ b/test/form/legacy/_expected/cjs.js @@ -1,11 +1,18 @@ 'use strict'; -const foo = 42; +const foo = 1; +const bar = 2; var namespace = (Object.freeze || Object)({ - foo: foo + foo: foo, + bar: bar }); -const x = 'foo'; -assert.equal( namespace[x], 42 ); +console.log( Object.keys( namespace ) ); + +const a = 1; +const b = 2; + +exports.a = a; +exports.b = b; diff --git a/test/form/legacy/_expected/es.js b/test/form/legacy/_expected/es.js index be10260..dab29e5 100644 --- a/test/form/legacy/_expected/es.js +++ b/test/form/legacy/_expected/es.js @@ -1,9 +1,15 @@ -const foo = 42; +const foo = 1; +const bar = 2; var namespace = (Object.freeze || Object)({ - foo: foo + foo: foo, + bar: bar }); -const x = 'foo'; -assert.equal( namespace[x], 42 ); +console.log( Object.keys( namespace ) ); + +const a = 1; +const b = 2; + +export { a, b }; diff --git a/test/form/legacy/_expected/iife.js b/test/form/legacy/_expected/iife.js index 095ddd0..19f8c91 100644 --- a/test/form/legacy/_expected/iife.js +++ b/test/form/legacy/_expected/iife.js @@ -1,14 +1,21 @@ -(function () { +(function (exports) { 'use strict'; - const foo = 42; + const foo = 1; + const bar = 2; var namespace = (Object.freeze || Object)({ - foo: foo + foo: foo, + bar: bar }); - const x = 'foo'; - assert.equal( namespace[x], 42 ); + console.log( Object.keys( namespace ) ); -}()); + const a = 1; + const b = 2; + + exports.a = a; + exports.b = b; + +}((this.myBundle = this.myBundle || {}))); diff --git a/test/form/legacy/_expected/umd.js b/test/form/legacy/_expected/umd.js index f3d0fa9..7c98779 100644 --- a/test/form/legacy/_expected/umd.js +++ b/test/form/legacy/_expected/umd.js @@ -1,17 +1,24 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory() : - typeof define === 'function' && define.amd ? define(factory) : - (factory()); -}(this, (function () { 'use strict'; + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.myBundle = global.myBundle || {}))); +}(this, (function (exports) { 'use strict'; - const foo = 42; + const foo = 1; + const bar = 2; var namespace = (Object.freeze || Object)({ - foo: foo + foo: foo, + bar: bar }); - const x = 'foo'; - assert.equal( namespace[x], 42 ); + console.log( Object.keys( namespace ) ); + + const a = 1; + const b = 2; + + exports.a = a; + exports.b = b; }))); diff --git a/test/form/legacy/main.js b/test/form/legacy/main.js index 321f9b3..d434187 100644 --- a/test/form/legacy/main.js +++ b/test/form/legacy/main.js @@ -1,4 +1,6 @@ import * as namespace from './namespace.js'; -const x = 'foo'; -assert.equal( namespace[x], 42 ); +console.log( Object.keys( namespace ) ); + +export const a = 1; +export const b = 2; diff --git a/test/form/legacy/namespace.js b/test/form/legacy/namespace.js index 9d7381d..e3a53f2 100644 --- a/test/form/legacy/namespace.js +++ b/test/form/legacy/namespace.js @@ -1 +1,2 @@ -export const foo = 42; +export const foo = 1; +export const bar = 2; From 5881a2867d5dbfd532761e0739962be795b19f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20S=C3=A1nchez=20Ortega?= Date: Thu, 20 Oct 2016 12:56:31 +0200 Subject: [PATCH 314/331] Do not output getter defs when in legacy mode --- src/Declaration.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Declaration.js b/src/Declaration.js index b550cec..021d0bf 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -79,7 +79,7 @@ export class SyntheticNamespaceDeclaration { const members = keys( this.originals ).map( name => { const original = this.originals[ name ]; - if ( original.isReassigned ) { + if ( original.isReassigned && !legacy ) { return `${indentString}get ${name} () { return ${original.getName( es )}; }`; } From ea704835ba6cec265f4f6d20a794463668bdf7ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20S=C3=A1nchez=20Ortega?= Date: Thu, 20 Oct 2016 13:22:47 +0200 Subject: [PATCH 315/331] Add testing of getter defs in legacy mode. --- test/form/legacy-getter/_config.js | 7 ++++++ test/form/legacy-getter/_expected/amd.js | 25 +++++++++++++++++++ test/form/legacy-getter/_expected/cjs.js | 23 ++++++++++++++++++ test/form/legacy-getter/_expected/es.js | 19 +++++++++++++++ test/form/legacy-getter/_expected/iife.js | 24 +++++++++++++++++++ test/form/legacy-getter/_expected/umd.js | 29 +++++++++++++++++++++++ test/form/legacy-getter/browserStuff.js | 9 +++++++ test/form/legacy-getter/main.js | 4 ++++ 8 files changed, 140 insertions(+) create mode 100644 test/form/legacy-getter/_config.js create mode 100644 test/form/legacy-getter/_expected/amd.js create mode 100644 test/form/legacy-getter/_expected/cjs.js create mode 100644 test/form/legacy-getter/_expected/es.js create mode 100644 test/form/legacy-getter/_expected/iife.js create mode 100644 test/form/legacy-getter/_expected/umd.js create mode 100644 test/form/legacy-getter/browserStuff.js create mode 100644 test/form/legacy-getter/main.js diff --git a/test/form/legacy-getter/_config.js b/test/form/legacy-getter/_config.js new file mode 100644 index 0000000..591c08e --- /dev/null +++ b/test/form/legacy-getter/_config.js @@ -0,0 +1,7 @@ +module.exports = { + description: 'Does not output getters when in legacy', + options: { + legacy: true, + moduleName: 'foo' + } +}; diff --git a/test/form/legacy-getter/_expected/amd.js b/test/form/legacy-getter/_expected/amd.js new file mode 100644 index 0000000..0dbbff2 --- /dev/null +++ b/test/form/legacy-getter/_expected/amd.js @@ -0,0 +1,25 @@ +define(['exports'], function (exports) { 'use strict'; + + var browserSpecificThing; + + if ('ActiveXObject' in window) { + browserSpecificThing = "InternetExplorerThing"; + } else { + browserSpecificThing = "DecentBrowserThing"; + } + + function foo() {} + + + var browserStuff = (Object.freeze || Object)({ + browserSpecificThing: browserSpecificThing, + foo: foo + }); + + console.log(browserSpecificThing); + + exports.B = browserStuff; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/form/legacy-getter/_expected/cjs.js b/test/form/legacy-getter/_expected/cjs.js new file mode 100644 index 0000000..3a59cff --- /dev/null +++ b/test/form/legacy-getter/_expected/cjs.js @@ -0,0 +1,23 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var browserSpecificThing; + +if ('ActiveXObject' in window) { + browserSpecificThing = "InternetExplorerThing"; +} else { + browserSpecificThing = "DecentBrowserThing"; +} + +function foo() {} + + +var browserStuff = (Object.freeze || Object)({ + browserSpecificThing: browserSpecificThing, + foo: foo +}); + +console.log(browserSpecificThing); + +exports.B = browserStuff; diff --git a/test/form/legacy-getter/_expected/es.js b/test/form/legacy-getter/_expected/es.js new file mode 100644 index 0000000..f2c9a6a --- /dev/null +++ b/test/form/legacy-getter/_expected/es.js @@ -0,0 +1,19 @@ +var browserSpecificThing; + +if ('ActiveXObject' in window) { + browserSpecificThing = "InternetExplorerThing"; +} else { + browserSpecificThing = "DecentBrowserThing"; +} + +function foo() {} + + +var browserStuff = (Object.freeze || Object)({ + browserSpecificThing: browserSpecificThing, + foo: foo +}); + +console.log(browserSpecificThing); + +export { browserStuff as B }; diff --git a/test/form/legacy-getter/_expected/iife.js b/test/form/legacy-getter/_expected/iife.js new file mode 100644 index 0000000..a588fbb --- /dev/null +++ b/test/form/legacy-getter/_expected/iife.js @@ -0,0 +1,24 @@ +(function (exports) { + 'use strict'; + + var browserSpecificThing; + + if ('ActiveXObject' in window) { + browserSpecificThing = "InternetExplorerThing"; + } else { + browserSpecificThing = "DecentBrowserThing"; + } + + function foo() {} + + + var browserStuff = (Object.freeze || Object)({ + browserSpecificThing: browserSpecificThing, + foo: foo + }); + + console.log(browserSpecificThing); + + exports.B = browserStuff; + +}((this.foo = this.foo || {}))); diff --git a/test/form/legacy-getter/_expected/umd.js b/test/form/legacy-getter/_expected/umd.js new file mode 100644 index 0000000..c53a23c --- /dev/null +++ b/test/form/legacy-getter/_expected/umd.js @@ -0,0 +1,29 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.foo = global.foo || {}))); +}(this, (function (exports) { 'use strict'; + + var browserSpecificThing; + + if ('ActiveXObject' in window) { + browserSpecificThing = "InternetExplorerThing"; + } else { + browserSpecificThing = "DecentBrowserThing"; + } + + function foo() {} + + + var browserStuff = (Object.freeze || Object)({ + browserSpecificThing: browserSpecificThing, + foo: foo + }); + + console.log(browserSpecificThing); + + exports.B = browserStuff; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/test/form/legacy-getter/browserStuff.js b/test/form/legacy-getter/browserStuff.js new file mode 100644 index 0000000..9f3d71c --- /dev/null +++ b/test/form/legacy-getter/browserStuff.js @@ -0,0 +1,9 @@ +export var browserSpecificThing; + +if ('ActiveXObject' in window) { + browserSpecificThing = "InternetExplorerThing"; +} else { + browserSpecificThing = "DecentBrowserThing"; +} + +export function foo() {} diff --git a/test/form/legacy-getter/main.js b/test/form/legacy-getter/main.js new file mode 100644 index 0000000..2791550 --- /dev/null +++ b/test/form/legacy-getter/main.js @@ -0,0 +1,4 @@ +import * as B from './browserStuff'; +export {B}; + +console.log(B.browserSpecificThing); From da4fb22e7a368ecc460ac2a875ff38fa3132e422 Mon Sep 17 00:00:00 2001 From: zackschuster Date: Sun, 23 Oct 2016 23:14:14 -0700 Subject: [PATCH 316/331] destructure options in Scope constructor i couldn't think of a reason you'd opt out of destructuring here; apologies if i'm mistaken somehow --- src/ast/scopes/Scope.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ast/scopes/Scope.js b/src/ast/scopes/Scope.js index 7bb1671..2c250a8 100644 --- a/src/ast/scopes/Scope.js +++ b/src/ast/scopes/Scope.js @@ -27,9 +27,7 @@ class Parameter { } export default class Scope { - constructor ( options ) { - options = options || {}; - + constructor ( options = {} ) { this.parent = options.parent; this.isBlockScope = !!options.isBlockScope; this.isLexicalBoundary = !!options.isLexicalBoundary; From ab3b38f15ac9ce0730737fb1a73161b7a47eb729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Segersv=C3=A4rd?= Date: Fri, 11 Nov 2016 22:41:49 +0100 Subject: [PATCH 317/331] Bundle execution is only dependent on program level call expressions --- src/ast/nodes/CallExpression.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/ast/nodes/CallExpression.js b/src/ast/nodes/CallExpression.js index 8fafc91..70d1e13 100644 --- a/src/ast/nodes/CallExpression.js +++ b/src/ast/nodes/CallExpression.js @@ -30,7 +30,9 @@ export default class CallExpression extends Node { } initialise ( scope ) { - this.module.bundle.dependentExpressions.push( this ); + if ( isProgramLevel( this ) ) { + this.module.bundle.dependentExpressions.push( this ); + } super.initialise( scope ); } @@ -38,3 +40,14 @@ export default class CallExpression extends Node { return this.hasEffects( this.findScope() ); } } + +function isProgramLevel ( node ) { + do { + if ( node.type === 'Program' ) { + return true; + } + node = node.parent; + } while ( node && !/Function/.test( node.type ) ); + + return false; +} From 59f815b0d3dbe36becca07fc154c43e405affd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Segersv=C3=A4rd?= Date: Fri, 11 Nov 2016 22:42:43 +0100 Subject: [PATCH 318/331] Update tests after #1037 --- test/form/unused-called-import/_expected/amd.js | 2 +- test/form/unused-called-import/_expected/cjs.js | 2 +- test/form/unused-called-import/_expected/es.js | 2 +- test/form/unused-called-import/_expected/iife.js | 2 +- test/form/unused-called-import/_expected/umd.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/form/unused-called-import/_expected/amd.js b/test/form/unused-called-import/_expected/amd.js index 98fec0b..f0cc768 100644 --- a/test/form/unused-called-import/_expected/amd.js +++ b/test/form/unused-called-import/_expected/amd.js @@ -1,6 +1,6 @@ define(function () { 'use strict'; - var foo = function() { return 'foo'; } + var foo = function() { return 'foo'; }; assert.equal( foo(), 'foo' ); diff --git a/test/form/unused-called-import/_expected/cjs.js b/test/form/unused-called-import/_expected/cjs.js index 084a719..b808398 100644 --- a/test/form/unused-called-import/_expected/cjs.js +++ b/test/form/unused-called-import/_expected/cjs.js @@ -1,5 +1,5 @@ 'use strict'; -var foo = function() { return 'foo'; } +var foo = function() { return 'foo'; }; assert.equal( foo(), 'foo' ); diff --git a/test/form/unused-called-import/_expected/es.js b/test/form/unused-called-import/_expected/es.js index 7d15eea..f24d612 100644 --- a/test/form/unused-called-import/_expected/es.js +++ b/test/form/unused-called-import/_expected/es.js @@ -1,3 +1,3 @@ -var foo = function() { return 'foo'; } +var foo = function() { return 'foo'; }; assert.equal( foo(), 'foo' ); diff --git a/test/form/unused-called-import/_expected/iife.js b/test/form/unused-called-import/_expected/iife.js index f7fa135..bc7e275 100644 --- a/test/form/unused-called-import/_expected/iife.js +++ b/test/form/unused-called-import/_expected/iife.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - var foo = function() { return 'foo'; } + var foo = function() { return 'foo'; }; assert.equal( foo(), 'foo' ); diff --git a/test/form/unused-called-import/_expected/umd.js b/test/form/unused-called-import/_expected/umd.js index 3cd2a2b..1469ca3 100644 --- a/test/form/unused-called-import/_expected/umd.js +++ b/test/form/unused-called-import/_expected/umd.js @@ -4,7 +4,7 @@ (factory()); }(this, (function () { 'use strict'; - var foo = function() { return 'foo'; } + var foo = function() { return 'foo'; }; assert.equal( foo(), 'foo' ); From fca14dbab102a9fa8efc7249287e2145583712ea Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 23 Nov 2016 09:01:25 -0500 Subject: [PATCH 319/331] -> v0.36.4 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24e644b..d7ec76d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # rollup changelog +## 0.36.4 + +* Only depend on program-level call expressions ([#977](https://github.com/rollup/rollup/issues/977)) + ## 0.36.3 * Add `legacy` option for IE8 support ([#989](https://github.com/rollup/rollup/pull/989)) diff --git a/package.json b/package.json index 47b3db8..2789f08 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.36.3", + "version": "0.36.4", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From ac04b8336247436ed462c8169a19947fa753105f Mon Sep 17 00:00:00 2001 From: kzc Date: Fri, 9 Dec 2016 14:39:05 -0500 Subject: [PATCH 320/331] fix paren issues with tree shaking (#1101 #1128) --- src/Module.js | 2 +- src/ast/nodes/AssignmentExpression.js | 3 +-- src/ast/nodes/ExportDefaultDeclaration.js | 17 ++++++++++++----- src/ast/nodes/ParenthesizedExpression.js | 11 ----------- src/ast/nodes/UpdateExpression.js | 3 +-- src/ast/nodes/index.js | 2 -- src/ast/nodes/shared/assignTo.js | 2 -- src/ast/nodes/shared/isUsedByBundle.js | 2 -- 8 files changed, 15 insertions(+), 27 deletions(-) delete mode 100644 src/ast/nodes/ParenthesizedExpression.js diff --git a/src/Module.js b/src/Module.js index 81a097c..ae01215 100644 --- a/src/Module.js +++ b/src/Module.js @@ -18,7 +18,7 @@ function tryParse ( code, comments, acornOptions, id ) { ecmaVersion: 7, sourceType: 'module', onComment: ( block, text, start, end ) => comments.push({ block, text, start, end }), - preserveParens: true + preserveParens: false }, acornOptions )); } catch ( err ) { err.code = 'PARSE_ERROR'; diff --git a/src/ast/nodes/AssignmentExpression.js b/src/ast/nodes/AssignmentExpression.js index f1fbcf3..6e4aa2b 100644 --- a/src/ast/nodes/AssignmentExpression.js +++ b/src/ast/nodes/AssignmentExpression.js @@ -5,8 +5,7 @@ import { NUMBER, STRING } from '../values.js'; export default class AssignmentExpression extends Node { bind ( scope ) { - let subject = this.left; - while ( this.left.type === 'ParenthesizedExpression' ) subject = subject.expression; + const subject = this.left; this.subject = subject; disallowIllegalReassignment( scope, subject ); diff --git a/src/ast/nodes/ExportDefaultDeclaration.js b/src/ast/nodes/ExportDefaultDeclaration.js index 81ae1c9..f583682 100644 --- a/src/ast/nodes/ExportDefaultDeclaration.js +++ b/src/ast/nodes/ExportDefaultDeclaration.js @@ -49,11 +49,18 @@ export default class ExportDefaultDeclaration extends Node { const treeshake = this.module.bundle.treeshake; const name = this.getName( es ); + // paren workaround: find first non-whitespace character position after `export default` + let declaration_start; + if ( this.declaration ) { + const statementStr = code.original.slice( this.start, this.end ); + declaration_start = this.start + statementStr.match(/^export\s+default\s*/)[0].length; + } + if ( this.shouldInclude || this.declaration.activated ) { if ( this.activated ) { if ( functionOrClassDeclaration.test( this.declaration.type ) ) { if ( this.declaration.id ) { - code.remove( this.start, this.declaration.start ); + code.remove( this.start, declaration_start ); } else { throw new Error( 'TODO anonymous class/function declaration' ); } @@ -65,14 +72,14 @@ export default class ExportDefaultDeclaration extends Node { code.remove( this.leadingCommentStart || this.start, this.next || this.end ); return; // don't render children. TODO this seems like a bit of a hack } else { - code.overwrite( this.start, this.declaration.start, `${this.module.bundle.varOrConst} ${name} = ` ); + code.overwrite( this.start, declaration_start, `${this.module.bundle.varOrConst} ${name} = ` ); } this.insertSemicolon( code ); } } else { // remove `var foo` from `var foo = bar()`, if `foo` is unused - code.remove( this.start, this.declaration.start ); + code.remove( this.start, declaration_start ); } super.render( code, es ); @@ -82,10 +89,10 @@ export default class ExportDefaultDeclaration extends Node { code.remove( this.leadingCommentStart || this.start, this.next || this.end ); } else { const hasEffects = this.declaration.hasEffects( this.module.scope ); - code.remove( this.start, hasEffects ? this.declaration.start : this.next || this.end ); + code.remove( this.start, hasEffects ? declaration_start : this.next || this.end ); } } else { - code.overwrite( this.start, this.declaration.start, `${this.module.bundle.varOrConst} ${name} = ` ); + code.overwrite( this.start, declaration_start, `${this.module.bundle.varOrConst} ${name} = ` ); } // code.remove( this.start, this.next || this.end ); } diff --git a/src/ast/nodes/ParenthesizedExpression.js b/src/ast/nodes/ParenthesizedExpression.js deleted file mode 100644 index 7037804..0000000 --- a/src/ast/nodes/ParenthesizedExpression.js +++ /dev/null @@ -1,11 +0,0 @@ -import Node from '../Node.js'; - -export default class ParenthesizedExpression extends Node { - getPossibleValues ( values ) { - return this.expression.getPossibleValues( values ); - } - - getValue () { - return this.expression.getValue(); - } -} diff --git a/src/ast/nodes/UpdateExpression.js b/src/ast/nodes/UpdateExpression.js index 656da69..9fcea9d 100644 --- a/src/ast/nodes/UpdateExpression.js +++ b/src/ast/nodes/UpdateExpression.js @@ -5,8 +5,7 @@ import { NUMBER } from '../values.js'; export default class UpdateExpression extends Node { bind ( scope ) { - let subject = this.argument; - while ( this.argument.type === 'ParenthesizedExpression' ) subject = subject.expression; + const subject = this.argument; this.subject = subject; disallowIllegalReassignment( scope, this.argument ); diff --git a/src/ast/nodes/index.js b/src/ast/nodes/index.js index 94d2f4c..1c3ba4c 100644 --- a/src/ast/nodes/index.js +++ b/src/ast/nodes/index.js @@ -24,7 +24,6 @@ import Literal from './Literal.js'; import MemberExpression from './MemberExpression.js'; import NewExpression from './NewExpression.js'; import ObjectExpression from './ObjectExpression.js'; -import ParenthesizedExpression from './ParenthesizedExpression.js'; import ReturnStatement from './ReturnStatement.js'; import Statement from './shared/Statement.js'; import TemplateLiteral from './TemplateLiteral.js'; @@ -63,7 +62,6 @@ export default { MemberExpression, NewExpression, ObjectExpression, - ParenthesizedExpression, ReturnStatement, SwitchStatement: Statement, TemplateLiteral, diff --git a/src/ast/nodes/shared/assignTo.js b/src/ast/nodes/shared/assignTo.js index 03512e1..2ec7d17 100644 --- a/src/ast/nodes/shared/assignTo.js +++ b/src/ast/nodes/shared/assignTo.js @@ -8,8 +8,6 @@ export default function assignToForLoopLeft ( node, scope, value ) { } else { - while ( node.type === 'ParenthesizedExpression' ) node = node.expression; - if ( node.type === 'MemberExpression' ) { // apparently this is legal JavaScript? Though I don't know what // kind of monster would write `for ( foo.bar of thing ) {...}` diff --git a/src/ast/nodes/shared/isUsedByBundle.js b/src/ast/nodes/shared/isUsedByBundle.js index 07e315f..d33561a 100644 --- a/src/ast/nodes/shared/isUsedByBundle.js +++ b/src/ast/nodes/shared/isUsedByBundle.js @@ -1,8 +1,6 @@ import { UNKNOWN } from '../../values.js'; export default function isUsedByBundle ( scope, node ) { - while ( node.type === 'ParenthesizedExpression' ) node = node.expression; - // const expression = node; while ( node.type === 'MemberExpression' ) node = node.object; From 209fe7c6946a64b87f52a1c2f93b5e566aa29f5e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 12 Dec 2016 11:48:18 -0500 Subject: [PATCH 321/331] apply https://github.com/rollup/rollup/pull/1062#issuecomment-255536598 --- src/ast/nodes/shared/callHasEffects.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/nodes/shared/callHasEffects.js b/src/ast/nodes/shared/callHasEffects.js index 8fa026d..6df76d1 100644 --- a/src/ast/nodes/shared/callHasEffects.js +++ b/src/ast/nodes/shared/callHasEffects.js @@ -11,7 +11,7 @@ function fnHasEffects ( fn ) { // handle body-less arrow functions const scope = fn.body.scope || fn.scope; - const body = Array.isArray(fn.body.body) && fn.body.body || [ fn.body ]; + const body = fn.body.type === 'BlockStatement' ? fn.body.body : [ fn.body ]; for ( const node of body ) { if ( node.hasEffects( scope ) ) { From 051cd9736cc76be6f0910a18981a1d36cbbe9eaa Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 12 Dec 2016 11:51:45 -0500 Subject: [PATCH 322/331] update legacy tests --- test/form/legacy-getter/_expected/amd.js | 2 -- test/form/legacy-getter/_expected/cjs.js | 2 -- test/form/legacy-getter/_expected/umd.js | 2 -- 3 files changed, 6 deletions(-) diff --git a/test/form/legacy-getter/_expected/amd.js b/test/form/legacy-getter/_expected/amd.js index 0dbbff2..4aba57b 100644 --- a/test/form/legacy-getter/_expected/amd.js +++ b/test/form/legacy-getter/_expected/amd.js @@ -20,6 +20,4 @@ define(['exports'], function (exports) { 'use strict'; exports.B = browserStuff; - Object.defineProperty(exports, '__esModule', { value: true }); - }); diff --git a/test/form/legacy-getter/_expected/cjs.js b/test/form/legacy-getter/_expected/cjs.js index 3a59cff..3b66561 100644 --- a/test/form/legacy-getter/_expected/cjs.js +++ b/test/form/legacy-getter/_expected/cjs.js @@ -1,7 +1,5 @@ 'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); - var browserSpecificThing; if ('ActiveXObject' in window) { diff --git a/test/form/legacy-getter/_expected/umd.js b/test/form/legacy-getter/_expected/umd.js index c53a23c..aa0b4f7 100644 --- a/test/form/legacy-getter/_expected/umd.js +++ b/test/form/legacy-getter/_expected/umd.js @@ -24,6 +24,4 @@ exports.B = browserStuff; - Object.defineProperty(exports, '__esModule', { value: true }); - }))); From 81bf0609697f0e9b1838738fb9bd1a5d2a460bb3 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 12 Dec 2016 12:11:13 -0500 Subject: [PATCH 323/331] quote reserved properties in legacy mode --- src/Declaration.js | 3 ++- src/utils/makeLegalIdentifier.js | 2 +- test/form/legacy-reified-namespace/_config.js | 7 +++++++ .../legacy-reified-namespace/_expected/amd.js | 14 ++++++++++++++ .../legacy-reified-namespace/_expected/cjs.js | 12 ++++++++++++ .../legacy-reified-namespace/_expected/es.js | 10 ++++++++++ .../legacy-reified-namespace/_expected/iife.js | 15 +++++++++++++++ .../legacy-reified-namespace/_expected/umd.js | 18 ++++++++++++++++++ test/form/legacy-reified-namespace/main.js | 3 +++ .../form/legacy-reified-namespace/namespace.js | 3 +++ test/form/legacy/_config.js | 2 +- 11 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 test/form/legacy-reified-namespace/_config.js create mode 100644 test/form/legacy-reified-namespace/_expected/amd.js create mode 100644 test/form/legacy-reified-namespace/_expected/cjs.js create mode 100644 test/form/legacy-reified-namespace/_expected/es.js create mode 100644 test/form/legacy-reified-namespace/_expected/iife.js create mode 100644 test/form/legacy-reified-namespace/_expected/umd.js create mode 100644 test/form/legacy-reified-namespace/main.js create mode 100644 test/form/legacy-reified-namespace/namespace.js diff --git a/src/Declaration.js b/src/Declaration.js index 021d0bf..1d13315 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -1,5 +1,5 @@ import { blank, forOwn, keys } from './utils/object.js'; -import makeLegalIdentifier from './utils/makeLegalIdentifier.js'; +import makeLegalIdentifier, { reservedWords } from './utils/makeLegalIdentifier.js'; import { UNKNOWN } from './ast/values.js'; export default class Declaration { @@ -83,6 +83,7 @@ export class SyntheticNamespaceDeclaration { return `${indentString}get ${name} () { return ${original.getName( es )}; }`; } + if ( legacy && ~reservedWords.indexOf( name ) ) name = `'${name}'`; return `${indentString}${name}: ${original.getName( es )}`; }); diff --git a/src/utils/makeLegalIdentifier.js b/src/utils/makeLegalIdentifier.js index c9733e5..846c42e 100644 --- a/src/utils/makeLegalIdentifier.js +++ b/src/utils/makeLegalIdentifier.js @@ -1,6 +1,6 @@ import { blank } from './object.js'; -const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public'.split( ' ' ); +export const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public'.split( ' ' ); const builtins = 'Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl'.split( ' ' ); const blacklisted = blank(); diff --git a/test/form/legacy-reified-namespace/_config.js b/test/form/legacy-reified-namespace/_config.js new file mode 100644 index 0000000..1905df3 --- /dev/null +++ b/test/form/legacy-reified-namespace/_config.js @@ -0,0 +1,7 @@ +module.exports = { + description: 'quotes reserved words in object literals', + options: { + moduleName: 'myBundle', + legacy: true + } +}; diff --git a/test/form/legacy-reified-namespace/_expected/amd.js b/test/form/legacy-reified-namespace/_expected/amd.js new file mode 100644 index 0000000..5fb5bd2 --- /dev/null +++ b/test/form/legacy-reified-namespace/_expected/amd.js @@ -0,0 +1,14 @@ +define(function () { 'use strict'; + + const _typeof = 'typeof'; + const foo = 1; + + + var namespace = (Object.freeze || Object)({ + 'typeof': _typeof, + foo: foo + }); + + console.log( namespace ); + +}); diff --git a/test/form/legacy-reified-namespace/_expected/cjs.js b/test/form/legacy-reified-namespace/_expected/cjs.js new file mode 100644 index 0000000..10ecf7c --- /dev/null +++ b/test/form/legacy-reified-namespace/_expected/cjs.js @@ -0,0 +1,12 @@ +'use strict'; + +const _typeof = 'typeof'; +const foo = 1; + + +var namespace = (Object.freeze || Object)({ + 'typeof': _typeof, + foo: foo +}); + +console.log( namespace ); diff --git a/test/form/legacy-reified-namespace/_expected/es.js b/test/form/legacy-reified-namespace/_expected/es.js new file mode 100644 index 0000000..7b52e33 --- /dev/null +++ b/test/form/legacy-reified-namespace/_expected/es.js @@ -0,0 +1,10 @@ +const _typeof = 'typeof'; +const foo = 1; + + +var namespace = (Object.freeze || Object)({ + 'typeof': _typeof, + foo: foo +}); + +console.log( namespace ); diff --git a/test/form/legacy-reified-namespace/_expected/iife.js b/test/form/legacy-reified-namespace/_expected/iife.js new file mode 100644 index 0000000..9b60efd --- /dev/null +++ b/test/form/legacy-reified-namespace/_expected/iife.js @@ -0,0 +1,15 @@ +(function () { + 'use strict'; + + const _typeof = 'typeof'; + const foo = 1; + + + var namespace = (Object.freeze || Object)({ + 'typeof': _typeof, + foo: foo + }); + + console.log( namespace ); + +}()); diff --git a/test/form/legacy-reified-namespace/_expected/umd.js b/test/form/legacy-reified-namespace/_expected/umd.js new file mode 100644 index 0000000..fe542c0 --- /dev/null +++ b/test/form/legacy-reified-namespace/_expected/umd.js @@ -0,0 +1,18 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + const _typeof = 'typeof'; + const foo = 1; + + + var namespace = (Object.freeze || Object)({ + 'typeof': _typeof, + foo: foo + }); + + console.log( namespace ); + +}))); diff --git a/test/form/legacy-reified-namespace/main.js b/test/form/legacy-reified-namespace/main.js new file mode 100644 index 0000000..5585c1e --- /dev/null +++ b/test/form/legacy-reified-namespace/main.js @@ -0,0 +1,3 @@ +import * as namespace from './namespace.js'; + +console.log( namespace ); diff --git a/test/form/legacy-reified-namespace/namespace.js b/test/form/legacy-reified-namespace/namespace.js new file mode 100644 index 0000000..46fe09d --- /dev/null +++ b/test/form/legacy-reified-namespace/namespace.js @@ -0,0 +1,3 @@ +const _typeof = 'typeof'; +export { _typeof as typeof }; +export const foo = 1; diff --git a/test/form/legacy/_config.js b/test/form/legacy/_config.js index 8ccc71d..a461d8e 100644 --- a/test/form/legacy/_config.js +++ b/test/form/legacy/_config.js @@ -1,7 +1,7 @@ module.exports = { description: 'supports environments without Object.freeze, Object.defined', options: { - moduleName: 'myBundle', + moduleName: 'myBundle', legacy: true } }; From a4927986bd872daa013bb2e0d030d3b7fe1a526b Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 12 Dec 2016 12:20:18 -0500 Subject: [PATCH 324/331] deduplicate --- src/Declaration.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Declaration.js b/src/Declaration.js index 14ec895..1d13315 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -82,9 +82,6 @@ export class SyntheticNamespaceDeclaration { if ( original.isReassigned && !legacy ) { return `${indentString}get ${name} () { return ${original.getName( es )}; }`; } - if (legacy) { - name = `'${name}'`; - } if ( legacy && ~reservedWords.indexOf( name ) ) name = `'${name}'`; return `${indentString}${name}: ${original.getName( es )}`; From fcf39281f8655b9bc6f8322edad18ed173b9b523 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 12 Dec 2016 12:30:31 -0500 Subject: [PATCH 325/331] -> v0.37.0 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ec76d..ef52701 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # rollup changelog +## 0.37.0 + +* [BREAKING] Default exports are not included in reified namespaces ([#1028](https://github.com/rollup/rollup/issues/1028)) +* Parentheses do not defeat tree-shaking ([#1101](https://github.com/rollup/rollup/issues/1101), [#1128](https://github.com/rollup/rollup/issues/1128)) +* More `legacy` fixes: do not create getters ([#1069](https://github.com/rollup/rollup/pull/1069)), do not include `__esModule` ([#1068](https://github.com/rollup/rollup/pull/1068)), quote reserved property names ([#1057](https://github.com/rollup/rollup/pull/1057)) +* Fix missing namespace member warnings ([#1045](https://github.com/rollup/rollup/issues/1045)) +* Fix TypeError in arrow function without braces returning a function ([#1062](https://github.com/rollup/rollup/pull/1062)) + ## 0.36.4 * Only depend on program-level call expressions ([#977](https://github.com/rollup/rollup/issues/977)) diff --git a/package.json b/package.json index 2789f08..ea85120 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.36.4", + "version": "0.37.0", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "module": "dist/rollup.es.js", From 2d32cddabf5a78b1c6943d60781c192666a1bd2c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 14 Dec 2016 15:54:14 -0500 Subject: [PATCH 326/331] implement gatherPossibleValues on ExternalDeclaration - fixes #957 --- src/Declaration.js | 4 ++++ test/function/call-external-function/_config.js | 11 +++++++++++ test/function/call-external-function/foo.js | 2 ++ test/function/call-external-function/main.js | 4 ++++ 4 files changed, 21 insertions(+) create mode 100644 test/function/call-external-function/_config.js create mode 100644 test/function/call-external-function/foo.js create mode 100644 test/function/call-external-function/main.js diff --git a/src/Declaration.js b/src/Declaration.js index 1d13315..88f5553 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -116,6 +116,10 @@ export class ExternalDeclaration { } } + gatherPossibleValues ( values ) { + values.add( UNKNOWN ); + } + getName ( es ) { if ( this.name === '*' ) { return this.module.name; diff --git a/test/function/call-external-function/_config.js b/test/function/call-external-function/_config.js new file mode 100644 index 0000000..9694314 --- /dev/null +++ b/test/function/call-external-function/_config.js @@ -0,0 +1,11 @@ +module.exports = { + description: 'handles call of aliased external function (#957)', + warnings () {}, + context: { + require ( id ) { + if ( id === 'foo' ) { + return () => 42; + } + } + } +}; diff --git a/test/function/call-external-function/foo.js b/test/function/call-external-function/foo.js new file mode 100644 index 0000000..a430876 --- /dev/null +++ b/test/function/call-external-function/foo.js @@ -0,0 +1,2 @@ +import foo from 'foo'; +export default foo; diff --git a/test/function/call-external-function/main.js b/test/function/call-external-function/main.js new file mode 100644 index 0000000..766cb6f --- /dev/null +++ b/test/function/call-external-function/main.js @@ -0,0 +1,4 @@ +import foo_ from './foo.js'; + +var foo = foo_; +assert.equal( foo(), 42 ); From f43fd995540f027e223eb7274cbad7f3213bebaf Mon Sep 17 00:00:00 2001 From: Chris Thielen Date: Wed, 14 Dec 2016 17:19:18 -0600 Subject: [PATCH 327/331] Access global.* using array notation This allows arbitrary `moduleName` (including names with dashes like `ui-router` or scoped npm packages like `@angular/core`) to be added to the global object. Closes #582 Closes #584 --- src/finalisers/iife.js | 15 +++++++++---- src/finalisers/shared/propertyStringFor.js | 17 +++++++++++++++ src/finalisers/umd.js | 21 ++++++++++++------- .../module-name-scoped-package/_config.js | 6 ++++++ .../_expected/amd.js | 9 ++++++++ .../_expected/cjs.js | 7 +++++++ .../_expected/es.js | 3 +++ .../_expected/iife.js | 8 +++++++ .../_expected/umd.js | 13 ++++++++++++ test/form/module-name-scoped-package/main.js | 1 + test/form/module-name-with-dashes/_config.js | 6 ++++++ .../module-name-with-dashes/_expected/amd.js | 9 ++++++++ .../module-name-with-dashes/_expected/cjs.js | 7 +++++++ .../module-name-with-dashes/_expected/es.js | 3 +++ .../module-name-with-dashes/_expected/iife.js | 8 +++++++ .../module-name-with-dashes/_expected/umd.js | 13 ++++++++++++ test/form/module-name-with-dashes/main.js | 1 + 17 files changed, 136 insertions(+), 11 deletions(-) create mode 100644 src/finalisers/shared/propertyStringFor.js create mode 100644 test/form/module-name-scoped-package/_config.js create mode 100644 test/form/module-name-scoped-package/_expected/amd.js create mode 100644 test/form/module-name-scoped-package/_expected/cjs.js create mode 100644 test/form/module-name-scoped-package/_expected/es.js create mode 100644 test/form/module-name-scoped-package/_expected/iife.js create mode 100644 test/form/module-name-scoped-package/_expected/umd.js create mode 100644 test/form/module-name-scoped-package/main.js create mode 100644 test/form/module-name-with-dashes/_config.js create mode 100644 test/form/module-name-with-dashes/_expected/amd.js create mode 100644 test/form/module-name-with-dashes/_expected/cjs.js create mode 100644 test/form/module-name-with-dashes/_expected/es.js create mode 100644 test/form/module-name-with-dashes/_expected/iife.js create mode 100644 test/form/module-name-with-dashes/_expected/umd.js create mode 100644 test/form/module-name-with-dashes/main.js diff --git a/src/finalisers/iife.js b/src/finalisers/iife.js index 8120594..3946286 100644 --- a/src/finalisers/iife.js +++ b/src/finalisers/iife.js @@ -3,16 +3,23 @@ import { getName } from '../utils/map-helpers.js'; import getInteropBlock from './shared/getInteropBlock.js'; import getExportBlock from './shared/getExportBlock.js'; import getGlobalNameMaker from './shared/getGlobalNameMaker.js'; +import propertyStringFor from './shared/propertyStringFor'; + +// thisProp('foo.bar.baz') === "this['foo']['bar']['baz']" +const thisProp = propertyStringFor('this'); + +// propString('foo.bar') === "['foo']['bar']" +const propString = propertyStringFor(''); function setupNamespace ( keypath ) { - const parts = keypath.split( '.' ); // TODO support e.g. `foo['something-hyphenated']`? + const parts = keypath.split( '.' ); parts.pop(); let acc = 'this'; return parts - .map( part => ( acc += `.${part}`, `${acc} = ${acc} || {};` ) ) + .map( part => ( acc += propString(part), `${acc} = ${acc} || {};` ) ) .join( '\n' ) + '\n'; } @@ -31,7 +38,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString, } if ( exportMode === 'named' ) { - dependencies.unshift( `(this.${name} = this.${name} || {})` ); + dependencies.unshift( `(${thisProp(name)} = ${thisProp(name)} || {})` ); args.unshift( 'exports' ); } @@ -41,7 +48,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString, const wrapperOutro = `\n\n}(${dependencies}));`; if ( exportMode === 'default' ) { - wrapperIntro = ( isNamespaced ? `this.` : `${bundle.varOrConst} ` ) + `${name} = ${wrapperIntro}`; + wrapperIntro = ( isNamespaced ? thisProp(name) : `${bundle.varOrConst} ${name}` ) + ` = ${wrapperIntro}`; } if ( isNamespaced ) { diff --git a/src/finalisers/shared/propertyStringFor.js b/src/finalisers/shared/propertyStringFor.js new file mode 100644 index 0000000..f0c2948 --- /dev/null +++ b/src/finalisers/shared/propertyStringFor.js @@ -0,0 +1,17 @@ +// Generate strings which dereference dotted properties, but use array notation + +const shouldUseDot = /^[a-zA-Z$_][a-zA-Z0-9$_]*$/; +const dereferenceString = prop => + prop.match(shouldUseDot) ? `.${prop}` : `['${prop}']`; + +/** + * returns a function which generates property dereference strings for the given name + * + * const getGlobalProp = propertyStringFor('global'); + * getGlobalProp('foo.bar.baz') => `global['foo']['bar']['baz']` + */ +const propertyStringFor = objName => propName => + objName + propName.split('.').map(dereferenceString).join(''); + + +export default propertyStringFor; \ No newline at end of file diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index 67b9860..6f0541f 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -4,6 +4,13 @@ import getInteropBlock from './shared/getInteropBlock.js'; import getExportBlock from './shared/getExportBlock.js'; import getGlobalNameMaker from './shared/getGlobalNameMaker.js'; import esModuleExport from './shared/esModuleExport.js'; +import propertyStringFor from './shared/propertyStringFor.js'; + +// globalProp('foo.bar') === "global['foo']['bar']" +const globalProp = propertyStringFor('global'); + +// propString('foo.bar') === "['foo']['bar']" +const propString = propertyStringFor(''); function setupNamespace ( name ) { const parts = name.split( '.' ); @@ -11,8 +18,8 @@ function setupNamespace ( name ) { let acc = 'global'; return parts - .map( part => ( acc += `.${part}`, `${acc} = ${acc} || {}` ) ) - .concat( `global.${name}` ) + .map( part => ( acc += propString(part), `${acc} = ${acc} || {}` ) ) + .concat( globalProp(name) ) .join( ', ' ); } @@ -27,14 +34,14 @@ export default function umd ( bundle, magicString, { exportMode, indentString, i const amdDeps = bundle.externalModules.map( quotePath ); const cjsDeps = bundle.externalModules.map( req ); - const globalDeps = bundle.externalModules.map( module => `global.${globalNameMaker( module )}` ); + const globalDeps = bundle.externalModules.map( module => globalProp(globalNameMaker( module )) ); const args = bundle.externalModules.map( getName ); if ( exportMode === 'named' ) { amdDeps.unshift( `'exports'` ); cjsDeps.unshift( `exports` ); - globalDeps.unshift( `(${setupNamespace(options.moduleName)} = global.${options.moduleName} || {})` ); + globalDeps.unshift( `(${setupNamespace(options.moduleName)} = ${globalProp(options.moduleName)} || {})` ); args.unshift( 'exports' ); } @@ -50,10 +57,10 @@ export default function umd ( bundle, magicString, { exportMode, indentString, i const globalExport = options.noConflict === true ? `(function() { - var current = global.${options.moduleName}; + var current = ${globalProp(options.moduleName)}; var exports = factory(${globalDeps}); - global.${options.moduleName} = exports; - exports.noConflict = function() { global.${options.moduleName} = current; return exports; }; + ${globalProp(options.moduleName)} = exports; + exports.noConflict = function() { ${globalProp(options.moduleName)} = current; return exports; }; })()` : `(${defaultExport}factory(${globalDeps}))`; const wrapperIntro = diff --git a/test/form/module-name-scoped-package/_config.js b/test/form/module-name-scoped-package/_config.js new file mode 100644 index 0000000..5681881 --- /dev/null +++ b/test/form/module-name-scoped-package/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'allows module name with dashes to be added to the global object', + options: { + moduleName: '@scoped/npm-package' + } +}; diff --git a/test/form/module-name-scoped-package/_expected/amd.js b/test/form/module-name-scoped-package/_expected/amd.js new file mode 100644 index 0000000..69586a0 --- /dev/null +++ b/test/form/module-name-scoped-package/_expected/amd.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + let foo = 'foo'; + + exports.foo = foo; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/form/module-name-scoped-package/_expected/cjs.js b/test/form/module-name-scoped-package/_expected/cjs.js new file mode 100644 index 0000000..796e3ef --- /dev/null +++ b/test/form/module-name-scoped-package/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +let foo = 'foo'; + +exports.foo = foo; diff --git a/test/form/module-name-scoped-package/_expected/es.js b/test/form/module-name-scoped-package/_expected/es.js new file mode 100644 index 0000000..3ee7d0b --- /dev/null +++ b/test/form/module-name-scoped-package/_expected/es.js @@ -0,0 +1,3 @@ +let foo = 'foo'; + +export { foo }; diff --git a/test/form/module-name-scoped-package/_expected/iife.js b/test/form/module-name-scoped-package/_expected/iife.js new file mode 100644 index 0000000..7445d49 --- /dev/null +++ b/test/form/module-name-scoped-package/_expected/iife.js @@ -0,0 +1,8 @@ +(function (exports) { + 'use strict'; + + let foo = 'foo'; + + exports.foo = foo; + +}((this['@scoped/npm-package'] = this['@scoped/npm-package'] || {}))); diff --git a/test/form/module-name-scoped-package/_expected/umd.js b/test/form/module-name-scoped-package/_expected/umd.js new file mode 100644 index 0000000..3382219 --- /dev/null +++ b/test/form/module-name-scoped-package/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global['@scoped/npm-package'] = global['@scoped/npm-package'] || {}))); +}(this, (function (exports) { 'use strict'; + + let foo = 'foo'; + + exports.foo = foo; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/test/form/module-name-scoped-package/main.js b/test/form/module-name-scoped-package/main.js new file mode 100644 index 0000000..816d625 --- /dev/null +++ b/test/form/module-name-scoped-package/main.js @@ -0,0 +1 @@ +export let foo = 'foo'; diff --git a/test/form/module-name-with-dashes/_config.js b/test/form/module-name-with-dashes/_config.js new file mode 100644 index 0000000..c466b88 --- /dev/null +++ b/test/form/module-name-with-dashes/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'allows module name with dashes to be added to the global object', + options: { + moduleName: 'module-name-with-dashes' + } +}; diff --git a/test/form/module-name-with-dashes/_expected/amd.js b/test/form/module-name-with-dashes/_expected/amd.js new file mode 100644 index 0000000..69586a0 --- /dev/null +++ b/test/form/module-name-with-dashes/_expected/amd.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + let foo = 'foo'; + + exports.foo = foo; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/form/module-name-with-dashes/_expected/cjs.js b/test/form/module-name-with-dashes/_expected/cjs.js new file mode 100644 index 0000000..796e3ef --- /dev/null +++ b/test/form/module-name-with-dashes/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +let foo = 'foo'; + +exports.foo = foo; diff --git a/test/form/module-name-with-dashes/_expected/es.js b/test/form/module-name-with-dashes/_expected/es.js new file mode 100644 index 0000000..3ee7d0b --- /dev/null +++ b/test/form/module-name-with-dashes/_expected/es.js @@ -0,0 +1,3 @@ +let foo = 'foo'; + +export { foo }; diff --git a/test/form/module-name-with-dashes/_expected/iife.js b/test/form/module-name-with-dashes/_expected/iife.js new file mode 100644 index 0000000..5eb1062 --- /dev/null +++ b/test/form/module-name-with-dashes/_expected/iife.js @@ -0,0 +1,8 @@ +(function (exports) { + 'use strict'; + + let foo = 'foo'; + + exports.foo = foo; + +}((this['module-name-with-dashes'] = this['module-name-with-dashes'] || {}))); diff --git a/test/form/module-name-with-dashes/_expected/umd.js b/test/form/module-name-with-dashes/_expected/umd.js new file mode 100644 index 0000000..8d90ff6 --- /dev/null +++ b/test/form/module-name-with-dashes/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global['module-name-with-dashes'] = global['module-name-with-dashes'] || {}))); +}(this, (function (exports) { 'use strict'; + + let foo = 'foo'; + + exports.foo = foo; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/test/form/module-name-with-dashes/main.js b/test/form/module-name-with-dashes/main.js new file mode 100644 index 0000000..816d625 --- /dev/null +++ b/test/form/module-name-with-dashes/main.js @@ -0,0 +1 @@ +export let foo = 'foo'; From bb546d342d88043d3c282a9057dae3e36897df48 Mon Sep 17 00:00:00 2001 From: Chris Thielen Date: Wed, 14 Dec 2016 17:24:37 -0600 Subject: [PATCH 328/331] Add test for bizzare moduleName --- test/form/module-name-wat/_config.js | 6 ++++++ test/form/module-name-wat/_expected/amd.js | 9 +++++++++ test/form/module-name-wat/_expected/cjs.js | 7 +++++++ test/form/module-name-wat/_expected/es.js | 3 +++ test/form/module-name-wat/_expected/iife.js | 11 +++++++++++ test/form/module-name-wat/_expected/umd.js | 13 +++++++++++++ test/form/module-name-wat/main.js | 1 + 7 files changed, 50 insertions(+) create mode 100644 test/form/module-name-wat/_config.js create mode 100644 test/form/module-name-wat/_expected/amd.js create mode 100644 test/form/module-name-wat/_expected/cjs.js create mode 100644 test/form/module-name-wat/_expected/es.js create mode 100644 test/form/module-name-wat/_expected/iife.js create mode 100644 test/form/module-name-wat/_expected/umd.js create mode 100644 test/form/module-name-wat/main.js diff --git a/test/form/module-name-wat/_config.js b/test/form/module-name-wat/_config.js new file mode 100644 index 0000000..31fe8d4 --- /dev/null +++ b/test/form/module-name-wat/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'properly dereferences properties on the global object regardless of nesting', + options: { + moduleName: 'foo.@scoped/npm-package.bar.why-would-you-do-this' + } +}; diff --git a/test/form/module-name-wat/_expected/amd.js b/test/form/module-name-wat/_expected/amd.js new file mode 100644 index 0000000..69586a0 --- /dev/null +++ b/test/form/module-name-wat/_expected/amd.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + let foo = 'foo'; + + exports.foo = foo; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/form/module-name-wat/_expected/cjs.js b/test/form/module-name-wat/_expected/cjs.js new file mode 100644 index 0000000..796e3ef --- /dev/null +++ b/test/form/module-name-wat/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +let foo = 'foo'; + +exports.foo = foo; diff --git a/test/form/module-name-wat/_expected/es.js b/test/form/module-name-wat/_expected/es.js new file mode 100644 index 0000000..3ee7d0b --- /dev/null +++ b/test/form/module-name-wat/_expected/es.js @@ -0,0 +1,3 @@ +let foo = 'foo'; + +export { foo }; diff --git a/test/form/module-name-wat/_expected/iife.js b/test/form/module-name-wat/_expected/iife.js new file mode 100644 index 0000000..2f7b7b2 --- /dev/null +++ b/test/form/module-name-wat/_expected/iife.js @@ -0,0 +1,11 @@ +this.foo = this.foo || {}; +this.foo['@scoped/npm-package'] = this.foo['@scoped/npm-package'] || {}; +this.foo['@scoped/npm-package'].bar = this.foo['@scoped/npm-package'].bar || {}; +(function (exports) { + 'use strict'; + + let foo = 'foo'; + + exports.foo = foo; + +}((this.foo['@scoped/npm-package'].bar['why-would-you-do-this'] = this.foo['@scoped/npm-package'].bar['why-would-you-do-this'] || {}))); diff --git a/test/form/module-name-wat/_expected/umd.js b/test/form/module-name-wat/_expected/umd.js new file mode 100644 index 0000000..22c8010 --- /dev/null +++ b/test/form/module-name-wat/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.foo = global.foo || {}, global.foo['@scoped/npm-package'] = global.foo['@scoped/npm-package'] || {}, global.foo['@scoped/npm-package'].bar = global.foo['@scoped/npm-package'].bar || {}, global.foo['@scoped/npm-package'].bar['why-would-you-do-this'] = global.foo['@scoped/npm-package'].bar['why-would-you-do-this'] || {}))); +}(this, (function (exports) { 'use strict'; + + let foo = 'foo'; + + exports.foo = foo; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/test/form/module-name-wat/main.js b/test/form/module-name-wat/main.js new file mode 100644 index 0000000..816d625 --- /dev/null +++ b/test/form/module-name-wat/main.js @@ -0,0 +1 @@ +export let foo = 'foo'; From 2521f2e6e3a8915451faa36fd494254346ad08d1 Mon Sep 17 00:00:00 2001 From: kzc Date: Thu, 15 Dec 2016 08:47:11 -0500 Subject: [PATCH 329/331] be more leniant in processing ExportDefaultDeclaration (#1146) --- src/ast/nodes/ExportDefaultDeclaration.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/nodes/ExportDefaultDeclaration.js b/src/ast/nodes/ExportDefaultDeclaration.js index f583682..94c2784 100644 --- a/src/ast/nodes/ExportDefaultDeclaration.js +++ b/src/ast/nodes/ExportDefaultDeclaration.js @@ -53,7 +53,7 @@ export default class ExportDefaultDeclaration extends Node { let declaration_start; if ( this.declaration ) { const statementStr = code.original.slice( this.start, this.end ); - declaration_start = this.start + statementStr.match(/^export\s+default\s*/)[0].length; + declaration_start = this.start + statementStr.match(/^\s*export\s+default\s+/)[0].length; } if ( this.shouldInclude || this.declaration.activated ) { From b1e4384865421b50a4102e89d708c8f7f926e8f2 Mon Sep 17 00:00:00 2001 From: Chris Thielen Date: Thu, 15 Dec 2016 10:00:49 -0600 Subject: [PATCH 330/331] Update comments describing property string generation --- src/finalisers/iife.js | 4 ++-- src/finalisers/shared/propertyStringFor.js | 5 +++-- src/finalisers/umd.js | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/finalisers/iife.js b/src/finalisers/iife.js index 3946286..01d1325 100644 --- a/src/finalisers/iife.js +++ b/src/finalisers/iife.js @@ -5,10 +5,10 @@ import getExportBlock from './shared/getExportBlock.js'; import getGlobalNameMaker from './shared/getGlobalNameMaker.js'; import propertyStringFor from './shared/propertyStringFor'; -// thisProp('foo.bar.baz') === "this['foo']['bar']['baz']" +// thisProp('foo.bar-baz.qux') === "this.foo['bar-baz'].qux" const thisProp = propertyStringFor('this'); -// propString('foo.bar') === "['foo']['bar']" +// propString('foo.bar-baz.qux') === ".foo['bar-baz'].qux" const propString = propertyStringFor(''); function setupNamespace ( keypath ) { diff --git a/src/finalisers/shared/propertyStringFor.js b/src/finalisers/shared/propertyStringFor.js index f0c2948..72ad1bb 100644 --- a/src/finalisers/shared/propertyStringFor.js +++ b/src/finalisers/shared/propertyStringFor.js @@ -1,4 +1,5 @@ -// Generate strings which dereference dotted properties, but use array notation +// Generate strings which dereference dotted properties, but use array notation `['prop-deref']` +// if the property name isn't trivial const shouldUseDot = /^[a-zA-Z$_][a-zA-Z0-9$_]*$/; const dereferenceString = prop => @@ -8,7 +9,7 @@ const dereferenceString = prop => * returns a function which generates property dereference strings for the given name * * const getGlobalProp = propertyStringFor('global'); - * getGlobalProp('foo.bar.baz') => `global['foo']['bar']['baz']` + * getGlobalProp('foo.bar-baz.qux') => `global.bar['bar-baz'].qux` */ const propertyStringFor = objName => propName => objName + propName.split('.').map(dereferenceString).join(''); diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index 6f0541f..dd8b9c6 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -6,10 +6,10 @@ import getGlobalNameMaker from './shared/getGlobalNameMaker.js'; import esModuleExport from './shared/esModuleExport.js'; import propertyStringFor from './shared/propertyStringFor.js'; -// globalProp('foo.bar') === "global['foo']['bar']" +// globalProp('foo.bar-baz') === "global.foo['bar-baz']" const globalProp = propertyStringFor('global'); -// propString('foo.bar') === "['foo']['bar']" +// propString('foo.bar-baz') === ".foo['bar']" const propString = propertyStringFor(''); function setupNamespace ( name ) { From 583b13d757493cd90db699665b198d9b8ecf9975 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder Date: Tue, 13 Dec 2016 23:32:20 +0100 Subject: [PATCH 331/331] Improves tree-shaking by only considering program-level assignments as a Bundle's dependent expressions. --- src/ast/nodes/AssignmentExpression.js | 6 +++++- src/ast/nodes/CallExpression.js | 12 +----------- src/ast/utils/isProgramLevel.js | 10 ++++++++++ test/form/side-effect-r/_config.js | 1 - test/form/side-effect-r/_expected/amd.js | 5 +++++ test/form/side-effect-r/_expected/cjs.js | 2 ++ test/form/side-effect-r/_expected/es.js | 1 + test/form/side-effect-r/_expected/iife.js | 6 ++++++ test/form/side-effect-r/_expected/umd.js | 9 +++++++++ test/form/side-effect-s/_config.js | 3 +++ test/form/side-effect-s/_expected/amd.js | 5 +++++ test/form/side-effect-s/_expected/cjs.js | 2 ++ test/form/side-effect-s/_expected/es.js | 1 + test/form/side-effect-s/_expected/iife.js | 6 ++++++ test/form/side-effect-s/_expected/umd.js | 9 +++++++++ test/form/side-effect-s/main.js | 7 +++++++ test/form/skips-dead-branches-h/_config.js | 3 +++ test/form/skips-dead-branches-h/_expected/amd.js | 8 ++++++++ test/form/skips-dead-branches-h/_expected/cjs.js | 6 ++++++ test/form/skips-dead-branches-h/_expected/es.js | 4 ++++ test/form/skips-dead-branches-h/_expected/iife.js | 9 +++++++++ test/form/skips-dead-branches-h/_expected/umd.js | 12 ++++++++++++ test/form/skips-dead-branches-h/main.js | 11 +++++++++++ test/form/skips-dead-branches-i/_config.js | 3 +++ test/form/skips-dead-branches-i/_expected/amd.js | 8 ++++++++ test/form/skips-dead-branches-i/_expected/cjs.js | 6 ++++++ test/form/skips-dead-branches-i/_expected/es.js | 4 ++++ test/form/skips-dead-branches-i/_expected/iife.js | 9 +++++++++ test/form/skips-dead-branches-i/_expected/umd.js | 12 ++++++++++++ test/form/skips-dead-branches-i/main.js | 12 ++++++++++++ 30 files changed, 179 insertions(+), 13 deletions(-) create mode 100644 src/ast/utils/isProgramLevel.js create mode 100644 test/form/side-effect-r/_expected/amd.js create mode 100644 test/form/side-effect-r/_expected/cjs.js create mode 100644 test/form/side-effect-r/_expected/es.js create mode 100644 test/form/side-effect-r/_expected/iife.js create mode 100644 test/form/side-effect-r/_expected/umd.js create mode 100644 test/form/side-effect-s/_config.js create mode 100644 test/form/side-effect-s/_expected/amd.js create mode 100644 test/form/side-effect-s/_expected/cjs.js create mode 100644 test/form/side-effect-s/_expected/es.js create mode 100644 test/form/side-effect-s/_expected/iife.js create mode 100644 test/form/side-effect-s/_expected/umd.js create mode 100644 test/form/side-effect-s/main.js create mode 100644 test/form/skips-dead-branches-h/_config.js create mode 100644 test/form/skips-dead-branches-h/_expected/amd.js create mode 100644 test/form/skips-dead-branches-h/_expected/cjs.js create mode 100644 test/form/skips-dead-branches-h/_expected/es.js create mode 100644 test/form/skips-dead-branches-h/_expected/iife.js create mode 100644 test/form/skips-dead-branches-h/_expected/umd.js create mode 100644 test/form/skips-dead-branches-h/main.js create mode 100644 test/form/skips-dead-branches-i/_config.js create mode 100644 test/form/skips-dead-branches-i/_expected/amd.js create mode 100644 test/form/skips-dead-branches-i/_expected/cjs.js create mode 100644 test/form/skips-dead-branches-i/_expected/es.js create mode 100644 test/form/skips-dead-branches-i/_expected/iife.js create mode 100644 test/form/skips-dead-branches-i/_expected/umd.js create mode 100644 test/form/skips-dead-branches-i/main.js diff --git a/src/ast/nodes/AssignmentExpression.js b/src/ast/nodes/AssignmentExpression.js index 6e4aa2b..bbbb7d0 100644 --- a/src/ast/nodes/AssignmentExpression.js +++ b/src/ast/nodes/AssignmentExpression.js @@ -1,6 +1,7 @@ import Node from '../Node.js'; import disallowIllegalReassignment from './shared/disallowIllegalReassignment.js'; import isUsedByBundle from './shared/isUsedByBundle.js'; +import isProgramLevel from '../utils/isProgramLevel.js'; import { NUMBER, STRING } from '../values.js'; export default class AssignmentExpression extends Node { @@ -36,7 +37,10 @@ export default class AssignmentExpression extends Node { initialise ( scope ) { this.scope = scope; - this.module.bundle.dependentExpressions.push( this ); + if ( isProgramLevel( this ) ) { + this.module.bundle.dependentExpressions.push( this ); + } + super.initialise( scope ); } diff --git a/src/ast/nodes/CallExpression.js b/src/ast/nodes/CallExpression.js index 70d1e13..720e866 100644 --- a/src/ast/nodes/CallExpression.js +++ b/src/ast/nodes/CallExpression.js @@ -1,6 +1,7 @@ import getLocation from '../../utils/getLocation.js'; import error from '../../utils/error.js'; import Node from '../Node.js'; +import isProgramLevel from '../utils/isProgramLevel.js'; import callHasEffects from './shared/callHasEffects.js'; export default class CallExpression extends Node { @@ -40,14 +41,3 @@ export default class CallExpression extends Node { return this.hasEffects( this.findScope() ); } } - -function isProgramLevel ( node ) { - do { - if ( node.type === 'Program' ) { - return true; - } - node = node.parent; - } while ( node && !/Function/.test( node.type ) ); - - return false; -} diff --git a/src/ast/utils/isProgramLevel.js b/src/ast/utils/isProgramLevel.js new file mode 100644 index 0000000..b23de12 --- /dev/null +++ b/src/ast/utils/isProgramLevel.js @@ -0,0 +1,10 @@ +export default function isProgramLevel ( node ) { + do { + if ( node.type === 'Program' ) { + return true; + } + node = node.parent; + } while ( node && !/Function/.test( node.type ) ); + + return false; +} diff --git a/test/form/side-effect-r/_config.js b/test/form/side-effect-r/_config.js index 2c3f470..3a59976 100644 --- a/test/form/side-effect-r/_config.js +++ b/test/form/side-effect-r/_config.js @@ -1,4 +1,3 @@ module.exports = { - skip: true, description: 'discards unused function expression assigned to a variable that calls itself and a global' }; diff --git a/test/form/side-effect-r/_expected/amd.js b/test/form/side-effect-r/_expected/amd.js new file mode 100644 index 0000000..f9f8229 --- /dev/null +++ b/test/form/side-effect-r/_expected/amd.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + + +}); diff --git a/test/form/side-effect-r/_expected/cjs.js b/test/form/side-effect-r/_expected/cjs.js new file mode 100644 index 0000000..eb109ab --- /dev/null +++ b/test/form/side-effect-r/_expected/cjs.js @@ -0,0 +1,2 @@ +'use strict'; + diff --git a/test/form/side-effect-r/_expected/es.js b/test/form/side-effect-r/_expected/es.js new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/form/side-effect-r/_expected/es.js @@ -0,0 +1 @@ + diff --git a/test/form/side-effect-r/_expected/iife.js b/test/form/side-effect-r/_expected/iife.js new file mode 100644 index 0000000..43ef542 --- /dev/null +++ b/test/form/side-effect-r/_expected/iife.js @@ -0,0 +1,6 @@ +(function () { + 'use strict'; + + + +}()); diff --git a/test/form/side-effect-r/_expected/umd.js b/test/form/side-effect-r/_expected/umd.js new file mode 100644 index 0000000..07ce27e --- /dev/null +++ b/test/form/side-effect-r/_expected/umd.js @@ -0,0 +1,9 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + + +}))); diff --git a/test/form/side-effect-s/_config.js b/test/form/side-effect-s/_config.js new file mode 100644 index 0000000..457689e --- /dev/null +++ b/test/form/side-effect-s/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'discards unused function expression assigned to a variable that calls itself and has side effects' +}; diff --git a/test/form/side-effect-s/_expected/amd.js b/test/form/side-effect-s/_expected/amd.js new file mode 100644 index 0000000..f9f8229 --- /dev/null +++ b/test/form/side-effect-s/_expected/amd.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + + +}); diff --git a/test/form/side-effect-s/_expected/cjs.js b/test/form/side-effect-s/_expected/cjs.js new file mode 100644 index 0000000..eb109ab --- /dev/null +++ b/test/form/side-effect-s/_expected/cjs.js @@ -0,0 +1,2 @@ +'use strict'; + diff --git a/test/form/side-effect-s/_expected/es.js b/test/form/side-effect-s/_expected/es.js new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/form/side-effect-s/_expected/es.js @@ -0,0 +1 @@ + diff --git a/test/form/side-effect-s/_expected/iife.js b/test/form/side-effect-s/_expected/iife.js new file mode 100644 index 0000000..43ef542 --- /dev/null +++ b/test/form/side-effect-s/_expected/iife.js @@ -0,0 +1,6 @@ +(function () { + 'use strict'; + + + +}()); diff --git a/test/form/side-effect-s/_expected/umd.js b/test/form/side-effect-s/_expected/umd.js new file mode 100644 index 0000000..07ce27e --- /dev/null +++ b/test/form/side-effect-s/_expected/umd.js @@ -0,0 +1,9 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + + +}))); diff --git a/test/form/side-effect-s/main.js b/test/form/side-effect-s/main.js new file mode 100644 index 0000000..3d63fdf --- /dev/null +++ b/test/form/side-effect-s/main.js @@ -0,0 +1,7 @@ +var foo = function foo(param) { + if ( whatever ) { + foo(param); + } else { + param.foo = 1; + } +}; diff --git a/test/form/skips-dead-branches-h/_config.js b/test/form/skips-dead-branches-h/_config.js new file mode 100644 index 0000000..85e8fbe --- /dev/null +++ b/test/form/skips-dead-branches-h/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'skips a dead branch (h)' +}; diff --git a/test/form/skips-dead-branches-h/_expected/amd.js b/test/form/skips-dead-branches-h/_expected/amd.js new file mode 100644 index 0000000..6847fcb --- /dev/null +++ b/test/form/skips-dead-branches-h/_expected/amd.js @@ -0,0 +1,8 @@ +define(function () { 'use strict'; + + function baz() { + console.log("baz"); + } + baz(); + +}); diff --git a/test/form/skips-dead-branches-h/_expected/cjs.js b/test/form/skips-dead-branches-h/_expected/cjs.js new file mode 100644 index 0000000..6f1ef21 --- /dev/null +++ b/test/form/skips-dead-branches-h/_expected/cjs.js @@ -0,0 +1,6 @@ +'use strict'; + +function baz() { + console.log("baz"); +} +baz(); diff --git a/test/form/skips-dead-branches-h/_expected/es.js b/test/form/skips-dead-branches-h/_expected/es.js new file mode 100644 index 0000000..788788a --- /dev/null +++ b/test/form/skips-dead-branches-h/_expected/es.js @@ -0,0 +1,4 @@ +function baz() { + console.log("baz"); +} +baz(); diff --git a/test/form/skips-dead-branches-h/_expected/iife.js b/test/form/skips-dead-branches-h/_expected/iife.js new file mode 100644 index 0000000..88532fd --- /dev/null +++ b/test/form/skips-dead-branches-h/_expected/iife.js @@ -0,0 +1,9 @@ +(function () { + 'use strict'; + + function baz() { + console.log("baz"); + } + baz(); + +}()); diff --git a/test/form/skips-dead-branches-h/_expected/umd.js b/test/form/skips-dead-branches-h/_expected/umd.js new file mode 100644 index 0000000..6286b12 --- /dev/null +++ b/test/form/skips-dead-branches-h/_expected/umd.js @@ -0,0 +1,12 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + function baz() { + console.log("baz"); + } + baz(); + +}))); diff --git a/test/form/skips-dead-branches-h/main.js b/test/form/skips-dead-branches-h/main.js new file mode 100644 index 0000000..7808b0d --- /dev/null +++ b/test/form/skips-dead-branches-h/main.js @@ -0,0 +1,11 @@ +function bar(umm) { + umm = hmm(); + console.log("bar"); +} +function hmm() { + return true; +} +function baz() { + console.log("baz"); +} +baz(); diff --git a/test/form/skips-dead-branches-i/_config.js b/test/form/skips-dead-branches-i/_config.js new file mode 100644 index 0000000..85e8fbe --- /dev/null +++ b/test/form/skips-dead-branches-i/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'skips a dead branch (h)' +}; diff --git a/test/form/skips-dead-branches-i/_expected/amd.js b/test/form/skips-dead-branches-i/_expected/amd.js new file mode 100644 index 0000000..6847fcb --- /dev/null +++ b/test/form/skips-dead-branches-i/_expected/amd.js @@ -0,0 +1,8 @@ +define(function () { 'use strict'; + + function baz() { + console.log("baz"); + } + baz(); + +}); diff --git a/test/form/skips-dead-branches-i/_expected/cjs.js b/test/form/skips-dead-branches-i/_expected/cjs.js new file mode 100644 index 0000000..6f1ef21 --- /dev/null +++ b/test/form/skips-dead-branches-i/_expected/cjs.js @@ -0,0 +1,6 @@ +'use strict'; + +function baz() { + console.log("baz"); +} +baz(); diff --git a/test/form/skips-dead-branches-i/_expected/es.js b/test/form/skips-dead-branches-i/_expected/es.js new file mode 100644 index 0000000..788788a --- /dev/null +++ b/test/form/skips-dead-branches-i/_expected/es.js @@ -0,0 +1,4 @@ +function baz() { + console.log("baz"); +} +baz(); diff --git a/test/form/skips-dead-branches-i/_expected/iife.js b/test/form/skips-dead-branches-i/_expected/iife.js new file mode 100644 index 0000000..88532fd --- /dev/null +++ b/test/form/skips-dead-branches-i/_expected/iife.js @@ -0,0 +1,9 @@ +(function () { + 'use strict'; + + function baz() { + console.log("baz"); + } + baz(); + +}()); diff --git a/test/form/skips-dead-branches-i/_expected/umd.js b/test/form/skips-dead-branches-i/_expected/umd.js new file mode 100644 index 0000000..6286b12 --- /dev/null +++ b/test/form/skips-dead-branches-i/_expected/umd.js @@ -0,0 +1,12 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + function baz() { + console.log("baz"); + } + baz(); + +}))); diff --git a/test/form/skips-dead-branches-i/main.js b/test/form/skips-dead-branches-i/main.js new file mode 100644 index 0000000..6380bcf --- /dev/null +++ b/test/form/skips-dead-branches-i/main.js @@ -0,0 +1,12 @@ +function bar() { + var t; + t = hmm(); + console.log("bar"); +} +function hmm() { + return true; +} +function baz() { + console.log("baz"); +} +baz();