@@ -25,6 +25,7 @@ import {
2525 isDataUrl ,
2626 isExternalUrl ,
2727 isInNodeModules ,
28+ isNodeLikeBuiltin ,
2829 isNonDriveRelativeAbsolutePath ,
2930 isObject ,
3031 isOptimizable ,
@@ -97,9 +98,9 @@ export interface EnvironmentResolveOptions {
9798 */
9899 external ?: string [ ] | true
99100 /**
100- * @internal
101+ * Array of strings or regular expressions that indicate what modules are builtin for the environment.
101102 */
102- enableBuiltinNoExternalCheck ?: boolean
103+ builtins ?: ( string | RegExp ) [ ]
103104}
104105
105106export interface ResolveOptions extends EnvironmentResolveOptions {
@@ -173,11 +174,8 @@ interface ResolvePluginOptions {
173174}
174175
175176export interface InternalResolveOptions
176- extends Required < Omit < ResolveOptions , 'enableBuiltinNoExternalCheck' > > ,
177- ResolvePluginOptions {
178- /** @internal this is always optional for backward compat */
179- enableBuiltinNoExternalCheck ?: boolean
180- }
177+ extends Required < ResolveOptions > ,
178+ ResolvePluginOptions { }
181179
182180// Defined ResolveOptions are used to overwrite the values for all environments
183181// It is used when creating custom resolvers (for CSS, scanning, etc)
@@ -422,47 +420,67 @@ export function resolvePlugin(
422420 return res
423421 }
424422
425- // node built-ins.
426- // externalize if building for a node compatible environment, otherwise redirect to empty module
427- if ( isBuiltin ( id ) ) {
428- if ( currentEnvironmentOptions . consumer === 'server' ) {
429- if (
430- options . enableBuiltinNoExternalCheck &&
431- options . noExternal === true &&
432- // if both noExternal and external are true, noExternal will take the higher priority and bundle it.
433- // only if the id is explicitly listed in external, we will externalize it and skip this error.
434- ( options . external === true || ! options . external . includes ( id ) )
435- ) {
436- let message = `Cannot bundle Node.js built-in " ${ id } "`
437- if ( importer ) {
438- message += ` imported from " ${ path . relative (
439- process . cwd ( ) ,
440- importer ,
441- ) } "`
442- }
443- message += `. Consider disabling environments. ${ this . environment . name } .noExternal or remove the built-in dependency.`
444- this . error ( message )
423+ // built-ins
424+ // externalize if building for a server environment, otherwise redirect to an empty module
425+ if (
426+ currentEnvironmentOptions . consumer === 'server' &&
427+ isBuiltin ( options . builtins , id )
428+ ) {
429+ return options . idOnly
430+ ? id
431+ : { id , external : true , moduleSideEffects : false }
432+ } else if (
433+ currentEnvironmentOptions . consumer === 'server' &&
434+ isNodeLikeBuiltin ( id )
435+ ) {
436+ if ( ! ( options . external === true || options . external . includes ( id ) ) ) {
437+ let message = `Automatically externalized node built-in module " ${ id } "`
438+ if ( importer ) {
439+ message += ` imported from " ${ path . relative (
440+ process . cwd ( ) ,
441+ importer ,
442+ ) } "`
445443 }
444+ message += `. Consider adding it to environments.${ this . environment . name } .external if it is intended.`
445+ this . error ( message )
446+ }
446447
447- return options . idOnly
448- ? id
449- : { id, external : true , moduleSideEffects : false }
450- } else {
451- if ( ! asSrc ) {
452- debug ?.(
453- `externalized node built-in "${ id } " to empty module. ` +
454- `(imported by: ${ colors . white ( colors . dim ( importer ) ) } )` ,
455- )
456- } else if ( isProduction ) {
457- this . warn (
458- `Module "${ id } " has been externalized for browser compatibility, imported by "${ importer } ". ` +
459- `See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.` ,
460- )
448+ return options . idOnly
449+ ? id
450+ : { id, external : true , moduleSideEffects : false }
451+ } else if (
452+ currentEnvironmentOptions . consumer === 'client' &&
453+ isNodeLikeBuiltin ( id )
454+ ) {
455+ if (
456+ options . noExternal === true &&
457+ // if both noExternal and external are true, noExternal will take the higher priority and bundle it.
458+ // only if the id is explicitly listed in external, we will externalize it and skip this error.
459+ ( options . external === true || ! options . external . includes ( id ) )
460+ ) {
461+ let message = `Cannot bundle built-in module "${ id } "`
462+ if ( importer ) {
463+ message += ` imported from "${ path . relative (
464+ process . cwd ( ) ,
465+ importer ,
466+ ) } "`
461467 }
462- return isProduction
463- ? browserExternalId
464- : `${ browserExternalId } :${ id } `
468+ message += `. Consider disabling environments.${ this . environment . name } .noExternal or remove the built-in dependency.`
469+ this . error ( message )
470+ }
471+
472+ if ( ! asSrc ) {
473+ debug ?.(
474+ `externalized node built-in "${ id } " to empty module. ` +
475+ `(imported by: ${ colors . white ( colors . dim ( importer ) ) } )` ,
476+ )
477+ } else if ( isProduction ) {
478+ this . warn (
479+ `Module "${ id } " has been externalized for browser compatibility, imported by "${ importer } ". ` +
480+ `See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.` ,
481+ )
465482 }
483+ return isProduction ? browserExternalId : `${ browserExternalId } :${ id } `
466484 }
467485 }
468486
@@ -720,8 +738,10 @@ export function tryNodeResolve(
720738 basedir = root
721739 }
722740
741+ const isModuleBuiltin = ( id : string ) => isBuiltin ( options . builtins , id )
742+
723743 let selfPkg = null
724- if ( ! isBuiltin ( id ) && ! id . includes ( '\0' ) && bareImportRE . test ( id ) ) {
744+ if ( ! isModuleBuiltin ( id ) && ! id . includes ( '\0' ) && bareImportRE . test ( id ) ) {
725745 // check if it's a self reference dep.
726746 const selfPackageData = findNearestPackageData ( basedir , packageCache )
727747 selfPkg =
@@ -738,7 +758,7 @@ export function tryNodeResolve(
738758 // if so, we can resolve to a special id that errors only when imported.
739759 if (
740760 basedir !== root && // root has no peer dep
741- ! isBuiltin ( id ) &&
761+ ! isModuleBuiltin ( id ) &&
742762 ! id . includes ( '\0' ) &&
743763 bareImportRE . test ( id )
744764 ) {
0 commit comments