Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

rollup

Package Overview
Dependencies
Maintainers
1
Versions
835
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rollup - npm Package Compare versions

Comparing version 0.11.4 to 0.12.0

src/finalisers/shared/getInteropBlock.js

8

bin/help.md

@@ -12,4 +12,6 @@ rollup version <%= version %>

-o, --output <output> Output (if absent, prints to stdout)
-f, --format [umd] Type of output (amd, cjs, es6, iife, umd)
-f, --format [es6] Type of output (amd, cjs, es6, 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
-n, --name Name for UMD export

@@ -20,6 +22,8 @@ -u, --id ID for AMD module (default is anonymous)

Example:
Examples:
rollup --format=cjs --output=bundle.js -- src/main.js
rollup -f iife --globals jquery:jQuery,angular:ng \
-i src/app.js -o build/app.js -m build/app.js.map

@@ -26,0 +30,0 @@ Notes:

require( 'source-map-support' ).install();
var path = require( 'path' );
var sander = require( 'sander' );
var Promise = sander.Promise;
var handleError = require( './handleError' );

@@ -22,2 +19,22 @@ var rollup = require( '../' );

var external = options.external ? options.external.split( ',' ) : [];
if ( options.globals ) {
var globals = Object.create( null );
options.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] );
}
});
options.globals = globals;
}
options.external = external;
try {

@@ -31,4 +48,2 @@ bundle( options ).catch( handleError );

function bundle ( options, method ) {
var bundleOptions, file;
if ( !options.input ) {

@@ -40,3 +55,3 @@ handleError({ code: 'MISSING_INPUT_OPTION' });

entry: options.input,
external: options.external && options.external.split( ',' )
external: options.external
}).then( function ( bundle ) {

@@ -46,2 +61,3 @@ var generateOptions = {

format: options.format,
globals: options.globals,
moduleId: options.id,

@@ -62,3 +78,4 @@ moduleName: options.name,

var code = result.code;
var code = result.code,
map = result.map;

@@ -65,0 +82,0 @@ if ( options.sourcemap === 'inline' ) {

# rollup changelog
## 0.12.0
* Internal re-architecting, resulting in more efficient bundling with reduced memory usage
* Shorthand properties are expanded if necessary ([#61](https://github.com/rollup/rollup/issues/61))
* Fixed various bugs with bundle external dependencies, particularly when generating ES6 bundles ([#59](https://github.com/rollup/rollup/issues/59))
* Add `--globals` option to CLI ([#60](https://github.com/rollup/rollup/pull/60))
* Allow imports of external modules for side-effects ([#55](https://github.com/rollup/rollup/pull/55))
* Prevent Rollup hanging on non-existent external module ([#54](https://github.com/rollup/rollup/pull/54))
## 0.11.4

@@ -4,0 +13,0 @@

{
"name": "rollup",
"version": "0.11.4",
"version": "0.12.0",
"description": "Next-generation ES6 module bundler",

@@ -49,3 +49,3 @@ "main": "dist/rollup.js",

"chalk": "^1.0.0",
"magic-string": "^0.6.2",
"magic-string": "^0.6.4",
"minimist": "^1.1.1",

@@ -52,0 +52,0 @@ "sander": "^0.3.3",

@@ -16,11 +16,2 @@ import { basename, extname } from './utils/path';

function isEmptyExportedVarDeclaration ( node, module, allBundleExports ) {
if ( node.type !== 'VariableDeclaration' || node.declarations[0].init ) return false;
const name = node.declarations[0].id.name;
const canonicalName = module.getCanonicalName( name );
return canonicalName in allBundleExports;
}
export default class Bundle {

@@ -94,8 +85,7 @@ constructor ( options ) {

.then( () => {
this.statements = this.sort();
this.deconflict();
this.orderedModules = this.sort();
});
}
deconflict () {
deconflict ( es6 ) {
let definers = blank();

@@ -121,30 +111,31 @@ let conflicts = blank();

// Discover conflicts (i.e. two statements in separate modules both define `foo`)
this.statements.forEach( statement => {
const module = statement.module;
const names = keys( statement.defines );
this.orderedModules.forEach( module => {
module.statements.forEach( statement => {
const names = keys( statement.defines );
// with default exports that are expressions (`export default 42`),
// we need to ensure that the name chosen for the expression does
// not conflict
if ( statement.node.type === 'ExportDefaultDeclaration' ) {
const name = module.getCanonicalName( 'default' );
// with default exports that are expressions (`export default 42`),
// we need to ensure that the name chosen for the expression does
// not conflict
if ( statement.node.type === 'ExportDefaultDeclaration' ) {
const name = module.getCanonicalName( 'default', es6 );
const isProxy = statement.node.declaration && statement.node.declaration.type === 'Identifier';
const shouldDeconflict = !isProxy || ( module.getCanonicalName( statement.node.declaration.name ) !== name );
const isProxy = statement.node.declaration && statement.node.declaration.type === 'Identifier';
const shouldDeconflict = !isProxy || ( module.getCanonicalName( statement.node.declaration.name, es6 ) !== name );
if ( shouldDeconflict && !~names.indexOf( name ) ) {
names.push( name );
if ( shouldDeconflict && !~names.indexOf( name ) ) {
names.push( name );
}
}
}
names.forEach( name => {
if ( definers[ name ] ) {
conflicts[ name ] = true;
} else {
definers[ name ] = [];
}
names.forEach( name => {
if ( definers[ name ] ) {
conflicts[ name ] = true;
} else {
definers[ name ] = [];
}
// TODO in good js, there shouldn't be duplicate definitions
// per module... but some people write bad js
definers[ name ].push( module );
// TODO in good js, there shouldn't be duplicate definitions
// per module... but some people write bad js
definers[ name ].push( module );
});
});

@@ -220,6 +211,56 @@ });

generate ( options = {} ) {
let magicString = new MagicString.Bundle({ separator: '' });
markAllModifierStatements () {
let settled = true;
let promises = [];
this.modules.forEach( module => {
module.statements.forEach( statement => {
if ( statement.isIncluded ) return;
keys( statement.modifies ).forEach( name => {
const definingStatement = module.definitions[ name ];
const exportDeclaration = module.exports[ name ] || (
module.exports.default && module.exports.default.identifier === name && module.exports.default
);
const shouldMark = ( definingStatement && definingStatement.isIncluded ) ||
( exportDeclaration && exportDeclaration.isUsed );
if ( shouldMark ) {
settled = false;
promises.push( statement.mark() );
return;
}
// special case - https://github.com/rollup/rollup/pull/40
const importDeclaration = module.imports[ name ];
if ( !importDeclaration ) return;
const promise = Promise.resolve( importDeclaration.module || this.fetchModule( importDeclaration.source, module.id ) )
.then( module => {
importDeclaration.module = module;
const exportDeclaration = module.exports[ importDeclaration.name ];
// TODO things like `export default a + b` don't apply here... right?
return module.findDefiningStatement( exportDeclaration.localName );
})
.then( definingStatement => {
if ( !definingStatement ) return;
settled = false;
return statement.mark();
});
promises.push( promise );
});
});
});
return Promise.all( promises ).then( () => {
if ( !settled ) return this.markAllModifierStatements();
});
}
render ( options = {} ) {
const format = options.format || 'es6';
this.deconflict( format === 'es6' );

@@ -250,3 +291,3 @@ // If we have named exports from the bundle, and those exports

if ( originalDeclaration && originalDeclaration.type === 'VariableDeclaration' ) {
const canonicalName = this.entryModule.getCanonicalName( exportDeclaration.localName );
const canonicalName = this.entryModule.getCanonicalName( exportDeclaration.localName, false );

@@ -264,109 +305,10 @@ allBundleExports[ canonicalName ] = `exports.${key}`;

// Apply new names and add to the output bundle
let previousModule = null;
let previousIndex = -1;
let previousMargin = 0;
this.statements.forEach( statement => {
// skip `export { foo, bar, baz }`
if ( statement.node.type === 'ExportNamedDeclaration' ) {
// skip `export { foo, bar, baz }`
if ( statement.node.specifiers.length ) return;
let magicString = new MagicString.Bundle({ separator: '\n\n' });
// skip `export var foo;` if foo is exported
if ( isEmptyExportedVarDeclaration( statement.node.declaration, statement.module, allBundleExports ) ) return;
this.orderedModules.forEach( module => {
const source = module.render( allBundleExports, format );
if ( source.toString().length ) {
magicString.addSource( source );
}
// skip empty var declarations for exported bindings
// (otherwise we're left with `exports.foo;`, which is useless)
if ( isEmptyExportedVarDeclaration( statement.node, statement.module, allBundleExports ) ) return;
let replacements = blank();
let bundleExports = blank();
keys( statement.dependsOn )
.concat( keys( statement.defines ) )
.forEach( name => {
const canonicalName = statement.module.getCanonicalName( name );
if ( allBundleExports[ canonicalName ] ) {
bundleExports[ name ] = replacements[ name ] = allBundleExports[ canonicalName ];
} else if ( name !== canonicalName ) {
replacements[ name ] = canonicalName;
}
});
const source = statement.replaceIdentifiers( replacements, bundleExports );
// modify exports as necessary
if ( statement.isExportDeclaration ) {
// remove `export` from `export var foo = 42`
if ( statement.node.type === 'ExportNamedDeclaration' && statement.node.declaration.type === 'VariableDeclaration' ) {
source.remove( statement.node.start, statement.node.declaration.start );
}
// remove `export` from `export class Foo {...}` or `export default Foo`
// TODO default exports need different treatment
else if ( statement.node.declaration.id ) {
source.remove( statement.node.start, statement.node.declaration.start );
}
else if ( statement.node.type === 'ExportDefaultDeclaration' ) {
const module = statement.module;
const canonicalName = module.getCanonicalName( 'default' );
if ( statement.node.declaration.type === 'Identifier' && canonicalName === module.getCanonicalName( statement.node.declaration.name ) ) {
return;
}
// anonymous functions should be converted into declarations
if ( statement.node.declaration.type === 'FunctionExpression' ) {
source.overwrite( statement.node.start, statement.node.declaration.start + 8, `function ${canonicalName}` );
} else {
source.overwrite( statement.node.start, statement.node.declaration.start, `var ${canonicalName} = ` );
}
}
else {
throw new Error( 'Unhandled export' );
}
}
// ensure there is always a newline between statements, and add
// additional newlines as necessary to reflect original source
const minSeparation = ( previousModule !== statement.module ) || ( statement.index !== previousIndex + 1 ) ? 3 : 2;
const margin = Math.max( minSeparation, statement.margin[0], previousMargin );
let newLines = new Array( margin ).join( '\n' );
// add leading comments
if ( statement.leadingComments.length ) {
const commentBlock = newLines + statement.leadingComments.map( ({ separator, comment }) => {
return separator + ( comment.block ?
`/*${comment.text}*/` :
`//${comment.text}` );
}).join( '' );
magicString.addSource( new MagicString( commentBlock ) );
newLines = new Array( statement.margin[0] ).join( '\n' ); // TODO handle gaps between comment block and statement
}
// add the statement itself
magicString.addSource({
content: source,
separator: newLines
});
// add trailing comments
const comment = statement.trailingComment;
if ( comment ) {
const commentBlock = comment.block ?
` /*${comment.text}*/` :
` //${comment.text}`;
magicString.append( commentBlock );
}
previousMargin = statement.margin[1];
previousModule = statement.module;
previousIndex = statement.index;
});

@@ -379,4 +321,4 @@

return `var ${module.getCanonicalName('*')} = {\n` +
exportKeys.map( key => `${indentString}get ${key} () { return ${module.getCanonicalName(key)}; }` ).join( ',\n' ) +
return `var ${module.getCanonicalName('*', format === 'es6')} = {\n` +
exportKeys.map( key => `${indentString}get ${key} () { return ${module.getCanonicalName(key, format === 'es6')}; }` ).join( ',\n' ) +
`\n};\n\n`;

@@ -418,53 +360,2 @@ }).join( '' );

markAllModifierStatements () {
let settled = true;
let promises = [];
this.modules.forEach( module => {
module.statements.forEach( statement => {
if ( statement.isIncluded ) return;
keys( statement.modifies ).forEach( name => {
const definingStatement = module.definitions[ name ];
const exportDeclaration = module.exports[ name ] || (
module.exports.default && module.exports.default.identifier === name && module.exports.default
);
const shouldMark = ( definingStatement && definingStatement.isIncluded ) ||
( exportDeclaration && exportDeclaration.isUsed );
if ( shouldMark ) {
settled = false;
promises.push( statement.mark() );
return;
}
// special case - https://github.com/rollup/rollup/pull/40
const importDeclaration = module.imports[ name ];
if ( !importDeclaration ) return;
const promise = Promise.resolve( importDeclaration.module || this.fetchModule( importDeclaration.source, module.id ) )
.then( module => {
importDeclaration.module = module;
const exportDeclaration = module.exports[ importDeclaration.name ];
// TODO things like `export default a + b` don't apply here... right?
return module.findDefiningStatement( exportDeclaration.localName );
})
.then( definingStatement => {
if ( !definingStatement ) return;
settled = false;
return statement.mark();
});
promises.push( promise );
});
});
});
return Promise.all( promises ).then( () => {
if ( !settled ) return this.markAllModifierStatements();
});
}
sort () {

@@ -551,12 +442,4 @@ let seen = {};

let statements = [];
ordered.forEach( module => {
module.statements.forEach( statement => {
if ( statement.isIncluded ) statements.push( statement );
});
});
return statements;
return ordered;
}
}

@@ -15,3 +15,10 @@ import { blank } from './utils/object';

this.needsDefault = false;
// Invariant: needsNamed and needsAll are never both true at once.
// Because an import with both a namespace and named import is invalid:
//
// import * as ns, { a } from '...'
//
this.needsNamed = false;
this.needsAll = false;
}

@@ -23,13 +30,12 @@

getCanonicalName ( name ) {
getCanonicalName ( name, es6 ) {
if ( name === 'default' ) {
return this.needsNamed ? `${this.name}__default` : this.name;
return this.needsNamed && !es6 ? `${this.name}__default` : this.name;
}
if ( name === '*' ) {
return this.name;
return this.name; // TODO is this correct in ES6?
}
// TODO this depends on the output format... works for CJS etc but not ES6
return `${this.name}.${name}`;
return es6 ? ( this.canonicalNames[ name ] || name ) : `${this.name}.${name}`;
}

@@ -36,0 +42,0 @@

import { getName, quoteId } from '../utils/map-helpers';
import getInteropBlock from './shared/getInteropBlock';

@@ -18,2 +19,6 @@ export default function amd ( bundle, magicString, { exportMode, indentString }, options ) {

// var foo__default = 'default' in foo ? foo['default'] : foo;
const interopBlock = getInteropBlock( bundle );
if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' );
const exports = bundle.entryModule.exports;

@@ -31,5 +36,3 @@

if ( exportBlock ) {
magicString.append( '\n\n' + exportBlock );
}
if ( exportBlock ) magicString.append( '\n\n' + exportBlock );

@@ -36,0 +39,0 @@ return magicString

import { keys } from '../utils/object';
export default function es6 ( bundle, magicString, { exportMode }, options ) {
const introBlock = ''; // TODO...
const importBlock = bundle.externalModules
.map( module => {
const specifiers = [];
if ( module.needsDefault ) {
specifiers.push( module.importedByBundle.filter( declaration =>
declaration.name === 'default' )[0].localName );
}
if ( module.needsAll ) {
specifiers.push( '* as ' + module.importedByBundle.filter( declaration =>
declaration.name === '*' )[0].localName );
}
if ( module.needsNamed ) {
specifiers.push( '{ ' + module.importedByBundle
.filter( declaration => !/^(default|\*)$/.test( declaration.name ) )
.map( ({ name, localName }) =>
name === localName ? name : `${name} as ${localName}` )
.join( ', ' ) + ' }' );
}
return specifiers.length ?
`import ${specifiers.join( ', ' )} from '${module.id}';` :
`import '${module.id}';`;
})
.join( '\n' );
if ( importBlock ) {
magicString.prepend( importBlock + '\n\n' );
}
const exports = bundle.entryModule.exports;

@@ -7,0 +37,0 @@ const exportBlock = keys( exports ).map( exportedName => {

import { blank } from '../utils/object';
import { getName } from '../utils/map-helpers';
import getInteropBlock from './shared/getInteropBlock';

@@ -25,2 +26,6 @@ export default function iife ( bundle, magicString, { exportMode, indentString }, options ) {

// var foo__default = 'default' in foo ? foo['default'] : foo;
const interopBlock = getInteropBlock( bundle );
if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' );
if ( exportMode === 'default' ) {

@@ -27,0 +32,0 @@ intro = `var ${options.moduleName} = ${intro}`;

import { blank } from '../utils/object';
import { getName, quoteId, req } from '../utils/map-helpers';
import getInteropBlock from './shared/getInteropBlock';

@@ -14,3 +15,3 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, options ) {

let globalDeps = bundle.externalModules.map( module => {
return globalNames[ module.id ] || module.name;
return 'global.' + (globalNames[ module.id ] || module.name);
});

@@ -44,2 +45,6 @@

// var foo__default = 'default' in foo ? foo['default'] : foo;
const interopBlock = getInteropBlock( bundle );
if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' );
const exports = bundle.entryModule.exports;

@@ -46,0 +51,0 @@

@@ -7,6 +7,4 @@ import { dirname } from './utils/path';

import walk from './ast/walk';
import analyse from './ast/analyse';
import { blank, keys } from './utils/object';
import { first, sequence } from './utils/promise';
import { isImportDeclaration, isExportDeclaration } from './utils/map-helpers';
import getLocation from './utils/getLocation';

@@ -25,2 +23,11 @@ import makeLegalIdentifier from './utils/makeLegalIdentifier';

function isEmptyExportedVarDeclaration ( node, module, allBundleExports, es6 ) {
if ( node.type !== 'VariableDeclaration' || node.declarations[0].init ) return false;
const name = node.declarations[0].id.name;
const canonicalName = module.getCanonicalName( name, es6 );
return canonicalName in allBundleExports;
}
export default class Module {

@@ -174,10 +181,8 @@ constructor ({ id, source, bundle }) {

this.statements.forEach( statement => {
if ( isImportDeclaration( statement ) ) this.addImport( statement );
else if ( isExportDeclaration( statement ) ) this.addExport( statement );
});
if ( statement.isImportDeclaration ) this.addImport( statement );
else if ( statement.isExportDeclaration ) this.addExport( statement );
analyse( this.magicString, this );
statement.analyse();
// consolidate names that are defined/modified in this module
this.statements.forEach( statement => {
// consolidate names that are defined/modified in this module
keys( statement.defines ).forEach( name => {

@@ -207,3 +212,3 @@ this.definitions[ name ] = statement;

this.statements.forEach( statement => {
if ( statement.isImportDeclaration && !statement.node.specifiers.length ) {
if ( statement.isImportDeclaration && !statement.node.specifiers.length && !statement.module.isExternal ) {
// include module for its side-effects

@@ -288,3 +293,3 @@ strongDependencies[ statement.module.id ] = statement.module; // TODO is this right? `statement.module` should be `this`, surely?

getCanonicalName ( localName ) {
getCanonicalName ( localName, es6 ) {
// Special case

@@ -300,3 +305,5 @@ if ( localName === 'default' && ( this.exports.default.isModified || !this.suggestedNames.default ) ) {

if ( !this.canonicalNames[ localName ] ) {
const id = localName + ( es6 ? '-es6' : '' ); // TODO ugh this seems like a terrible hack
if ( !this.canonicalNames[ id ] ) {
let canonicalName;

@@ -326,3 +333,3 @@

canonicalName = module.getCanonicalName( exporterLocalName );
canonicalName = module.getCanonicalName( exporterLocalName, es6 );
}

@@ -335,6 +342,6 @@ }

this.canonicalNames[ localName ] = canonicalName;
this.canonicalNames[ id ] = canonicalName;
}
return this.canonicalNames[ localName ];
return this.canonicalNames[ id ];
}

@@ -380,2 +387,4 @@

module.needsDefault = true;
} else if ( importDeclaration.name === '*' ) {
module.needsAll = true;
} else {

@@ -487,2 +496,5 @@ module.needsNamed = true;

statement.module = module;
if ( module.isExternal ) {
return;
}
return module.markAllStatements();

@@ -536,4 +548,6 @@ });

let statements = [];
let lastChar = 0;
let commentIndex = 0;
ast.body.map( node => {
ast.body.forEach( node => {
// special case - top-level var declarations with multiple declarators

@@ -543,27 +557,48 @@ // should be split up. Otherwise, we may end up including code we

if ( node.type === 'VariableDeclaration' && node.declarations.length > 1 ) {
node.declarations.forEach( declarator => {
const magicString = this.magicString.snip( declarator.start, declarator.end ).trim();
magicString.prepend( `${node.kind} ` ).append( ';' );
// remove the leading var/let/const
this.magicString.remove( node.start, node.declarations[0].start );
node.declarations.forEach( ( declarator, i ) => {
const { start, end } = declarator;
const syntheticNode = {
type: 'VariableDeclaration',
kind: node.kind,
start: node.start,
end: node.end,
declarations: [ declarator ]
start,
end,
declarations: [ declarator ],
isSynthetic: true
};
const statement = new Statement( syntheticNode, magicString, this, statements.length );
const statement = new Statement( syntheticNode, this, start, end );
statements.push( statement );
});
lastChar = node.end; // TODO account for trailing line comment
}
else {
const magicString = this.magicString.snip( node.start, node.end ).trim();
const statement = new Statement( node, magicString, this, statements.length );
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;
}
});
statements.forEach( ( statement, i ) => {
const nextStatement = statements[ i + 1 ];
statement.next = nextStatement ? nextStatement.start : statement.end;
});
return statements;

@@ -573,5 +608,102 @@ }

rename ( name, replacement ) {
this.canonicalNames[ name ] = replacement;
// TODO again, hacky...
this.canonicalNames[ name ] = this.canonicalNames[ name + '-es6' ] = replacement;
}
render ( allBundleExports, format ) {
let magicString = this.magicString.clone();
let previousIndex = -1;
let previousMargin = 0;
this.statements.forEach( ( statement, i ) => {
if ( !statement.isIncluded ) {
magicString.remove( statement.start, statement.next );
return;
}
// skip `export { foo, bar, baz }`
if ( statement.node.type === 'ExportNamedDeclaration' ) {
// skip `export { foo, bar, baz }`
if ( statement.node.specifiers.length ) {
magicString.remove( statement.start, statement.next );
return;
};
// skip `export var foo;` if foo is exported
if ( isEmptyExportedVarDeclaration( statement.node.declaration, statement.module, allBundleExports, format === 'es6' ) ) {
magicString.remove( statement.start, statement.next );
return;
}
}
// skip empty var declarations for exported bindings
// (otherwise we're left with `exports.foo;`, which is useless)
if ( isEmptyExportedVarDeclaration( statement.node, statement.module, allBundleExports, format === 'es6' ) ) {
magicString.remove( statement.start, statement.next );
return;
}
// split up/remove var declarations as necessary
if ( statement.node.isSynthetic ) {
magicString.insert( statement.start, `${statement.node.kind} ` );
magicString.overwrite( statement.end, statement.next, ';\n' ); // TODO account for trailing newlines
}
let replacements = blank();
let bundleExports = blank();
keys( statement.dependsOn )
.concat( keys( statement.defines ) )
.forEach( name => {
const canonicalName = statement.module.getCanonicalName( name, format === 'es6' );
if ( allBundleExports[ canonicalName ] ) {
bundleExports[ name ] = replacements[ name ] = allBundleExports[ canonicalName ];
} else if ( name !== canonicalName ) {
replacements[ name ] = canonicalName;
}
});
statement.replaceIdentifiers( magicString, replacements, bundleExports );
// modify exports as necessary
if ( statement.isExportDeclaration ) {
// remove `export` from `export var foo = 42`
if ( statement.node.type === 'ExportNamedDeclaration' && statement.node.declaration.type === 'VariableDeclaration' ) {
magicString.remove( statement.node.start, statement.node.declaration.start );
}
// 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 module = statement.module;
const canonicalName = module.getCanonicalName( 'default', format === 'es6' );
if ( statement.node.declaration.type === 'Identifier' && canonicalName === module.getCanonicalName( statement.node.declaration.name, format === 'es6' ) ) {
magicString.remove( statement.start, statement.next );
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 ${canonicalName}` );
} else {
magicString.overwrite( statement.node.start, statement.node.declaration.start, `var ${canonicalName} = ` );
}
}
else {
throw new Error( 'Unhandled export' );
}
}
});
return magicString.trim();
}
suggestName ( defaultOrBatch, suggestion ) {

@@ -578,0 +710,0 @@ // deconflict anonymous default exports with this module's definitions

@@ -17,3 +17,3 @@ import { basename } from './utils/path';

return {
generate: options => bundle.generate( options ),
generate: options => bundle.render( options ),
write: options => {

@@ -25,3 +25,3 @@ if ( !options || !options.dest ) {

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

@@ -28,0 +28,0 @@ let promises = [];

@@ -12,8 +12,8 @@ import { blank, keys } from './utils/object';

export default class Statement {
constructor ( node, magicString, module, index ) {
constructor ( node, module, start, end ) {
this.node = node;
this.module = module;
this.magicString = magicString;
this.index = index;
this.id = module.id + '#' + index;
this.start = start;
this.end = end;
this.next = null; // filled in later

@@ -28,10 +28,4 @@ this.scope = new Scope();

this.leadingComments = [];
this.trailingComment = null;
this.margin = [ 0, 0 ];
// some facts about this statement...
this.isImportDeclaration = node.type === 'ImportDeclaration';
this.isExportDeclaration = /^Export/.test( node.type );
this.isExportAllDeclaration = /^ExportAll/.test( node.type );
}

@@ -42,5 +36,2 @@

const statement = this; // TODO use arrow functions instead
const magicString = this.magicString;
let scope = this.scope;

@@ -52,4 +43,2 @@

magicString.addSourcemapLocation( node.start );
switch ( node.type ) {

@@ -153,3 +142,3 @@ case 'FunctionExpression':

keys( scope.declarations ).forEach( name => {
statement.defines[ name ] = true;
this.defines[ name ] = true;
});

@@ -255,4 +244,3 @@ }

replaceIdentifiers ( names, bundleExports ) {
const magicString = this.magicString.clone();
replaceIdentifiers ( magicString, names, bundleExports ) {
const replacementStack = [ names ];

@@ -301,7 +289,9 @@ const nameList = keys( names );

// TODO clean this up
try {
magicString.insert( node.end, exportInitialisers );
} catch ( err ) {
magicString.append( exportInitialisers );
if ( exportInitialisers ) {
// TODO clean this up
try {
magicString.insert( node.end, exportInitialisers );
} catch ( err ) {
magicString.append( exportInitialisers );
}
}

@@ -347,4 +337,17 @@ }

// We want to rewrite identifiers (that aren't property names etc)
if ( node.type !== 'Identifier' ) return;
// if there's no replacement, or it's the same, there's nothing more to do
const name = names[ node.name ];
if ( !name || name === node.name ) return;
// shorthand properties (`obj = { foo }`) need to be expanded
if ( parent.type === 'Property' && parent.shorthand ) {
magicString.insert( node.end, `: ${name}` );
parent.key._skip = true;
parent.value._skip = true; // redundant, but defensive
return;
}
// property names etc can be disregarded
if ( parent.type === 'MemberExpression' && !parent.computed && node !== parent.object ) return;

@@ -355,7 +358,4 @@ if ( parent.type === 'Property' && node !== parent.value ) return;

const name = names[ node.name ];
if ( name && name !== node.name ) {
magicString.overwrite( node.start, node.end, name );
}
// all other identifiers should be overwritten
magicString.overwrite( node.start, node.end, name );
},

@@ -362,0 +362,0 @@

@@ -12,9 +12,1 @@ export function getName ( x ) {

}
export function isImportDeclaration ( statement ) {
return statement.isImportDeclaration;
}
export function isExportDeclaration ( statement ) {
return statement.isExportDeclaration;
}

@@ -14,5 +14,9 @@ // TODO does this all work on windows?

export function dirname ( path ) {
const match = /(\/|\\)[^\/\\]+$/.exec( path );
const match = /(\/|\\)[^\/\\]*$/.exec( path );
if ( !match ) return '.';
return path.slice( 0, -match[0].length );
const dir = path.slice( 0, -match[0].length );
// If `dir` is the empty string, we're at root.
return dir ? dir : '/';
}

@@ -23,3 +27,3 @@

if ( !match ) return '';
return match[0]
return match[0];
}

@@ -26,0 +30,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc