diff --git a/src/node/optimizer/index.ts b/src/node/optimizer/index.ts index b1e49ebe14c94a..a6ce65ee4aeb93 100644 --- a/src/node/optimizer/index.ts +++ b/src/node/optimizer/index.ts @@ -43,6 +43,11 @@ export interface DepOptimizationOptions { * are also included for optimization. */ link?: string[] + /** + * A list of depdendencies that imports Node built-ins, but do not actually + * use them in browsers. + */ + allowNodeBuiltins?: string[] /** * Automatically run `vite optimize` on server start? * @default true @@ -181,7 +186,9 @@ export async function optimizeDeps( onwarn: onRollupWarning(spinner), ...config.rollupInputOptions, plugins: [ - createBuiltInBailPlugin(), + createBuiltInBailPlugin( + config.optimizeDeps && config.optimizeDeps.allowNodeBuiltins + ), depAssetExternalPlugin, ...(await createBaseRollupPlugins(root, resolver, config)), createDepAssetPlugin(resolver) @@ -225,12 +232,13 @@ export async function optimizeDeps( `Tip:\nMake sure your "dependencies" only include packages that you\n` + `intend to use in the browser. If it's a Node.js package, it\n` + `should be in "devDependencies".\n\n` + - `You can also configure what deps to include/exclude for\n` + - `optimization using the "optimizeDeps" option in vite.config.js.\n\n` + - `If you do intend to use this dependency in the browser, then\n` + - `unfortunately it is not distributed in a web-friendly way and\n` + - `it is recommended to look for a modern alternative that ships\n` + - `ES module build.\n` + `If you do intend to use this dependency in the browser and the\n` + + `dependency does not actually use these Node built-ins in the\n` + + `browser, you can add the dependency (not the built-in) to the\n` + + `"optimizeDeps.allowNodeBuiltins" option in vite.config.js.\n\n` + + `If that results in a runtime error, then unfortunately the\n` + + `package is not distributed in a web-friendly format. You should\n` + + `open an issue in its repo, or look for a modern alternative.` ) // TODO link to docs once we have it ) diff --git a/src/node/optimizer/pluginBuiltInBail.ts b/src/node/optimizer/pluginBuiltInBail.ts index 849a8b072311df..c095140b92b15c 100644 --- a/src/node/optimizer/pluginBuiltInBail.ts +++ b/src/node/optimizer/pluginBuiltInBail.ts @@ -1,7 +1,11 @@ import { Plugin } from 'rollup' import { lookupFile } from '../utils' +import { DepOptimizationOptions } from '.' +import chalk from 'chalk' -export const createBuiltInBailPlugin = (): Plugin => { +export const createBuiltInBailPlugin = ( + allowList: DepOptimizationOptions['allowNodeBuiltins'] +): Plugin => { const isbuiltin = require('isbuiltin') return { @@ -15,12 +19,18 @@ export const createBuiltInBailPlugin = (): Plugin => { importingDep = pkg.name } } + if (importingDep && allowList && allowList.includes(importingDep)) { + return null + } const dep = importingDep - ? `Dependency "${importingDep}"` + ? `Dependency ${chalk.yellow(importingDep)}` : `A dependency` throw new Error( - `${dep} is attempting to import Node built-in module "${id}". ` + - `This will not work in a browser environment.` + `${dep} is attempting to import Node built-in module ${chalk.yellow( + id + )}.\n` + + `This will not work in a browser environment.\n` + + `Imported by: ${chalk.gray(importer)}` ) } return null