diff --git a/snowpack/src/sources/local.ts b/snowpack/src/sources/local.ts index 203ca6fb3b..d100039dc3 100644 --- a/snowpack/src/sources/local.ts +++ b/snowpack/src/sources/local.ts @@ -452,10 +452,8 @@ export class PackageSourceLocal implements PackageSource { } // Check to see if this package is marked as external, in which case skip the build. - for (const externalPackage of config.packageOptions.external) { - if (_packageName === externalPackage || _packageName.startsWith(externalPackage + '/')) { - return; - } + if(this.isExternal(_packageName, spec)) { + return; } await this.installPackage(_packageName, source); @@ -684,10 +682,8 @@ export class PackageSourceLocal implements PackageSource { const [packageName] = parsePackageImportSpecifier(spec); // If this import is marked as external, do not transform the original spec - for (const externalPackage of config.packageOptions.external) { - if (packageName === externalPackage || packageName.startsWith(externalPackage + '/')) { - return spec; - } + if(this.isExternal(packageName, spec)) { + return spec; } const isSymlink = !entrypoint.includes(path.join('node_modules', packageName)); @@ -742,4 +738,14 @@ export class PackageSourceLocal implements PackageSource { getCacheFolder() { return this.cacheDirectory; } + + private isExternal(packageName: string, specifier: string): boolean { + const {config} = this; + for (const external of config.packageOptions.external) { + if (packageName === external || specifier === external || packageName.startsWith(external + '/')) { + return true; + } + } + return false; + } } diff --git a/test/snowpack/config/packageOptions.external/index.test.js b/test/snowpack/config/packageOptions.external/index.test.js index c1f6e76705..d3db0aa245 100644 --- a/test/snowpack/config/packageOptions.external/index.test.js +++ b/test/snowpack/config/packageOptions.external/index.test.js @@ -24,4 +24,44 @@ describe('packageOptions.external', () => { expect(result['index.js']).toContain(`import 'fs';`); }); + + it('Does not install externals that are deep package imports', async () => { + const result = await testFixture({ + 'packages/some-thing/main.js': dedent` + export default 'ok'; + `, + 'packages/some-thing/deep.js': dedent` + export default 'oops'; + `, + 'packages/some-thing/package.json': dedent` + { + "version": "1.0.0", + "name": "some-thing", + "module": "main.js" + } + `, + 'package.json': dedent` + { + "version": "1.0.1", + "name": "@snowpack/test-config-external", + "dependencies": { + "some-thing": "file:./packages/some-thing" + } + } + `, + 'index.js': dedent` + import 'some-thing'; + import 'some-thing/deep.js'; + `, + 'snowpack.config.js': dedent` + module.exports = { + packageOptions: { + external: ['some-thing/deep.js'] + } + } + ` + }); + + expect(result['index.js']).toContain(`import 'some-thing/deep.js';`); + }) });