@@ -34,11 +34,8 @@ export interface ExternalsOptions {
3434 */
3535 export default function externals ( options : ExternalsOptions = { } ) : Plugin {
3636
37- // Store eventual warnings until we can display them
38- const warnings : string [ ] = [ ]
39-
4037 // Consolidate options
41- const opts : Required < ExternalsOptions > = {
38+ const consolidatedOptions : Required < ExternalsOptions > = {
4239 packagePath : [ ] ,
4340 builtins : true ,
4441 deps : false ,
@@ -50,9 +47,12 @@ export interface ExternalsOptions {
5047 ...options
5148 }
5249
50+ // This will store all eventual warnings until we can display them
51+ const warnings : string [ ] = [ ]
52+
5353 // Map the include and exclude options to arrays of regexes
54- const [ include , exclude ] = [ 'include' , 'exclude' ] . map ( option => new Array ( )
55- . concat ( ( opts as any ) [ option ] )
54+ const [ include , exclude ] = [ 'include' , 'exclude' ] . map ( optionName => new Array ( )
55+ . concat ( ( consolidatedOptions as any ) [ optionName ] )
5656 . map ( ( entry : string | RegExp , index : number ) : RegExp => {
5757 if ( entry instanceof RegExp ) {
5858 return entry
@@ -62,68 +62,69 @@ export interface ExternalsOptions {
6262 }
6363 else {
6464 if ( ! ! entry ) {
65- warnings . push ( `Ignoring wrong entry type #${ index } in '${ option } ' option: '${ entry } '` )
65+ warnings . push ( `Ignoring wrong entry type #${ index } in '${ optionName } ' option: '${ entry } '` )
6666 }
6767 return / (? = n o ) m a t c h /
6868 }
6969 } )
7070 )
7171
72- // Build a function to filter out unwanted dependencies
73- const filterFn = ( dep : string ) => ! exclude . some ( rx => rx . test ( dep ) )
72+ // Build a function to keep only non excluded dependencies
73+ const isNotExcluded = ( id : string ) => ! exclude . some ( rx => rx . test ( id ) )
7474
75- // Filter NodeJS builtins
76- const builtins = ( opts . builtins ? builtinModules : [ ] ) . filter ( filterFn )
77-
78- // Normalize package paths
79- let packagePaths : string [ ] = ( [ ] as string [ ] ) . concat ( opts . packagePath )
80-
81- // Array of the final regexes, include potential import from a sub directory (e.g. 'lodash/map')
75+ // Array of the final regexes
8276 const externals : RegExp [ ] = [ ]
77+ const isExternal = ( id : string ) => externals . some ( deps => deps . test ( id ) )
8378
8479 return {
8580 name : 'node-externals' ,
8681
8782 async buildStart ( ) {
8883
89- // Find and filter dependencies
84+ // 1) Filter NodeJS builtins, supporting potential import from a sub directory (e.g. 'fs/promises')
85+ const builtins = ( consolidatedOptions . builtins ? builtinModules : [ ] ) . filter ( isNotExcluded )
86+ if ( builtins . length > 0 ) {
87+ externals . push ( new RegExp ( '^(?:' + builtins . join ( '|' ) + ')(\/.+)?$' ) )
88+ }
89+
90+ // 2) Find and filter dependencies, supporting potential import from a sub directory (e.g. 'lodash/map')
91+ const packagePaths : string [ ] = ( [ ] as string [ ] ) . concat ( consolidatedOptions . packagePath )
9092 const dependencies = ( await findDependencies ( {
9193 packagePaths : packagePaths . length > 0 ? packagePaths : findPackagePaths ( ) ,
9294 keys : [
93- opts . deps && 'dependencies' ,
94- opts . devDeps && 'devDependencies' ,
95- opts . peerDeps && 'peerDependencies' ,
96- opts . optDeps && 'optionalDependencies'
95+ consolidatedOptions . deps && 'dependencies' ,
96+ consolidatedOptions . devDeps && 'devDependencies' ,
97+ consolidatedOptions . peerDeps && 'peerDependencies' ,
98+ consolidatedOptions . optDeps && 'optionalDependencies'
9799 ] . filter ( Boolean ) as string [ ] ,
98100 warnings
99- } ) ) . filter ( filterFn )
100-
101- // Issue the warnings we may have collected
102- let msg : string | undefined
103- while ( msg = warnings . shift ( ) ) {
104- this . warn ( msg )
105- }
106-
107- // Build regexes
108- if ( builtins . length > 0 ) {
109- externals . push ( new RegExp ( '^(?:' + builtins . join ( '|' ) + ')(\/.+)?$' ) )
110- }
101+ } ) ) . filter ( isNotExcluded )
111102
112103 if ( dependencies . length > 0 ) {
113104 externals . push ( new RegExp ( '^(?:' + dependencies . join ( '|' ) + ')(\/.+)?$' ) )
114105 }
115106
107+ // 3) Add the include option
116108 if ( include . length > 0 ) {
117109 externals . push ( ...include )
118110 }
111+
112+ // All done. Issue the warnings we may have collected
113+ let msg : string | undefined
114+ while ( msg = warnings . shift ( ) ) {
115+ this . warn ( msg )
116+ }
119117 } ,
120118
121119 resolveId ( id , importer ) {
120+ // Ignore entry chunks & don't mess with other plugins
121+ if ( ! importer ?. charCodeAt ( 0 ) || ! id . charCodeAt ( 0 ) ) {
122+ return null
123+ }
124+
122125 // Return `false` if importee should be treated as an external module,
123- // otherwise return `null` to let Rollup and other plugins handle it.
124- return importer && ! / \0 / . test ( id ) && externals . some ( deps => deps . test ( id ) ) && filterFn ( id )
125- ? false
126- : null
126+ // otherwise return `null` to let Rollup and other plugins handle it
127+ return isExternal ( id ) && isNotExcluded ( id ) ? false : null
127128 }
128129 }
129130}
0 commit comments