diff --git a/esinstall/src/index.ts b/esinstall/src/index.ts index cb3c9cd467..6e246e102c 100644 --- a/esinstall/src/index.ts +++ b/esinstall/src/index.ts @@ -373,7 +373,8 @@ ${colors.dim( warning.code === 'CIRCULAR_DEPENDENCY' || warning.code === 'NAMESPACE_CONFLICT' || warning.code === 'THIS_IS_UNDEFINED' || - warning.code === 'EMPTY_BUNDLE' + warning.code === 'EMPTY_BUNDLE' || + warning.code === 'UNUSED_EXTERNAL_IMPORT' ) { logger.debug(logMessage); } else { diff --git a/snowpack/assets/require-or-import.js b/snowpack/assets/require-or-import.js index 686b6e7e52..18505d70e6 100644 --- a/snowpack/assets/require-or-import.js +++ b/snowpack/assets/require-or-import.js @@ -20,16 +20,28 @@ module.exports = async function requireOrImport(filepath, { from = process.cwd() }); try { const mdl = NATIVE_REQUIRE(resolvedPath); + + // Add a `default` property on a CommonJS export so that it can be accessed from import statements. + // This is set to enumerable: false to make it hidden(ish) to code. + if(mdl && !('default' in mdl)) { + Object.defineProperty(mdl, 'default', { + configurable: true, + enumerable: false, + writable: true, + value: mdl + }); + } + resolve(mdl); } catch (e) { if (e instanceof SyntaxError && /export|import/.test(e.message)) { console.error(`Failed to load "${filepath}"!\nESM format is not natively supported in "node@${process.version}".\nPlease use CommonJS or upgrade to an LTS version of node above "node@12.17.0".`) } else if (e.code === 'ERR_REQUIRE_ESM') { const url = pathToFileURL(resolvedPath); - return NATIVE_IMPORT(url).then(mdl => resolve(mdl.default ? mdl.default : mdl)); - }; + return NATIVE_IMPORT(url).then(mdl => resolve(mdl.default ? mdl.default : mdl), err => reject(err)); + } try { - return NATIVE_IMPORT(pathToFileURL(resolvedPath)).then(mdl => resolve(mdl.default ? mdl.default : mdl)); + return NATIVE_IMPORT(pathToFileURL(resolvedPath)).then(mdl => resolve(mdl.default ? mdl.default : mdl), err => reject(err)); } catch (e) { reject(e); } diff --git a/test/snowpack/runtime/runtime.test.js b/test/snowpack/runtime/runtime.test.js index 0c74432fcc..34f6f8fe12 100644 --- a/test/snowpack/runtime/runtime.test.js +++ b/test/snowpack/runtime/runtime.test.js @@ -90,4 +90,49 @@ describe('runtime', () => { await fixture.cleanup(); } }); + + it('Can import a CommonJS module as the default export', async () => { + const fixture = await testRuntimeFixture({ + 'packages/other/package.json': dedent` + { + "version": "1.0.0", + "name": "other", + "main": "main.js" + } + `, + 'packages/other/main.js': dedent` + module.exports = () => 'works'; + `, + 'main.js': dedent` + import fn from 'other'; + + export function test() { + return fn(); + } + `, + 'package.json': dedent` + { + "version": "1.0.1", + "name": "@snowpack/test-runtime-import-cjs", + "dependencies": { + "other": "file:./packages/other" + } + } + `, + 'snowpack.config.json': dedent` + { + "packageOptions": { + "external": ["other"] + } + } + ` + }); + + try { + let mod = await fixture.runtime.importModule('/main.js'); + expect(await mod.exports.test()).toEqual('works'); + } finally { + await fixture.cleanup(); + } + }); });