diff --git a/src/index.js b/src/index.js index d9778e9..7947c2b 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import fs from 'fs'; const ES6_BROWSER_EMPTY = resolve( __dirname, '../src/empty.js' ); const CONSOLE_WARN = ( ...args ) => console.warn( ...args ); // eslint-disable-line no-console +const exts = [ '.js', '.json', '.node' ]; export default function nodeResolve ( options = {} ) { const useModule = options.module !== false; @@ -37,13 +38,14 @@ export default function nodeResolve ( options = {} ) { if ( !importer ) return null; if (options.browser && browserMapCache[importer]) { + const resolvedImportee = resolve( dirname( importer ), importee ); const browser = browserMapCache[importer]; - if (browser[importee]) { - importee = browser[importee]; - } - if (browser[importee] === false) { + if (browser[importee] === false || browser[resolvedImportee] === false) { return ES6_BROWSER_EMPTY; } + if (browser[importee] || browser[resolvedImportee] || browser[resolvedImportee + '.js'] || browser[resolvedImportee + '.json']) { + importee = browser[importee] || browser[resolvedImportee] || browser[resolvedImportee + '.js'] || browser[resolvedImportee + '.json']; + } } @@ -66,19 +68,28 @@ export default function nodeResolve ( options = {} ) { importee, Object.assign({ basedir: dirname( importer ), - packageFilter ( pkg ) { + packageFilter ( pkg, pkgPath ) { + const pkgRoot = dirname( pkgPath ); if (options.browser && typeof pkg[ 'browser' ] === 'object') { packageBrowserField = Object.keys(pkg[ 'browser' ]).reduce((browser, key) => { - browser[ key ] = pkg[ 'browser' ][key]; - if (key[0] === '.' && !extname(key)) browser[ key + '.js'] = browser[ key + '.json' ] = browser[ key ]; + const resolved = pkg[ 'browser' ][ key ] === false ? false : resolve( pkgRoot, pkg[ 'browser' ][ key ] ); + browser[ key ] = resolved; + if ( key[0] === '.' ) { + const absoluteKey = resolve( pkgRoot, key ); + browser[ absoluteKey ] = resolved; + if ( !extname(key) ) { + exts.reduce( ( browser, ext ) => { + browser[ absoluteKey + ext ] = browser[ key ]; + return browser; + }, browser ); + } + } return browser; }, {}); } if (options.browser && typeof pkg[ 'browser' ] === 'string') { pkg[ 'main' ] = pkg[ 'browser' ]; - } else if (options.browser && typeof pkg[ 'browser' ] === 'object' && pkg[ 'browser' ][ pkg[ 'main' ] ]) { - pkg[ 'main' ] = pkg[ 'browser' ][ pkg[ 'main' ] ]; } else if ( useModule && pkg[ 'module' ] ) { pkg[ 'main' ] = pkg[ 'module' ]; } else if ( useJsnext && pkg[ 'jsnext:main' ] ) { @@ -91,7 +102,12 @@ export default function nodeResolve ( options = {} ) { extensions: options.extensions }, customResolveOptions ), ( err, resolved ) => { - if (options.browser && packageBrowserField) browserMapCache[resolved] = packageBrowserField; + if (options.browser && packageBrowserField) { + if (packageBrowserField[ resolved ]) { + resolved = packageBrowserField[ resolved ]; + } + browserMapCache[resolved] = packageBrowserField; + } if ( !disregardResult && !err ) { if ( resolved && fs.existsSync( resolved ) ) { diff --git a/test/node_modules/builtins-browser/fs.js b/test/node_modules/builtins-browser/fs.js new file mode 100644 index 0000000..ff4756e --- /dev/null +++ b/test/node_modules/builtins-browser/fs.js @@ -0,0 +1 @@ +export default 'browser-fs'; diff --git a/test/node_modules/builtins-browser/index.js b/test/node_modules/builtins-browser/index.js new file mode 100644 index 0000000..f0a6c3c --- /dev/null +++ b/test/node_modules/builtins-browser/index.js @@ -0,0 +1,2 @@ +import fs from 'fs'; +export default fs; diff --git a/test/node_modules/builtins-browser/package.json b/test/node_modules/builtins-browser/package.json new file mode 100644 index 0000000..5486738 --- /dev/null +++ b/test/node_modules/builtins-browser/package.json @@ -0,0 +1,6 @@ +{ + "main": "./index.js", + "browser": { + "fs": "./fs.js" + } +} diff --git a/test/node_modules/isomorphic-nested/lib/browser-dep.js b/test/node_modules/isomorphic-nested/lib/browser-dep.js new file mode 100644 index 0000000..35ba3db --- /dev/null +++ b/test/node_modules/isomorphic-nested/lib/browser-dep.js @@ -0,0 +1 @@ +export default 'browser-dep'; diff --git a/test/node_modules/isomorphic-nested/lib/browser-test.js b/test/node_modules/isomorphic-nested/lib/browser-test.js new file mode 100644 index 0000000..8efc729 --- /dev/null +++ b/test/node_modules/isomorphic-nested/lib/browser-test.js @@ -0,0 +1 @@ +export default 43; diff --git a/test/node_modules/isomorphic-nested/lib/browser.js b/test/node_modules/isomorphic-nested/lib/browser.js new file mode 100644 index 0000000..7b14d9a --- /dev/null +++ b/test/node_modules/isomorphic-nested/lib/browser.js @@ -0,0 +1,5 @@ +import dep from './dep.js'; +import test from './test'; + +var env = 'browser'; +export { env, dep, test }; diff --git a/test/node_modules/isomorphic-nested/lib/dep.js b/test/node_modules/isomorphic-nested/lib/dep.js new file mode 100644 index 0000000..2089e19 --- /dev/null +++ b/test/node_modules/isomorphic-nested/lib/dep.js @@ -0,0 +1 @@ +export default 'node-dep'; diff --git a/test/node_modules/isomorphic-nested/lib/index.js b/test/node_modules/isomorphic-nested/lib/index.js new file mode 100644 index 0000000..12299ac --- /dev/null +++ b/test/node_modules/isomorphic-nested/lib/index.js @@ -0,0 +1,5 @@ +import dep from './dep.js'; +import test from 'test'; + +var env = 'node'; +export { env, dep, test }; diff --git a/test/node_modules/isomorphic-nested/package.json b/test/node_modules/isomorphic-nested/package.json new file mode 100644 index 0000000..976f6d3 --- /dev/null +++ b/test/node_modules/isomorphic-nested/package.json @@ -0,0 +1,8 @@ +{ + "main": "./lib/index.js", + "browser": { + "./lib/index.js": "./lib/browser.js", + "./lib/dep.js": "./lib/browser-dep.js", + "./lib/test": "./lib/browser-test.js" + } +} diff --git a/test/node_modules/isomorphic-object-main-implicit/browser.js b/test/node_modules/isomorphic-object-main-implicit/browser.js new file mode 100644 index 0000000..866654a --- /dev/null +++ b/test/node_modules/isomorphic-object-main-implicit/browser.js @@ -0,0 +1,2 @@ +var env = 'browser'; +export { env }; diff --git a/test/node_modules/isomorphic-object-main-implicit/index.js b/test/node_modules/isomorphic-object-main-implicit/index.js new file mode 100644 index 0000000..6a845dc --- /dev/null +++ b/test/node_modules/isomorphic-object-main-implicit/index.js @@ -0,0 +1,2 @@ +var env = 'node'; +export { env }; diff --git a/test/node_modules/isomorphic-object-main-implicit/package.json b/test/node_modules/isomorphic-object-main-implicit/package.json new file mode 100644 index 0000000..dadb70d --- /dev/null +++ b/test/node_modules/isomorphic-object-main-implicit/package.json @@ -0,0 +1,5 @@ +{ + "browser": { + "./index.js": "./browser.js" + } +} diff --git a/test/node_modules/isomorphic-object-main/browser-dep.js b/test/node_modules/isomorphic-object-main/browser-dep.js new file mode 100644 index 0000000..35ba3db --- /dev/null +++ b/test/node_modules/isomorphic-object-main/browser-dep.js @@ -0,0 +1 @@ +export default 'browser-dep'; diff --git a/test/node_modules/isomorphic-object-main/browser-test.js b/test/node_modules/isomorphic-object-main/browser-test.js new file mode 100644 index 0000000..8efc729 --- /dev/null +++ b/test/node_modules/isomorphic-object-main/browser-test.js @@ -0,0 +1 @@ +export default 43; diff --git a/test/node_modules/isomorphic-object-main/browser.js b/test/node_modules/isomorphic-object-main/browser.js new file mode 100644 index 0000000..136fdc4 --- /dev/null +++ b/test/node_modules/isomorphic-object-main/browser.js @@ -0,0 +1,5 @@ +import dep from './dep.js'; +import test from 'test'; + +var env = 'browser'; +export { env, dep, test }; diff --git a/test/node_modules/isomorphic-object-main/dep.js b/test/node_modules/isomorphic-object-main/dep.js new file mode 100644 index 0000000..2089e19 --- /dev/null +++ b/test/node_modules/isomorphic-object-main/dep.js @@ -0,0 +1 @@ +export default 'node-dep'; diff --git a/test/node_modules/isomorphic-object-main/index.js b/test/node_modules/isomorphic-object-main/index.js new file mode 100644 index 0000000..12299ac --- /dev/null +++ b/test/node_modules/isomorphic-object-main/index.js @@ -0,0 +1,5 @@ +import dep from './dep.js'; +import test from 'test'; + +var env = 'node'; +export { env, dep, test }; diff --git a/test/node_modules/isomorphic-object-main/package.json b/test/node_modules/isomorphic-object-main/package.json new file mode 100644 index 0000000..39bbc8b --- /dev/null +++ b/test/node_modules/isomorphic-object-main/package.json @@ -0,0 +1,8 @@ +{ + "main": "index.js", + "browser": { + "./index.js": "./browser.js", + "./dep.js": "./browser-dep.js", + "test": "./browser-test.js" + } +} diff --git a/test/samples/browser-object-builtin/main.js b/test/samples/browser-object-builtin/main.js new file mode 100644 index 0000000..6b1126e --- /dev/null +++ b/test/samples/browser-object-builtin/main.js @@ -0,0 +1,2 @@ +import main from 'builtins-browser'; +export default main; diff --git a/test/samples/browser-object-main/main.js b/test/samples/browser-object-main/main.js new file mode 100644 index 0000000..eac1b42 --- /dev/null +++ b/test/samples/browser-object-main/main.js @@ -0,0 +1,2 @@ +import { env, dep, test } from 'isomorphic-object-main'; +export { env, dep, test }; diff --git a/test/samples/browser-object-nested/main.js b/test/samples/browser-object-nested/main.js new file mode 100644 index 0000000..4ffdd23 --- /dev/null +++ b/test/samples/browser-object-nested/main.js @@ -0,0 +1,2 @@ +import { env, dep, test } from 'isomorphic-nested'; +export { env, dep, test }; diff --git a/test/samples/browser-object/main-implicit.js b/test/samples/browser-object/main-implicit.js new file mode 100644 index 0000000..01d728f --- /dev/null +++ b/test/samples/browser-object/main-implicit.js @@ -0,0 +1,2 @@ +import { env } from 'isomorphic-object-main-implicit'; +export { env }; diff --git a/test/test.js b/test/test.js index 614a687..ae5b3c8 100644 --- a/test/test.js +++ b/test/test.js @@ -155,6 +155,66 @@ describe( 'rollup-plugin-node-resolve', function () { }); }); + it( 'allows use of object browser field, resolving `main`', function () { + return rollup.rollup({ + entry: 'samples/browser-object-main/main.js', + plugins: [ + nodeResolve({ + main: true, + browser: true + }) + ] + }).then( executeBundle ).then( module => { + assert.equal( module.exports.env, 'browser' ); + assert.equal( module.exports.dep, 'browser-dep' ); + assert.equal( module.exports.test, 43 ); + }); + }); + + it( 'allows use of object browser field, resolving implicit `main`', function () { + return rollup.rollup({ + entry: 'samples/browser-object/main-implicit.js', + plugins: [ + nodeResolve({ + main: true, + browser: true + }) + ] + }).then( executeBundle ).then( module => { + assert.equal( module.exports.env, 'browser' ); + }); + }); + + it( 'allows use of object browser field, resolving replaced builtins', function () { + return rollup.rollup({ + entry: 'samples/browser-object-builtin/main.js', + plugins: [ + nodeResolve({ + main: true, + browser: true + }) + ] + }).then( executeBundle ).then( module => { + assert.equal( module.exports, 'browser-fs' ); + }); + }); + + it( 'allows use of object browser field, resolving nested directories', function () { + return rollup.rollup({ + entry: 'samples/browser-object-nested/main.js', + plugins: [ + nodeResolve({ + main: true, + browser: true + }) + ] + }).then( executeBundle ).then( module => { + assert.equal( module.exports.env, 'browser' ); + assert.equal( module.exports.dep, 'browser-dep' ); + assert.equal( module.exports.test, 43 ); + }); + }); + it( 'supports `false` in browser field', function () { return rollup.rollup({ entry: 'samples/browser-false/main.js',