From 599bf0d818e22ffce7fc5c1f5aac1ff1262375f5 Mon Sep 17 00:00:00 2001 From: Keith Cirkel Date: Thu, 27 Sep 2018 12:18:34 +0100 Subject: [PATCH] feat: add `mainFields` api. Deprecate `browser`, `jsnext`, `module`, `main` --- src/index.js | 50 +++++++++++++++++++--------- test/test.js | 93 +++++++++++++++++++++++++++------------------------- 2 files changed, 84 insertions(+), 59 deletions(-) diff --git a/src/index.js b/src/index.js index b3f5c4f..9f487f5 100644 --- a/src/index.js +++ b/src/index.js @@ -38,12 +38,29 @@ function cachedIsFile (file, cb) { isFileCache[file].then(contents => cb(null, contents), cb); } +function deprecatedMainField (options, option, mainFields, field = option) { + if (option in options) { + CONSOLE_WARN(`node-resolve: setting options.${option} is deprecated, please override options.mainFields instead`); + if (options[option] === false) { + return mainFields.filter(mainField => mainField === field); + } else if (options[option] === true && mainFields.indexOf(field) === -1) { + return [field].concat(mainFields); + } + } + return mainFields; +} + const resolveIdAsync = (file, opts) => new Promise((fulfil, reject) => resolveId(file, opts, (err, contents) => err ? reject(err) : fulfil(contents))); export default function nodeResolve ( options = {} ) { - const useModule = options.module !== false; - const useMain = options.main !== false; - const useJsnext = options.jsnext === true; + if ('mainFields' in options && ('module' in options || 'main' in options || 'jsnext' in options)) { + throw new Error(`node-resolve: do not use deprecated 'module', 'main', 'jsnext' options with 'mainFields'`); + } + let mainFields = options.mainFields || ['module', 'main']; + mainFields = deprecatedMainField(options, 'browser', mainFields); + mainFields = deprecatedMainField(options, 'jsnext', mainFields, 'jsnext:main'); + mainFields = deprecatedMainField(options, 'module', mainFields); + mainFields = deprecatedMainField(options, 'main', mainFields); const isPreferBuiltinsSet = options.preferBuiltins === true || options.preferBuiltins === false; const preferBuiltins = isPreferBuiltinsSet ? options.preferBuiltins : true; const customResolveOptions = options.customResolveOptions || {}; @@ -62,8 +79,8 @@ export default function nodeResolve ( options = {} ) { throw new Error( 'options.skip is no longer supported — you should use the main Rollup `external` option instead' ); } - if ( !useModule && !useMain && !useJsnext ) { - throw new Error( `At least one of options.module, options.main or options.jsnext must be true` ); + if ( !mainFields.length ) { + throw new Error( `Please ensure at least one 'mainFields' value is specified` ); } let preserveSymlinks; @@ -86,7 +103,7 @@ export default function nodeResolve ( options = {} ) { // disregard entry module if ( !importer ) return null; - if (options.browser && browserMapCache[importer]) { + if (mainFields.indexOf('browser') !== -1 && browserMapCache[importer]) { const resolvedImportee = resolve( dirname( importer ), importee ); const browser = browserMapCache[importer]; if (browser[importee] === false || browser[resolvedImportee] === false) { @@ -119,7 +136,7 @@ export default function nodeResolve ( options = {} ) { basedir: dirname( importer ), packageFilter ( pkg, pkgPath ) { const pkgRoot = dirname( pkgPath ); - if (options.browser && typeof pkg[ 'browser' ] === 'object') { + if (mainFields.indexOf('browser') !== -1 && typeof pkg[ 'browser' ] === 'object') { packageBrowserField = Object.keys(pkg[ 'browser' ]).reduce((browser, key) => { const resolved = pkg[ 'browser' ][ key ] === false ? false : resolve( pkgRoot, pkg[ 'browser' ][ key ] ); browser[ key ] = resolved; @@ -137,13 +154,16 @@ export default function nodeResolve ( options = {} ) { }, {}); } - if (options.browser && typeof pkg[ 'browser' ] === 'string') { - pkg[ 'main' ] = pkg[ 'browser' ]; - } else if ( useModule && pkg[ 'module' ] ) { - pkg[ 'main' ] = pkg[ 'module' ]; - } else if ( useJsnext && pkg[ 'jsnext:main' ] ) { - pkg[ 'main' ] = pkg[ 'jsnext:main' ]; - } else if ( ( useJsnext || useModule ) && !useMain ) { + let overriddenMain = false; + for ( const i in mainFields ) { + const field = mainFields[i]; + if ( typeof pkg[ field ] === 'string' ) { + pkg[ 'main' ] = pkg[ field ]; + overriddenMain = true; + break; + } + } + if ( overriddenMain === false && mainFields.indexOf( 'main' ) === -1 ) { disregardResult = true; } return pkg; @@ -163,7 +183,7 @@ export default function nodeResolve ( options = {} ) { ) .catch(() => false) .then(resolved => { - if (options.browser && packageBrowserField) { + if (mainFields.indexOf('browser') !== -1 && packageBrowserField) { if (packageBrowserField[ resolved ]) { resolved = packageBrowserField[ resolved ]; } diff --git a/test/test.js b/test/test.js index 47d44b8..e695e07 100644 --- a/test/test.js +++ b/test/test.js @@ -23,6 +23,17 @@ function executeBundle ( bundle ) { describe( 'rollup-plugin-node-resolve', function () { it( 'finds a module with jsnext:main', function () { + return rollup.rollup({ + input: 'samples/jsnext/main.js', + plugins: [ + nodeResolve({ mainFields: ['jsnext:main', 'module', 'main'] }) + ] + }).then( executeBundle ).then( module => { + assert.equal( module.exports, '2H' ); + }); + }); + + it( 'DEPRECATED: options.jsnext still works', function () { return rollup.rollup({ input: 'samples/jsnext/main.js', plugins: [ @@ -37,7 +48,7 @@ describe( 'rollup-plugin-node-resolve', function () { return rollup.rollup({ input: 'samples/commonjs/main.js', plugins: [ - nodeResolve({ main: true }), + nodeResolve({ mainFields: ['main'] }), commonjs() ] }).then( executeBundle ).then( module => { @@ -49,7 +60,7 @@ describe( 'rollup-plugin-node-resolve', function () { return rollup.rollup({ input: 'samples/trailing-slash/main.js', plugins: [ - nodeResolve({ main: true }), + nodeResolve({ mainFields: ['main'] }), commonjs() ] }).then( executeBundle ).then( module => { @@ -99,10 +110,7 @@ describe( 'rollup-plugin-node-resolve', function () { return rollup.rollup({ input: 'samples/browser/main.js', plugins: [ - nodeResolve({ - main: true, - browser: false - }) + nodeResolve() ] }).then( executeBundle ).then( module => { assert.equal( module.exports, 'node' ); @@ -114,8 +122,7 @@ describe( 'rollup-plugin-node-resolve', function () { input: 'samples/browser/main.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -127,10 +134,7 @@ describe( 'rollup-plugin-node-resolve', function () { return rollup.rollup({ input: 'samples/browser-object/main.js', plugins: [ - nodeResolve({ - main: true, - browser: false - }) + nodeResolve() ] }).then( executeBundle ).then( module => { assert.equal( module.exports.env, 'node' ); @@ -144,8 +148,7 @@ describe( 'rollup-plugin-node-resolve', function () { input: 'samples/browser-object/main.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -160,7 +163,21 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object-main/main.js', plugins: [ nodeResolve({ - main: true, + mainFields: [ 'browser', 'main' ] + }) + ] + }).then( executeBundle ).then( module => { + assert.equal( module.exports.env, 'browser' ); + assert.equal( module.exports.dep, 'browser-dep' ); + assert.equal( module.exports.test, 43 ); + }); + }); + + it( 'DEPRECATED: options.browser = true still works', function () { + return rollup.rollup({ + entry: 'samples/browser-object-main/main.js', + plugins: [ + nodeResolve({ browser: true }) ] @@ -176,8 +193,7 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object/main-implicit.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -190,8 +206,7 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object-builtin/main.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -204,8 +219,7 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object-nested/main.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -220,8 +234,7 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object-main/main.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -236,8 +249,7 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object/main-implicit.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -250,8 +262,7 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object-builtin/main.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -264,8 +275,7 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object-nested/main.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -280,8 +290,7 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object-main/main.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -296,8 +305,7 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object/main-implicit.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -310,8 +318,7 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object-builtin/main.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -324,8 +331,7 @@ describe( 'rollup-plugin-node-resolve', function () { entry: 'samples/browser-object-nested/main.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ).then( module => { @@ -340,8 +346,7 @@ describe( 'rollup-plugin-node-resolve', function () { input: 'samples/browser-false/main.js', plugins: [ nodeResolve({ - main: true, - browser: true + mainFields: [ 'browser', 'main' ] }) ] }).then( executeBundle ); @@ -425,11 +430,11 @@ describe( 'rollup-plugin-node-resolve', function () { }); }); - it( 'prefers module field over jsnext:main and main', () => { + it( 'respects order if given module,jsnext:main,main', () => { return rollup.rollup({ input: 'samples/prefer-module/main.js', plugins: [ - nodeResolve({ jsnext: true, preferBuiltins: false }) + nodeResolve({ mainFields: [ 'module', 'jsnext:main', 'main' ], preferBuiltins: false }) ] }).then( executeBundle ).then( module => { assert.equal( module.exports, 'MODULE-ENTRY' ); @@ -516,11 +521,11 @@ describe( 'rollup-plugin-node-resolve', function () { }); }); - it( 'prefers jsnext:main field over main', () => { + it( 'respects order if given jsnext:main, main', () => { return rollup.rollup({ input: 'samples/prefer-jsnext/main.js', plugins: [ - nodeResolve({ jsnext: true, module: false, preferBuiltins: false }) + nodeResolve({ mainFields: ['jsnext:main', 'main'], preferBuiltins: false }) ] }).then( executeBundle ).then( module => { assert.equal( module.exports, 'JSNEXT-ENTRY' ); @@ -531,7 +536,7 @@ describe( 'rollup-plugin-node-resolve', function () { return rollup.rollup({ input: './samples/jsnext/main.js', plugins: [ - nodeResolve({ jsnext: true }) + nodeResolve({}) ] }).then( executeBundle ).then( module => { assert.equal( module.exports, '2H' );