Browse Source

Merge pull request #393 from rollup/destruction-in-exports

Destruction in exports
gh-438-b
Rich Harris 9 years ago
parent
commit
8d25fa2dd0
  1. 12
      CHANGELOG.md
  2. 11
      bin/help.md
  3. 16
      bin/runRollup.js
  4. 4
      package.json
  5. 25
      src/Module.js
  6. 34
      src/ast/Scope.js
  7. 31
      src/ast/extractNames.js
  8. 5
      test/cli/config-env/_config.js
  9. 2
      test/cli/config-env/main.js
  10. 12
      test/cli/config-env/rollup.config.js
  11. 12
      test/function/export-destruction/_config.js
  12. 5
      test/function/export-destruction/main.js
  13. 3
      test/function/vars-not-removed/_config.js
  14. 3
      test/function/vars-not-removed/bar.js
  15. 3
      test/function/vars-not-removed/foo.js
  16. 2
      test/function/vars-not-removed/main.js

12
CHANGELOG.md

@ -1,5 +1,17 @@
# rollup changelog
## 0.22.2
* Prevent lost `var` keywords ([#390](https://github.com/rollup/rollup/issues/390))
## 0.22.1
* Update expected option keys ([#379](https://github.com/rollup/rollup/issues/379))
* Handle transformers that return stringified sourcemaps ([#377](https://github.com/rollup/rollup/issues/377))
* Automatically create missing namespaces if `moduleName` contains dots ([#378](https://github.com/rollup/rollup/issues/378))
* Ignore external dependency warnings coming from config file ([#333](https://github.com/rollup/rollup/issues/333))
* Update to latest magic-string for performance boost
## 0.22.0
* Duplicate warnings are squelched ([#362](https://github.com/rollup/rollup/issues/362))

11
bin/help.md

@ -20,14 +20,23 @@ Basic options:
-m, --sourcemap Generate sourcemap (`-m inline` for inline map)
--no-strict Don't emit a `"use strict";` in the generated modules.
--no-indent Don't indent result
--environment <values> Settings passed to config file (see example)
Examples:
# use settings in config file
rollup -c
# in config file, process.env.INCLUDE_DEPS === 'true'
# and process.env.BUILD === 'production'
rollup -c --environment INCLUDE_DEPS,BUILD:production
# create CommonJS bundle.js from src/main.js
rollup --format=cjs --output=bundle.js -- src/main.js
rollup -f iife --globals jquery:jQuery,angular:ng \
# create self-executing IIFE using `window.jQuery`
# and `window._` as external globals
rollup -f iife --globals jquery:jQuery,lodash:_ \
-i src/app.js -o build/app.js -m build/app.js.map
Notes:

16
bin/runRollup.js

@ -20,6 +20,17 @@ module.exports = function ( command ) {
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 ) {
@ -27,7 +38,10 @@ module.exports = function ( command ) {
rollup.rollup({
entry: config,
onwarn: log
onwarn: function ( message ) {
if ( /Treating .+ as external dependency/.test( message ) ) return;
log( message );
}
}).then( function ( bundle ) {
var code = bundle.generate({
format: 'cjs'

4
package.json

@ -1,6 +1,6 @@
{
"name": "rollup",
"version": "0.22.0",
"version": "0.22.2",
"description": "Next-generation ES6 module bundler",
"main": "dist/rollup.js",
"jsnext:main": "src/rollup.js",
@ -48,7 +48,7 @@
"eslint": "^1.7.1",
"estree-walker": "^0.2.0",
"istanbul": "^0.4.0",
"magic-string": "^0.10.0",
"magic-string": "^0.10.1",
"mocha": "^2.3.3",
"remap-istanbul": "^0.4.0",
"rollup": "^0.20.2",

25
src/Module.js

@ -10,6 +10,7 @@ import SOURCEMAPPING_URL from './utils/sourceMappingURL.js';
import { SyntheticDefaultDeclaration, SyntheticNamespaceDeclaration } from './Declaration.js';
import { isFalsy, isTruthy } from './ast/conditions.js';
import { emptyBlockStatement } from './ast/create.js';
import extractNames from './ast/extractNames.js';
export default class Module {
constructor ({ id, code, originalCode, ast, sourceMapChain, bundle }) {
@ -97,6 +98,7 @@ export default class Module {
}
// export { foo, bar, baz }
// export var { foo, bar } = ...
// export var foo = 42;
// export var a = 1, b = 2, c = 3;
// export function foo () {}
@ -114,17 +116,18 @@ export default class Module {
else {
let declaration = node.declaration;
let name;
if ( declaration.type === 'VariableDeclaration' ) {
// export var foo = 42
name = declaration.declarations[0].id.name;
} else {
declaration.declarations.forEach( decl => {
extractNames( decl.id ).forEach( localName => {
this.exports[ localName ] = { localName };
});
});
}
else {
// export function foo () {}
name = declaration.id.name;
const localName = declaration.id.name;
this.exports[ localName ] = { localName };
}
this.exports[ name ] = { localName: name };
}
}
}
@ -497,10 +500,14 @@ export default class Module {
// 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 = statement.node.declaration.declarations[0].id.name;
const name = extractNames( statement.node.declaration.declarations[ 0 ].id )[ 0 ];
const declaration = this.declarations[ name ];
if ( !declaration ) throw new Error( `Missing declaration for ${name}!` );
const end = declaration.isExported && declaration.isReassigned ?
statement.node.declaration.declarations[0].start :
statement.node.declaration.start;

34
src/ast/Scope.js

@ -1,38 +1,6 @@
import { blank, keys } from '../utils/object.js';
import Declaration from '../Declaration.js';
const extractors = {
Identifier ( names, param ) {
names.push( param.name );
},
ObjectPattern ( names, param ) {
param.properties.forEach( prop => {
extractors[ prop.key.type ]( names, prop.key );
});
},
ArrayPattern ( names, param ) {
param.elements.forEach( element => {
if ( element ) extractors[ element.type ]( names, element );
});
},
RestElement ( names, param ) {
extractors[ param.argument.type ]( names, param.argument );
},
AssignmentPattern ( names, param ) {
return extractors[ param.left.type ]( names, param.left );
}
};
function extractNames ( param ) {
let names = [];
extractors[ param.type ]( names, param );
return names;
}
import extractNames from './extractNames.js';
export default class Scope {
constructor ( options ) {

31
src/ast/extractNames.js

@ -0,0 +1,31 @@
export default function extractNames ( param ) {
const names = [];
extractors[ param.type ]( names, param );
return names;
}
const extractors = {
Identifier ( names, param ) {
names.push( param.name );
},
ObjectPattern ( names, param ) {
param.properties.forEach( prop => {
extractors[ prop.value.type ]( names, prop.value );
});
},
ArrayPattern ( names, param ) {
param.elements.forEach( element => {
if ( element ) extractors[ element.type ]( names, element );
});
},
RestElement ( names, param ) {
extractors[ param.argument.type ]( names, param.argument );
},
AssignmentPattern ( names, param ) {
extractors[ param.left.type ]( names, param.left );
}
};

5
test/cli/config-env/_config.js

@ -0,0 +1,5 @@
module.exports = {
description: 'passes environment variables to config file',
command: 'rollup --config --environment PRODUCTION,FOO:bar',
execute: true
};

2
test/cli/config-env/main.js

@ -0,0 +1,2 @@
assert.equal( '__ENVIRONMENT__', 'production' );
assert.equal( '__FOO__', 'bar' );

12
test/cli/config-env/rollup.config.js

@ -0,0 +1,12 @@
var replace = require( 'rollup-plugin-replace' );
module.exports = {
entry: 'main.js',
format: 'cjs',
plugins: [
replace({
__ENVIRONMENT__: process.env.PRODUCTION ? 'production' : 'development',
__FOO__: process.env.FOO
})
]
};

12
test/function/export-destruction/_config.js

@ -0,0 +1,12 @@
var assert = require( 'assert' );
module.exports = {
description: 'handle destruction patterns in export declarations',
babel: true,
exports: function ( exports ) {
assert.deepEqual( Object.keys( exports ), [ 'baz', 'quux' ] );
assert.equal( exports.baz, 5 );
assert.equal( exports.quux, 17 );
}
};

5
test/function/export-destruction/main.js

@ -0,0 +1,5 @@
var foo = { bar: { baz: 5 } };
var arr = [ { quux: 'wrong' }, { quux: 17 } ];
export var { bar: { baz } } = foo;
export var [ /* skip */, { quux } ] = arr;

3
test/function/vars-not-removed/_config.js

@ -0,0 +1,3 @@
module.exports = {
description: 'does not erroneously remove var/let/const keywords (#390)'
};

3
test/function/vars-not-removed/bar.js

@ -0,0 +1,3 @@
var a = 2, b = 3;
assert.equal( a + b, 5 );

3
test/function/vars-not-removed/foo.js

@ -0,0 +1,3 @@
var a = 1, b = 2;
assert.equal( a + b, 3 );

2
test/function/vars-not-removed/main.js

@ -0,0 +1,2 @@
import './foo.js';
import './bar.js';
Loading…
Cancel
Save