diff --git a/docs/09-troubleshooting.md b/docs/09-troubleshooting.md new file mode 100644 index 0000000000..d528385200 --- /dev/null +++ b/docs/09-troubleshooting.md @@ -0,0 +1,26 @@ +## Troubleshooting + +### Node built-in could not be resolved + +``` +✖ /my-application/node_modules/dep/index.js + "http" (Node.js built-in) could not be resolved. +``` + +Some packages are written with dependencies on Node.js built-in modules. This is a problem on the web, since Node.js built-in modules don't exist in the browser. For example, `import 'path'` will run just fine in Node.js but would fail in the browser. + +To solve this issue, you can either replace the offending package ([pika.dev](https://pika.dev/) is a great resource for web-friendly packages) or add Node.js polyfill support: + +```js +// snowpack.config.js +// Plugin: https://github.com/ionic-team/rollup-plugin-node-polyfills +module.exports = { + installOptions: { + rollup: { + plugins: [require("rollup-plugin-node-polyfills")()] + } + } +}; +``` + + diff --git a/src/commands/install.ts b/src/commands/install.ts index bc25f994e2..8460cd4302 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -347,6 +347,7 @@ export async function install( rollupPluginCatchUnresolved(), ].filter(Boolean) as Plugin[], onwarn(warning, warn) { + // Warn about the first circular dependency, but then ignore the rest. if (warning.code === 'CIRCULAR_DEPENDENCY') { if (!isCircularImportFound) { isCircularImportFound = true; @@ -354,6 +355,16 @@ export async function install( } return; } + // Log "unresolved" import warnings as an error, causing Snowpack to fail at the end. + if ( + warning.code === 'PLUGIN_WARNING' && + warning.plugin === 'snowpack:rollup-plugin-catch-unresolved' + ) { + // Display posix-style on all environments, mainly to help with CI :) + const fileName = warning.id!.replace(cwd + path.sep, '').replace(/\\/g, '/'); + logError(`${fileName}\n ${warning.message}`); + return; + } warn(warning); }, }; @@ -457,7 +468,7 @@ export async function command({cwd, config, lockfile, pkgManifest}: CommandOptio if (finalResult) { spinner.succeed( chalk.bold(`snowpack`) + - ` install complete.` + + ` install complete${spinnerHasError ? ' with errors.' : '.'}` + chalk.dim(` [${((Date.now() - startTime) / 1000).toFixed(2)}s]`), ); if (!!dependencyStats) { diff --git a/src/rollup-plugin-catch-unresolved.ts b/src/rollup-plugin-catch-unresolved.ts index 0a52274768..e3726ea70c 100644 --- a/src/rollup-plugin-catch-unresolved.ts +++ b/src/rollup-plugin-catch-unresolved.ts @@ -11,37 +11,17 @@ export function rollupPluginCatchUnresolved(): Plugin { return { name: 'snowpack:rollup-plugin-catch-unresolved', resolveId(id, importer) { - if (!isNodeBuiltin(id)) { - console.error( - chalk.red( - chalk.bold(`! ${id}`) + ` is imported by '${importer}', but could not be resolved.`, - ), - ); - return false; + if (isNodeBuiltin(id)) { + this.warn({ + id: importer, + message: `"${id}" (Node.js built-in) could not be resolved. (https://www.snowpack.dev/#node-built-in-could-not-be-resolved)`, + }); + } else { + this.warn({ + id: importer, + message: `"${id}" could not be resolved.`, + }); } - - console.error( - chalk.red( - chalk.bold(`! ${id}`) + - ` is a Node.js built-in module that does not exist in the browser.\n`, - ), - ); - console.error( - ` 1. Search pika.dev for a more web-friendly package alternative${ - importer ? ` to ${chalk.bold(importer)}.` : '.' - }`, - ); - console.error( - ` 2. Or, add this rollup plugin to your installer to polyfill Node.js packages:\n\n` + - chalk.dim( - ` // snowpack.config.js\n` + - ` module.exports = {\n` + - ` installOptions: {\n` + - ` rollup: {plugins: [require("rollup-plugin-node-polyfills")()]}\n` + - ` }\n` + - ` };\n`, - ), - ); return false; }, }; diff --git a/test/integration/error-node-builtin-unresolved/expected-output.txt b/test/integration/error-node-builtin-unresolved/expected-output.txt new file mode 100644 index 0000000000..146d193216 --- /dev/null +++ b/test/integration/error-node-builtin-unresolved/expected-output.txt @@ -0,0 +1,8 @@ +- snowpack installing... +⠼ snowpack installing... mock-test-package +✖ node_modules/mock-test-package/entrypoint.js + "http" (Node.js built-in) could not be resolved. (https://www.snowpack.dev/#node-built-in-could-not-be-resolved) +✔ snowpack install complete with errors. + + ⦿ web_modules/ size gzip brotli + └─ mock-test-package.js XXXX KB XXXX KB XXXX KB \ No newline at end of file diff --git a/test/integration/error-node-builtin-unresolved/node_modules/mock-test-package/entrypoint.js b/test/integration/error-node-builtin-unresolved/node_modules/mock-test-package/entrypoint.js new file mode 100644 index 0000000000..db8e367d61 --- /dev/null +++ b/test/integration/error-node-builtin-unresolved/node_modules/mock-test-package/entrypoint.js @@ -0,0 +1,3 @@ +export const FOO = 42; +// ERROR: This shouldn't work without polyfill support +import 'http'; \ No newline at end of file diff --git a/test/integration/error-node-builtin-unresolved/node_modules/mock-test-package/package.json b/test/integration/error-node-builtin-unresolved/node_modules/mock-test-package/package.json new file mode 100644 index 0000000000..274cc9a53f --- /dev/null +++ b/test/integration/error-node-builtin-unresolved/node_modules/mock-test-package/package.json @@ -0,0 +1,5 @@ +{ + "name": "mock-test-package", + "version": "1.2.3", + "module": "entrypoint.js" +} diff --git a/test/integration/error-node-builtin-unresolved/package.json b/test/integration/error-node-builtin-unresolved/package.json new file mode 100644 index 0000000000..9d240155a2 --- /dev/null +++ b/test/integration/error-node-builtin-unresolved/package.json @@ -0,0 +1,11 @@ +{ + "scripts": { + "TEST": "node ../../../pkg/dist-node/index.bin.js" + }, + "dependencies": { + "mock-test-package": "^1.2.3" + }, + "snowpack": { + "install": ["mock-test-package"] + } +} \ No newline at end of file