From 40217fd2e1a487bc99268f6684fe7febb68a15fb Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sun, 5 Jun 2016 09:36:06 -0400 Subject: [PATCH] allow options.external to be a function. closes #522 --- src/Bundle.js | 14 ++++++++++---- test/function/external-function/_config.js | 14 ++++++++++++++ test/function/external-function/main.js | 2 ++ 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 test/function/external-function/_config.js create mode 100644 test/function/external-function/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 0b7902f..fb160c0 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -34,7 +34,7 @@ export default class Bundle { 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 ) ); @@ -62,7 +62,13 @@ 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 @@ -198,14 +204,14 @@ export default class Bundle { // This could be an external, relative dependency, based on the current module's parent dir. externalName = resolve( module.id, '..', source ); } - const forcedExternal = externalName && ~this.external.indexOf( externalName ); + 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. 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 );