Skip to content
This repository has been archived by the owner on Aug 4, 2021. It is now read-only.

Commit

Permalink
Merge pull request #20 from rollup/optimise-wrappers-redux
Browse files Browse the repository at this point in the history
Optimise wrappers (redux)
  • Loading branch information
Rich-Harris committed Dec 27, 2015
2 parents 3a47efc + d6a4c60 commit 05e3f0f
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 101 deletions.
40 changes: 21 additions & 19 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function getName ( id ) {
export default function commonjs ( options = {} ) {
const filter = createFilter( options.include, options.exclude );
let bundleUsesGlobal = false;
let bundleRequiresWrappers = false;

const sourceMap = options.sourceMap !== false;

Expand Down Expand Up @@ -70,8 +71,7 @@ export default function commonjs ( options = {} ) {

let scope = attachScopes( ast, 'scope' );
let namedExports = {};
let usesModuleOrExports;
let usesGlobal;
let uses = { module: false, exports: false, global: false };

walk( ast, {
enter ( node, parent ) {
Expand Down Expand Up @@ -108,8 +108,7 @@ export default function commonjs ( options = {} ) {
}

if ( node.type === 'Identifier' ) {
if ( ( node.name === 'module' || node.name === 'exports' ) && isReference( node, parent ) && !scope.contains( node.name ) ) usesModuleOrExports = true;
if ( node.name === 'global' && isReference( node, parent ) && !scope.contains( 'global' ) ) usesGlobal = true;
if ( ( node.name in uses && !uses[ node.name ] ) && isReference( node, parent ) && !scope.contains( node.name ) ) uses[ node.name ] = true;
return;
}

Expand Down Expand Up @@ -139,25 +138,20 @@ export default function commonjs ( options = {} ) {

const sources = Object.keys( required );

if ( !sources.length && !usesModuleOrExports && !usesGlobal ) return null; // not a CommonJS module
if ( !sources.length && !uses.module && !uses.exports && !uses.global ) return null; // not a CommonJS module

bundleRequiresWrappers = true;

const name = getName( id );

const importBlock = sources.length ?
sources.map( source => `import ${required[ source ].name} from '${source}';` ).join( '\n' ) :
'';

const intro = `
var ${name} = (function (module${usesGlobal ? ', global' : ''}) {
var exports = module.exports;
`;

let outro = `
return module.exports;
})({exports:{}}${usesGlobal ? ', __commonjs_global' : ''});
const args = `module${uses.exports || uses.global ? ', exports' : ''}${uses.global ? ', global' : ''}`;

export default (${name} && typeof ${name} === 'object' && 'default' in ${name} ? ${name}['default'] : ${name});\n`;
const intro = `\n\nvar ${name} = __commonjs(function (${args}) {\n`;
let outro = `\n});\n\nexport default (${name} && typeof ${name} === 'object' && 'default' in ${name} ? ${name}['default'] : ${name});\n`;

outro += Object.keys( namedExports )
.filter( key => !blacklistedExports[ key ] )
Expand All @@ -172,15 +166,23 @@ export default (${name} && typeof ${name} === 'object' && 'default' in ${name} ?
code = magicString.toString();
const map = sourceMap ? magicString.generateMap() : null;

if ( usesGlobal ) bundleUsesGlobal = true;
if ( uses.global ) bundleUsesGlobal = true;

return { code, map };
},

intro () {
return bundleUsesGlobal ?
`var __commonjs_global = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : this;` :
'';
var intros = [];

if ( bundleUsesGlobal ) {
intros.push( `var __commonjs_global = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : this;` );
}

if ( bundleRequiresWrappers ) {
intros.push( `function __commonjs(fn, module) { return module = { exports: {} }, fn(module, module.exports${bundleUsesGlobal ? ', __commonjs_global' : ''}), module.exports; }\n` );
}

return intros.join( '\n' );
}
};
}
108 changes: 26 additions & 82 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,58 +6,44 @@ var commonjs = require( '..' );

process.chdir( __dirname );

function executeBundle ( bundle ) {
var generated = bundle.generate({
format: 'cjs'
});

var fn = new Function ( 'module', 'assert', generated.code );
var module = {};

fn( module, assert );

return module;
}

describe( 'rollup-plugin-commonjs', function () {
it( 'converts a basic CommonJS module', function () {
return rollup.rollup({
entry: 'samples/basic/main.js',
plugins: [ commonjs() ]
}).then( function ( bundle ) {
var generated = bundle.generate({
format: 'cjs'
});

var fn = new Function ( 'module', generated.code );
var module = {};

fn( module );

assert.equal( module.exports, 42 );
})
assert.equal( executeBundle( bundle ).exports, 42 );
});
});

it( 'converts a CommonJS module that mutates exports instead of replacing', function () {
return rollup.rollup({
entry: 'samples/exports/main.js',
plugins: [ commonjs() ]
}).then( function ( bundle ) {
var generated = bundle.generate({
format: 'cjs'
});

var fn = new Function ( 'module', generated.code );
var module = {};

fn( module );

assert.equal( module.exports, 'BARBAZ' );
})
assert.equal( executeBundle( bundle ).exports, 'BARBAZ' );
});
});

it( 'converts inline require calls', function () {
return rollup.rollup({
entry: 'samples/inline/main.js',
plugins: [ commonjs() ]
}).then( function ( bundle ) {
var generated = bundle.generate({
format: 'cjs'
});

var fn = new Function ( 'module', generated.code );
var module = {};

fn( module );

assert.equal( module.exports(), 2 );
assert.equal( executeBundle( bundle ).exports(), 2 );
});
});

Expand All @@ -74,12 +60,12 @@ describe( 'rollup-plugin-commonjs', function () {

var smc = new SourceMapConsumer( generated.map );

var loc = smc.originalPositionFor({ line: 3, column: 17 }); // 42
var loc = smc.originalPositionFor({ line: 5, column: 17 }); // 42
assert.equal( loc.source, 'samples/sourcemap/foo.js' );
assert.equal( loc.line, 1 );
assert.equal( loc.column, 15 );

loc = smc.originalPositionFor({ line: 8, column: 8 });
loc = smc.originalPositionFor({ line: 9, column: 8 }); // log
assert.equal( loc.source, 'samples/sourcemap/main.js' );
assert.equal( loc.line, 2 );
assert.equal( loc.column, 8 );
Expand All @@ -90,28 +76,14 @@ describe( 'rollup-plugin-commonjs', function () {
return rollup.rollup({
entry: 'samples/index/main.js',
plugins: [ commonjs() ]
}).then( function ( bundle ) {
var generated = bundle.generate({
format: 'cjs'
});

var fn = new Function ( 'module', 'assert', generated.code );
fn( {}, assert );
});
}).then( executeBundle );
});

it( 'handles reassignments to imports', function () {
return rollup.rollup({
entry: 'samples/reassignment/main.js',
plugins: [ commonjs() ]
}).then( function ( bundle ) {
var generated = bundle.generate({
format: 'cjs'
});

var fn = new Function ( 'module', 'assert', generated.code );
fn( {}, assert );
});
}).then( executeBundle );
});

it( 'handles imports with a trailing slash', function () {
Expand All @@ -120,56 +92,28 @@ describe( 'rollup-plugin-commonjs', function () {
return rollup.rollup({
entry: 'samples/trailing-slash/main.js',
plugins: [ commonjs() ]
}).then( function ( bundle ) {
var generated = bundle.generate({
format: 'cjs'
});

var fn = new Function ( 'module', 'assert', generated.code );
fn( {}, assert );
});
}).then( executeBundle );
});

it( 'handles imports with a non-extension dot', function () {
return rollup.rollup({
entry: 'samples/dot/main.js',
plugins: [ commonjs() ]
}).then( function ( bundle ) {
var generated = bundle.generate({
format: 'cjs'
});

var fn = new Function ( 'module', 'assert', generated.code );
fn( {}, assert );
});
}).then( executeBundle );
});

it( 'handles shadowed require', function () {
return rollup.rollup({
entry: 'samples/shadowing/main.js',
plugins: [ commonjs() ]
}).then( function ( bundle ) {
var generated = bundle.generate({
format: 'cjs'
});

var fn = new Function ( 'module', 'assert', generated.code );
fn( {}, assert );
});
}).then( executeBundle );
});

it( 'identifies named exports', function () {
return rollup.rollup({
entry: 'samples/named-exports/main.js',
plugins: [ commonjs() ]
}).then( function ( bundle ) {
var generated = bundle.generate({
format: 'cjs'
});

var fn = new Function ( 'module', 'assert', generated.code );
fn( {}, assert );
});
}).then( executeBundle );
});

it( 'handles references to `global`', function () {
Expand Down

0 comments on commit 05e3f0f

Please sign in to comment.