@@ -25,6 +25,7 @@ import {
25
25
isDataUrl ,
26
26
isExternalUrl ,
27
27
isInNodeModules ,
28
+ isNodeLikeBuiltin ,
28
29
isNonDriveRelativeAbsolutePath ,
29
30
isObject ,
30
31
isOptimizable ,
@@ -97,9 +98,9 @@ export interface EnvironmentResolveOptions {
97
98
*/
98
99
external ?: string [ ] | true
99
100
/**
100
- * @internal
101
+ * Array of strings or regular expressions that indicate what modules are builtin for the environment.
101
102
*/
102
- enableBuiltinNoExternalCheck ?: boolean
103
+ builtins ?: ( string | RegExp ) [ ]
103
104
}
104
105
105
106
export interface ResolveOptions extends EnvironmentResolveOptions {
@@ -173,11 +174,8 @@ interface ResolvePluginOptions {
173
174
}
174
175
175
176
export 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 { }
181
179
182
180
// Defined ResolveOptions are used to overwrite the values for all environments
183
181
// It is used when creating custom resolvers (for CSS, scanning, etc)
@@ -422,47 +420,67 @@ export function resolvePlugin(
422
420
return res
423
421
}
424
422
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
+ ) } "`
445
443
}
444
+ message += `. Consider adding it to environments.${ this . environment . name } .external if it is intended.`
445
+ this . error ( message )
446
+ }
446
447
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
+ ) } "`
461
467
}
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
+ )
465
482
}
483
+ return isProduction ? browserExternalId : `${ browserExternalId } :${ id } `
466
484
}
467
485
}
468
486
@@ -720,8 +738,10 @@ export function tryNodeResolve(
720
738
basedir = root
721
739
}
722
740
741
+ const isModuleBuiltin = ( id : string ) => isBuiltin ( options . builtins , id )
742
+
723
743
let selfPkg = null
724
- if ( ! isBuiltin ( id ) && ! id . includes ( '\0' ) && bareImportRE . test ( id ) ) {
744
+ if ( ! isModuleBuiltin ( id ) && ! id . includes ( '\0' ) && bareImportRE . test ( id ) ) {
725
745
// check if it's a self reference dep.
726
746
const selfPackageData = findNearestPackageData ( basedir , packageCache )
727
747
selfPkg =
@@ -738,7 +758,7 @@ export function tryNodeResolve(
738
758
// if so, we can resolve to a special id that errors only when imported.
739
759
if (
740
760
basedir !== root && // root has no peer dep
741
- ! isBuiltin ( id ) &&
761
+ ! isModuleBuiltin ( id ) &&
742
762
! id . includes ( '\0' ) &&
743
763
bareImportRE . test ( id )
744
764
) {
0 commit comments