1
1
import { createRequire } from 'node:module'
2
2
import inject from '@rollup/plugin-inject'
3
+ import browserResolve from 'browser-resolve'
3
4
import stdLibBrowser from 'node-stdlib-browser'
4
5
import { handleCircularDependancyWarning } from 'node-stdlib-browser/helpers/rollup/plugin'
5
6
import esbuildPlugin from 'node-stdlib-browser/helpers/esbuild/plugin'
6
7
import type { Plugin } from 'vite'
7
- import { compareModuleNames , isEnabled , isNodeProtocolImport , toRegExp , withoutNodeProtocol } from './utils'
8
+ import { compareModuleNames , isEnabled , isNodeProtocolImport , resolvePolyfill , toEntries , toRegExp , withoutNodeProtocol } from './utils'
8
9
9
- export type BuildTarget = 'build' | 'dev'
10
+ export type BareModuleName < T = ModuleName > = T extends `node:${infer P } ` ? P : never
11
+ export type BareModuleNameWithSubpath < T = ModuleName > = T extends `node:${infer P } ` ? `${P } /${string } ` : never
10
12
export type BooleanOrBuildTarget = boolean | BuildTarget
13
+ export type BuildTarget = 'build' | 'dev'
11
14
export type ModuleName = keyof typeof stdLibBrowser
12
- export type ModuleNameWithoutNodePrefix < T = ModuleName > = T extends `node:${infer P } ` ? P : never
15
+ export type OverrideOptions = {
16
+
17
+ }
13
18
14
19
export type PolyfillOptions = {
15
20
/**
@@ -22,7 +27,7 @@ export type PolyfillOptions = {
22
27
* })
23
28
* ```
24
29
*/
25
- include ?: ModuleNameWithoutNodePrefix [ ] ,
30
+ include ?: BareModuleName [ ] ,
26
31
/**
27
32
* @example
28
33
*
@@ -32,7 +37,7 @@ export type PolyfillOptions = {
32
37
* })
33
38
* ```
34
39
*/
35
- exclude ?: ModuleNameWithoutNodePrefix [ ] ,
40
+ exclude ?: BareModuleName [ ] ,
36
41
/**
37
42
* Specify whether specific globals should be polyfilled.
38
43
*
@@ -66,7 +71,7 @@ export type PolyfillOptions = {
66
71
* })
67
72
* ```
68
73
*/
69
- overrides ?: { [ Key in ModuleNameWithoutNodePrefix ] ?: string } ,
74
+ overrides ?: { [ Key in BareModuleName | BareModuleNameWithSubpath ] ?: string } ,
70
75
/**
71
76
* Specify whether the Node protocol version of an import (e.g. `node:buffer`) should be polyfilled too.
72
77
*
@@ -76,14 +81,14 @@ export type PolyfillOptions = {
76
81
}
77
82
78
83
export type PolyfillOptionsResolved = {
79
- include : ModuleNameWithoutNodePrefix [ ] ,
80
- exclude : ModuleNameWithoutNodePrefix [ ] ,
84
+ include : BareModuleName [ ] ,
85
+ exclude : BareModuleName [ ] ,
81
86
globals : {
82
87
Buffer : BooleanOrBuildTarget ,
83
88
global : BooleanOrBuildTarget ,
84
89
process : BooleanOrBuildTarget ,
85
90
} ,
86
- overrides : { [ Key in ModuleNameWithoutNodePrefix ] ?: string } ,
91
+ overrides : { [ Key in BareModuleName | BareModuleNameWithSubpath ] ?: string } ,
87
92
protocolImports : boolean ,
88
93
}
89
94
@@ -153,16 +158,16 @@ export const nodePolyfills = (options: PolyfillOptions = {}): Plugin => {
153
158
return optionsResolved . exclude . some ( ( excludedName ) => compareModuleNames ( moduleName , excludedName ) )
154
159
}
155
160
156
- const toOverride = ( name : ModuleNameWithoutNodePrefix ) : string | void => {
157
- if ( isEnabled ( optionsResolved . globals . Buffer , 'dev' ) && / ^ b u f f e r $ / . test ( name ) ) {
161
+ const toOverride = ( name : BareModuleName ) : string | void => {
162
+ if ( / ^ b u f f e r $ / . test ( name ) ) {
158
163
return 'vite-plugin-node-polyfills/shims/buffer'
159
164
}
160
165
161
- if ( isEnabled ( optionsResolved . globals . global , 'dev' ) && / ^ g l o b a l $ / . test ( name ) ) {
166
+ if ( / ^ g l o b a l $ / . test ( name ) ) {
162
167
return 'vite-plugin-node-polyfills/shims/global'
163
168
}
164
169
165
- if ( isEnabled ( optionsResolved . globals . process , 'dev' ) && / ^ p r o c e s s $ / . test ( name ) ) {
170
+ if ( / ^ p r o c e s s $ / . test ( name ) ) {
166
171
return 'vite-plugin-node-polyfills/shims/process'
167
172
}
168
173
@@ -201,6 +206,7 @@ export const nodePolyfills = (options: PolyfillOptions = {}): Plugin => {
201
206
202
207
return {
203
208
name : 'vite-plugin-node-polyfills' ,
209
+ enforce : 'pre' ,
204
210
config : ( config , env ) => {
205
211
const isDev = env . command === 'serve'
206
212
@@ -246,21 +252,25 @@ export const nodePolyfills = (options: PolyfillOptions = {}): Plugin => {
246
252
...globalShimPaths ,
247
253
] ,
248
254
plugins : [
249
- esbuildPlugin ( polyfills ) ,
255
+ esbuildPlugin ( {
256
+ ...polyfills ,
257
+ } ) ,
250
258
// Supress the 'injected path "..." cannot be marked as external' error in Vite 4 (emitted by esbuild).
251
259
// https://github.com/evanw/esbuild/blob/edede3c49ad6adddc6ea5b3c78c6ea7507e03020/internal/bundler/bundler.go#L1469
252
260
{
253
261
name : 'vite-plugin-node-polyfills-shims-resolver' ,
254
- setup ( build ) {
262
+ setup : ( build ) => {
255
263
for ( const globalShimPath of globalShimPaths ) {
256
264
const globalShimsFilter = toRegExp ( globalShimPath )
257
265
258
266
// https://esbuild.github.io/plugins/#on-resolve
259
267
build . onResolve ( { filter : globalShimsFilter } , ( ) => {
268
+ const resolved = browserResolve . sync ( globalShimPath )
269
+
260
270
return {
261
271
// https://github.com/evanw/esbuild/blob/edede3c49ad6adddc6ea5b3c78c6ea7507e03020/internal/bundler/bundler.go#L1468
262
272
external : false ,
263
- path : globalShimPath ,
273
+ path : resolved ,
264
274
}
265
275
} )
266
276
}
@@ -277,5 +287,28 @@ export const nodePolyfills = (options: PolyfillOptions = {}): Plugin => {
277
287
} ,
278
288
}
279
289
} ,
290
+ async resolveId ( id ) {
291
+ for ( const [ moduleName , modulePath ] of toEntries ( polyfills ) ) {
292
+ if ( id . startsWith ( modulePath ) ) {
293
+ // Grab the subpath without the forward slash. E.g. `path/posix` -> `posix`
294
+ const moduleSubpath = id . slice ( modulePath . length + 1 )
295
+
296
+ if ( moduleSubpath . length > 0 ) {
297
+ const moduleNameWithoutProtocol = withoutNodeProtocol ( moduleName )
298
+ const overrideName = `${ moduleNameWithoutProtocol } /${ moduleSubpath } ` as const
299
+ const override = optionsResolved . overrides [ overrideName ]
300
+
301
+ if ( ! override ) {
302
+ // Todo: Maybe throw error?
303
+ return undefined
304
+ }
305
+
306
+ return await resolvePolyfill ( this , override )
307
+ }
308
+
309
+ return browserResolve . sync ( modulePath )
310
+ }
311
+ }
312
+ } ,
280
313
}
281
314
}
0 commit comments