From ad44c4ba5b624c711787c01f9e86aedfd35135b1 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sat, 21 May 2016 22:52:50 +0300 Subject: [PATCH] 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); + }); + }); + }); + }); });