diff --git a/src/Resolver.js b/src/Resolver.js index 04079b45ad1..dc17e77447c 100644 --- a/src/Resolver.js +++ b/src/Resolver.js @@ -47,10 +47,11 @@ class Resolver { // Expose the path to the package.json file pkg.pkgfile = pkgfile; - // npm libraries can specify alternative main fields in their package.json, - // we resolve the "module" and "jsnext:main" in priority of "browser" to get the full dependency tree. // libraries like d3.js specifies node.js specific files in the "main" which breaks the build - const main = pkg.module || pkg['jsnext:main'] || pkg.browser; + // we use the "module" or "jsnext:main" field to get the full dependency tree if available + const main = [pkg.module, pkg['jsnext:main']].find( + entry => typeof entry === 'string' + ); if (main) { pkg.main = main; diff --git a/test/integration/resolve-entries/both-fields.js b/test/integration/resolve-entries/both-fields.js new file mode 100644 index 00000000000..6740099f164 --- /dev/null +++ b/test/integration/resolve-entries/both-fields.js @@ -0,0 +1,7 @@ +const required = require('./pkg-both') + +if(required.test() !== 'pkg-es6-module') { + throw new Error('Invalid module') +} + +export const test = required.test diff --git a/test/integration/resolve-entries/browser-multiple.js b/test/integration/resolve-entries/browser-multiple.js new file mode 100644 index 00000000000..92950ec4248 --- /dev/null +++ b/test/integration/resolve-entries/browser-multiple.js @@ -0,0 +1,7 @@ +const required = require('./pkg-browser-multiple/projected') + +if(required.test() !== 'pkg-browser-multiple') { + throw new Error('Invalid module') +} + +export const test = required.test diff --git a/test/integration/resolve-entries/browser.js b/test/integration/resolve-entries/browser.js new file mode 100644 index 00000000000..2bce4d5ab85 --- /dev/null +++ b/test/integration/resolve-entries/browser.js @@ -0,0 +1,7 @@ +const required = require('./pkg-browser') + +if(required.test() !== 'pkg-browser') { + throw new Error('Invalid module') +} + +export const test = required.test diff --git a/test/integration/resolve-entries/jsnext-field.js b/test/integration/resolve-entries/jsnext-field.js new file mode 100644 index 00000000000..6af1dd937ca --- /dev/null +++ b/test/integration/resolve-entries/jsnext-field.js @@ -0,0 +1,7 @@ +const required = require('./pkg-jsnext-module') + +if(required.test() !== 'pkg-jsnext-module') { + throw new Error('Invalid module') +} + +export const test = required.test diff --git a/test/integration/resolve-entries/main-field.js b/test/integration/resolve-entries/main-field.js new file mode 100644 index 00000000000..a045b3ad805 --- /dev/null +++ b/test/integration/resolve-entries/main-field.js @@ -0,0 +1,7 @@ +const required = require('./pkg-main') + +if(required.test() !== 'pkg-main-module') { + throw new Error('Invalid module') +} + +export const test = required.test diff --git a/test/integration/resolve-entries/module-field.js b/test/integration/resolve-entries/module-field.js new file mode 100644 index 00000000000..f04c2e81583 --- /dev/null +++ b/test/integration/resolve-entries/module-field.js @@ -0,0 +1,7 @@ +const required = require('./pkg-es6-module') + +if(required.test() !== 'pkg-es6-module') { + throw new Error('Invalid module') +} + +export const test = required.test diff --git a/test/integration/resolve-entries/pkg-both/es6.module.js b/test/integration/resolve-entries/pkg-both/es6.module.js new file mode 100644 index 00000000000..83911e2d097 --- /dev/null +++ b/test/integration/resolve-entries/pkg-both/es6.module.js @@ -0,0 +1,3 @@ +export function test() { + return 'pkg-es6-module' +} diff --git a/test/integration/resolve-entries/pkg-both/package.json b/test/integration/resolve-entries/pkg-both/package.json new file mode 100644 index 00000000000..1c7f5190320 --- /dev/null +++ b/test/integration/resolve-entries/pkg-both/package.json @@ -0,0 +1,6 @@ +{ + "name": "pkg-both", + "main": "./does-not-exist.js", + "jsnext:main": "./jsnext.module.js", + "module": "./es6.module.js" +} \ No newline at end of file diff --git a/test/integration/resolve-entries/pkg-browser-multiple/package.json b/test/integration/resolve-entries/pkg-browser-multiple/package.json new file mode 100644 index 00000000000..e3e274d981e --- /dev/null +++ b/test/integration/resolve-entries/pkg-browser-multiple/package.json @@ -0,0 +1,7 @@ +{ + "name": "pkg-browser-multiple", + "main": "./does-not-exist.js", + "browser": { + "./projected.js": "./projected-module.js" + } +} \ No newline at end of file diff --git a/test/integration/resolve-entries/pkg-browser-multiple/projected-module.js b/test/integration/resolve-entries/pkg-browser-multiple/projected-module.js new file mode 100644 index 00000000000..c17cf98b686 --- /dev/null +++ b/test/integration/resolve-entries/pkg-browser-multiple/projected-module.js @@ -0,0 +1,3 @@ +export function test() { + return 'pkg-browser-multiple' +} diff --git a/test/integration/resolve-entries/pkg-browser/browser-module.js b/test/integration/resolve-entries/pkg-browser/browser-module.js new file mode 100644 index 00000000000..a72bbd1bd52 --- /dev/null +++ b/test/integration/resolve-entries/pkg-browser/browser-module.js @@ -0,0 +1,3 @@ +export function test() { + return 'pkg-browser' +} diff --git a/test/integration/resolve-entries/pkg-browser/package.json b/test/integration/resolve-entries/pkg-browser/package.json new file mode 100644 index 00000000000..c8610ec13f6 --- /dev/null +++ b/test/integration/resolve-entries/pkg-browser/package.json @@ -0,0 +1,5 @@ +{ + "name": "pkg-browser", + "main": "./does-not-exist.js", + "browser": "./browser-module.js" +} \ No newline at end of file diff --git a/test/integration/resolve-entries/pkg-es6-module/es6.module.js b/test/integration/resolve-entries/pkg-es6-module/es6.module.js new file mode 100644 index 00000000000..83911e2d097 --- /dev/null +++ b/test/integration/resolve-entries/pkg-es6-module/es6.module.js @@ -0,0 +1,3 @@ +export function test() { + return 'pkg-es6-module' +} diff --git a/test/integration/resolve-entries/pkg-es6-module/package.json b/test/integration/resolve-entries/pkg-es6-module/package.json new file mode 100644 index 00000000000..e8492420ce6 --- /dev/null +++ b/test/integration/resolve-entries/pkg-es6-module/package.json @@ -0,0 +1,5 @@ +{ + "name": "pkg-es6-module", + "main": "./does-not-exist.js", + "module": "./es6.module.js" +} \ No newline at end of file diff --git a/test/integration/resolve-entries/pkg-jsnext-module/jsnext.module.js b/test/integration/resolve-entries/pkg-jsnext-module/jsnext.module.js new file mode 100644 index 00000000000..d5dfa0ab0bf --- /dev/null +++ b/test/integration/resolve-entries/pkg-jsnext-module/jsnext.module.js @@ -0,0 +1,3 @@ +export function test() { + return 'pkg-jsnext-module' +} diff --git a/test/integration/resolve-entries/pkg-jsnext-module/package.json b/test/integration/resolve-entries/pkg-jsnext-module/package.json new file mode 100644 index 00000000000..64e73ca4c85 --- /dev/null +++ b/test/integration/resolve-entries/pkg-jsnext-module/package.json @@ -0,0 +1,5 @@ +{ + "name": "pkg-jsnext-module", + "main": "./does-not-exist.js", + "jsnext:main": "./jsnext.module.js" +} \ No newline at end of file diff --git a/test/integration/resolve-entries/pkg-main/main.js b/test/integration/resolve-entries/pkg-main/main.js new file mode 100644 index 00000000000..245f554359e --- /dev/null +++ b/test/integration/resolve-entries/pkg-main/main.js @@ -0,0 +1,3 @@ +export function test() { + return 'pkg-main-module' +} diff --git a/test/integration/resolve-entries/pkg-main/package.json b/test/integration/resolve-entries/pkg-main/package.json new file mode 100644 index 00000000000..6091d416bd7 --- /dev/null +++ b/test/integration/resolve-entries/pkg-main/package.json @@ -0,0 +1,4 @@ +{ + "name": "pkg-main", + "main": "./main.js" +} \ No newline at end of file diff --git a/test/javascript.js b/test/javascript.js index 58b0c2dd948..f918fc7334f 100644 --- a/test/javascript.js +++ b/test/javascript.js @@ -257,4 +257,104 @@ describe('javascript', function() { assert.equal(typeof output, 'function'); assert.equal(output(), 3); }); + + it('should resolve the browser field before main', async function() { + let b = await bundle(__dirname + '/integration/resolve-entries/browser.js'); + + assertBundleTree(b, { + name: 'browser.js', + assets: ['browser.js', 'browser-module.js'], + childBundles: [] + }); + + let output = run(b); + + assert.equal(typeof output.test, 'function'); + assert.equal(output.test(), 'pkg-browser'); + }); + + it('should resolve advanced browser resolution', async function() { + let b = await bundle( + __dirname + '/integration/resolve-entries/browser-multiple.js' + ); + + assertBundleTree(b, { + name: 'browser-multiple.js', + assets: ['browser-multiple.js', 'projected-module.js'], + childBundles: [] + }); + + let output = run(b); + + assert.equal(typeof output.test, 'function'); + assert.equal(output.test(), 'pkg-browser-multiple'); + }); + + it('should resolve the module field before main', async function() { + let b = await bundle( + __dirname + '/integration/resolve-entries/module-field.js' + ); + + assertBundleTree(b, { + name: 'module-field.js', + assets: ['module-field.js', 'es6.module.js'], + childBundles: [] + }); + + let output = run(b); + + assert.equal(typeof output.test, 'function'); + assert.equal(output.test(), 'pkg-es6-module'); + }); + + it('should resolve the jsnext:main field before main', async function() { + let b = await bundle( + __dirname + '/integration/resolve-entries/jsnext-field.js' + ); + + assertBundleTree(b, { + name: 'jsnext-field.js', + assets: ['jsnext-field.js', 'jsnext.module.js'], + childBundles: [] + }); + + let output = run(b); + + assert.equal(typeof output.test, 'function'); + assert.equal(output.test(), 'pkg-jsnext-module'); + }); + + it('should resolve the module field before jsnext:main', async function() { + let b = await bundle( + __dirname + '/integration/resolve-entries/both-fields.js' + ); + + assertBundleTree(b, { + name: 'both-fields.js', + assets: ['both-fields.js', 'es6.module.js'], + childBundles: [] + }); + + let output = run(b); + + assert.equal(typeof output.test, 'function'); + assert.equal(output.test(), 'pkg-es6-module'); + }); + + it('should resolve the main field', async function() { + let b = await bundle( + __dirname + '/integration/resolve-entries/main-field.js' + ); + + assertBundleTree(b, { + name: 'main-field.js', + assets: ['main-field.js', 'main.js'], + childBundles: [] + }); + + let output = run(b); + + assert.equal(typeof output.test, 'function'); + assert.equal(output.test(), 'pkg-main-module'); + }); });