diff --git a/.eslintrc b/.eslintrc index 6e5fb1a..0f98dff 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,23 +1,23 @@ { - "rules": { - "indent": [ 2, "tab", { "SwitchCase": 1 } ], - "quotes": [ 2, "single" ], - "linebreak-style": [ 2, "unix" ], - "semi": [ 2, "always" ], - "space-after-keywords": [ 2, "always" ], - "space-before-blocks": [ 2, "always" ], - "space-before-function-paren": [ 2, "always" ], - "no-mixed-spaces-and-tabs": [ 2, "smart-tabs" ], - "no-cond-assign": [ 0 ] - }, - "env": { - "es6": true, - "browser": true, - "mocha": true, - "node": true - }, - "extends": "eslint:recommended", - "ecmaFeatures": { - "modules": true - } + "root": true, + "rules": { + "indent": [ 2, "tab", { "SwitchCase": 1 } ], + "semi": [ 2, "always" ], + "keyword-spacing": [ 2, { "before": true, "after": true } ], + "space-before-blocks": [ 2, "always" ], + "space-before-function-paren": [ 2, "always" ], + "no-mixed-spaces-and-tabs": [ 2, "smart-tabs" ], + "no-cond-assign": [ 0 ] + }, + "env": { + "es6": true, + "browser": true, + "mocha": true, + "node": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + } } diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..4964429 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.js eol=lf diff --git a/CHANGELOG.md b/CHANGELOG.md index 009ccd4..03d0f1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,87 @@ # rollup changelog +## 0.26.6 + +* Deconflict named imports from external modules in ES bundles ([#659](https://github.com/rollup/rollup/issues/659)) +* Support `options.preferConst` to generate `const` declarations for exports rather than `var` declarations ([#653](https://github.com/rollup/rollup/issues/653)) + +## 0.26.5 + +* Preserve `debugger` statements ([#664](https://github.com/rollup/rollup/issues/664)) +* Allow `options.external` to be a function ([#522](https://github.com/rollup/rollup/issues/522)) + +## 0.26.4 + +* Prevent plugin-provided external IDs being normalised ([#630](https://github.com/rollup/rollup/issues/630), [#633](https://github.com/rollup/rollup/issues/633)) +* Throw if module exports/re-exports the same name twice, or has multiple default exports ([#679](https://github.com/rollup/rollup/issues/679)) +* Warn about `eval` security issue ([#675]((https://github.com/rollup/rollup/issues/675))) + + +## 0.26.3 + +* Ensure reference is not incorrectly marked as a reassignment ([#648](https://github.com/rollup/rollup/issues/648)) + +## 0.26.2 + +* Sanity check output of `load` hook ([#607](https://github.com/rollup/rollup/issues/607)) +* Correct scoping for ID class expressions ([#626](https://github.com/rollup/rollup/issues/626)) +* Warn if named and default exports are used together in auto mode ([#587](https://github.com/rollup/rollup/issues/587)) +* Allow variable initialisers to be rewritten if necessary ([#632](https://github.com/rollup/rollup/issues/632)) +* Prevent double `var` with no-treeshake option ([#639](https://github.com/rollup/rollup/pull/639)) + +## 0.26.1 + +* Add `treeshake: false`/`--no-treeshake` option for debugging ([#505](https://github.com/rollup/rollup/issues/505)) +* Update build process to use Bublé ([#620](https://github.com/rollup/rollup/pull/620)) + +## 0.26.0 + +* Add `noConflict`/`--no-conflict` option for UMD builds ([#580](https://github.com/rollup/rollup/pull/580)) +* Normalise relative external paths ([#591](https://github.com/rollup/rollup/pull/591)) +* Report files causing transform errors ([#609](https://github.com/rollup/rollup/pull/609)) +* Handle sourcemap segments with a single member ([#619](https://github.com/rollup/rollup/pull/619)) +* Update dependencies + +## 0.25.8 + +* Unixize entry path ([#586](https://github.com/rollup/rollup/pull/586)) + +## 0.25.7 + +* Expand deshadowed shorthand properties ([#575](https://github.com/rollup/rollup/issues/575)) +* Allow external files to be non-existent ([#532](https://github.com/rollup/rollup/issues/532)) + +## 0.25.6 + +* Fix a regression introduced by #566 ([#569](https://github.com/rollup/rollup/issues/569)) +* Prune dead conditional expressions more carefully ([#567](https://github.com/rollup/rollup/issues/567)) + +## 0.25.5 + +* Make sure shorthand destructuring assignments don't break ([#528](https://github.com/rollup/rollup/issues/528)) +* Allow 'exports' key ([#542](https://github.com/rollup/rollup/issues/542)) +* Ensure `foo. bar` where `foo` is a namespace import is rewritten correctly ([#566](https://github.com/rollup/rollup/issues/566)) +* Fix an edge case for exported globals (e.g. `export { document }`) ([#562](https://github.com/rollup/rollup/issues/562)) + +## 0.25.4 + +* Fix misnamed exports of default imports in ES bundles ([#513](https://github.com/rollup/rollup/issues/513)) +* CLI: warn on missing config ([#515](https://github.com/rollup/rollup/pull/515)) +* Detect side-effects in non-top-level member expression assignment ([#476](https://github.com/rollup/rollup/issues/476)) +* Don't remove computed property class keys ([#504](https://github.com/rollup/rollup/issues/504)) +* Augment existing global object rather than replacing ([#493](https://github.com/rollup/rollup/issues/493)) +* Don't fail on `export {}`, warn instead ([#486](https://github.com/rollup/rollup/issues/486)) + +## 0.25.3 + +* Handle non-objects and `null` in `_interopDefault` ([#474](https://github.com/rollup/rollup/issues/474)) + +## 0.25.2 + +* Skip dead branches of a conditional expression (#[465](https://github.com/rollup/rollup/pull/465)) +* Allow globals to be exported ([#472](https://github.com/rollup/rollup/pull/472)) +* Ensure reassigned exports are exported ([#484](https://github.com/rollup/rollup/issues/484)) + ## 0.25.1 * Throw error if namespace is called ([#446](https://github.com/rollup/rollup/issues/446)) diff --git a/README.md b/README.md index c2a6077..6e02e51 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ build status - + npm version @@ -17,8 +17,8 @@ dependency status - - Coverage via Codecov + + Coverage via Codecov Settings passed to config file (see example) +--no-conflict Generate a noConflict method for UMD globals --intro Content to insert at top of bundle (inside wrapper) --outro Content to insert at end of bundle (inside wrapper) --banner Content to insert at top of bundle (outside wrapper) diff --git a/bin/runRollup.js b/bin/runRollup.js index 5b665ed..220c378 100644 --- a/bin/runRollup.js +++ b/bin/runRollup.js @@ -59,6 +59,9 @@ module.exports = function ( command ) { try { var options = require( path.resolve( config ) ); + if ( Object.keys( options ).length === 0 ) { + handleError({ code: 'MISSING_CONFIG' }); + } } catch ( err ) { handleError( err ); } @@ -79,12 +82,14 @@ var equivalents = { format: 'format', globals: 'globals', id: 'moduleId', + indent: 'indent', input: 'entry', intro: 'intro', name: 'moduleName', output: 'dest', outro: 'outro', - sourcemap: 'sourceMap' + sourcemap: 'sourceMap', + treeshake: 'treeshake' }; function execute ( options, command ) { @@ -110,10 +115,13 @@ function execute ( options, command ) { options.onwarn = options.onwarn || log; options.external = external; - options.indent = command.indent !== false; + options.noConflict = command.conflict === false; + delete command.conflict; + + // Use any options passed through the CLI as overrides. Object.keys( equivalents ).forEach( function ( cliOption ) { - if ( command[ cliOption ] ) { + if ( command.hasOwnProperty( cliOption ) ) { options[ equivalents[ cliOption ] ] = command[ cliOption ]; } }); diff --git a/package.json b/package.json index 1d8bdc0..be499e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "0.25.1", + "version": "0.26.6", "description": "Next-generation ES6 module bundler", "main": "dist/rollup.js", "jsnext:main": "src/rollup.js", @@ -9,7 +9,7 @@ }, "scripts": { "pretest": "npm run build", - "test": "mocha", + "test": "mocha --compilers js:buble/register", "pretest-coverage": "npm run build", "test-coverage": "rm -rf coverage/* && istanbul cover --report json node_modules/.bin/_mocha -- -u exports -R spec test/test.js", "posttest-coverage": "remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.json -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped.lcov -t lcovonly -b dist && remap-istanbul -i coverage/coverage-final.json -o coverage/coverage-remapped -t html -b dist", @@ -40,22 +40,23 @@ }, "homepage": "https://github.com/rollup/rollup", "devDependencies": { - "acorn": "^2.6.4", + "acorn": "^3.1.0", "babel-core": "^5.8.32", + "buble": "^0.6.4", "codecov.io": "^0.1.6", - "console-group": "^0.1.2", + "console-group": "^0.2.0", "es6-promise": "^3.0.2", - "eslint": "^1.7.1", + "eslint": "^2.9.0", "estree-walker": "^0.2.0", "istanbul": "^0.4.0", "magic-string": "^0.10.1", "mocha": "^2.3.3", - "remap-istanbul": "^0.4.0", - "rollup": "^0.20.2", - "rollup-plugin-babel": "^1.0.0", - "rollup-plugin-npm": "^1.0.0", + "remap-istanbul": "^0.5.1", + "rollup": "^0.26.2", + "rollup-plugin-buble": "^0.6.0", + "rollup-plugin-node-resolve": "^1.5.0", "rollup-plugin-replace": "^1.0.1", - "sander": "^0.4.0", + "sander": "^0.5.0", "source-map": "^0.5.3", "sourcemap-codec": "^1.2.1", "uglify-js": "^2.6.1" @@ -63,7 +64,7 @@ "dependencies": { "chalk": "^1.1.1", "minimist": "^1.2.0", - "source-map-support": "^0.3.2" + "source-map-support": "^0.4.0" }, "files": [ "src", diff --git a/rollup.config.js b/rollup.config.js index 090c17b..521d614 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,6 +1,6 @@ import { readFileSync } from 'fs'; -import babel from 'rollup-plugin-babel'; -import npm from 'rollup-plugin-npm'; +import buble from 'rollup-plugin-buble'; +import npm from 'rollup-plugin-node-resolve'; import replace from 'rollup-plugin-replace'; var pkg = JSON.parse( readFileSync( 'package.json', 'utf-8' ) ); @@ -22,7 +22,7 @@ export default { entry: 'src/rollup.js', format: 'cjs', plugins: [ - babel({ + buble({ include: [ 'src/**', 'node_modules/acorn/**' ] }), diff --git a/src/Bundle.js b/src/Bundle.js index 754ad8f..95c0d10 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -1,7 +1,6 @@ -import Promise from 'es6-promise/lib/es6-promise/promise.js'; import MagicString from 'magic-string'; import first from './utils/first.js'; -import { blank, keys } from './utils/object.js'; +import { blank, forOwn, keys } from './utils/object.js'; import Module from './Module.js'; import ExternalModule from './ExternalModule.js'; import finalisers from './finalisers/index.js'; @@ -10,12 +9,13 @@ import { load, makeOnwarn, resolveId } from './utils/defaults.js'; import getExportMode from './utils/getExportMode.js'; import getIndentString from './utils/getIndentString.js'; import { unixizePath } from './utils/normalizePlatform.js'; +import { mapSequence } from './utils/promise.js'; import transform from './utils/transform.js'; import transformBundle from './utils/transformBundle.js'; import collapseSourcemaps from './utils/collapseSourcemaps.js'; import SOURCEMAPPING_URL from './utils/sourceMappingURL.js'; import callIfFunction from './utils/callIfFunction.js'; -import { isRelative, resolve } from './utils/path.js'; +import { dirname, isRelative, isAbsolute, relative, resolve } from './utils/path.js'; export default class Bundle { constructor ( options ) { @@ -27,11 +27,14 @@ export default class Bundle { } }); - this.entry = options.entry; + this.entry = unixizePath( options.entry ); + this.entryId = null; this.entryModule = null; + this.treeshake = options.treeshake !== false; + this.resolveId = first( - [ id => ~this.external.indexOf( id ) ? false : null ] + [ id => this.isExternal( id ) ? false : null ] .concat( this.plugins.map( plugin => plugin.resolveId ).filter( Boolean ) ) .concat( resolveId ) ); @@ -59,11 +62,19 @@ export default class Bundle { this.assumedGlobals = blank(); - this.external = ensureArray( options.external ).map( id => id.replace( /[\/\\]/g, '/' ) ); + if ( typeof options.external === 'function' ) { + this.isExternal = options.external; + } else { + const ids = ensureArray( options.external ).map( id => id.replace( /[\/\\]/g, '/' ) ); + this.isExternal = id => ids.indexOf( id ) !== -1; + } + this.onwarn = options.onwarn || makeOnwarn(); // TODO strictly speaking, this only applies with non-ES6, non-default-only bundles [ 'module', 'exports', '_interopDefault' ].forEach( global => this.assumedGlobals[ global ] = true ); + + this.varOrConst = options.preferConst ? 'const' : 'var'; } build () { @@ -71,7 +82,10 @@ export default class Bundle { // modules it imports, and import those, until we have all // of the entry module's dependencies return this.resolveId( this.entry, undefined ) - .then( id => this.fetchModule( id, undefined ) ) + .then( id => { + this.entryId = id; + return this.fetchModule( id, undefined ); + }) .then( entryModule => { this.entryModule = entryModule; @@ -98,7 +112,7 @@ export default class Bundle { settled = true; this.modules.forEach( module => { - if ( module.run() ) settled = false; + if ( module.run( this.treeshake ) ) settled = false; }); } @@ -130,15 +144,14 @@ export default class Bundle { // ensure we don't shadow named external imports, if // we're creating an ES6 bundle - keys( module.declarations ).forEach( name => { - const declaration = module.declarations[ name ]; + forOwn( module.declarations, ( declaration, name ) => { declaration.setSafeName( getSafeName( name ) ); }); }); this.modules.forEach( module => { - keys( module.declarations ).forEach( originalName => { - const declaration = module.declarations[ originalName ]; + forOwn( module.declarations, ( declaration, originalName ) => { + if ( declaration.isGlobal ) return; if ( originalName === 'default' ) { if ( declaration.original && !declaration.original.isReassigned ) return; @@ -162,6 +175,12 @@ export default class Bundle { msg += `: ${err.message}`; throw new Error( msg ); }) + .then( source => { + if ( typeof source === 'string' ) return source; + if ( source && typeof source === 'object' && source.code ) return source; + + 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 => { const { code, originalCode, ast, sourceMapChain } = source; @@ -176,23 +195,39 @@ export default class Bundle { } fetchAllDependencies ( module ) { - const promises = module.sources.map( source => { + return mapSequence( module.sources, source => { return this.resolveId( source, module.id ) .then( resolvedId => { - // If the `resolvedId` is supposed to be external, make it so. - const forcedExternal = resolvedId && ~this.external.indexOf( resolvedId.replace( /[\/\\]/g, '/' ) ); + let externalName; + if ( resolvedId ) { + // If the `resolvedId` is supposed to be external, make it so. + externalName = resolvedId.replace( /[\/\\]/g, '/' ); + } else if ( isRelative( source ) ) { + // This could be an external, relative dependency, based on the current module's parent dir. + externalName = resolve( module.id, '..', source ); + } + const forcedExternal = externalName && this.isExternal( externalName ); if ( !resolvedId || forcedExternal ) { + let normalizedExternal = source; + if ( !forcedExternal ) { if ( isRelative( source ) ) throw new Error( `Could not resolve ${source} from ${module.id}` ); - if ( !~this.external.indexOf( source ) ) this.onwarn( `Treating '${source}' as external dependency` ); + if ( !this.isExternal( source ) ) this.onwarn( `Treating '${source}' as external dependency` ); + } else if ( resolvedId ) { + if ( isRelative(resolvedId) || isAbsolute(resolvedId) ) { + // Try to deduce relative path from entry dir if resolvedId is defined as a relative path. + normalizedExternal = this.getPathRelativeToEntryDirname( resolvedId ); + } else { + normalizedExternal = resolvedId; + } } - module.resolvedIds[ source ] = source; + module.resolvedIds[ source ] = normalizedExternal; - if ( !this.moduleById[ source ] ) { - const module = new ExternalModule( source ); + if ( !this.moduleById[ normalizedExternal ] ) { + const module = new ExternalModule( normalizedExternal ); this.externalModules.push( module ); - this.moduleById[ source ] = module; + this.moduleById[ normalizedExternal ] = module; } } @@ -206,15 +241,26 @@ export default class Bundle { } }); }); + } + + getPathRelativeToEntryDirname ( resolvedId ) { + // Get a path relative to the resolved entry directory + const entryDirname = dirname( this.entryId ); + const relativeToEntry = relative( entryDirname, resolvedId ); + + if ( isRelative( relativeToEntry )) { + return relativeToEntry; + } - return Promise.all( promises ); + // The path is missing the `./` prefix + return `./${relativeToEntry}`; } render ( options = {} ) { const format = options.format || 'es6'; // Determine export mode - 'default', 'named', 'none' - const exportMode = getExportMode( this, options.exports ); + const exportMode = getExportMode( this, options.exports, options.moduleName ); let magicString = new MagicString.Bundle({ separator: '\n\n' }); let usedModules = []; diff --git a/src/Declaration.js b/src/Declaration.js index 8c61bd2..0601606 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -1,7 +1,9 @@ -import { blank, keys } from './utils/object.js'; +import { blank, forOwn, keys } from './utils/object.js'; import run from './utils/run.js'; import { SyntheticReference } from './Reference.js'; +const use = alias => alias.use(); + export default class Declaration { constructor ( node, isParam, statement ) { if ( node ) { @@ -68,7 +70,7 @@ export default class Declaration { this.isUsed = true; if ( this.statement ) this.statement.mark(); - this.aliases.forEach( alias => alias.use() ); + this.aliases.forEach( use ); } } @@ -129,7 +131,44 @@ export class SyntheticDefaultDeclaration { if ( this.original ) this.original.use(); - this.aliases.forEach( alias => alias.use() ); + this.aliases.forEach( use ); + } +} + +export class SyntheticGlobalDeclaration { + constructor ( name ) { + this.name = name; + this.isExternal = true; + this.isGlobal = true; + this.isReassigned = false; + + this.aliases = []; + + this.isUsed = false; + } + + addAlias ( declaration ) { + this.aliases.push( declaration ); + } + + addReference ( reference ) { + reference.declaration = this; + if ( reference.isReassignment ) this.isReassigned = true; + } + + render () { + return this.name; + } + + run () { + return true; + } + + use () { + if ( this.isUsed ) return; + this.isUsed = true; + + this.aliases.forEach( use ); } } @@ -156,9 +195,9 @@ export class SyntheticNamespaceDeclaration { // if we have e.g. `foo.bar`, we can optimise // the reference by pointing directly to `bar` if ( reference.parts.length ) { - reference.name = reference.parts.shift(); - - reference.end += reference.name.length + 1; // TODO this is brittle + const ref = reference.parts.shift(); + reference.name = ref.name; + reference.end = ref.end; const original = this.originals[ reference.name ]; @@ -182,8 +221,8 @@ export class SyntheticNamespaceDeclaration { // add synthetic references, in case of chained // namespace imports - keys( this.originals ).forEach( name => { - this.originals[ name ].addReference( new SyntheticReference( name ) ); + forOwn( this.originals, ( original, name ) => { + original.addReference( new SyntheticReference( name ) ); }); } @@ -202,7 +241,7 @@ export class SyntheticNamespaceDeclaration { return `${indentString}${name}: ${original.render()}`; }); - return `var ${this.render()} = Object.freeze({\n${members.join( ',\n' )}\n});\n\n`; + return `${this.module.bundle.varOrConst} ${this.render()} = Object.freeze({\n${members.join( ',\n' )}\n});\n\n`; } render () { @@ -210,11 +249,8 @@ export class SyntheticNamespaceDeclaration { } use () { - keys( this.originals ).forEach( name => { - this.originals[ name ].use(); - }); - - this.aliases.forEach( alias => alias.use() ); + forOwn( this.originals, use ); + this.aliases.forEach( use ); } } @@ -246,7 +282,7 @@ export class ExternalDeclaration { } if ( this.name === 'default' ) { - return !es6 && this.module.exportsNames ? + return this.module.exportsNamespace || ( !es6 && this.module.exportsNames ) ? `${this.module.name}__default` : this.module.name; } diff --git a/src/ExternalModule.js b/src/ExternalModule.js index 3113a5d..db9c062 100644 --- a/src/ExternalModule.js +++ b/src/ExternalModule.js @@ -27,9 +27,8 @@ export default class ExternalModule { } traceExport ( name ) { - if ( name !== 'default' && name !== '*' ) { - this.exportsNames = true; - } + if ( name !== 'default' && name !== '*' ) this.exportsNames = true; + if ( name === '*' ) this.exportsNamespace = true; return this.declarations[ name ] || ( this.declarations[ name ] = new ExternalDeclaration( this, name ) diff --git a/src/Module.js b/src/Module.js index 0e42f77..175ecd5 100644 --- a/src/Module.js +++ b/src/Module.js @@ -7,7 +7,11 @@ import { basename, extname } from './utils/path.js'; import getLocation from './utils/getLocation.js'; import makeLegalIdentifier from './utils/makeLegalIdentifier.js'; import SOURCEMAPPING_URL from './utils/sourceMappingURL.js'; -import { SyntheticDefaultDeclaration, SyntheticNamespaceDeclaration } from './Declaration.js'; +import { + SyntheticDefaultDeclaration, + SyntheticGlobalDeclaration, + SyntheticNamespaceDeclaration +} from './Declaration.js'; import { isFalsy, isTruthy } from './ast/conditions.js'; import { emptyBlockStatement } from './ast/create.js'; import extractNames from './ast/extractNames.js'; @@ -73,7 +77,13 @@ export default class Module { else { node.specifiers.forEach( specifier => { - this.reexports[ specifier.exported.name ] = { + const name = specifier.exported.name; + + if ( this.exports[ name ] || this.reexports[ name ] ) { + throw new Error( `A module cannot have multiple exports with the same name ('${name}')` ); + } + + this.reexports[ name ] = { start: specifier.start, source, localName: specifier.local.name, @@ -89,6 +99,11 @@ export default class Module { else if ( node.type === 'ExportDefaultDeclaration' ) { const identifier = ( node.declaration.id && node.declaration.id.name ) || node.declaration.name; + if ( this.exports.default ) { + // TODO indicate location + throw new Error( 'A module can only have one default export' ); + } + this.exports.default = { localName: 'default', identifier @@ -98,37 +113,41 @@ export default class Module { this.declarations.default = new SyntheticDefaultDeclaration( node, statement, identifier || this.basename() ); } - // export { foo, bar, baz } // export var { foo, bar } = ... // export var foo = 42; // export var a = 1, b = 2, c = 3; // export function foo () {} - else if ( node.type === 'ExportNamedDeclaration' ) { + else if ( node.declaration ) { + let declaration = node.declaration; + + if ( declaration.type === 'VariableDeclaration' ) { + declaration.declarations.forEach( decl => { + extractNames( decl.id ).forEach( localName => { + this.exports[ localName ] = { localName }; + }); + }); + } else { + // export function foo () {} + const localName = declaration.id.name; + this.exports[ localName ] = { localName }; + } + } + + // export { foo, bar, baz } + else { if ( node.specifiers.length ) { - // export { foo, bar, baz } node.specifiers.forEach( specifier => { const localName = specifier.local.name; const exportedName = specifier.exported.name; + if ( this.exports[ exportedName ] || this.reexports[ exportedName ] ) { + throw new Error( `A module cannot have multiple exports with the same name ('${exportedName}')` ); + } + this.exports[ exportedName ] = { localName }; }); - } - - else { - let declaration = node.declaration; - - if ( declaration.type === 'VariableDeclaration' ) { - declaration.declarations.forEach( decl => { - extractNames( decl.id ).forEach( localName => { - this.exports[ localName ] = { localName }; - }); - }); - } - else { - // export function foo () {} - const localName = declaration.id.name; - this.exports[ localName ] = { localName }; - } + } else { + this.bundle.onwarn( `Module ${this.id} has an empty export declaration` ); } } } @@ -185,7 +204,7 @@ export default class Module { const declaration = this.declarations[ name ]; const statement = declaration.statement; - if ( statement.node.type !== 'VariableDeclaration' ) return; + if ( !statement || statement.node.type !== 'VariableDeclaration' ) return; const init = statement.node.declarations[0].init; if ( !init || init.type === 'FunctionExpression' ) return; @@ -314,6 +333,20 @@ export default class Module { this.magicString.addSourcemapLocation( node.start ); this.magicString.addSourcemapLocation( node.end ); + }, + + leave: ( node, parent, prop ) => { + // eliminate dead branches early + if ( node.type === 'ConditionalExpression' ) { + if ( isFalsy( node.test ) ) { + this.magicString.remove( node.start, node.alternate.start ); + parent[prop] = node.alternate; + } else if ( isTruthy( node.test ) ) { + this.magicString.remove( node.start, node.consequent.start ); + this.magicString.remove( node.consequent.end, node.end ); + parent[prop] = node.consequent; + } + } } }); @@ -441,7 +474,7 @@ export default class Module { if ( declaration.exportName && declaration.isReassigned ) { // `var foo = ...` becomes `exports.foo = ...` magicString.remove( statement.start, declarator.init ? declarator.start : statement.next ); - return; + if ( !declarator.init ) return; } } @@ -503,7 +536,8 @@ export default class Module { if ( keys( toDeshadow ).length ) { statement.references.forEach( reference => { if ( !reference.rewritten && reference.name in toDeshadow ) { - magicString.overwrite( reference.start, reference.end, toDeshadow[ reference.name ], true ); + const replacement = toDeshadow[ reference.name ]; + magicString.overwrite( reference.start, reference.end, reference.isShorthandProperty ? `${reference.name}: ${replacement}` : replacement, true ); } }); } @@ -558,7 +592,7 @@ export default class Module { if ( statement.node.declaration.type === 'FunctionExpression' ) { magicString.overwrite( statement.node.start, statement.node.declaration.start + 8, `function ${defaultName}` ); } else { - magicString.overwrite( statement.node.start, statement.node.declaration.start, `var ${defaultName} = ` ); + magicString.overwrite( statement.node.start, statement.node.declaration.start, `${this.bundle.varOrConst} ${defaultName} = ` ); } } @@ -577,7 +611,23 @@ export default class Module { return magicString.trim(); } - run () { + /** + * Statically runs the module marking the top-level statements that must be + * included for the module to execute successfully. + * + * @param {boolean} treeshake - if we should tree-shake the module + * @return {boolean} marked - if any new statements were marked for inclusion + */ + run ( treeshake ) { + if ( !treeshake ) { + this.statements.forEach( statement => { + if ( statement.isImportDeclaration || ( statement.isExportDeclaration && statement.node.isSynthetic ) ) return; + + statement.mark(); + }); + return false; + } + let marked = false; this.statements.forEach( statement => { @@ -624,7 +674,13 @@ export default class Module { const exportDeclaration = this.exports[ name ]; if ( exportDeclaration ) { - return this.trace( exportDeclaration.localName ); + const name = exportDeclaration.localName; + const declaration = this.trace( name ); + + if ( declaration ) return declaration; + + this.bundle.assumedGlobals[ name ] = true; + return ( this.declarations[ name ] = new SyntheticGlobalDeclaration( name ) ); } for ( let i = 0; i < this.exportAllModules.length; i += 1 ) { diff --git a/src/Reference.js b/src/Reference.js index e86ad9b..5c5c3e9 100644 --- a/src/Reference.js +++ b/src/Reference.js @@ -10,7 +10,7 @@ export class Reference { let root = node; while ( root.type === 'MemberExpression' ) { - this.parts.unshift( root.property.name ); + this.parts.unshift( root.property ); root = root.object; } diff --git a/src/Statement.js b/src/Statement.js index 8bdd85c..3c00c36 100644 --- a/src/Statement.js +++ b/src/Statement.js @@ -44,10 +44,11 @@ export default class Statement { let readDepth = 0; walk( this.node, { - enter ( node, parent ) { + enter ( node, parent, prop ) { // warn about eval if ( node.type === 'CallExpression' && node.callee.name === 'eval' && !scope.contains( 'eval' ) ) { - module.bundle.onwarn( `Use of \`eval\` (in ${module.id}) is discouraged, as it may cause issues with minification. See https://github.com/rollup/rollup/wiki/Troubleshooting#avoiding-eval for more details` ); + // TODO show location + module.bundle.onwarn( `Use of \`eval\` (in ${module.id}) is strongly discouraged, as it poses security risks and may cause issues with minification. See https://github.com/rollup/rollup/wiki/Troubleshooting#avoiding-eval for more details` ); } // skip re-export declarations @@ -61,42 +62,36 @@ export default class Statement { if ( node._scope ) scope = node._scope; if ( /Function/.test( node.type ) ) readDepth += 1; - // special case – shorthand properties. because node.key === node.value, - // we can't differentiate once we've descended into the node - if ( node.type === 'Property' && node.shorthand && parent.type !== 'ObjectPattern' ) { - const reference = new Reference( node.key, scope ); - reference.isShorthandProperty = true; // TODO feels a bit kludgy - references.push( reference ); - return this.skip(); - } - let isReassignment; if ( parent && isModifierNode( parent ) ) { let subject = parent[ modifierNodes[ parent.type ] ]; - let depth = 0; - while ( subject.type === 'MemberExpression' ) { - subject = subject.object; - depth += 1; - } + if ( node === subject ) { + let depth = 0; + + while ( subject.type === 'MemberExpression' ) { + subject = subject.object; + depth += 1; + } - const importDeclaration = module.imports[ subject.name ]; + const importDeclaration = module.imports[ subject.name ]; - if ( !scope.contains( subject.name ) && importDeclaration ) { - const minDepth = importDeclaration.name === '*' ? - 2 : // cannot do e.g. `namespace.foo = bar` - 1; // cannot do e.g. `foo = bar`, but `foo.bar = bar` is fine + if ( !scope.contains( subject.name ) && importDeclaration ) { + const minDepth = importDeclaration.name === '*' ? + 2 : // cannot do e.g. `namespace.foo = bar` + 1; // cannot do e.g. `foo = bar`, but `foo.bar = bar` is fine - if ( depth < minDepth ) { - const err = new Error( `Illegal reassignment to import '${subject.name}'` ); - err.file = module.id; - err.loc = getLocation( module.magicString.toString(), subject.start ); - throw err; + if ( depth < minDepth ) { + const err = new Error( `Illegal reassignment to import '${subject.name}'` ); + err.file = module.id; + err.loc = getLocation( module.magicString.original, subject.start ); + throw err; + } } - } - isReassignment = !depth; + isReassignment = !depth; + } } if ( isReference( node, parent ) ) { @@ -106,9 +101,19 @@ export default class Statement { scope.parent : scope; + const isShorthandProperty = parent.type === 'Property' && parent.shorthand; + + // Since `node.key` can equal `node.value` for shorthand properties + // we must use the `prop` argument provided by `estree-walker` to determine + // if we're looking at the key or the value. + // If they are equal, we'll return to not create duplicate references. + if ( isShorthandProperty && parent.value === parent.key && prop === 'value' ) { + return; + } + const reference = new Reference( node, referenceScope, statement ); reference.isReassignment = isReassignment; - + reference.isShorthandProperty = isShorthandProperty; references.push( reference ); this.skip(); // don't descend from `foo.bar.baz` into `foo.bar` diff --git a/src/ast/attachScopes.js b/src/ast/attachScopes.js index 92798e8..51fc28a 100644 --- a/src/ast/attachScopes.js +++ b/src/ast/attachScopes.js @@ -29,7 +29,7 @@ export default function attachScopes ( statement ) { let newScope; // create new function scope - if ( /Function/.test( node.type ) ) { + if ( /(Function|Class)/.test( node.type ) ) { newScope = new Scope({ parent: scope, block: false, @@ -38,7 +38,7 @@ export default function attachScopes ( statement ) { // named function expressions - the name is considered // part of the function's scope - if ( node.type === 'FunctionExpression' && node.id ) { + if ( /(Function|Class)Expression/.test( node.type ) && node.id ) { newScope.addDeclaration( node, false, false ); } } diff --git a/src/ast/isReference.js b/src/ast/isReference.js index 0c9a9d7..c2e6c89 100644 --- a/src/ast/isReference.js +++ b/src/ast/isReference.js @@ -10,7 +10,9 @@ export default function isReference ( node, parent ) { if ( !parent ) return true; // TODO is this right? - if ( parent.type === 'MemberExpression' ) return parent.computed || node === parent.object; + if ( parent.type === 'MemberExpression' || parent.type === 'MethodDefinition' ) { + return parent.computed || node === parent.object; + } // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }` if ( parent.type === 'Property' ) return parent.computed || node === parent.value; diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index c71f59d..f6302ff 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -3,28 +3,37 @@ import getExportBlock from './shared/getExportBlock.js'; export default function cjs ( bundle, magicString, { exportMode }, options ) { let intro = options.useStrict === false ? `` : `'use strict';\n\n`; - const hasDefaultImport = bundle.externalModules.some( mod => mod.declarations.default); + let needsInterop = false; - if (hasDefaultImport) { - intro += `function _interopDefault (ex) { return 'default' in ex ? ex['default'] : ex; }\n\n`; - } + const varOrConst = bundle.varOrConst; // TODO handle empty imports, once they're supported const importBlock = bundle.externalModules .map( module => { if ( module.declarations.default ) { - if (module.exportsNames) { - return `var ${module.name} = require('${module.id}');` + - `\nvar ${module.name}__default = _interopDefault(${module.name});`; - } else { - return `var ${module.name} = _interopDefault(require('${module.id}'));`; + if ( module.exportsNamespace ) { + return `${varOrConst} ${module.name} = require('${module.id}');` + + `\n${varOrConst} ${module.name}__default = ${module.name}['default'];`; + } + + needsInterop = true; + + if ( module.exportsNames ) { + return `${varOrConst} ${module.name} = require('${module.id}');` + + `\n${varOrConst} ${module.name}__default = _interopDefault(${module.name});`; } + + return `${varOrConst} ${module.name} = _interopDefault(require('${module.id}'));`; } else { - return `var ${module.name} = require('${module.id}');`; + return `${varOrConst} ${module.name} = require('${module.id}');`; } }) .join( '\n' ); + if ( needsInterop ) { + intro += `function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\n`; + } + if ( importBlock ) { intro += importBlock + '\n\n'; } diff --git a/src/finalisers/es6.js b/src/finalisers/es6.js index 7de4c74..bd3f93f 100644 --- a/src/finalisers/es6.js +++ b/src/finalisers/es6.js @@ -10,10 +10,20 @@ export default function es6 ( bundle, magicString ) { const specifiers = []; const specifiersList = [specifiers]; const importedNames = keys( module.declarations ) - .filter( name => name !== '*' && name !== 'default' ); + .filter( name => name !== '*' && name !== 'default' ) + .map( name => { + const declaration = module.declarations[ name ]; + + if ( declaration.name === declaration.safeName ) return declaration.name; + return `${declaration.name} as ${declaration.safeName}`; + }); if ( module.declarations.default ) { - specifiers.push( module.name ); + if ( module.exportsNamespace ) { + specifiersList.push([ `${module.name}__default` ]); + } else { + specifiers.push( module.name ); + } } const namespaceSpecifier = module.declarations['*'] ? `* as ${module.name}` : null; @@ -47,10 +57,11 @@ export default function es6 ( bundle, magicString ) { const specifiers = module.getExports().filter( notDefault ).map( name => { const declaration = module.traceExport( name ); + const rendered = declaration.render( true ); - return declaration.name === name ? + return rendered === name ? name : - `${declaration.name} as ${name}`; + `${rendered} as ${name}`; }); let exportBlock = specifiers.length ? `export { ${specifiers.join(', ')} };` : ''; diff --git a/src/finalisers/iife.js b/src/finalisers/iife.js index 95c6d65..adb7019 100644 --- a/src/finalisers/iife.js +++ b/src/finalisers/iife.js @@ -31,7 +31,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString } } if ( exportMode === 'named' ) { - dependencies.unshift( `(this.${name} = {})` ); + dependencies.unshift( `(this.${name} = this.${name} || {})` ); args.unshift( 'exports' ); } @@ -41,7 +41,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString } let outro = `\n\n}(${dependencies}));`; if ( exportMode === 'default' ) { - intro = ( isNamespaced ? `this.` : `var ` ) + `${name} = ${intro}`; + intro = ( isNamespaced ? `this.` : `${bundle.varOrConst} ` ) + `${name} = ${intro}`; } if ( isNamespaced ) { diff --git a/src/finalisers/shared/getInteropBlock.js b/src/finalisers/shared/getInteropBlock.js index e0e2617..67a26d7 100644 --- a/src/finalisers/shared/getInteropBlock.js +++ b/src/finalisers/shared/getInteropBlock.js @@ -1,11 +1,17 @@ export default function getInteropBlock ( bundle ) { return bundle.externalModules .map( module => { - return module.declarations.default ? - ( module.exportsNames ? - `var ${module.name}__default = 'default' in ${module.name} ? ${module.name}['default'] : ${module.name};` : - `${module.name} = 'default' in ${module.name} ? ${module.name}['default'] : ${module.name};` ) : - null; + if ( !module.declarations.default ) return null; + + if ( module.exportsNamespace ) { + return `${bundle.varOrConst} ${module.name}__default = ${module.name}['default'];`; + } + + if ( module.exportsNames ) { + return `${bundle.varOrConst} ${module.name}__default = 'default' in ${module.name} ? ${module.name}['default'] : ${module.name};`; + } + + return `${module.name} = 'default' in ${module.name} ? ${module.name}['default'] : ${module.name};`; }) .filter( Boolean ) .join( '\n' ); diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index 3e8e813..0ec344e 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -31,7 +31,7 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, if ( exportMode === 'named' ) { amdDeps.unshift( `'exports'` ); cjsDeps.unshift( `exports` ); - globalDeps.unshift( `(${setupNamespace(options.moduleName)} = {})` ); + globalDeps.unshift( `(${setupNamespace(options.moduleName)} = global.${options.moduleName} || {})` ); args.unshift( 'exports' ); } @@ -45,11 +45,19 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, const useStrict = options.useStrict !== false ? ` 'use strict';` : ``; + const globalExport = options.noConflict === true ? + `(function() { + var current = global.${options.moduleName}; + var exports = factory(${globalDeps}); + global.${options.moduleName} = exports; + exports.noConflict = function() { global.${options.moduleName} = current; return exports; }; + })()` : `(${defaultExport}factory(${globalDeps}))`; + const intro = `(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? ${cjsExport}factory(${cjsDeps.join( ', ' )}) : typeof define === 'function' && define.amd ? define(${amdParams}factory) : - (${defaultExport}factory(${globalDeps})); + ${globalExport}; }(this, function (${args}) {${useStrict} `.replace( /^\t\t/gm, '' ).replace( /^\t/gm, magicString.getIndentString() ); diff --git a/src/rollup.js b/src/rollup.js index d509bd2..77a97bd 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -12,6 +12,7 @@ const ALLOWED_KEYS = [ 'banner', 'dest', 'entry', + 'exports', 'external', 'footer', 'format', @@ -20,10 +21,14 @@ const ALLOWED_KEYS = [ 'intro', 'moduleId', 'moduleName', + 'noConflict', 'onwarn', 'outro', 'plugins', - 'sourceMap' + 'preferConst', + 'sourceMap', + 'treeshake', + 'useStrict' ]; export function rollup ( options ) { diff --git a/src/utils/collapseSourcemaps.js b/src/utils/collapseSourcemaps.js index 36a46c8..ff86eaf 100644 --- a/src/utils/collapseSourcemaps.js +++ b/src/utils/collapseSourcemaps.js @@ -1,25 +1,25 @@ import { encode, decode } from 'sourcemap-codec'; -function Source ( index ) { - this.isOriginal = true; - this.index = index; -} +class Source { + constructor ( index ) { + this.isOriginal = true; + this.index = index; + } -Source.prototype = { traceSegment ( line, column, name ) { return { line, column, name, index: this.index }; } -}; +} -function Link ( map, sources ) { - if ( !map ) throw new Error( 'Cannot generate a sourcemap if non-sourcemap-generating transformers are used' ); +class Link { + constructor ( map, sources ) { + if ( !map ) throw new Error( 'Cannot generate a sourcemap if non-sourcemap-generating transformers are used' ); - this.sources = sources; - this.names = map.names; - this.mappings = decode( map.mappings ); -} + this.sources = sources; + this.names = map.names; + this.mappings = decode( map.mappings ); + } -Link.prototype = { // TODO bring into line with others post-https://github.com/rollup/rollup/pull/386 traceMappings () { let names = []; @@ -57,7 +57,7 @@ Link.prototype = { // TODO bring into line with others post-https://github.com/r }); return { names, mappings }; - }, + } traceSegment ( line, column, name ) { const segments = this.mappings[ line ]; @@ -71,8 +71,7 @@ Link.prototype = { // TODO bring into line with others post-https://github.com/r if ( segment[0] === column ) { const source = this.sources[ segment[1] ]; - - if ( !source ) throw new Error( 'Bad sourcemap' ); + if ( !source ) return null; return source.traceSegment( segment[2], segment[3], this.names[ segment[4] ] || name ); } @@ -80,7 +79,7 @@ Link.prototype = { // TODO bring into line with others post-https://github.com/r return null; } -}; +} export default function collapseSourcemaps ( map, modules, bundleSourcemapChain ) { const sources = modules.map( ( module, i ) => { diff --git a/src/utils/getExportMode.js b/src/utils/getExportMode.js index ed52c6a..f37ff1e 100644 --- a/src/utils/getExportMode.js +++ b/src/utils/getExportMode.js @@ -4,7 +4,7 @@ function badExports ( option, keys ) { throw new Error( `'${option}' was specified for options.exports, but entry module has following exports: ${keys.join(', ')}` ); } -export default function getExportMode ( bundle, exportMode ) { +export default function getExportMode ( bundle, exportMode, moduleName ) { const exportKeys = keys( bundle.entryModule.exports ) .concat( keys( bundle.entryModule.reexports ) ) .concat( bundle.entryModule.exportAllSources ); // not keys, but makes our job easier this way @@ -23,6 +23,9 @@ export default function getExportMode ( bundle, exportMode ) { } else if ( exportKeys.length === 1 && exportKeys[0] === 'default' ) { exportMode = 'default'; } else { + if ( bundle.entryModule.exports.default ) { + bundle.onwarn( `Using named and default exports together. Consumers of your bundle will have to use ${moduleName || 'bundle'}['default'] to access the default export, which may not be what you want. Use \`exports: 'named'\` to disable this warning. See https://github.com/rollup/rollup/wiki/JavaScript-API#exports for more information` ); + } exportMode = 'named'; } } diff --git a/src/utils/object.js b/src/utils/object.js index a11ea25..b4e1ff1 100644 --- a/src/utils/object.js +++ b/src/utils/object.js @@ -1,5 +1,9 @@ -export const keys = Object.keys; +export const { keys } = Object; export function blank () { return Object.create( null ); } + +export function forOwn ( object, func ) { + Object.keys( object ).forEach( key => func( object[ key ], key ) ); +} diff --git a/src/utils/promise.js b/src/utils/promise.js new file mode 100644 index 0000000..1730de8 --- /dev/null +++ b/src/utils/promise.js @@ -0,0 +1,16 @@ +import Promise from 'es6-promise/lib/es6-promise/promise.js'; + +export function mapSequence ( array, fn ) { + let results = []; + let promise = Promise.resolve(); + + function next ( member, i ) { + return fn( member ).then( value => results[i] = value ); + } + + for ( let i = 0; i < array.length; i += 1 ) { + promise = promise.then( () => next( array[i], i ) ); + } + + return promise.then( () => results ); +} diff --git a/src/utils/run.js b/src/utils/run.js index 4470305..3e91d63 100644 --- a/src/utils/run.js +++ b/src/utils/run.js @@ -75,6 +75,10 @@ export default function run ( node, scope, statement, strongDependencies, force } } + else if ( node.type === 'DebuggerStatement' ) { + hasSideEffect = true; + } + else if ( node.type === 'ThrowStatement' ) { // we only care about errors thrown at the top level, otherwise // any function with error checking gets included if called @@ -95,6 +99,8 @@ export default function run ( node, scope, statement, strongDependencies, force if ( declaration ) { if ( declaration.isParam ) hasSideEffect = true; + } else if ( !scope.isTopLevel ) { + hasSideEffect = true; } else { declaration = statement.module.trace( subject.name ); diff --git a/src/utils/transform.js b/src/utils/transform.js index 5ddde28..b401370 100644 --- a/src/utils/transform.js +++ b/src/utils/transform.js @@ -39,5 +39,10 @@ export default function transform ( source, id, transformers ) { }, Promise.resolve( source.code ) ) - .then( code => ({ code, originalCode, ast, sourceMapChain }) ); + .then( code => ({ code, originalCode, ast, sourceMapChain }) ) + .catch( err => { + err.id = id; + err.message = `Error loading ${id}: ${err.message}`; + throw err; + }); } diff --git a/.babelrc b/test/.babelrc similarity index 100% rename from .babelrc rename to test/.babelrc diff --git a/test/cli/config-missing-export/_config.js b/test/cli/config-missing-export/_config.js new file mode 100644 index 0000000..051f155 --- /dev/null +++ b/test/cli/config-missing-export/_config.js @@ -0,0 +1,9 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'throws error if config does not export an object', + command: 'rollup -c', + error: function ( err ) { + assert.ok( /Config file must export an options object/.test( err.message ) ); + } +}; diff --git a/test/cli/config-missing-export/rollup.config.js b/test/cli/config-missing-export/rollup.config.js new file mode 100644 index 0000000..e69de29 diff --git a/test/cli/no-treeshake/_config.js b/test/cli/no-treeshake/_config.js new file mode 100644 index 0000000..18d8b69 --- /dev/null +++ b/test/cli/no-treeshake/_config.js @@ -0,0 +1,4 @@ +module.exports = { + description: 'generates IIFE export with all code', + command: 'rollup main.js --format iife --name shakeless --no-treeshake' +}; diff --git a/test/cli/no-treeshake/_expected.js b/test/cli/no-treeshake/_expected.js new file mode 100644 index 0000000..6c3cf53 --- /dev/null +++ b/test/cli/no-treeshake/_expected.js @@ -0,0 +1,10 @@ +var shakeless = (function () { + 'use strict'; + + const version = '1.2.0'; + + var main = ( x, y ) => x + y; + + return main; + +}()); diff --git a/test/cli/no-treeshake/main.js b/test/cli/no-treeshake/main.js new file mode 100644 index 0000000..1aa6a51 --- /dev/null +++ b/test/cli/no-treeshake/main.js @@ -0,0 +1,3 @@ +const version = '1.2.0'; + +export default ( x, y ) => x + y; diff --git a/test/form/assignment-to-exports-class-declaration/_config.js b/test/form/assignment-to-exports-class-declaration/_config.js new file mode 100644 index 0000000..0f3d2ef --- /dev/null +++ b/test/form/assignment-to-exports-class-declaration/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'does not rewrite class declaration IDs', + options: { + moduleName: 'myModule' + } +}; diff --git a/test/form/assignment-to-exports-class-declaration/_expected/amd.js b/test/form/assignment-to-exports-class-declaration/_expected/amd.js new file mode 100644 index 0000000..c2d0691 --- /dev/null +++ b/test/form/assignment-to-exports-class-declaration/_expected/amd.js @@ -0,0 +1,6 @@ +define(['exports'], function (exports) { 'use strict'; + + exports.Foo = class Foo {} + exports.Foo = lol( exports.Foo ); + +}); diff --git a/test/form/assignment-to-exports-class-declaration/_expected/cjs.js b/test/form/assignment-to-exports-class-declaration/_expected/cjs.js new file mode 100644 index 0000000..b062474 --- /dev/null +++ b/test/form/assignment-to-exports-class-declaration/_expected/cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +exports.Foo = class Foo {} +exports.Foo = lol( exports.Foo ); diff --git a/test/form/assignment-to-exports-class-declaration/_expected/es6.js b/test/form/assignment-to-exports-class-declaration/_expected/es6.js new file mode 100644 index 0000000..08e82c9 --- /dev/null +++ b/test/form/assignment-to-exports-class-declaration/_expected/es6.js @@ -0,0 +1,4 @@ +Foo = class Foo {} +Foo = lol( Foo ); + +export { Foo }; \ No newline at end of file diff --git a/test/form/assignment-to-exports-class-declaration/_expected/iife.js b/test/form/assignment-to-exports-class-declaration/_expected/iife.js new file mode 100644 index 0000000..fa37538 --- /dev/null +++ b/test/form/assignment-to-exports-class-declaration/_expected/iife.js @@ -0,0 +1,7 @@ +(function (exports) { + 'use strict'; + + exports.Foo = class Foo {} + exports.Foo = lol( exports.Foo ); + +}((this.myModule = this.myModule || {}))); diff --git a/test/form/assignment-to-exports-class-declaration/_expected/umd.js b/test/form/assignment-to-exports-class-declaration/_expected/umd.js new file mode 100644 index 0000000..bbefc87 --- /dev/null +++ b/test/form/assignment-to-exports-class-declaration/_expected/umd.js @@ -0,0 +1,10 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.myModule = global.myModule || {}))); +}(this, function (exports) { 'use strict'; + + exports.Foo = class Foo {} + exports.Foo = lol( exports.Foo ); + +})); diff --git a/test/form/assignment-to-exports-class-declaration/main.js b/test/form/assignment-to-exports-class-declaration/main.js new file mode 100644 index 0000000..ceae376 --- /dev/null +++ b/test/form/assignment-to-exports-class-declaration/main.js @@ -0,0 +1,2 @@ +export let Foo = class Foo {} +Foo = lol( Foo ); diff --git a/test/form/computed-properties/_expected/amd.js b/test/form/computed-properties/_expected/amd.js index 4fd933f..0ccd4d8 100644 --- a/test/form/computed-properties/_expected/amd.js +++ b/test/form/computed-properties/_expected/amd.js @@ -1,9 +1,19 @@ define(['exports'], function (exports) { 'use strict'; var foo = 'foo'; + var bar = 'bar'; + var baz = 'baz'; + var bam = 'bam'; - var x = {[foo]: 'bar'}; + var x = { [foo]: 'bar' }; + + class X { + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} + } exports.x = x; + exports.X = X; }); \ No newline at end of file diff --git a/test/form/computed-properties/_expected/cjs.js b/test/form/computed-properties/_expected/cjs.js index 22126d8..443bab3 100644 --- a/test/form/computed-properties/_expected/cjs.js +++ b/test/form/computed-properties/_expected/cjs.js @@ -1,7 +1,17 @@ 'use strict'; var foo = 'foo'; +var bar = 'bar'; +var baz = 'baz'; +var bam = 'bam'; -var x = {[foo]: 'bar'}; +var x = { [foo]: 'bar' }; -exports.x = x; \ No newline at end of file +class X { + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} +} + +exports.x = x; +exports.X = X; \ No newline at end of file diff --git a/test/form/computed-properties/_expected/es6.js b/test/form/computed-properties/_expected/es6.js index 6dc09ca..d818b11 100644 --- a/test/form/computed-properties/_expected/es6.js +++ b/test/form/computed-properties/_expected/es6.js @@ -1,5 +1,14 @@ var foo = 'foo'; +var bar = 'bar'; +var baz = 'baz'; +var bam = 'bam'; -var x = {[foo]: 'bar'}; +var x = { [foo]: 'bar' }; -export { x }; \ No newline at end of file +class X { + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} +} + +export { x, X }; \ No newline at end of file diff --git a/test/form/computed-properties/_expected/iife.js b/test/form/computed-properties/_expected/iife.js index 35b80af..031368a 100644 --- a/test/form/computed-properties/_expected/iife.js +++ b/test/form/computed-properties/_expected/iife.js @@ -2,9 +2,19 @@ 'use strict'; var foo = 'foo'; + var bar = 'bar'; + var baz = 'baz'; + var bam = 'bam'; - var x = {[foo]: 'bar'}; + var x = { [foo]: 'bar' }; + + class X { + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} + } exports.x = x; + exports.X = X; -}((this.computedProperties = {}))); \ No newline at end of file +}((this.computedProperties = this.computedProperties || {}))); \ No newline at end of file diff --git a/test/form/computed-properties/_expected/umd.js b/test/form/computed-properties/_expected/umd.js index 5f7d146..ae57683 100644 --- a/test/form/computed-properties/_expected/umd.js +++ b/test/form/computed-properties/_expected/umd.js @@ -1,13 +1,23 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.computedProperties = {}))); + (factory((global.computedProperties = global.computedProperties || {}))); }(this, function (exports) { 'use strict'; var foo = 'foo'; + var bar = 'bar'; + var baz = 'baz'; + var bam = 'bam'; - var x = {[foo]: 'bar'}; + var x = { [foo]: 'bar' }; + + class X { + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} + } exports.x = x; + exports.X = X; })); \ No newline at end of file diff --git a/test/form/computed-properties/main.js b/test/form/computed-properties/main.js index 65bb97c..6cfc64a 100644 --- a/test/form/computed-properties/main.js +++ b/test/form/computed-properties/main.js @@ -1,3 +1,12 @@ var foo = 'foo'; +var bar = 'bar'; +var baz = 'baz'; +var bam = 'bam'; -export var x = {[foo]: 'bar'}; +export var x = { [foo]: 'bar' }; + +export class X { + [bar] () {} + get [baz] () {} + set [bam] ( value ) {} +} diff --git a/test/form/conflicting-imports/_config.js b/test/form/conflicting-imports/_config.js new file mode 100644 index 0000000..a9b8ddf --- /dev/null +++ b/test/form/conflicting-imports/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'ensures bundle imports are deconflicted (#659)' +}; diff --git a/test/form/conflicting-imports/_expected/amd.js b/test/form/conflicting-imports/_expected/amd.js new file mode 100644 index 0000000..e3b61ef --- /dev/null +++ b/test/form/conflicting-imports/_expected/amd.js @@ -0,0 +1,7 @@ +define(['foo', 'bar'], function (foo, bar) { 'use strict'; + + console.log( bar.a ); + + console.log( foo.a ); + +}); \ No newline at end of file diff --git a/test/form/conflicting-imports/_expected/cjs.js b/test/form/conflicting-imports/_expected/cjs.js new file mode 100644 index 0000000..2c2c321 --- /dev/null +++ b/test/form/conflicting-imports/_expected/cjs.js @@ -0,0 +1,8 @@ +'use strict'; + +var foo = require('foo'); +var bar = require('bar'); + +console.log( bar.a ); + +console.log( foo.a ); \ No newline at end of file diff --git a/test/form/conflicting-imports/_expected/es6.js b/test/form/conflicting-imports/_expected/es6.js new file mode 100644 index 0000000..281b463 --- /dev/null +++ b/test/form/conflicting-imports/_expected/es6.js @@ -0,0 +1,6 @@ +import { a } from 'foo'; +import { a as a$1 } from 'bar'; + +console.log( a$1 ); + +console.log( a ); diff --git a/test/form/conflicting-imports/_expected/iife.js b/test/form/conflicting-imports/_expected/iife.js new file mode 100644 index 0000000..6f9d443 --- /dev/null +++ b/test/form/conflicting-imports/_expected/iife.js @@ -0,0 +1,8 @@ +(function (foo,bar) { + 'use strict'; + + console.log( bar.a ); + + console.log( foo.a ); + +}(foo,bar)); \ No newline at end of file diff --git a/test/form/conflicting-imports/_expected/umd.js b/test/form/conflicting-imports/_expected/umd.js new file mode 100644 index 0000000..8254c77 --- /dev/null +++ b/test/form/conflicting-imports/_expected/umd.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('foo'), require('bar')) : + typeof define === 'function' && define.amd ? define(['foo', 'bar'], factory) : + (factory(global.foo,global.bar)); +}(this, function (foo,bar) { 'use strict'; + + console.log( bar.a ); + + console.log( foo.a ); + +})); \ No newline at end of file diff --git a/test/form/conflicting-imports/main.js b/test/form/conflicting-imports/main.js new file mode 100644 index 0000000..8ed570b --- /dev/null +++ b/test/form/conflicting-imports/main.js @@ -0,0 +1,4 @@ +import { a } from 'foo'; +import './other.js'; + +console.log( a ); diff --git a/test/form/conflicting-imports/other.js b/test/form/conflicting-imports/other.js new file mode 100644 index 0000000..157ab35 --- /dev/null +++ b/test/form/conflicting-imports/other.js @@ -0,0 +1,3 @@ +import { a } from 'bar'; + +console.log( a ); diff --git a/test/form/dedupes-external-imports/_expected/iife.js b/test/form/dedupes-external-imports/_expected/iife.js index 17ed0b7..57e6649 100644 --- a/test/form/dedupes-external-imports/_expected/iife.js +++ b/test/form/dedupes-external-imports/_expected/iife.js @@ -30,4 +30,4 @@ exports.bar = bar; exports.baz = baz; -}((this.myBundle = {}),external)); +}((this.myBundle = this.myBundle || {}),external)); diff --git a/test/form/dedupes-external-imports/_expected/umd.js b/test/form/dedupes-external-imports/_expected/umd.js index 70bc301..06be0e7 100644 --- a/test/form/dedupes-external-imports/_expected/umd.js +++ b/test/form/dedupes-external-imports/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('external')) : typeof define === 'function' && define.amd ? define(['exports', 'external'], factory) : - (factory((global.myBundle = {}),global.external)); + (factory((global.myBundle = global.myBundle || {}),global.external)); }(this, function (exports,external) { 'use strict'; class Foo extends external.Component { diff --git a/test/form/erroneous-nested-member-expression/_config.js b/test/form/erroneous-nested-member-expression/_config.js new file mode 100644 index 0000000..684fe7c --- /dev/null +++ b/test/form/erroneous-nested-member-expression/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'erroneous nested member expression does not mess up naming' +}; diff --git a/test/form/erroneous-nested-member-expression/_expected/amd.js b/test/form/erroneous-nested-member-expression/_expected/amd.js new file mode 100644 index 0000000..6499b90 --- /dev/null +++ b/test/form/erroneous-nested-member-expression/_expected/amd.js @@ -0,0 +1,13 @@ +define(function () { 'use strict'; + + function yar() { + return { + har() { + console.log('har?'); + } + }; + }; + + yar.har(); + +}); \ No newline at end of file diff --git a/test/form/erroneous-nested-member-expression/_expected/cjs.js b/test/form/erroneous-nested-member-expression/_expected/cjs.js new file mode 100644 index 0000000..aa4b949 --- /dev/null +++ b/test/form/erroneous-nested-member-expression/_expected/cjs.js @@ -0,0 +1,11 @@ +'use strict'; + +function yar() { + return { + har() { + console.log('har?'); + } + }; +}; + +yar.har(); \ No newline at end of file diff --git a/test/form/erroneous-nested-member-expression/_expected/es6.js b/test/form/erroneous-nested-member-expression/_expected/es6.js new file mode 100644 index 0000000..34c4e2e --- /dev/null +++ b/test/form/erroneous-nested-member-expression/_expected/es6.js @@ -0,0 +1,9 @@ +function yar() { + return { + har() { + console.log('har?'); + } + }; +}; + +yar.har(); \ No newline at end of file diff --git a/test/form/erroneous-nested-member-expression/_expected/iife.js b/test/form/erroneous-nested-member-expression/_expected/iife.js new file mode 100644 index 0000000..4233cfe --- /dev/null +++ b/test/form/erroneous-nested-member-expression/_expected/iife.js @@ -0,0 +1,14 @@ +(function () { + 'use strict'; + + function yar() { + return { + har() { + console.log('har?'); + } + }; + }; + + yar.har(); + +}()); \ No newline at end of file diff --git a/test/form/erroneous-nested-member-expression/_expected/umd.js b/test/form/erroneous-nested-member-expression/_expected/umd.js new file mode 100644 index 0000000..d11bd9f --- /dev/null +++ b/test/form/erroneous-nested-member-expression/_expected/umd.js @@ -0,0 +1,17 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, function () { 'use strict'; + + function yar() { + return { + har() { + console.log('har?'); + } + }; + }; + + yar.har(); + +})); \ No newline at end of file diff --git a/test/form/erroneous-nested-member-expression/foo.js b/test/form/erroneous-nested-member-expression/foo.js new file mode 100644 index 0000000..44f5e23 --- /dev/null +++ b/test/form/erroneous-nested-member-expression/foo.js @@ -0,0 +1,7 @@ +export function yar() { + return { + har() { + console.log('har?'); + } + }; +}; diff --git a/test/form/erroneous-nested-member-expression/main.js b/test/form/erroneous-nested-member-expression/main.js new file mode 100644 index 0000000..37c4b16 --- /dev/null +++ b/test/form/erroneous-nested-member-expression/main.js @@ -0,0 +1,2 @@ +import * as foo from './foo.js'; +foo.yar.har(); diff --git a/test/form/export-all-from-internal/_expected/iife.js b/test/form/export-all-from-internal/_expected/iife.js index b5dad56..8a3cd17 100644 --- a/test/form/export-all-from-internal/_expected/iife.js +++ b/test/form/export-all-from-internal/_expected/iife.js @@ -7,4 +7,4 @@ exports.a = a; exports.b = b; -}((this.exposedInternals = {}))); +}((this.exposedInternals = this.exposedInternals || {}))); diff --git a/test/form/export-all-from-internal/_expected/umd.js b/test/form/export-all-from-internal/_expected/umd.js index 74613b4..b249cc6 100644 --- a/test/form/export-all-from-internal/_expected/umd.js +++ b/test/form/export-all-from-internal/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.exposedInternals = {}))); + (factory((global.exposedInternals = global.exposedInternals || {}))); }(this, function (exports) { 'use strict'; const a = 1; diff --git a/test/form/export-default-import/_config.js b/test/form/export-default-import/_config.js new file mode 100644 index 0000000..860f688 --- /dev/null +++ b/test/form/export-default-import/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'correctly exports a default import, even in ES mode (#513)', + options: { + moduleName: 'myBundle' + } +}; diff --git a/test/form/export-default-import/_expected/amd.js b/test/form/export-default-import/_expected/amd.js new file mode 100644 index 0000000..9158c43 --- /dev/null +++ b/test/form/export-default-import/_expected/amd.js @@ -0,0 +1,9 @@ +define(['exports', 'x'], function (exports, x) { 'use strict'; + + x = 'default' in x ? x['default'] : x; + + + + exports.x = x; + +}); \ No newline at end of file diff --git a/test/form/export-default-import/_expected/cjs.js b/test/form/export-default-import/_expected/cjs.js new file mode 100644 index 0000000..60037db --- /dev/null +++ b/test/form/export-default-import/_expected/cjs.js @@ -0,0 +1,9 @@ +'use strict'; + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var x = _interopDefault(require('x')); + + + +exports.x = x; \ No newline at end of file diff --git a/test/form/export-default-import/_expected/es6.js b/test/form/export-default-import/_expected/es6.js new file mode 100644 index 0000000..87ab795 --- /dev/null +++ b/test/form/export-default-import/_expected/es6.js @@ -0,0 +1,5 @@ +import x from 'x'; + + + +export { x }; diff --git a/test/form/export-default-import/_expected/iife.js b/test/form/export-default-import/_expected/iife.js new file mode 100644 index 0000000..4c3865e --- /dev/null +++ b/test/form/export-default-import/_expected/iife.js @@ -0,0 +1,10 @@ +(function (exports,x) { + 'use strict'; + + x = 'default' in x ? x['default'] : x; + + + + exports.x = x; + +}((this.myBundle = this.myBundle || {}),x)); \ No newline at end of file diff --git a/test/form/export-default-import/_expected/umd.js b/test/form/export-default-import/_expected/umd.js new file mode 100644 index 0000000..872c0d8 --- /dev/null +++ b/test/form/export-default-import/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('x')) : + typeof define === 'function' && define.amd ? define(['exports', 'x'], factory) : + (factory((global.myBundle = global.myBundle || {}),global.x)); +}(this, function (exports,x) { 'use strict'; + + x = 'default' in x ? x['default'] : x; + + + + exports.x = x; + +})); \ No newline at end of file diff --git a/test/form/export-default-import/main.js b/test/form/export-default-import/main.js new file mode 100644 index 0000000..31bb602 --- /dev/null +++ b/test/form/export-default-import/main.js @@ -0,0 +1,3 @@ +import x from 'x'; + +export { x }; diff --git a/test/form/exports-at-end-if-possible/_expected/iife.js b/test/form/exports-at-end-if-possible/_expected/iife.js index a0ce6a9..1c5c67b 100644 --- a/test/form/exports-at-end-if-possible/_expected/iife.js +++ b/test/form/exports-at-end-if-possible/_expected/iife.js @@ -9,4 +9,4 @@ exports.FOO = FOO; -}((this.myBundle = {}))); +}((this.myBundle = this.myBundle || {}))); diff --git a/test/form/exports-at-end-if-possible/_expected/umd.js b/test/form/exports-at-end-if-possible/_expected/umd.js index 20d0d2a..e9cbc8d 100644 --- a/test/form/exports-at-end-if-possible/_expected/umd.js +++ b/test/form/exports-at-end-if-possible/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.myBundle = {}))); + (factory((global.myBundle = global.myBundle || {}))); }(this, function (exports) { 'use strict'; var FOO = 'foo'; diff --git a/test/form/external-imports-custom-names/_expected/cjs.js b/test/form/external-imports-custom-names/_expected/cjs.js index 8f6506e..9600acd 100644 --- a/test/form/external-imports-custom-names/_expected/cjs.js +++ b/test/form/external-imports-custom-names/_expected/cjs.js @@ -1,6 +1,6 @@ 'use strict'; -function _interopDefault (ex) { return 'default' in ex ? ex['default'] : ex; } +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var $ = _interopDefault(require('jquery')); diff --git a/test/form/external-imports/_expected/cjs.js b/test/form/external-imports/_expected/cjs.js index a3ee9b0..94dbdae 100644 --- a/test/form/external-imports/_expected/cjs.js +++ b/test/form/external-imports/_expected/cjs.js @@ -1,6 +1,6 @@ 'use strict'; -function _interopDefault (ex) { return 'default' in ex ? ex['default'] : ex; } +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var factory = _interopDefault(require('factory')); var baz = require('baz'); diff --git a/test/form/import-external-namespace-and-default/_config.js b/test/form/import-external-namespace-and-default/_config.js new file mode 100644 index 0000000..5ee7b48 --- /dev/null +++ b/test/form/import-external-namespace-and-default/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'disinguishes between external default and namespace (#637)' +}; diff --git a/test/form/import-external-namespace-and-default/_expected/amd.js b/test/form/import-external-namespace-and-default/_expected/amd.js new file mode 100644 index 0000000..1f4b3f9 --- /dev/null +++ b/test/form/import-external-namespace-and-default/_expected/amd.js @@ -0,0 +1,9 @@ +define(['foo'], function (foo) { 'use strict'; + + var foo__default = foo['default']; + + console.log( foo.bar ); + + console.log( foo__default ); + +}); diff --git a/test/form/import-external-namespace-and-default/_expected/cjs.js b/test/form/import-external-namespace-and-default/_expected/cjs.js new file mode 100644 index 0000000..14c733e --- /dev/null +++ b/test/form/import-external-namespace-and-default/_expected/cjs.js @@ -0,0 +1,8 @@ +'use strict'; + +var foo = require('foo'); +var foo__default = foo['default']; + +console.log( foo.bar ); + +console.log( foo__default ); diff --git a/test/form/import-external-namespace-and-default/_expected/es6.js b/test/form/import-external-namespace-and-default/_expected/es6.js new file mode 100644 index 0000000..5655595 --- /dev/null +++ b/test/form/import-external-namespace-and-default/_expected/es6.js @@ -0,0 +1,6 @@ +import * as foo from 'foo'; +import foo__default from 'foo'; + +console.log( foo.bar ); + +console.log( foo__default ); diff --git a/test/form/import-external-namespace-and-default/_expected/iife.js b/test/form/import-external-namespace-and-default/_expected/iife.js new file mode 100644 index 0000000..b2c5788 --- /dev/null +++ b/test/form/import-external-namespace-and-default/_expected/iife.js @@ -0,0 +1,10 @@ +(function (foo) { + 'use strict'; + + var foo__default = foo['default']; + + console.log( foo.bar ); + + console.log( foo__default ); + +}(foo)); diff --git a/test/form/import-external-namespace-and-default/_expected/umd.js b/test/form/import-external-namespace-and-default/_expected/umd.js new file mode 100644 index 0000000..ddcdcbd --- /dev/null +++ b/test/form/import-external-namespace-and-default/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('foo')) : + typeof define === 'function' && define.amd ? define(['foo'], factory) : + (factory(global.foo)); +}(this, function (foo) { 'use strict'; + + var foo__default = foo['default']; + + console.log( foo.bar ); + + console.log( foo__default ); + +})); diff --git a/test/form/import-external-namespace-and-default/main.js b/test/form/import-external-namespace-and-default/main.js new file mode 100644 index 0000000..719a96a --- /dev/null +++ b/test/form/import-external-namespace-and-default/main.js @@ -0,0 +1,4 @@ +import foo from 'foo'; +import './other.js'; + +console.log( foo ); diff --git a/test/form/import-external-namespace-and-default/other.js b/test/form/import-external-namespace-and-default/other.js new file mode 100644 index 0000000..8149fb6 --- /dev/null +++ b/test/form/import-external-namespace-and-default/other.js @@ -0,0 +1,3 @@ +import * as foo from 'foo'; + +console.log( foo.bar ); diff --git a/test/form/import-named-exported-global-with-alias/_config.js b/test/form/import-named-exported-global-with-alias/_config.js new file mode 100644 index 0000000..85b39fe --- /dev/null +++ b/test/form/import-named-exported-global-with-alias/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'allow globals to be exported and imported', + options: { + moduleName: 'doc' + } +}; diff --git a/test/form/import-named-exported-global-with-alias/_expected/amd.js b/test/form/import-named-exported-global-with-alias/_expected/amd.js new file mode 100644 index 0000000..ec759b1 --- /dev/null +++ b/test/form/import-named-exported-global-with-alias/_expected/amd.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + + +}); \ No newline at end of file diff --git a/test/form/import-named-exported-global-with-alias/_expected/cjs.js b/test/form/import-named-exported-global-with-alias/_expected/cjs.js new file mode 100644 index 0000000..eb109ab --- /dev/null +++ b/test/form/import-named-exported-global-with-alias/_expected/cjs.js @@ -0,0 +1,2 @@ +'use strict'; + diff --git a/test/form/import-named-exported-global-with-alias/_expected/es6.js b/test/form/import-named-exported-global-with-alias/_expected/es6.js new file mode 100644 index 0000000..e69de29 diff --git a/test/form/import-named-exported-global-with-alias/_expected/iife.js b/test/form/import-named-exported-global-with-alias/_expected/iife.js new file mode 100644 index 0000000..f3d1016 --- /dev/null +++ b/test/form/import-named-exported-global-with-alias/_expected/iife.js @@ -0,0 +1,6 @@ +(function () { + 'use strict'; + + + +}()); \ No newline at end of file diff --git a/test/form/import-named-exported-global-with-alias/_expected/umd.js b/test/form/import-named-exported-global-with-alias/_expected/umd.js new file mode 100644 index 0000000..f3395b7 --- /dev/null +++ b/test/form/import-named-exported-global-with-alias/_expected/umd.js @@ -0,0 +1,9 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, function () { 'use strict'; + + + +})); \ No newline at end of file diff --git a/test/form/import-named-exported-global-with-alias/browser.js b/test/form/import-named-exported-global-with-alias/browser.js new file mode 100644 index 0000000..a7aab36 --- /dev/null +++ b/test/form/import-named-exported-global-with-alias/browser.js @@ -0,0 +1 @@ +export { document }; diff --git a/test/form/import-named-exported-global-with-alias/main.js b/test/form/import-named-exported-global-with-alias/main.js new file mode 100644 index 0000000..5d3739c --- /dev/null +++ b/test/form/import-named-exported-global-with-alias/main.js @@ -0,0 +1,2 @@ +import { document } from './browser.js'; +var d = document; diff --git a/test/form/multiple-exports/_expected/iife.js b/test/form/multiple-exports/_expected/iife.js index 3a3975d..d2da90f 100644 --- a/test/form/multiple-exports/_expected/iife.js +++ b/test/form/multiple-exports/_expected/iife.js @@ -7,4 +7,4 @@ exports.foo = foo; exports.bar = bar; -}((this.myBundle = {}))); +}((this.myBundle = this.myBundle || {}))); diff --git a/test/form/multiple-exports/_expected/umd.js b/test/form/multiple-exports/_expected/umd.js index 485e381..30a54d6 100644 --- a/test/form/multiple-exports/_expected/umd.js +++ b/test/form/multiple-exports/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.myBundle = {}))); + (factory((global.myBundle = global.myBundle || {}))); }(this, function (exports) { 'use strict'; var foo = 1; diff --git a/test/form/namespaced-named-exports/_expected/iife.js b/test/form/namespaced-named-exports/_expected/iife.js index 2fc75df..69637e9 100644 --- a/test/form/namespaced-named-exports/_expected/iife.js +++ b/test/form/namespaced-named-exports/_expected/iife.js @@ -7,4 +7,4 @@ this.foo.bar = this.foo.bar || {}; exports.answer = answer; -}((this.foo.bar.baz = {}))); +}((this.foo.bar.baz = this.foo.bar.baz || {}))); diff --git a/test/form/namespaced-named-exports/_expected/umd.js b/test/form/namespaced-named-exports/_expected/umd.js index aeb7775..9a0f47d 100644 --- a/test/form/namespaced-named-exports/_expected/umd.js +++ b/test/form/namespaced-named-exports/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.foo = global.foo || {}, global.foo.bar = global.foo.bar || {}, global.foo.bar.baz = {}))); + (factory((global.foo = global.foo || {}, global.foo.bar = global.foo.bar || {}, global.foo.bar.baz = global.foo.bar.baz || {}))); }(this, function (exports) { 'use strict'; var answer = 42; diff --git a/test/form/no-treeshake/_config.js b/test/form/no-treeshake/_config.js new file mode 100644 index 0000000..a997358 --- /dev/null +++ b/test/form/no-treeshake/_config.js @@ -0,0 +1,11 @@ +module.exports = { + description: 'all code should be included if tree-shaking is disabled', + options: { + external: [ 'external' ], + globals: { + external: 'external' + }, + moduleName: /* not shaken, but */ 'stirred', + treeshake: false + } +}; diff --git a/test/form/no-treeshake/_expected/amd.js b/test/form/no-treeshake/_expected/amd.js new file mode 100644 index 0000000..7bbe64b --- /dev/null +++ b/test/form/no-treeshake/_expected/amd.js @@ -0,0 +1,25 @@ +define(['exports', 'external'], function (exports, external) { 'use strict'; + + var foo = 'unused'; + + const quux = 1; + + const other = () => quux; + + function bar () { + return foo; + } + + function baz () { + return 13 + external.value; + } + + var create = Object.create; + var getPrototypeOf = Object.getPrototypeOf; + + exports.baz = baz; + exports.create = create; + exports.getPrototypeOf = getPrototypeOf; + exports.strange = quux; + +}); diff --git a/test/form/no-treeshake/_expected/cjs.js b/test/form/no-treeshake/_expected/cjs.js new file mode 100644 index 0000000..c188f06 --- /dev/null +++ b/test/form/no-treeshake/_expected/cjs.js @@ -0,0 +1,25 @@ +'use strict'; + +var external = require('external'); + +var foo = 'unused'; + +const quux = 1; + +const other = () => quux; + +function bar () { + return foo; +} + +function baz () { + return 13 + external.value; +} + +var create = Object.create; +var getPrototypeOf = Object.getPrototypeOf; + +exports.baz = baz; +exports.create = create; +exports.getPrototypeOf = getPrototypeOf; +exports.strange = quux; diff --git a/test/form/no-treeshake/_expected/es6.js b/test/form/no-treeshake/_expected/es6.js new file mode 100644 index 0000000..54f2add --- /dev/null +++ b/test/form/no-treeshake/_expected/es6.js @@ -0,0 +1,20 @@ +import * as external from 'external'; + +var foo = 'unused'; + +const quux = 1; + +const other = () => quux; + +function bar () { + return foo; +} + +function baz () { + return 13 + external.value; +} + +var create = Object.create; +var getPrototypeOf = Object.getPrototypeOf; + +export { baz, create, getPrototypeOf, quux as strange }; diff --git a/test/form/no-treeshake/_expected/iife.js b/test/form/no-treeshake/_expected/iife.js new file mode 100644 index 0000000..7c3ad8d --- /dev/null +++ b/test/form/no-treeshake/_expected/iife.js @@ -0,0 +1,26 @@ +(function (exports,external) { + 'use strict'; + + var foo = 'unused'; + + const quux = 1; + + const other = () => quux; + + function bar () { + return foo; + } + + function baz () { + return 13 + external.value; + } + + var create = Object.create; + var getPrototypeOf = Object.getPrototypeOf; + + exports.baz = baz; + exports.create = create; + exports.getPrototypeOf = getPrototypeOf; + exports.strange = quux; + +}((this.stirred = this.stirred || {}),external)); diff --git a/test/form/no-treeshake/_expected/umd.js b/test/form/no-treeshake/_expected/umd.js new file mode 100644 index 0000000..2136453 --- /dev/null +++ b/test/form/no-treeshake/_expected/umd.js @@ -0,0 +1,29 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('external')) : + typeof define === 'function' && define.amd ? define(['exports', 'external'], factory) : + (factory((global.stirred = global.stirred || {}),global.external)); +}(this, function (exports,external) { 'use strict'; + + var foo = 'unused'; + + const quux = 1; + + const other = () => quux; + + function bar () { + return foo; + } + + function baz () { + return 13 + external.value; + } + + var create = Object.create; + var getPrototypeOf = Object.getPrototypeOf; + + exports.baz = baz; + exports.create = create; + exports.getPrototypeOf = getPrototypeOf; + exports.strange = quux; + +})); diff --git a/test/form/no-treeshake/foo.js b/test/form/no-treeshake/foo.js new file mode 100644 index 0000000..e4c7f51 --- /dev/null +++ b/test/form/no-treeshake/foo.js @@ -0,0 +1 @@ +export default 'unused'; diff --git a/test/form/no-treeshake/main.js b/test/form/no-treeshake/main.js new file mode 100644 index 0000000..5a5f67e --- /dev/null +++ b/test/form/no-treeshake/main.js @@ -0,0 +1,13 @@ +import * as external from 'external'; +import foo from './foo.js' +export { quux as strange } from './quux.js'; + +function bar () { + return foo; +} + +export function baz () { + return 13 + external.value; +} + +export var create = Object.create, getPrototypeOf = Object.getPrototypeOf; diff --git a/test/form/no-treeshake/quux.js b/test/form/no-treeshake/quux.js new file mode 100644 index 0000000..ceb5f12 --- /dev/null +++ b/test/form/no-treeshake/quux.js @@ -0,0 +1,3 @@ +export const quux = 1; + +const other = () => quux; diff --git a/test/form/prefer-const/_config.js b/test/form/prefer-const/_config.js new file mode 100644 index 0000000..ebb4828 --- /dev/null +++ b/test/form/prefer-const/_config.js @@ -0,0 +1,7 @@ +module.exports = { + description: 'uses const instead of var if specified (#653)', + options: { + preferConst: true, + moduleName: 'myBundle' + } +}; diff --git a/test/form/prefer-const/_expected/amd.js b/test/form/prefer-const/_expected/amd.js new file mode 100644 index 0000000..a89dacd --- /dev/null +++ b/test/form/prefer-const/_expected/amd.js @@ -0,0 +1,18 @@ +define(['external', 'other', 'another'], function (external, other, another) { 'use strict'; + + const a = 1; + const b = 2; + + + const namespace = Object.freeze({ + a: a, + b: b + }); + + console.log( Object.keys( namespace ) ); + + const main = 42; + + return main; + +}); diff --git a/test/form/prefer-const/_expected/cjs.js b/test/form/prefer-const/_expected/cjs.js new file mode 100644 index 0000000..5c2e4da --- /dev/null +++ b/test/form/prefer-const/_expected/cjs.js @@ -0,0 +1,20 @@ +'use strict'; + +const external = require('external'); +const other = require('other'); +const another = require('another'); + +const a = 1; +const b = 2; + + +const namespace = Object.freeze({ + a: a, + b: b +}); + +console.log( Object.keys( namespace ) ); + +const main = 42; + +module.exports = main; diff --git a/test/form/prefer-const/_expected/es6.js b/test/form/prefer-const/_expected/es6.js new file mode 100644 index 0000000..8f5a5c9 --- /dev/null +++ b/test/form/prefer-const/_expected/es6.js @@ -0,0 +1,18 @@ +import 'external'; +import 'other'; +import 'another'; + +const a = 1; +const b = 2; + + +const namespace = Object.freeze({ + a: a, + b: b +}); + +console.log( Object.keys( namespace ) ); + +const main = 42; + +export default main; diff --git a/test/form/prefer-const/_expected/iife.js b/test/form/prefer-const/_expected/iife.js new file mode 100644 index 0000000..9c66729 --- /dev/null +++ b/test/form/prefer-const/_expected/iife.js @@ -0,0 +1,19 @@ +const myBundle = (function (external,other,another) { + 'use strict'; + + const a = 1; + const b = 2; + + + const namespace = Object.freeze({ + a: a, + b: b + }); + + console.log( Object.keys( namespace ) ); + + const main = 42; + + return main; + +}(external,other,another)); diff --git a/test/form/prefer-const/_expected/umd.js b/test/form/prefer-const/_expected/umd.js new file mode 100644 index 0000000..0c54878 --- /dev/null +++ b/test/form/prefer-const/_expected/umd.js @@ -0,0 +1,22 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('external'), require('other'), require('another')) : + typeof define === 'function' && define.amd ? define(['external', 'other', 'another'], factory) : + (global.myBundle = factory(global.external,global.other,global.another)); +}(this, function (external,other,another) { 'use strict'; + + const a = 1; + const b = 2; + + + const namespace = Object.freeze({ + a: a, + b: b + }); + + console.log( Object.keys( namespace ) ); + + const main = 42; + + return main; + +})); diff --git a/test/form/prefer-const/main.js b/test/form/prefer-const/main.js new file mode 100644 index 0000000..e8cc563 --- /dev/null +++ b/test/form/prefer-const/main.js @@ -0,0 +1,9 @@ +import external from 'external'; +import a from 'other'; +import { b } from 'other'; +import { another } from 'another'; +import * as namespace from './namespace.js'; + +console.log( Object.keys( namespace ) ); + +export default 42; diff --git a/test/form/prefer-const/namespace.js b/test/form/prefer-const/namespace.js new file mode 100644 index 0000000..72ab60e --- /dev/null +++ b/test/form/prefer-const/namespace.js @@ -0,0 +1,2 @@ +export const a = 1; +export const b = 2; diff --git a/test/form/preserve-debugger/_config.js b/test/form/preserve-debugger/_config.js new file mode 100644 index 0000000..3e65815 --- /dev/null +++ b/test/form/preserve-debugger/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'debugger statements are preserved (#664)' +}; diff --git a/test/form/preserve-debugger/_expected/amd.js b/test/form/preserve-debugger/_expected/amd.js new file mode 100644 index 0000000..be1ef13 --- /dev/null +++ b/test/form/preserve-debugger/_expected/amd.js @@ -0,0 +1,7 @@ +define(function () { 'use strict'; + + before(); + debugger; + after(); + +}); diff --git a/test/form/preserve-debugger/_expected/cjs.js b/test/form/preserve-debugger/_expected/cjs.js new file mode 100644 index 0000000..ae69f57 --- /dev/null +++ b/test/form/preserve-debugger/_expected/cjs.js @@ -0,0 +1,5 @@ +'use strict'; + +before(); +debugger; +after(); diff --git a/test/form/preserve-debugger/_expected/es6.js b/test/form/preserve-debugger/_expected/es6.js new file mode 100644 index 0000000..ce1bafd --- /dev/null +++ b/test/form/preserve-debugger/_expected/es6.js @@ -0,0 +1,3 @@ +before(); +debugger; +after(); diff --git a/test/form/preserve-debugger/_expected/iife.js b/test/form/preserve-debugger/_expected/iife.js new file mode 100644 index 0000000..b40a100 --- /dev/null +++ b/test/form/preserve-debugger/_expected/iife.js @@ -0,0 +1,8 @@ +(function () { + 'use strict'; + + before(); + debugger; + after(); + +}()); diff --git a/test/form/preserve-debugger/_expected/umd.js b/test/form/preserve-debugger/_expected/umd.js new file mode 100644 index 0000000..dd19c2d --- /dev/null +++ b/test/form/preserve-debugger/_expected/umd.js @@ -0,0 +1,11 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, function () { 'use strict'; + + before(); + debugger; + after(); + +})); diff --git a/test/form/preserve-debugger/main.js b/test/form/preserve-debugger/main.js new file mode 100644 index 0000000..ce1bafd --- /dev/null +++ b/test/form/preserve-debugger/main.js @@ -0,0 +1,3 @@ +before(); +debugger; +after(); diff --git a/test/form/preserves-comments-after-imports/_expected/iife.js b/test/form/preserves-comments-after-imports/_expected/iife.js index e9338dc..ee4c000 100644 --- a/test/form/preserves-comments-after-imports/_expected/iife.js +++ b/test/form/preserves-comments-after-imports/_expected/iife.js @@ -9,4 +9,4 @@ exports.obj = obj; -}((this.myBundle = {}))); +}((this.myBundle = this.myBundle || {}))); diff --git a/test/form/preserves-comments-after-imports/_expected/umd.js b/test/form/preserves-comments-after-imports/_expected/umd.js index ac58856..13a54bf 100644 --- a/test/form/preserves-comments-after-imports/_expected/umd.js +++ b/test/form/preserves-comments-after-imports/_expected/umd.js @@ -1,7 +1,7 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : - (factory((global.myBundle = {}))); + (factory((global.myBundle = global.myBundle || {}))); }(this, function (exports) { 'use strict'; /** A comment for a number */ diff --git a/test/form/umd-noconflict/_config.js b/test/form/umd-noconflict/_config.js new file mode 100644 index 0000000..9bbcec6 --- /dev/null +++ b/test/form/umd-noconflict/_config.js @@ -0,0 +1,10 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'exports noConflict method for default umd when requested', + options: { + noConflict: true, + moduleName: 'FooBar' + } +}; + diff --git a/test/form/umd-noconflict/_expected/amd.js b/test/form/umd-noconflict/_expected/amd.js new file mode 100644 index 0000000..16ca409 --- /dev/null +++ b/test/form/umd-noconflict/_expected/amd.js @@ -0,0 +1,15 @@ +define(['exports'], function (exports) { 'use strict'; + + function doThings() { + console.log( 'doing things...' ); + } + + const number = 42; + + var setting = 'no'; + + exports.doThings = doThings; + exports.number = number; + exports.setting = setting; + +}); \ No newline at end of file diff --git a/test/form/umd-noconflict/_expected/cjs.js b/test/form/umd-noconflict/_expected/cjs.js new file mode 100644 index 0000000..4379f50 --- /dev/null +++ b/test/form/umd-noconflict/_expected/cjs.js @@ -0,0 +1,13 @@ +'use strict'; + +function doThings() { + console.log( 'doing things...' ); +} + +const number = 42; + +var setting = 'no'; + +exports.doThings = doThings; +exports.number = number; +exports.setting = setting; \ No newline at end of file diff --git a/test/form/umd-noconflict/_expected/es6.js b/test/form/umd-noconflict/_expected/es6.js new file mode 100644 index 0000000..26bd5fb --- /dev/null +++ b/test/form/umd-noconflict/_expected/es6.js @@ -0,0 +1,9 @@ +function doThings() { + console.log( 'doing things...' ); +} + +const number = 42; + +var setting = 'no'; + +export { doThings, number, setting }; \ No newline at end of file diff --git a/test/form/umd-noconflict/_expected/iife.js b/test/form/umd-noconflict/_expected/iife.js new file mode 100644 index 0000000..5d76948 --- /dev/null +++ b/test/form/umd-noconflict/_expected/iife.js @@ -0,0 +1,16 @@ +(function (exports) { + 'use strict'; + + function doThings() { + console.log( 'doing things...' ); + } + + const number = 42; + + var setting = 'no'; + + exports.doThings = doThings; + exports.number = number; + exports.setting = setting; + +}((this.FooBar = this.FooBar || {}))); \ No newline at end of file diff --git a/test/form/umd-noconflict/_expected/umd.js b/test/form/umd-noconflict/_expected/umd.js new file mode 100644 index 0000000..5578ce9 --- /dev/null +++ b/test/form/umd-noconflict/_expected/umd.js @@ -0,0 +1,24 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (function() { + var current = global.FooBar; + var exports = factory((global.FooBar = global.FooBar || {})); + global.FooBar = exports; + exports.noConflict = function() { global.FooBar = current; return exports; }; + })(); +}(this, function (exports) { 'use strict'; + + function doThings() { + console.log( 'doing things...' ); + } + + const number = 42; + + var setting = 'no'; + + exports.doThings = doThings; + exports.number = number; + exports.setting = setting; + +})); diff --git a/test/form/umd-noconflict/main.js b/test/form/umd-noconflict/main.js new file mode 100644 index 0000000..136039a --- /dev/null +++ b/test/form/umd-noconflict/main.js @@ -0,0 +1,7 @@ +export function doThings() { + console.log( 'doing things...' ); +} + +export const number = 42; + +export var setting = 'no'; diff --git a/test/form/whitespace-around-namespace-member-expression/_config.js b/test/form/whitespace-around-namespace-member-expression/_config.js new file mode 100644 index 0000000..a97b168 --- /dev/null +++ b/test/form/whitespace-around-namespace-member-expression/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'whitespace around the "." in member expressions does not mess up renaming' +}; diff --git a/test/form/whitespace-around-namespace-member-expression/_expected/amd.js b/test/form/whitespace-around-namespace-member-expression/_expected/amd.js new file mode 100644 index 0000000..00fa37b --- /dev/null +++ b/test/form/whitespace-around-namespace-member-expression/_expected/amd.js @@ -0,0 +1,9 @@ +define(function () { 'use strict'; + + function yar() { + console.log('yar?'); + } + + yar(); + +}); \ No newline at end of file diff --git a/test/form/whitespace-around-namespace-member-expression/_expected/cjs.js b/test/form/whitespace-around-namespace-member-expression/_expected/cjs.js new file mode 100644 index 0000000..c47867c --- /dev/null +++ b/test/form/whitespace-around-namespace-member-expression/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +function yar() { + console.log('yar?'); +} + +yar(); \ No newline at end of file diff --git a/test/form/whitespace-around-namespace-member-expression/_expected/es6.js b/test/form/whitespace-around-namespace-member-expression/_expected/es6.js new file mode 100644 index 0000000..9ad6744 --- /dev/null +++ b/test/form/whitespace-around-namespace-member-expression/_expected/es6.js @@ -0,0 +1,5 @@ +function yar() { + console.log('yar?'); +} + +yar(); \ No newline at end of file diff --git a/test/form/whitespace-around-namespace-member-expression/_expected/iife.js b/test/form/whitespace-around-namespace-member-expression/_expected/iife.js new file mode 100644 index 0000000..5a0d920 --- /dev/null +++ b/test/form/whitespace-around-namespace-member-expression/_expected/iife.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + function yar() { + console.log('yar?'); + } + + yar(); + +}()); \ No newline at end of file diff --git a/test/form/whitespace-around-namespace-member-expression/_expected/umd.js b/test/form/whitespace-around-namespace-member-expression/_expected/umd.js new file mode 100644 index 0000000..ae6ce6f --- /dev/null +++ b/test/form/whitespace-around-namespace-member-expression/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, function () { 'use strict'; + + function yar() { + console.log('yar?'); + } + + yar(); + +})); \ No newline at end of file diff --git a/test/form/whitespace-around-namespace-member-expression/foo.js b/test/form/whitespace-around-namespace-member-expression/foo.js new file mode 100644 index 0000000..1479860 --- /dev/null +++ b/test/form/whitespace-around-namespace-member-expression/foo.js @@ -0,0 +1,3 @@ +export function yar() { + console.log('yar?'); +} diff --git a/test/form/whitespace-around-namespace-member-expression/main.js b/test/form/whitespace-around-namespace-member-expression/main.js new file mode 100644 index 0000000..eba0ddf --- /dev/null +++ b/test/form/whitespace-around-namespace-member-expression/main.js @@ -0,0 +1,2 @@ +import * as foo from './foo.js'; +foo .yar(); diff --git a/test/function/assignment-to-exports-b/_config.js b/test/function/assignment-to-exports-b/_config.js new file mode 100644 index 0000000..9abbeab --- /dev/null +++ b/test/function/assignment-to-exports-b/_config.js @@ -0,0 +1,8 @@ +const assert = require( 'assert' ); + +module.exports = { + description: 'exports are rewritten inside a variable init', + exports: exports => { + assert.equal( exports.b, 42 ); + } +}; diff --git a/test/function/assignment-to-exports-b/main.js b/test/function/assignment-to-exports-b/main.js new file mode 100644 index 0000000..d503419 --- /dev/null +++ b/test/function/assignment-to-exports-b/main.js @@ -0,0 +1,9 @@ +var a = { prop: 42 }; +var b = a.prop; + +function set ( new_a, new_b ) { + a = new_a; + b = new_b; +} + +export { a, b, set }; diff --git a/test/function/configure-relative-external-module/_config.js b/test/function/configure-relative-external-module/_config.js new file mode 100644 index 0000000..bbcebcf --- /dev/null +++ b/test/function/configure-relative-external-module/_config.js @@ -0,0 +1,21 @@ +var assert = require( 'assert' ); +var path = require( 'path' ); + +var mockedValue = { + val: 'A value' +}; + +module.exports = { + description: 'allows a nonexistent relative module to be configured as external', + options: { + external: [ path.join( __dirname, './nonexistent-relative-dependency.js') ] + }, + context: { + require: function() { + return mockedValue; + } + }, + exports: function () { + assert.equal( mockedValue.wasAltered, true ); + } +}; diff --git a/test/function/configure-relative-external-module/main.js b/test/function/configure-relative-external-module/main.js new file mode 100644 index 0000000..317fa9f --- /dev/null +++ b/test/function/configure-relative-external-module/main.js @@ -0,0 +1,3 @@ +import relativeDep from './nonexistent-relative-dependency.js'; + +relativeDep.wasAltered = true; diff --git a/test/function/confused-default-identifier/_config.js b/test/function/confused-default-identifier/_config.js index 75c2e8f..1b0bbf2 100644 --- a/test/function/confused-default-identifier/_config.js +++ b/test/function/confused-default-identifier/_config.js @@ -1,5 +1,8 @@ +var assert = require( 'assert' ); + module.exports = { - description: 'Rollup should not get confused and allow "default" as an identifier name' + description: 'Rollup should not get confused and allow "default" as an identifier name', + warnings: function () {} // suppress }; // https://github.com/rollup/rollup/issues/215 diff --git a/test/function/custom-path-resolver-async/_config.js b/test/function/custom-path-resolver-async/_config.js index 2d7539a..a0df42f 100644 --- a/test/function/custom-path-resolver-async/_config.js +++ b/test/function/custom-path-resolver-async/_config.js @@ -21,6 +21,11 @@ module.exports = { } }] }, + warnings: function ( warnings ) { + assert.deepEqual( warnings, [ + "Treating 'path' as external dependency" + ]); + }, exports: function ( exports ) { assert.strictEqual( exports.path, require( 'path' ) ); } diff --git a/test/function/custom-path-resolver-sync/_config.js b/test/function/custom-path-resolver-sync/_config.js index 4e0b5bf..b676f5d 100644 --- a/test/function/custom-path-resolver-sync/_config.js +++ b/test/function/custom-path-resolver-sync/_config.js @@ -13,6 +13,11 @@ module.exports = { } }] }, + warnings: function ( warnings ) { + assert.deepEqual( warnings, [ + "Treating 'path' as external dependency" + ]); + }, exports: function ( exports ) { assert.strictEqual( exports.path, require( 'path' ) ); } diff --git a/test/function/deshadowed-shorthand-property/_config.js b/test/function/deshadowed-shorthand-property/_config.js new file mode 100644 index 0000000..352f7f3 --- /dev/null +++ b/test/function/deshadowed-shorthand-property/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'shorthand properties referencing deshadowed variables are expanded' +}; diff --git a/test/function/deshadowed-shorthand-property/foo.js b/test/function/deshadowed-shorthand-property/foo.js new file mode 100644 index 0000000..c03d7e4 --- /dev/null +++ b/test/function/deshadowed-shorthand-property/foo.js @@ -0,0 +1,3 @@ +export default function answer () { + return 42; +} diff --git a/test/function/deshadowed-shorthand-property/main.js b/test/function/deshadowed-shorthand-property/main.js new file mode 100644 index 0000000..7942ca4 --- /dev/null +++ b/test/function/deshadowed-shorthand-property/main.js @@ -0,0 +1,8 @@ +import foo from './foo.js'; + +function x () { + var answer = foo(); + return { answer }; +} + +assert.equal( x().answer, 42 ); diff --git a/test/function/disappearing-exported-value/_config.js b/test/function/disappearing-exported-value/_config.js new file mode 100644 index 0000000..534c5ae --- /dev/null +++ b/test/function/disappearing-exported-value/_config.js @@ -0,0 +1,9 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'exported values do not mysteriously disappear (#484)', + exports: function ( exports ) { + assert.equal( exports.exportedAnswer, 42 ); + assert.equal( exports.foo(), 42 ); + } +}; diff --git a/test/function/disappearing-exported-value/answer.js b/test/function/disappearing-exported-value/answer.js new file mode 100644 index 0000000..1cdee13 --- /dev/null +++ b/test/function/disappearing-exported-value/answer.js @@ -0,0 +1,2 @@ +var answer = 42; +export { answer }; diff --git a/test/function/disappearing-exported-value/main.js b/test/function/disappearing-exported-value/main.js new file mode 100644 index 0000000..260980c --- /dev/null +++ b/test/function/disappearing-exported-value/main.js @@ -0,0 +1,8 @@ +import { answer as importedAnswer } from './answer.js'; +export { answer as exportedAnswer } from './answer.js'; + +export function foo () { + var value; + value = importedAnswer; + return value; +} diff --git a/test/function/double-default-export/_config.js b/test/function/double-default-export/_config.js new file mode 100644 index 0000000..26e86e7 --- /dev/null +++ b/test/function/double-default-export/_config.js @@ -0,0 +1,8 @@ +const assert = require( 'assert' ); + +module.exports = { + description: 'throws on double default exports', + error: err => { + assert.equal( err.message, 'A module can only have one default export' ); + } +}; diff --git a/test/function/double-default-export/foo.js b/test/function/double-default-export/foo.js new file mode 100644 index 0000000..13ef7e5 --- /dev/null +++ b/test/function/double-default-export/foo.js @@ -0,0 +1,2 @@ +export default 1; +export default 2; diff --git a/test/function/double-default-export/main.js b/test/function/double-default-export/main.js new file mode 100644 index 0000000..afac292 --- /dev/null +++ b/test/function/double-default-export/main.js @@ -0,0 +1,2 @@ +import foo from './foo.js'; +console.log( foo ); diff --git a/test/function/double-named-export/_config.js b/test/function/double-named-export/_config.js new file mode 100644 index 0000000..577b421 --- /dev/null +++ b/test/function/double-named-export/_config.js @@ -0,0 +1,8 @@ +const assert = require( 'assert' ); + +module.exports = { + description: 'throws on duplicate named exports', + error: err => { + assert.equal( err.message, `A module cannot have multiple exports with the same name ('foo')` ); + } +}; diff --git a/test/function/double-named-export/foo.js b/test/function/double-named-export/foo.js new file mode 100644 index 0000000..d0dbc69 --- /dev/null +++ b/test/function/double-named-export/foo.js @@ -0,0 +1,3 @@ +var foo = 1; +export { foo }; +export { foo }; diff --git a/test/function/double-named-export/main.js b/test/function/double-named-export/main.js new file mode 100644 index 0000000..1b3e409 --- /dev/null +++ b/test/function/double-named-export/main.js @@ -0,0 +1,2 @@ +import { foo } from './foo.js'; +console.log( foo ); diff --git a/test/function/double-named-reexport/_config.js b/test/function/double-named-reexport/_config.js new file mode 100644 index 0000000..577b421 --- /dev/null +++ b/test/function/double-named-reexport/_config.js @@ -0,0 +1,8 @@ +const assert = require( 'assert' ); + +module.exports = { + description: 'throws on duplicate named exports', + error: err => { + assert.equal( err.message, `A module cannot have multiple exports with the same name ('foo')` ); + } +}; diff --git a/test/function/double-named-reexport/bar.js b/test/function/double-named-reexport/bar.js new file mode 100644 index 0000000..2263b5a --- /dev/null +++ b/test/function/double-named-reexport/bar.js @@ -0,0 +1 @@ +export var foo = 2; diff --git a/test/function/double-named-reexport/foo.js b/test/function/double-named-reexport/foo.js new file mode 100644 index 0000000..434e3eb --- /dev/null +++ b/test/function/double-named-reexport/foo.js @@ -0,0 +1,3 @@ +var foo = 1; +export { foo }; +export { foo } from './bar.js'; diff --git a/test/function/double-named-reexport/main.js b/test/function/double-named-reexport/main.js new file mode 100644 index 0000000..1b3e409 --- /dev/null +++ b/test/function/double-named-reexport/main.js @@ -0,0 +1,2 @@ +import { foo } from './foo.js'; +console.log( foo ); diff --git a/test/function/empty-exports/_config.js b/test/function/empty-exports/_config.js new file mode 100644 index 0000000..65b2185 --- /dev/null +++ b/test/function/empty-exports/_config.js @@ -0,0 +1,17 @@ +var assert = require( 'assert' ); + +var warned = false; + +module.exports = { + description: 'warns on export {}, but does not fail', + options: { + onwarn: function ( msg ) { + warned = true; + assert.ok( /main\.js has an empty export declaration/.test( msg ) ); + } + }, + exports: function ( exports ) { + assert.equal( Object.keys( exports ).length, 0 ); + assert.ok( warned, 'did not warn' ); + } +}; diff --git a/test/function/empty-exports/main.js b/test/function/empty-exports/main.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/test/function/empty-exports/main.js @@ -0,0 +1 @@ +export {}; diff --git a/test/function/export-global/_config.js b/test/function/export-global/_config.js new file mode 100644 index 0000000..ab430c2 --- /dev/null +++ b/test/function/export-global/_config.js @@ -0,0 +1,9 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'any global variables in scope can be re-exported', + + exports: function ( exports ) { + assert.equal( exports.Buffer, Buffer ); + } +}; diff --git a/test/function/export-global/main.js b/test/function/export-global/main.js new file mode 100644 index 0000000..8e0da61 --- /dev/null +++ b/test/function/export-global/main.js @@ -0,0 +1 @@ +export { Buffer }; diff --git a/test/function/export-two-ways-function/_config.js b/test/function/export-two-ways-function/_config.js new file mode 100644 index 0000000..ec064dd --- /dev/null +++ b/test/function/export-two-ways-function/_config.js @@ -0,0 +1,9 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'exports the same function more than one way (#648)', + exports: function ( exports ) { + assert.equal( exports.foo, exports.bar ); + assert.equal( exports.foo(), 42 ); + } +}; diff --git a/test/function/export-two-ways-function/main.js b/test/function/export-two-ways-function/main.js new file mode 100644 index 0000000..7b14c6e --- /dev/null +++ b/test/function/export-two-ways-function/main.js @@ -0,0 +1,8 @@ +var bar; +bar = foo; + +function foo () { + return 42; +} + +export { foo, bar }; diff --git a/test/function/exports-flag-allowed-in-options/_config.js b/test/function/exports-flag-allowed-in-options/_config.js new file mode 100644 index 0000000..9fb6472 --- /dev/null +++ b/test/function/exports-flag-allowed-in-options/_config.js @@ -0,0 +1,12 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'exports flag is passed through to bundle options', + options: { + exports: 'named' + }, + exports: function ( exports ) { + assert.equal( exports.y, 42 ); + assert.ok( !( 'x' in exports ) ); + } +}; diff --git a/test/function/exports-flag-allowed-in-options/foo.js b/test/function/exports-flag-allowed-in-options/foo.js new file mode 100644 index 0000000..a48ffd9 --- /dev/null +++ b/test/function/exports-flag-allowed-in-options/foo.js @@ -0,0 +1 @@ +export var x = 42; diff --git a/test/function/exports-flag-allowed-in-options/main.js b/test/function/exports-flag-allowed-in-options/main.js new file mode 100644 index 0000000..04b166b --- /dev/null +++ b/test/function/exports-flag-allowed-in-options/main.js @@ -0,0 +1 @@ +export { x as y } from './foo'; diff --git a/test/function/external-alias/_config.js b/test/function/external-alias/_config.js new file mode 100644 index 0000000..3232f3b --- /dev/null +++ b/test/function/external-alias/_config.js @@ -0,0 +1,28 @@ +var assert = require( 'assert' ); +var path = require( 'path' ); + +module.exports = { + description: 'includes an external module included dynamically by an alias', + options: { + entry: path.join( __dirname, 'first', 'main.js' ), + external: [ 'lodash' ], + + // Define a simple alias plugin for underscore + plugins: [ + { + resolveId: function ( id ) { + if ( id === 'underscore' ) { + return 'lodash'; + } + } + } + ] + }, + + context: { + require: function ( required ) { + assert.equal( required, 'lodash' ); + return 1; + } + } +}; diff --git a/test/function/external-alias/first/main.js b/test/function/external-alias/first/main.js new file mode 100644 index 0000000..3503622 --- /dev/null +++ b/test/function/external-alias/first/main.js @@ -0,0 +1,10 @@ +import _ from 'underscore'; +import first from './module'; + +export default function ( inputs ) { + if ( !_.isArray( inputs ) ) { + return inputs; + } + + return first.square( inputs ); +}; diff --git a/test/function/external-alias/first/module.js b/test/function/external-alias/first/module.js new file mode 100644 index 0000000..4bacbea --- /dev/null +++ b/test/function/external-alias/first/module.js @@ -0,0 +1,7 @@ +import _ from 'underscore'; + +export default function square ( inputs ) { + return _.map( inputs, function ( x ) { + return x * x; + }); +}; diff --git a/test/function/external-function/_config.js b/test/function/external-function/_config.js new file mode 100644 index 0000000..ec2b8a6 --- /dev/null +++ b/test/function/external-function/_config.js @@ -0,0 +1,14 @@ +module.exports = { + description: 'allows external option to be a function (#522)', + options: { + external: id => { + return id === 'external'; + } + }, + context: { + require: id => { + if ( id === 'external' ) return 42; + return require( id ); + } + } +}; diff --git a/test/function/external-function/main.js b/test/function/external-function/main.js new file mode 100644 index 0000000..bfc7dca --- /dev/null +++ b/test/function/external-function/main.js @@ -0,0 +1,2 @@ +import ext from 'external'; +assert.equal( ext, 42 ); diff --git a/test/function/external-normalization/_config.js b/test/function/external-normalization/_config.js new file mode 100644 index 0000000..d0b4cfb --- /dev/null +++ b/test/function/external-normalization/_config.js @@ -0,0 +1,18 @@ +var path = require( 'path' ); +var assert = require( 'assert' ); + +module.exports = { + description: 'external paths from custom resolver remain external (#633)', + options: { + external: [ 'path' ], + plugins: [{ + resolveId: ( id ) => { + if ( id == './dep.js' ) return 'path'; + return id; + } + }] + }, + exports: exports => { + assert.equal( exports, path.resolve ); + } +}; diff --git a/test/function/external-normalization/main.js b/test/function/external-normalization/main.js new file mode 100644 index 0000000..d6b8c6c --- /dev/null +++ b/test/function/external-normalization/main.js @@ -0,0 +1,2 @@ +import { resolve } from './dep.js'; +export default resolve; diff --git a/test/function/load-returns-string-or-null/_config.js b/test/function/load-returns-string-or-null/_config.js new file mode 100644 index 0000000..ea80699 --- /dev/null +++ b/test/function/load-returns-string-or-null/_config.js @@ -0,0 +1,15 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'throws error if load returns something wacky', + options: { + plugins: [{ + load: function () { + return 42; + } + }] + }, + error: function ( err ) { + assert.ok( /load hook should return a string, a \{ code, map \} object, or nothing\/null/.test( err.message ) ); + } +}; diff --git a/test/function/member-expression-assignment-in-function/_config.js b/test/function/member-expression-assignment-in-function/_config.js new file mode 100644 index 0000000..bf7e6fc --- /dev/null +++ b/test/function/member-expression-assignment-in-function/_config.js @@ -0,0 +1,10 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'detect side effect in member expression assignment when not top level', + code: function ( code ) { + assert.equal( code.indexOf( 'function set(key, value) { foo[key] = value; }' ) >= 0, true, code ); + assert.equal( code.indexOf( 'set("bar", 2);' ) >= 0, true, code ); + assert.equal( code.indexOf( 'set("qux", 3);' ) >= 0, true, code ); + } +} diff --git a/test/function/member-expression-assignment-in-function/main.js b/test/function/member-expression-assignment-in-function/main.js new file mode 100644 index 0000000..f627721 --- /dev/null +++ b/test/function/member-expression-assignment-in-function/main.js @@ -0,0 +1,9 @@ +var foo = {}; + +function set(key, value) { foo[key] = value; } + +set("bar", 2); +set("qux", 3); + +console.log(foo); + diff --git a/test/function/object-destructuring-renaming/_config.js b/test/function/object-destructuring-renaming/_config.js new file mode 100644 index 0000000..4a1b8b6 --- /dev/null +++ b/test/function/object-destructuring-renaming/_config.js @@ -0,0 +1,12 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'renaming destructured object properties should request the correct property (#527)', + + // we must transpile the object destructuring to test it + babel: true, + + exports: function ( exports ) { + assert.equal( exports.env, process.env ); + } +}; diff --git a/test/function/object-destructuring-renaming/main.js b/test/function/object-destructuring-renaming/main.js new file mode 100644 index 0000000..cc67a81 --- /dev/null +++ b/test/function/object-destructuring-renaming/main.js @@ -0,0 +1,3 @@ +import { getEnv } from './module.js'; + +export var env = getEnv(); diff --git a/test/function/object-destructuring-renaming/module.js b/test/function/object-destructuring-renaming/module.js new file mode 100644 index 0000000..787b1b9 --- /dev/null +++ b/test/function/object-destructuring-renaming/module.js @@ -0,0 +1,5 @@ +const { env } = process; + +export function getEnv() { + return env; +} diff --git a/test/function/relative-external-include-once-nested/_config.js b/test/function/relative-external-include-once-nested/_config.js new file mode 100644 index 0000000..07aa08e --- /dev/null +++ b/test/function/relative-external-include-once-nested/_config.js @@ -0,0 +1,18 @@ +var assert = require( 'assert' ); +var path = require( 'path' ); + +module.exports = { + description: 'includes a relative external module only once (nested version)', + options: { + external: path.join( __dirname, './first/foo.js' ) + }, + context: { + require: function ( required ) { + assert.equal( required, './first/foo.js' ); + return 1; + } + }, + exports: function ( exports ) { + assert.equal( exports, 3 ); + } +}; diff --git a/test/function/relative-external-include-once-nested/first/foo.js b/test/function/relative-external-include-once-nested/first/foo.js new file mode 100644 index 0000000..e69de29 diff --git a/test/function/relative-external-include-once-nested/first/module.js b/test/function/relative-external-include-once-nested/first/module.js new file mode 100644 index 0000000..a0aecca --- /dev/null +++ b/test/function/relative-external-include-once-nested/first/module.js @@ -0,0 +1,4 @@ +import foo from './foo'; +import second from './second/module'; + +export default foo + second; diff --git a/test/function/relative-external-include-once-nested/first/second/module.js b/test/function/relative-external-include-once-nested/first/second/module.js new file mode 100644 index 0000000..4fa8fdc --- /dev/null +++ b/test/function/relative-external-include-once-nested/first/second/module.js @@ -0,0 +1,3 @@ +import foo from '../foo'; + +export default foo; diff --git a/test/function/relative-external-include-once-nested/main.js b/test/function/relative-external-include-once-nested/main.js new file mode 100644 index 0000000..545e333 --- /dev/null +++ b/test/function/relative-external-include-once-nested/main.js @@ -0,0 +1,4 @@ +import foo from './first/foo'; +import first from './first/module'; + +export default foo + first; diff --git a/test/function/relative-external-include-once-two-external/_config.js b/test/function/relative-external-include-once-two-external/_config.js new file mode 100644 index 0000000..d83e72f --- /dev/null +++ b/test/function/relative-external-include-once-two-external/_config.js @@ -0,0 +1,22 @@ +var assert = require( 'assert' ); +var path = require( 'path' ); + + +module.exports = { + description: 'includes a relative external module only once (two external deps)', + options: { + external: [ + path.join( __dirname, './foo.js' ), + path.join( __dirname, './first/foo.js' ) + ] + }, + context: { + require: function ( required ) { + assert( [ './foo.js', './first/foo.js' ].indexOf(required) !== -1, 'required wrong module' ); + return required === './foo.js' ? 'a' : 'b'; + } + }, + exports: function ( exports ) { + assert( exports === 'ab' || exports === 'ba', 'two different modules should be required' ); + } +}; diff --git a/test/function/relative-external-include-once-two-external/first/foo.js b/test/function/relative-external-include-once-two-external/first/foo.js new file mode 100644 index 0000000..e69de29 diff --git a/test/function/relative-external-include-once-two-external/first/module.js b/test/function/relative-external-include-once-two-external/first/module.js new file mode 100644 index 0000000..4ad6554 --- /dev/null +++ b/test/function/relative-external-include-once-two-external/first/module.js @@ -0,0 +1,3 @@ +import foo from './foo'; + +export default foo; diff --git a/test/function/relative-external-include-once-two-external/foo.js b/test/function/relative-external-include-once-two-external/foo.js new file mode 100644 index 0000000..e69de29 diff --git a/test/function/relative-external-include-once-two-external/main.js b/test/function/relative-external-include-once-two-external/main.js new file mode 100644 index 0000000..dff375c --- /dev/null +++ b/test/function/relative-external-include-once-two-external/main.js @@ -0,0 +1,4 @@ +import foo from './foo'; +import first from './first/module'; + +export default foo + first; diff --git a/test/function/relative-external-include-once-up/_config.js b/test/function/relative-external-include-once-up/_config.js new file mode 100644 index 0000000..15821ba --- /dev/null +++ b/test/function/relative-external-include-once-up/_config.js @@ -0,0 +1,19 @@ +var assert = require( 'assert' ); +var path = require( 'path' ); + +module.exports = { + description: 'includes a relative external module only once (from upper directory too)', + options: { + entry: path.join( __dirname, 'first', 'main.js' ), + external: path.join( __dirname, './foo.js' ) + }, + context: { + require: function ( required ) { + assert.equal( required, '../foo.js' ); + return 1; + } + }, + exports: function ( exports ) { + assert.equal( exports, 3 ); + } +}; diff --git a/test/function/relative-external-include-once-up/first/main.js b/test/function/relative-external-include-once-up/first/main.js new file mode 100644 index 0000000..a07e358 --- /dev/null +++ b/test/function/relative-external-include-once-up/first/main.js @@ -0,0 +1,4 @@ +import foo from '../foo'; +import first from './module'; + +export default foo + first; diff --git a/test/function/relative-external-include-once-up/first/module.js b/test/function/relative-external-include-once-up/first/module.js new file mode 100644 index 0000000..0798b47 --- /dev/null +++ b/test/function/relative-external-include-once-up/first/module.js @@ -0,0 +1,4 @@ +import foo from '../foo'; +import second from './second/module'; + +export default foo + second; diff --git a/test/function/relative-external-include-once-up/first/second/module.js b/test/function/relative-external-include-once-up/first/second/module.js new file mode 100644 index 0000000..b643f0c --- /dev/null +++ b/test/function/relative-external-include-once-up/first/second/module.js @@ -0,0 +1,3 @@ +import foo from '../../foo'; + +export default foo; diff --git a/test/function/relative-external-include-once-up/foo.js b/test/function/relative-external-include-once-up/foo.js new file mode 100644 index 0000000..e69de29 diff --git a/test/function/relative-external-include-once/_config.js b/test/function/relative-external-include-once/_config.js new file mode 100644 index 0000000..4349dc1 --- /dev/null +++ b/test/function/relative-external-include-once/_config.js @@ -0,0 +1,18 @@ +var assert = require( 'assert' ); +var path = require( 'path' ); + +module.exports = { + description: 'includes a relative external module only once', + options: { + external: path.join( __dirname, './foo.js' ) + }, + context: { + require: function ( required ) { + assert.equal( required, './foo.js' ); + return 1; + } + }, + exports: function ( exports ) { + assert.equal( exports, 3 ); + } +}; diff --git a/test/function/relative-external-include-once/first/module.js b/test/function/relative-external-include-once/first/module.js new file mode 100644 index 0000000..0798b47 --- /dev/null +++ b/test/function/relative-external-include-once/first/module.js @@ -0,0 +1,4 @@ +import foo from '../foo'; +import second from './second/module'; + +export default foo + second; diff --git a/test/function/relative-external-include-once/first/second/module.js b/test/function/relative-external-include-once/first/second/module.js new file mode 100644 index 0000000..b643f0c --- /dev/null +++ b/test/function/relative-external-include-once/first/second/module.js @@ -0,0 +1,3 @@ +import foo from '../../foo'; + +export default foo; diff --git a/test/function/relative-external-include-once/foo.js b/test/function/relative-external-include-once/foo.js new file mode 100644 index 0000000..e69de29 diff --git a/test/function/relative-external-include-once/main.js b/test/function/relative-external-include-once/main.js new file mode 100644 index 0000000..dff375c --- /dev/null +++ b/test/function/relative-external-include-once/main.js @@ -0,0 +1,4 @@ +import foo from './foo'; +import first from './first/module'; + +export default foo + first; diff --git a/test/function/report-transform-error-file/_config.js b/test/function/report-transform-error-file/_config.js new file mode 100644 index 0000000..c856974 --- /dev/null +++ b/test/function/report-transform-error-file/_config.js @@ -0,0 +1,17 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'reports which file caused a transform error', + options: { + plugins: [{ + transform: function ( code, id ) { + if ( /foo/.test( id ) ) { + throw new Error( 'nope' ); + } + } + }] + }, + error: function ( err ) { + assert.ok( ~err.message.indexOf( 'foo.js' ) ); + } +}; diff --git a/test/function/report-transform-error-file/foo.js b/test/function/report-transform-error-file/foo.js new file mode 100644 index 0000000..a2db33b --- /dev/null +++ b/test/function/report-transform-error-file/foo.js @@ -0,0 +1,3 @@ +export default function () { + console.log( 'foo' ); +} diff --git a/test/function/report-transform-error-file/main.js b/test/function/report-transform-error-file/main.js new file mode 100644 index 0000000..e1fb5c4 --- /dev/null +++ b/test/function/report-transform-error-file/main.js @@ -0,0 +1,3 @@ +import foo from './foo.js'; + +foo(); diff --git a/test/function/skips-dead-branches-f/_config.js b/test/function/skips-dead-branches-f/_config.js index 428bd69..e43c622 100644 --- a/test/function/skips-dead-branches-f/_config.js +++ b/test/function/skips-dead-branches-f/_config.js @@ -1,7 +1,7 @@ var assert = require( 'assert' ); module.exports = { - description: 'skips a dead branch (g)', + description: 'skips a dead branch (f)', code: function ( code ) { assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); } diff --git a/test/function/skips-dead-branches-g/_config.js b/test/function/skips-dead-branches-g/_config.js new file mode 100644 index 0000000..d1e507d --- /dev/null +++ b/test/function/skips-dead-branches-g/_config.js @@ -0,0 +1,9 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'skips a dead conditional expression branch (g)', + code: function ( code ) { + assert.ok( code.indexOf( 'var c = a;' ) >= 0, code ); + assert.ok( code.indexOf( 'var d = b;' ) >= 0, code ); + } +}; diff --git a/test/function/skips-dead-branches-g/main.js b/test/function/skips-dead-branches-g/main.js new file mode 100644 index 0000000..0c271f4 --- /dev/null +++ b/test/function/skips-dead-branches-g/main.js @@ -0,0 +1,6 @@ +var a = 0; +var b = 1; +var c = true ? a : b; +var d = false ? a : b; + +console.log( c + d ); diff --git a/test/function/trim-conditional-branches-in-exports/_config.js b/test/function/trim-conditional-branches-in-exports/_config.js new file mode 100644 index 0000000..c084f7e --- /dev/null +++ b/test/function/trim-conditional-branches-in-exports/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'trims conditional branches with a renamed default export' +}; diff --git a/test/function/trim-conditional-branches-in-exports/foo.js b/test/function/trim-conditional-branches-in-exports/foo.js new file mode 100644 index 0000000..82df459 --- /dev/null +++ b/test/function/trim-conditional-branches-in-exports/foo.js @@ -0,0 +1,2 @@ +var foo = 0; +export default Math.random() < 0.5 ? foo : foo; diff --git a/test/function/trim-conditional-branches-in-exports/main.js b/test/function/trim-conditional-branches-in-exports/main.js new file mode 100644 index 0000000..8e67e6f --- /dev/null +++ b/test/function/trim-conditional-branches-in-exports/main.js @@ -0,0 +1,2 @@ +import foo from './foo.js'; +console.log( true ? false ? foo : 0 : 1 ); diff --git a/test/function/warn-on-auto-named-default-exports/_config.js b/test/function/warn-on-auto-named-default-exports/_config.js new file mode 100644 index 0000000..f093781 --- /dev/null +++ b/test/function/warn-on-auto-named-default-exports/_config.js @@ -0,0 +1,10 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'warns if default and named exports are used in auto mode', + warnings: function ( warnings ) { + assert.deepEqual( warnings, [ + 'Using named and default exports together. Consumers of your bundle will have to use bundle[\'default\'] to access the default export, which may not be what you want. Use `exports: \'named\'` to disable this warning. See https://github.com/rollup/rollup/wiki/JavaScript-API#exports for more information' + ]); + } +}; diff --git a/test/function/warn-on-auto-named-default-exports/main.js b/test/function/warn-on-auto-named-default-exports/main.js new file mode 100644 index 0000000..74d988c --- /dev/null +++ b/test/function/warn-on-auto-named-default-exports/main.js @@ -0,0 +1,10 @@ +function foo () { + console.log( 'foo' ); +} + +function bar () { + console.log( 'bar' ); +} + +export default foo; +export { bar }; diff --git a/test/function/warn-on-eval/_config.js b/test/function/warn-on-eval/_config.js index 62a3ee4..169171c 100644 --- a/test/function/warn-on-eval/_config.js +++ b/test/function/warn-on-eval/_config.js @@ -8,7 +8,7 @@ module.exports = { options: { onwarn: function ( message ) { warned = true; - assert.ok( /Use of `eval` \(in .+?main\.js\) is discouraged, as it may cause issues with minification\. See https:\/\/github.com\/rollup\/rollup\/wiki\/Troubleshooting#avoiding-eval for more details/.test( message ) ); + assert.ok( /Use of `eval` \(in .+?main\.js\) is strongly discouraged, as it poses security risks and may cause issues with minification\. See https:\/\/github.com\/rollup\/rollup\/wiki\/Troubleshooting#avoiding-eval for more details/.test( message ) ); } }, exports: function () { diff --git a/test/sourcemaps/single-length-segments/_config.js b/test/sourcemaps/single-length-segments/_config.js new file mode 100644 index 0000000..76d47e0 --- /dev/null +++ b/test/sourcemaps/single-length-segments/_config.js @@ -0,0 +1,37 @@ +var fs = require( 'fs' ); +var path = require( 'path' ); +var assert = require( 'assert' ); +var getLocation = require( '../../utils/getLocation' ); +var SourceMapConsumer = require( 'source-map' ).SourceMapConsumer; + +var original = fs.readFileSync( path.resolve( __dirname, 'main.js' ), 'utf-8' ); + +module.exports = { + description: 'handles single-length sourcemap segments', + options: { + plugins: [ + { + transform: function () { + return { + code: fs.readFileSync( path.resolve( __dirname, 'output.js' ), 'utf-8' ), + map: fs.readFileSync( path.resolve( __dirname, 'output.js.map' ), 'utf-8' ) + }; + } + } + ], + moduleName: 'x' + }, + test: function ( code, map ) { + var smc = new SourceMapConsumer( map ); + + [ 'Foo', 'log' ].forEach( function ( token ) { + var generatedLoc = getLocation( code, code.indexOf( token ) ); + var originalLoc = smc.originalPositionFor( generatedLoc ); + var expectedLoc = getLocation( original, original.indexOf( token ) ); + + assert.ok( /main/.test( originalLoc.source ) ); + assert.equal( originalLoc.line, expectedLoc.line ); + assert.equal( originalLoc.column, expectedLoc.column ); + }); + } +}; diff --git a/test/sourcemaps/single-length-segments/main.js b/test/sourcemaps/single-length-segments/main.js new file mode 100644 index 0000000..49c57e7 --- /dev/null +++ b/test/sourcemaps/single-length-segments/main.js @@ -0,0 +1,7 @@ +class Foo { + bar () { + console.log( 42 ); + } +} + +export { Foo }; diff --git a/test/sourcemaps/single-length-segments/output.js b/test/sourcemaps/single-length-segments/output.js new file mode 100644 index 0000000..4121f3a --- /dev/null +++ b/test/sourcemaps/single-length-segments/output.js @@ -0,0 +1,15 @@ +var Foo = function () { + function Foo() { + babelHelpers.classCallCheck(this, Foo); + } + + babelHelpers.createClass(Foo, [{ + key: "bar", + value: function bar() { + console.log(42); + } + }]); + return Foo; +}(); + +export { Foo }; diff --git a/test/sourcemaps/single-length-segments/output.js.map b/test/sourcemaps/single-length-segments/output.js.map new file mode 100644 index 0000000..4f0165c --- /dev/null +++ b/test/sourcemaps/single-length-segments/output.js.map @@ -0,0 +1,8 @@ +{ + "version":3, + "sources":["index.js"], + "names":[], + "mappings":"IAAM,G;;;;;;;wBACE;AACN,WAAQ,GAAR,CAAa,EAAb;AACA;;;;;AAGF,SAAS,GAAT", + "file":"index.js", + "sourcesContent":["class Foo {\n\tbar () {\n\t\tconsole.log( 42 );\n\t}\n}\n\nexport { Foo };\n"] +} diff --git a/test/test.js b/test/test.js index bf6e5a2..22239fe 100644 --- a/test/test.js +++ b/test/test.js @@ -76,7 +76,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( function () { throw new Error( 'Missing expected error' ); }, function ( err ) { - assert.equal( 'Unexpected key \'plUgins\' found, expected one of: banner, dest, entry, external, footer, format, globals, indent, intro, moduleId, moduleName, onwarn, outro, plugins, sourceMap', err.message ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: banner, dest, entry, exports, external, footer, format, globals, indent, intro, moduleId, moduleName, noConflict, onwarn, outro, plugins, preferConst, sourceMap, treeshake, useStrict' ); }); }); }); @@ -133,9 +133,13 @@ describe( 'rollup', function () { var config = loadConfig( FUNCTION + '/' + dir + '/_config.js' ); ( config.skip ? it.skip : config.solo ? it.only : it )( dir, function () { - var options = extend( {}, config.options, { - entry: FUNCTION + '/' + dir + '/main.js' - }); + var warnings = []; + var captureWarning = msg => warnings.push( msg ); + + var options = extend( { + entry: FUNCTION + '/' + dir + '/main.js', + onwarn: captureWarning + }, config.options ); if ( config.solo ) console.group( dir ); @@ -149,6 +153,7 @@ describe( 'rollup', function () { // try to generate output try { + if(config.bundleOptions) { console.log(config.bundleOptions); } var result = bundle.generate( extend( {}, config.bundleOptions, { format: 'cjs' })); @@ -214,6 +219,12 @@ describe( 'rollup', function () { } } + if ( config.warnings ) { + config.warnings( warnings ); + } else if ( warnings.length ) { + throw new Error( `Got unexpected warnings:\n${warnings.join('\n')}` ); + } + if ( config.show || unintendedError ) { console.log( code + '\n\n\n' ); } @@ -342,7 +353,10 @@ describe( 'rollup', function () { PATH: path.resolve( __dirname, '../bin' ) + path.delimiter + process.env.PATH } }, function ( err, code, stderr ) { - if ( err ) return done( err ); + if ( err || config.error ) { + config.error( err ); + return done(); + } if ( stderr ) console.error( stderr );