diff --git a/src/Module.js b/src/Module.js index 0940ad2..3bbf32e 100644 --- a/src/Module.js +++ b/src/Module.js @@ -81,10 +81,9 @@ class SyntheticNamespaceDeclaration { // throw with an informative error message if the reference doesn't exist. if ( !original ) { - const err = new Error( `Export '${reference.name}' is not defined by '${this.module.id}'` ); - err.code = 'MISSING_EXPORT'; - err.file = this.module.id; - throw err; + this.module.bundle.onwarn( `Export '${reference.name}' is not defined by '${this.module.id}'` ); + reference.isUndefined = true; + return; } original.addReference( reference ); @@ -581,15 +580,20 @@ export default class Module { let toDeshadow = blank(); statement.references.forEach( reference => { + const { start, end } = reference; + + if ( reference.isUndefined ) { + magicString.overwrite( start, end, 'undefined', true ); + } + const declaration = reference.declaration; if ( declaration ) { - const { start, end } = reference; const name = declaration.render( es6 ); // the second part of this check is necessary because of // namespace optimisation – name of `foo.bar` could be `bar` - if ( reference.name === name && name.length === reference.end - reference.start ) return; + if ( reference.name === name && name.length === end - start ) return; reference.rewritten = true; @@ -690,17 +694,20 @@ export default class Module { return otherModule.namespace(); } - return otherModule.traceExport( importDeclaration.name, this ); + const declaration = otherModule.traceExport( importDeclaration.name ); + + if ( !declaration ) throw new Error( `Module ${otherModule.id} does not export ${importDeclaration.name} (imported by ${this.id})` ); + return declaration; } return null; } - traceExport ( name, importer ) { + traceExport ( name ) { // export { foo } from './other.js' const reexportDeclaration = this.reexports[ name ]; if ( reexportDeclaration ) { - return reexportDeclaration.module.traceExport( reexportDeclaration.localName, this ); + return reexportDeclaration.module.traceExport( reexportDeclaration.localName ); } const exportDeclaration = this.exports[ name ]; @@ -710,14 +717,9 @@ export default class Module { for ( let i = 0; i < this.exportAllModules.length; i += 1 ) { const module = this.exportAllModules[i]; - const declaration = module.traceExport( name, this ); + const declaration = module.traceExport( name ); if ( declaration ) return declaration; } - - let errorMessage = `Module ${this.id} does not export ${name}`; - if ( importer ) errorMessage += ` (imported by ${importer.id})`; - - throw new Error( errorMessage ); } } diff --git a/test/function/export-all-multiple/_config.js b/test/function/export-all-multiple/_config.js new file mode 100644 index 0000000..409610b --- /dev/null +++ b/test/function/export-all-multiple/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'allows multiple export * statements' +}; diff --git a/test/function/export-all-multiple/bar.js b/test/function/export-all-multiple/bar.js new file mode 100644 index 0000000..73e87ae --- /dev/null +++ b/test/function/export-all-multiple/bar.js @@ -0,0 +1 @@ +export var BAR = 2; diff --git a/test/function/export-all-multiple/foo.js b/test/function/export-all-multiple/foo.js new file mode 100644 index 0000000..23c5d5e --- /dev/null +++ b/test/function/export-all-multiple/foo.js @@ -0,0 +1 @@ +export var FOO = 1; diff --git a/test/function/export-all-multiple/main.js b/test/function/export-all-multiple/main.js new file mode 100644 index 0000000..364742d --- /dev/null +++ b/test/function/export-all-multiple/main.js @@ -0,0 +1,2 @@ +export * from './foo.js'; +export * from './bar.js'; diff --git a/test/function/namespace-missing-export/_config.js b/test/function/namespace-missing-export/_config.js index 963724b..69f1405 100644 --- a/test/function/namespace-missing-export/_config.js +++ b/test/function/namespace-missing-export/_config.js @@ -2,8 +2,9 @@ var assert = require( 'assert' ); var path = require( 'path' ); module.exports = { - error: function ( err ) { - assert.equal( path.normalize( err.file ), path.resolve( __dirname, 'empty.js' ) ); - assert.ok( /Export 'foo' is not defined by/.test( err.message ) ); + options: { + onwarn: function ( msg ) { + assert.ok( /Export 'foo' is not defined by/.test( msg ) ); + } } }; diff --git a/test/function/namespace-missing-export/empty.js b/test/function/namespace-missing-export/empty.js index e69de29..8d5a2a2 100644 --- a/test/function/namespace-missing-export/empty.js +++ b/test/function/namespace-missing-export/empty.js @@ -0,0 +1 @@ +// this space left intentionally blank diff --git a/test/function/namespace-missing-export/main.js b/test/function/namespace-missing-export/main.js index bfb885d..d403460 100644 --- a/test/function/namespace-missing-export/main.js +++ b/test/function/namespace-missing-export/main.js @@ -1,3 +1,3 @@ import * as mod from './empty.js'; -mod.foo(); +assert.equal( typeof mod.foo, 'undefined' );