Skip to content

Commit

Permalink
Support for async transformBundle
Browse files Browse the repository at this point in the history
  • Loading branch information
caccialdo committed Jul 7, 2017
1 parent ef59ea2 commit 05fb800
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 155 deletions.
17 changes: 9 additions & 8 deletions bin/src/runRollup.js
Expand Up @@ -73,10 +73,11 @@ export default function runRollup ( command ) {
onwarn: handleWarning
})
.then( bundle => {
const { code } = bundle.generate({
return bundle.generate({
format: 'cjs'
});

})
.then( ({ code }) => {
if ( command.watch ) process.env.ROLLUP_WATCH = 'true';

// temporarily override require
Expand Down Expand Up @@ -270,13 +271,13 @@ function bundle ( options ) {
});
}

let { code, map } = bundle.generate( options );

if ( options.sourceMap === 'inline' ) {
code += `\n//# ${SOURCEMAPPING_URL}=${map.toUrl()}\n`;
}
return bundle.generate(options).then( ({ code, map }) => {
if ( options.sourceMap === 'inline' ) {
code += `\n//# ${SOURCEMAPPING_URL}=${map.toUrl()}\n`;
}

process.stdout.write( code );
process.stdout.write( code );
});
})
.catch( handleError );
}
172 changes: 87 additions & 85 deletions src/Bundle.js
Expand Up @@ -437,119 +437,121 @@ export default class Bundle {
}

render ( options = {} ) {
if ( options.format === 'es6' ) {
this.warn({
code: 'DEPRECATED_ES6',
message: 'The es6 format is deprecated – use `es` instead'
});

options.format = 'es';
}
return Promise.resolve().then( () => {
if ( options.format === 'es6' ) {
this.warn({
code: 'DEPRECATED_ES6',
message: 'The es6 format is deprecated – use `es` instead'
});

// Determine export mode - 'default', 'named', 'none'
const exportMode = getExportMode( this, options );
options.format = 'es';
}

let magicString = new MagicStringBundle({ separator: '\n\n' });
const usedModules = [];
// Determine export mode - 'default', 'named', 'none'
const exportMode = getExportMode( this, options );

timeStart( 'render modules' );
let magicString = new MagicStringBundle({ separator: '\n\n' });
const usedModules = [];

this.orderedModules.forEach( module => {
const source = module.render( options.format === 'es', this.legacy );
timeStart( 'render modules' );

if ( source.toString().length ) {
magicString.addSource( source );
usedModules.push( module );
}
});
this.orderedModules.forEach( module => {
const source = module.render( options.format === 'es', this.legacy );

if ( !magicString.toString().trim() && this.entryModule.getExports().length === 0 ) {
this.warn({
code: 'EMPTY_BUNDLE',
message: 'Generated an empty bundle'
if ( source.toString().length ) {
magicString.addSource( source );
usedModules.push( module );
}
});
}

timeEnd( 'render modules' );
if ( !magicString.toString().trim() && this.entryModule.getExports().length === 0 ) {
this.warn({
code: 'EMPTY_BUNDLE',
message: 'Generated an empty bundle'
});
}

let intro = [ options.intro ]
.concat(
this.plugins.map( plugin => plugin.intro && plugin.intro() )
)
.filter( Boolean )
.join( '\n\n' );
timeEnd( 'render modules' );

if ( intro ) intro += '\n\n';
let intro = [ options.intro ]
.concat(
this.plugins.map( plugin => plugin.intro && plugin.intro() )
)
.filter( Boolean )
.join( '\n\n' );

let outro = [ options.outro ]
.concat(
this.plugins.map( plugin => plugin.outro && plugin.outro() )
)
.filter( Boolean )
.join( '\n\n' );
if ( intro ) intro += '\n\n';

if ( outro ) outro = `\n\n${outro}`;
let outro = [ options.outro ]
.concat(
this.plugins.map( plugin => plugin.outro && plugin.outro() )
)
.filter( Boolean )
.join( '\n\n' );

const indentString = getIndentString( magicString, options );
if ( outro ) outro = `\n\n${outro}`;

const finalise = finalisers[ options.format ];
if ( !finalise ) {
error({
code: 'INVALID_OPTION',
message: `You must specify an output type - valid options are ${keys( finalisers ).join( ', ' )}`
});
}
const indentString = getIndentString( magicString, options );

timeStart( 'render format' );
const finalise = finalisers[ options.format ];
if ( !finalise ) {
error({
code: 'INVALID_OPTION',
message: `You must specify an output type - valid options are ${keys( finalisers ).join( ', ' )}`
});
}

magicString = finalise( this, magicString.trim(), { exportMode, indentString, intro, outro }, options );
timeStart( 'render format' );

timeEnd( 'render format' );
magicString = finalise( this, magicString.trim(), { exportMode, indentString, intro, outro }, options );

const banner = [ options.banner ]
.concat( this.plugins.map( plugin => plugin.banner ) )
.map( callIfFunction )
.filter( Boolean )
.join( '\n' );
timeEnd( 'render format' );

const footer = [ options.footer ]
.concat( this.plugins.map( plugin => plugin.footer ) )
.map( callIfFunction )
.filter( Boolean )
.join( '\n' );
const banner = [ options.banner ]
.concat( this.plugins.map( plugin => plugin.banner ) )
.map( callIfFunction )
.filter( Boolean )
.join( '\n' );

if ( banner ) magicString.prepend( banner + '\n' );
if ( footer ) magicString.append( '\n' + footer );
const footer = [ options.footer ]
.concat( this.plugins.map( plugin => plugin.footer ) )
.map( callIfFunction )
.filter( Boolean )
.join( '\n' );

let code = magicString.toString();
let map = null;
const bundleSourcemapChain = [];
if ( banner ) magicString.prepend( banner + '\n' );
if ( footer ) magicString.append( '\n' + footer );

code = transformBundle( code, this.plugins, bundleSourcemapChain, options );
const prevCode = magicString.toString();
let map = null;
const bundleSourcemapChain = [];

if ( options.sourceMap ) {
timeStart( 'sourceMap' );
return transformBundle( prevCode, this.plugins, bundleSourcemapChain, options ).then( code => {
if ( options.sourceMap ) {
timeStart( 'sourceMap' );

let file = options.sourceMapFile || options.dest;
if ( file ) file = resolve( typeof process !== 'undefined' ? process.cwd() : '', file );
let file = options.sourceMapFile || options.dest;
if ( file ) file = resolve( typeof process !== 'undefined' ? process.cwd() : '', file );

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( this, file, map, usedModules, bundleSourcemapChain );
} else {
map = magicString.generateMap({ file, includeContent: true });
}
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( this, file, map, usedModules, bundleSourcemapChain );
} else {
map = magicString.generateMap({ file, includeContent: true });
}

map.sources = map.sources.map( normalize );
map.sources = map.sources.map( normalize );

timeEnd( 'sourceMap' );
}
timeEnd( 'sourceMap' );
}

if ( code[ code.length - 1 ] !== '\n' ) code += '\n';
return { code, map };
if ( code[ code.length - 1 ] !== '\n' ) code += '\n';
return { code, map };
});
});
}

sort () {
Expand Down
65 changes: 34 additions & 31 deletions src/rollup.js
Expand Up @@ -94,21 +94,23 @@ export function rollup ( options ) {

timeStart( '--GENERATE--' );

const rendered = bundle.render( options );
return Promise.resolve().then(() => {
return bundle.render( options );
}).then( rendered => {
timeEnd( '--GENERATE--' );

bundle.plugins.forEach( plugin => {
if ( plugin.ongenerate ) {
plugin.ongenerate( assign({
bundle: result
}, options ), rendered);
}
});

timeEnd( '--GENERATE--' );
flushTime();

bundle.plugins.forEach( plugin => {
if ( plugin.ongenerate ) {
plugin.ongenerate( assign({
bundle: result
}, options ), rendered);
}
return rendered;
});

flushTime();

return rendered;
}

const result = {
Expand All @@ -126,30 +128,31 @@ export function rollup ( options ) {
}

const dest = options.dest;
const output = generate( options );
let { code, map } = output;
return generate( options ).then( output => {
let { code, map } = output;

const promises = [];
const promises = [];

if ( options.sourceMap ) {
let url;
if ( options.sourceMap ) {
let url;

if ( options.sourceMap === 'inline' ) {
url = map.toUrl();
} else {
url = `${basename( dest )}.map`;
promises.push( writeFile( dest + '.map', map.toString() ) );
}
if ( options.sourceMap === 'inline' ) {
url = map.toUrl();
} else {
url = `${basename( dest )}.map`;
promises.push( writeFile( dest + '.map', map.toString() ) );
}

code += `//# ${SOURCEMAPPING_URL}=${url}\n`;
}
code += `//# ${SOURCEMAPPING_URL}=${url}\n`;
}

promises.push( writeFile( dest, code ) );
return Promise.all( promises ).then( () => {
return mapSequence( bundle.plugins.filter( plugin => plugin.onwrite ), plugin => {
return Promise.resolve( plugin.onwrite( assign({
bundle: result
}, options ), output));
promises.push( writeFile( dest, code ) );
return Promise.all( promises ).then( () => {
return mapSequence( bundle.plugins.filter( plugin => plugin.onwrite ), plugin => {
return Promise.resolve( plugin.onwrite( assign({
bundle: result
}, options ), output));
});
});
});
}
Expand Down
63 changes: 32 additions & 31 deletions src/utils/transformBundle.js
Expand Up @@ -2,37 +2,38 @@ import { decode } from 'sourcemap-codec';
import error from './error.js';

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, { format : options.format } );
} catch ( err ) {
error({
code: 'BAD_BUNDLE_TRANSFORMER',
message: `Error transforming bundle${plugin.name ? ` with '${plugin.name}' plugin` : ''}: ${err.message}`,
plugin: plugin.name
return plugins.reduce( ( promise, plugin ) => {
if ( !plugin.transformBundle ) return promise;

return promise.then( code => {
return Promise.resolve().then( () => {
return plugin.transformBundle( code, { format : options.format } );
}).then( result => {
if ( result == null ) return code;

if ( typeof result === 'string' ) {
result = {
code: result,
map: null
};
}

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;
}).catch( err => {
error({
code: 'BAD_BUNDLE_TRANSFORMER',
message: `Error transforming bundle${plugin.name ? ` with '${plugin.name}' plugin` : ''}: ${err.message}`,
plugin: plugin.name
});
});
}

if ( result == null ) return code;

if ( typeof result === 'string' ) {
result = {
code: result,
map: null
};
}

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;
}, code );
}, Promise.resolve( code ) );
}

0 comments on commit 05fb800

Please sign in to comment.