@@ -13,7 +13,6 @@ import type {
13
13
ConfigEnv ,
14
14
DevEnvironmentOptions ,
15
15
HmrContext ,
16
- ResolvedConfig ,
17
16
UserConfig ,
18
17
ViteDevServer ,
19
18
} from '../..'
@@ -33,6 +32,10 @@ const logger = createLogger('info', {
33
32
allowClearScreen : false ,
34
33
} )
35
34
35
+ //
36
+ // Vite plugin hooks
37
+ //
38
+
36
39
export function rolldownDevHandleConfig (
37
40
config : UserConfig ,
38
41
env : ConfigEnv ,
@@ -64,6 +67,7 @@ export function rolldownDevHandleConfig(
64
67
// NOTE
65
68
// this is not "build" option any more (or is there a way to handle entry lazily?)
66
69
build : {
70
+ modulePreload : false ,
67
71
rollupOptions : {
68
72
input :
69
73
config . build ?. rollupOptions ?. input ??
@@ -167,6 +171,10 @@ window.__rolldown_hot = hot;
167
171
return code
168
172
}
169
173
174
+ //
175
+ // Rolldown dev environment
176
+ //
177
+
170
178
class RolldownEnvironment extends DevEnvironment {
171
179
instance ! : rolldown . RolldownBuild
172
180
result ! : rolldown . RolldownOutput
@@ -220,7 +228,9 @@ class RolldownEnvironment extends DevEnvironment {
220
228
plugins = plugins . filter (
221
229
( p ) =>
222
230
! ( typeof p . name === 'number' || p . name ?. startsWith ( 'vite:' ) ) ||
223
- [ 'vite:define' ] . includes ( p . name ) ||
231
+ [ 'vite:define' , 'vite:build-html' , 'vite:build-metadata' ] . includes (
232
+ p . name ,
233
+ ) ||
224
234
[ 'AliasPlugin' , 'TransformPlugin' ] . includes ( p . constructor . name ) ,
225
235
)
226
236
plugins = plugins . map ( ( p ) => injectEnvironmentToHooks ( this as any , p ) )
@@ -238,7 +248,7 @@ class RolldownEnvironment extends DevEnvironment {
238
248
} ,
239
249
plugins : [
240
250
...plugins ,
241
- rolldownHtmlPlugin ( this . config , this . rolldownDevOptions ) ,
251
+ patchRuntimePlugin ( ) ,
242
252
reactRefreshPlugin ( this . rolldownDevOptions ) ,
243
253
] ,
244
254
}
@@ -293,60 +303,18 @@ class RolldownEnvironment extends DevEnvironment {
293
303
}
294
304
}
295
305
296
- // TODO: use vite:build-html plugin
297
- function rolldownHtmlPlugin (
298
- config : ResolvedConfig ,
299
- rolldownDevOptions : RolldownDevOptions ,
300
- ) : rolldown . Plugin {
301
- const htmlEntryMap = new Map < string , MagicString > ( )
302
-
306
+ function patchRuntimePlugin ( ) : rolldown . Plugin {
303
307
return {
304
- name : 'vite:rolldown-html' ,
305
- transform : {
306
- filter : {
307
- id : {
308
- include : [ / \. h t m l $ / ] ,
309
- } ,
310
- } ,
311
- async handler ( code , id ) {
312
- // process html (will be emiited later during generateBundle)
313
- const htmlOutput = new MagicString ( code )
314
- htmlEntryMap . set ( id , htmlOutput )
315
-
316
- let jsOutput = ``
317
- if ( rolldownDevOptions ?. reactRefresh ) {
318
- jsOutput += `import "virtual:react-refresh/entry";\n`
319
- }
320
-
321
- // extract <script src="...">
322
- const matches = code . matchAll (
323
- / < s c r i p t \b [ ^ > ] + \b s r c = [ " ' ] ( [ ^ " ' ] + ) [ " ' ] [ ^ > ] * > .* ?< \/ s c r i p t > / dg,
324
- )
325
- for ( const match of matches ) {
326
- const src = match [ 1 ]
327
- const resolved = await this . resolve ( src , id )
328
- if ( ! resolved ) {
329
- this . warn ( `unresolved src '${ src } ' in '${ id } '` )
330
- continue
331
- }
332
- jsOutput += `import ${ JSON . stringify ( resolved . id ) } ;\n`
333
- const [ start , end ] = match . indices ! [ 0 ]
334
- htmlOutput . remove ( start , end )
335
- }
336
-
337
- // emit js entry
338
- return {
339
- code : jsOutput ,
340
- moduleSideEffects : 'no-treeshake' ,
341
- }
342
- } ,
343
- } ,
308
+ name : 'vite:rolldown-patch-runtime' ,
344
309
renderChunk ( code ) {
345
310
// patch rolldown_runtime to workaround a few things
346
311
if ( code . includes ( '//#region rolldown:runtime' ) ) {
347
312
const output = new MagicString ( code )
348
- // patch out hard-coded WebSocket setup "const socket = WebSocket(`ws://localhost:8080`)"
349
- output . replace ( / c o n s t s o c k e t = .* ?\n \} ; / s, '' )
313
+ // replace hard-coded WebSocket setup with custom client
314
+ output . replace (
315
+ / c o n s t s o c k e t = .* ?\n \} ; / s,
316
+ 'import("/@rolldown/client");' ,
317
+ )
350
318
// trigger full rebuild on non-accepting entry invalidation
351
319
output
352
320
. replace ( 'parents: [parent],' , 'parents: parent ? [parent] : [],' )
@@ -362,40 +330,11 @@ function rolldownHtmlPlugin(
362
330
return { code : output . toString ( ) , map : output . generateMap ( ) }
363
331
}
364
332
} ,
365
- generateBundle ( options , bundle ) {
366
- for ( const key in bundle ) {
367
- const chunk = bundle [ key ]
368
- // emit final html
369
- if ( chunk . type === 'chunk' && chunk . facadeModuleId ) {
370
- const htmlId = chunk . facadeModuleId
371
- const htmlOutput = htmlEntryMap . get ( htmlId )
372
- if ( htmlOutput ) {
373
- // inject js entry
374
- htmlOutput . appendLeft (
375
- htmlOutput . original . indexOf ( `</body>` ) ,
376
- `<script ${ options . format === 'es' ? 'type="module"' : '' } src="/${ chunk . fileName } "></script>` ,
377
- )
378
-
379
- // inject client
380
- htmlOutput . appendLeft (
381
- htmlOutput . original . indexOf ( `</head>` ) ,
382
- `<script type="module" src="/@rolldown/client"></script>` ,
383
- )
384
-
385
- this . emitFile ( {
386
- type : 'asset' ,
387
- fileName : path . relative ( config . root , htmlId ) ,
388
- originalFileName : htmlId ,
389
- source : htmlOutput . toString ( ) ,
390
- } )
391
- }
392
- }
393
- }
394
- } ,
395
333
}
396
334
}
397
335
398
336
// TODO: workaround rolldownExperimental.reactPlugin which injects js to html via `load` hook
337
+ // TODO: can we inject to "react" itself?
399
338
function reactRefreshPlugin (
400
339
rolldownDevOptions : RolldownDevOptions ,
401
340
) : rolldown . Plugin {
0 commit comments