From 4b1c92d6228f9869da76958d3c2cd12586ce84ab Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Mon, 18 Sep 2023 17:09:22 +0800 Subject: [PATCH] feat: improve deno and bun support (#14379) --- packages/vite/src/node/config.ts | 9 +++-- packages/vite/src/node/ssr/ssrModuleLoader.ts | 2 +- packages/vite/src/node/utils.ts | 40 ++++++++----------- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index b85788422672c1..123e206ccb1e3f 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -33,6 +33,7 @@ import { dynamicImport, isBuiltin, isExternalUrl, + isNodeBuiltin, isObject, lookupFile, mergeAlias, @@ -1082,13 +1083,15 @@ async function bundleConfigFile( if ( kind === 'entry-point' || path.isAbsolute(id) || - isBuiltin(id) + isNodeBuiltin(id) ) { return } - // partial deno support as `npm:` does not work with esbuild - if (id.startsWith('npm:')) { + // With the `isNodeBuiltin` check above, this check captures if the builtin is a + // non-node built-in, which esbuild doesn't know how to handle. In that case, we + // externalize it so the non-node runtime handles it instead. + if (isBuiltin(id)) { return { external: true } } diff --git a/packages/vite/src/node/ssr/ssrModuleLoader.ts b/packages/vite/src/node/ssr/ssrModuleLoader.ts index 3e498809f32829..129d91b5f0a428 100644 --- a/packages/vite/src/node/ssr/ssrModuleLoader.ts +++ b/packages/vite/src/node/ssr/ssrModuleLoader.ts @@ -268,7 +268,7 @@ async function nodeImport( resolveOptions: InternalResolveOptionsWithOverrideConditions, ) { let url: string - if (id.startsWith('node:') || id.startsWith('data:') || isBuiltin(id)) { + if (id.startsWith('data:') || isBuiltin(id)) { url = id } else { const resolved = tryNodeResolve( diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 66d071dddc7bbd..a53ee86e614e67 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -88,31 +88,25 @@ export const flattenId = (id: string): string => export const normalizeId = (id: string): string => id.replace(replaceNestedIdRE, ' > ') -//TODO: revisit later to see if the edge case that "compiling using node v12 code to be run in node v16 in the server" is what we intend to support. -const builtins = new Set([ - ...builtinModules, - 'assert/strict', - 'diagnostics_channel', - 'dns/promises', - 'fs/promises', - 'path/posix', - 'path/win32', - 'readline/promises', - 'stream/consumers', - 'stream/promises', - 'stream/web', - 'timers/promises', - 'util/types', - 'wasi', -]) - +// Supported by Node, Deno, Bun const NODE_BUILTIN_NAMESPACE = 'node:' +// Supported by Deno +const NPM_BUILTIN_NAMESPACE = 'npm:' +// Supported by Bun +const BUN_BUILTIN_NAMESPACE = 'bun:' +// Some runtimes like Bun injects namespaced modules here, which is not a node builtin +const nodeBuiltins = builtinModules.filter((id) => !id.includes(':')) + +// TODO: Use `isBuiltin` from `node:module`, but Deno doesn't support it export function isBuiltin(id: string): boolean { - return builtins.has( - id.startsWith(NODE_BUILTIN_NAMESPACE) - ? id.slice(NODE_BUILTIN_NAMESPACE.length) - : id, - ) + if (process.versions.deno && id.startsWith(NPM_BUILTIN_NAMESPACE)) return true + if (process.versions.bun && id.startsWith(BUN_BUILTIN_NAMESPACE)) return true + return isNodeBuiltin(id) +} + +export function isNodeBuiltin(id: string): boolean { + if (id.startsWith(NODE_BUILTIN_NAMESPACE)) return true + return nodeBuiltins.includes(id) } export function isInNodeModules(id: string): boolean {