UNPKG

vite-plugin-node-polyfills

Version:

A Vite plugin to polyfill Node's Core Modules for browser environments.

1 lines 16 kB
{"version":3,"file":"index.cjs","sources":["../src/utils.ts","../src/index.ts"],"sourcesContent":["import type { BooleanOrBuildTarget, ModuleName, ModuleNameWithoutNodePrefix } from './index'\n\nexport const compareModuleNames = (moduleA: ModuleName, moduleB: ModuleName) => {\n return withoutNodeProtocol(moduleA) === withoutNodeProtocol(moduleB)\n}\n\nexport const isEnabled = (value: BooleanOrBuildTarget, mode: 'build' | 'dev') => {\n if (!value) return false\n if (value === true) return true\n\n return value === mode\n}\n\nexport const isNodeProtocolImport = (name: string) => {\n return name.startsWith('node:')\n}\n\nexport const toRegExp = (text: string) => {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping\n const escapedText = text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\n return new RegExp(`^${escapedText}$`)\n}\n\nexport const withoutNodeProtocol = (name: ModuleName): ModuleNameWithoutNodePrefix => {\n return name.replace(/^node:/, '') as ModuleNameWithoutNodePrefix\n}\n","import { createRequire } from 'node:module'\nimport inject from '@rollup/plugin-inject'\nimport stdLibBrowser from 'node-stdlib-browser'\nimport { handleCircularDependancyWarning } from 'node-stdlib-browser/helpers/rollup/plugin'\nimport esbuildPlugin from 'node-stdlib-browser/helpers/esbuild/plugin'\nimport type { Plugin } from 'vite'\nimport { compareModuleNames, isEnabled, isNodeProtocolImport, toRegExp, withoutNodeProtocol } from './utils'\n\nexport type BuildTarget = 'build' | 'dev'\nexport type BooleanOrBuildTarget = boolean | BuildTarget\nexport type ModuleName = keyof typeof stdLibBrowser\nexport type ModuleNameWithoutNodePrefix<T = ModuleName> = T extends `node:${infer P}` ? P : never\n\nexport type PolyfillOptions = {\n /**\n * Includes specific modules. If empty, includes all modules\n * @example\n *\n * ```ts\n * nodePolyfills({\n * include: ['fs', 'path'],\n * })\n * ```\n */\n include?: ModuleNameWithoutNodePrefix[],\n /**\n * @example\n *\n * ```ts\n * nodePolyfills({\n * exclude: ['fs', 'path'],\n * })\n * ```\n */\n exclude?: ModuleNameWithoutNodePrefix[],\n /**\n * Specify whether specific globals should be polyfilled.\n *\n * @example\n *\n * ```ts\n * nodePolyfills({\n * globals: {\n * Buffer: false,\n * global: true,\n * process: 'build',\n * },\n * })\n * ```\n */\n globals?: {\n Buffer?: BooleanOrBuildTarget,\n global?: BooleanOrBuildTarget,\n process?: BooleanOrBuildTarget,\n },\n /**\n * Specify alternative modules to use in place of the default polyfills.\n *\n * @example\n *\n * ```ts\n * nodePolyfills({\n * overrides: {\n * fs: 'memfs',\n * },\n * })\n * ```\n */\n overrides?: { [Key in ModuleNameWithoutNodePrefix]?: string },\n /**\n * Specify whether the Node protocol version of an import (e.g. `node:buffer`) should be polyfilled too.\n *\n * @default true\n */\n protocolImports?: boolean,\n}\n\nexport type PolyfillOptionsResolved = {\n include: ModuleNameWithoutNodePrefix[],\n exclude: ModuleNameWithoutNodePrefix[],\n globals: {\n Buffer: BooleanOrBuildTarget,\n global: BooleanOrBuildTarget,\n process: BooleanOrBuildTarget,\n },\n overrides: { [Key in ModuleNameWithoutNodePrefix]?: string },\n protocolImports: boolean,\n}\n\nconst globalShimBanners = {\n buffer: [\n `import __buffer_polyfill from 'vite-plugin-node-polyfills/shims/buffer'`,\n `globalThis.Buffer = globalThis.Buffer || __buffer_polyfill`,\n ],\n global: [\n `import __global_polyfill from 'vite-plugin-node-polyfills/shims/global'`,\n `globalThis.global = globalThis.global || __global_polyfill`,\n ],\n process: [\n `import __process_polyfill from 'vite-plugin-node-polyfills/shims/process'`,\n `globalThis.process = globalThis.process || __process_polyfill`,\n ],\n}\n\n/**\n * Returns a Vite plugin to polyfill Node's Core Modules for browser environments. Supports `node:` protocol imports.\n *\n * @example\n *\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite'\n * import { nodePolyfills } from 'vite-plugin-node-polyfills'\n *\n * export default defineConfig({\n * plugins: [\n * nodePolyfills({\n * // Specific modules that should not be polyfilled.\n * exclude: [],\n * // Whether to polyfill specific globals.\n * globals: {\n * Buffer: true, // can also be 'build', 'dev', or false\n * global: true,\n * process: true,\n * },\n * // Whether to polyfill `node:` protocol imports.\n * protocolImports: true,\n * }),\n * ],\n * })\n * ```\n */\nexport const nodePolyfills = (options: PolyfillOptions = {}): Plugin => {\n const optionsResolved: PolyfillOptionsResolved = {\n include: [],\n exclude: [],\n overrides: {},\n protocolImports: true,\n ...options,\n globals: {\n Buffer: true,\n global: true,\n process: true,\n ...options.globals,\n },\n }\n\n const isExcluded = (moduleName: ModuleName) => {\n if (optionsResolved.include.length > 0) {\n return !optionsResolved.include.some((includedName) => compareModuleNames(moduleName, includedName))\n }\n\n return optionsResolved.exclude.some((excludedName) => compareModuleNames(moduleName, excludedName))\n }\n\n const toOverride = (name: ModuleNameWithoutNodePrefix): string | void => {\n if (isEnabled(optionsResolved.globals.Buffer, 'dev') && /^buffer$/.test(name)) {\n return 'vite-plugin-node-polyfills/shims/buffer'\n }\n\n if (isEnabled(optionsResolved.globals.global, 'dev') && /^global$/.test(name)) {\n return 'vite-plugin-node-polyfills/shims/global'\n }\n\n if (isEnabled(optionsResolved.globals.process, 'dev') && /^process$/.test(name)) {\n return 'vite-plugin-node-polyfills/shims/process'\n }\n\n if (name in optionsResolved.overrides) {\n return optionsResolved.overrides[name]\n }\n }\n\n const polyfills = (Object.entries(stdLibBrowser) as Array<[ModuleName, string]>).reduce<Record<ModuleName, string>>((included, [name, value]) => {\n if (!optionsResolved.protocolImports) {\n if (isNodeProtocolImport(name)) {\n return included\n }\n }\n\n if (!isExcluded(name)) {\n included[name] = toOverride(withoutNodeProtocol(name)) || value\n }\n\n return included\n }, {} as Record<ModuleName, string>)\n\n const require = createRequire(import.meta.url)\n const globalShimPaths = [\n ...((isEnabled(optionsResolved.globals.Buffer, 'dev')) ? [require.resolve('vite-plugin-node-polyfills/shims/buffer')] : []),\n ...((isEnabled(optionsResolved.globals.global, 'dev')) ? [require.resolve('vite-plugin-node-polyfills/shims/global')] : []),\n ...((isEnabled(optionsResolved.globals.process, 'dev')) ? [require.resolve('vite-plugin-node-polyfills/shims/process')] : []),\n ]\n\n const globalShimsBanner = [\n ...((isEnabled(optionsResolved.globals.Buffer, 'dev')) ? globalShimBanners.buffer : []),\n ...((isEnabled(optionsResolved.globals.global, 'dev')) ? globalShimBanners.global : []),\n ...((isEnabled(optionsResolved.globals.process, 'dev')) ? globalShimBanners.process : []),\n ``,\n ].join('\\n')\n\n return {\n name: 'vite-plugin-node-polyfills',\n config(config, env) {\n const isDev = env.command === 'serve'\n // @ts-expect-error - this.meta.rolldownVersion only exists with rolldown-vite 7+\n const isRolldownVite = !!this?.meta?.rolldownVersion\n\n // https://github.com/niksy/node-stdlib-browser/blob/3e7cd7f3d115ac5c4593b550e7d8c4a82a0d4ac4/README.md?plain=1#L203-L209\n const defines = {\n ...((isDev && isEnabled(optionsResolved.globals.Buffer, 'dev')) ? { Buffer: 'Buffer' } : {}),\n ...((isDev && isEnabled(optionsResolved.globals.global, 'dev')) ? { global: 'global' } : {}),\n ...((isDev && isEnabled(optionsResolved.globals.process, 'dev')) ? { process: 'process' } : {}),\n }\n\n const shimsToInject = {\n // https://github.com/niksy/node-stdlib-browser/blob/3e7cd7f3d115ac5c4593b550e7d8c4a82a0d4ac4/README.md#vite\n ...(isEnabled(optionsResolved.globals.Buffer, 'build') ? { Buffer: 'vite-plugin-node-polyfills/shims/buffer' } : {}),\n ...(isEnabled(optionsResolved.globals.global, 'build') ? { global: 'vite-plugin-node-polyfills/shims/global' } : {}),\n ...(isEnabled(optionsResolved.globals.process, 'build') ? { process: 'vite-plugin-node-polyfills/shims/process' } : {}),\n }\n\n return {\n build: {\n rollupOptions: {\n onwarn: (warning, rollupWarn) => {\n handleCircularDependancyWarning(warning, () => {\n if (config.build?.rollupOptions?.onwarn) {\n return config.build.rollupOptions.onwarn(warning, rollupWarn)\n }\n\n rollupWarn(warning)\n })\n },\n ...Object.keys(shimsToInject).length > 0\n ? isRolldownVite\n ? { inject: shimsToInject }\n : { plugins: [inject(shimsToInject)] }\n : {},\n },\n },\n esbuild: {\n // In dev, the global polyfills need to be injected as a banner in order for isolated scripts (such as Vue SFCs) to have access to them.\n banner: isDev ? globalShimsBanner : undefined,\n },\n optimizeDeps: {\n exclude: [\n ...globalShimPaths,\n ],\n ...isRolldownVite\n ? {\n rollupOptions: {\n define: defines,\n resolve: {\n // https://github.com/niksy/node-stdlib-browser/blob/3e7cd7f3d115ac5c4593b550e7d8c4a82a0d4ac4/README.md?plain=1#L150\n alias: {\n ...polyfills,\n },\n },\n plugins: [\n {\n name: 'vite-plugin-node-polyfills:optimizer',\n banner: isDev ? globalShimsBanner : undefined,\n },\n ],\n },\n }\n : {\n esbuildOptions: {\n banner: isDev ? { js: globalShimsBanner } : undefined,\n define: defines,\n inject: [\n ...globalShimPaths,\n ],\n plugins: [\n esbuildPlugin(polyfills),\n // Supress the 'injected path \"...\" cannot be marked as external' error in Vite 4 (emitted by esbuild).\n // https://github.com/evanw/esbuild/blob/edede3c49ad6adddc6ea5b3c78c6ea7507e03020/internal/bundler/bundler.go#L1469\n {\n name: 'vite-plugin-node-polyfills-shims-resolver',\n setup(build) {\n for (const globalShimPath of globalShimPaths) {\n const globalShimsFilter = toRegExp(globalShimPath)\n\n // https://esbuild.github.io/plugins/#on-resolve\n build.onResolve({ filter: globalShimsFilter }, () => {\n return {\n // https://github.com/evanw/esbuild/blob/edede3c49ad6adddc6ea5b3c78c6ea7507e03020/internal/bundler/bundler.go#L1468\n external: false,\n path: globalShimPath,\n }\n })\n }\n },\n },\n ],\n },\n },\n },\n resolve: {\n // https://github.com/niksy/node-stdlib-browser/blob/3e7cd7f3d115ac5c4593b550e7d8c4a82a0d4ac4/README.md?plain=1#L150\n alias: {\n ...polyfills,\n },\n },\n }\n },\n }\n}\n"],"names":["compareModuleNames","moduleA","moduleB","withoutNodeProtocol","isEnabled","value","mode","isNodeProtocolImport","name","toRegExp","text","escapedText","globalShimBanners","nodePolyfills","options","optionsResolved","isExcluded","moduleName","includedName","excludedName","toOverride","polyfills","stdLibBrowser","included","require","createRequire","_documentCurrentScript","globalShimPaths","globalShimsBanner","config","env","isDev","isRolldownVite","defines","shimsToInject","warning","rollupWarn","handleCircularDependancyWarning","inject","esbuildPlugin","build","globalShimPath","globalShimsFilter"],"mappings":"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"}