diff --git a/packages/core/parcel-bundler/src/Resolver.js b/packages/core/parcel-bundler/src/Resolver.js index ab96d494ee7..9f00f52dd18 100755 --- a/packages/core/parcel-bundler/src/Resolver.js +++ b/packages/core/parcel-bundler/src/Resolver.js @@ -228,14 +228,17 @@ class Resolver { try { pkg = await this.readPackage(dir); - // First try loading package.main as a file, then try as a directory. - let main = this.getPackageMain(pkg); - let res = - (await this.loadAsFile(main, extensions, pkg)) || - (await this.loadDirectory(main, extensions, pkg)); - - if (res) { - return res; + // Get a list of possible package entry points. + let entries = this.getPackageEntries(pkg); + + for (let file of entries) { + // First try loading package.main as a file, then try as a directory. + const res = + (await this.loadAsFile(file, extensions, pkg)) || + (await this.loadDirectory(file, extensions, pkg)); + if (res) { + return res; + } } } catch (err) { // ignore @@ -275,7 +278,7 @@ class Resolver { return target === 'browser' ? pkg.browser : null; } - getPackageMain(pkg) { + getPackageEntries(pkg) { let browser = this.getBrowserField(pkg); if (browser && typeof browser === 'object' && browser[pkg.name]) { browser = browser[pkg.name]; @@ -284,16 +287,16 @@ class Resolver { // libraries like d3.js specifies node.js specific files in the "main" which breaks the build // we use the "browser" or "module" field to get the full dependency tree if available. // If this is a linked module with a `source` field, use that as the entry point. - let main = [pkg.source, browser, pkg.module, pkg.main].find( - entry => typeof entry === 'string' - ); - - // Default to index file if no main field find - if (!main || main === '.' || main === './') { - main = 'index'; - } + return [pkg.source, browser, pkg.module, pkg.main] + .filter(entry => typeof entry === 'string') + .map(main => { + // Default to index file if no main field find + if (!main || main === '.' || main === './') { + main = 'index'; + } - return path.resolve(pkg.pkgdir, main); + return path.resolve(pkg.pkgdir, main); + }); } async loadAsFile(file, extensions, pkg) { diff --git a/packages/core/parcel-bundler/test/integration/resolver/node_modules/package-module-fallback/main.js b/packages/core/parcel-bundler/test/integration/resolver/node_modules/package-module-fallback/main.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/core/parcel-bundler/test/integration/resolver/node_modules/package-module-fallback/package.json b/packages/core/parcel-bundler/test/integration/resolver/node_modules/package-module-fallback/package.json new file mode 100644 index 00000000000..e64cf59ee7e --- /dev/null +++ b/packages/core/parcel-bundler/test/integration/resolver/node_modules/package-module-fallback/package.json @@ -0,0 +1,5 @@ +{ + "name": "package-module-fallback", + "main": "main.js", + "module": "module.js" +} diff --git a/packages/core/parcel-bundler/test/resolver.js b/packages/core/parcel-bundler/test/resolver.js index ed1fc739569..ff440a0bf89 100644 --- a/packages/core/parcel-bundler/test/resolver.js +++ b/packages/core/parcel-bundler/test/resolver.js @@ -176,6 +176,18 @@ describe('resolver', function() { assert.equal(resolved.pkg.name, 'package-browser'); }); + it('should fall back to package.main when package.module does not exist', async function() { + let resolved = await resolver.resolve( + 'package-module-fallback', + path.join(rootDir, 'foo.js') + ); + assert.equal( + resolved.path, + path.join(rootDir, 'node_modules', 'package-module-fallback', 'main.js') + ); + assert.equal(resolved.pkg.name, 'package-module-fallback'); + }); + it('should not resolve a node_modules package.browser main field with --target=node', async function() { let resolver = new Resolver({ rootDir,