@@ -8,6 +8,7 @@ import { init, parse as parseImports } from 'es-module-lexer'
8
8
import type { SourceMap } from 'rolldown'
9
9
import type { RawSourceMap } from '@ampproject/remapping'
10
10
import convertSourceMap from 'convert-source-map'
11
+ import { buildImportAnalysisPlugin as nativeBuildImportAnalysisPlugin } from 'rolldown/experimental'
11
12
import {
12
13
combineSourcemaps ,
13
14
generateCodeFrame ,
@@ -170,16 +171,43 @@ function preload(
170
171
/**
171
172
* Build only. During serve this is performed as part of ./importAnalysis.
172
173
*/
173
- export function buildImportAnalysisPlugin ( config : ResolvedConfig ) : Plugin {
174
+ export function buildImportAnalysisPlugin ( config : ResolvedConfig ) : [ Plugin ] {
174
175
const getInsertPreload = ( environment : Environment ) =>
175
176
environment . config . consumer === 'client' &&
176
177
! config . isWorker &&
177
178
! config . build . lib
178
179
180
+ const enableNativePlugin = config . experimental . enableNativePlugin
179
181
const renderBuiltUrl = config . experimental . renderBuiltUrl
180
182
const isRelativeBase = config . base === './' || config . base === ''
181
183
182
- return {
184
+ // TODO: make this environment-specific
185
+ const { modulePreload } = config . build // this.environment.config.build
186
+
187
+ const scriptRel =
188
+ modulePreload && modulePreload . polyfill
189
+ ? `'modulepreload'`
190
+ : `/* @__PURE__ */ (${ detectScriptRel . toString ( ) } )()`
191
+
192
+ // There are two different cases for the preload list format in __vitePreload
193
+ //
194
+ // __vitePreload(() => import(asyncChunk), [ ...deps... ])
195
+ //
196
+ // This is maintained to keep backwards compatibility as some users developed plugins
197
+ // using regex over this list to workaround the fact that module preload wasn't
198
+ // configurable.
199
+ const assetsURL =
200
+ renderBuiltUrl || isRelativeBase
201
+ ? // If `experimental.renderBuiltUrl` is used, the dependencies might be relative to the current chunk.
202
+ // If relative base is used, the dependencies are relative to the current chunk.
203
+ // The importerUrl is passed as third parameter to __vitePreload in this case
204
+ `function(dep, importerUrl) { return new URL(dep, importerUrl).href }`
205
+ : // If the base isn't relative, then the deps are relative to the projects `outDir` and the base
206
+ // is appended inside __vitePreload too.
207
+ `function(dep) { return ${ JSON . stringify ( config . base ) } +dep }`
208
+ const preloadCode = `const scriptRel = ${ scriptRel } ;const assetsURL = ${ assetsURL } ;const seen = {};export const ${ preloadMethod } = ${ preload . toString ( ) } `
209
+
210
+ const jsPlugin = {
183
211
name : 'vite:build-import-analysis' ,
184
212
resolveId ( id ) {
185
213
if ( id === preloadHelperId ) {
@@ -189,30 +217,6 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
189
217
190
218
load ( id ) {
191
219
if ( id === preloadHelperId ) {
192
- const { modulePreload } = this . environment . config . build
193
-
194
- const scriptRel =
195
- modulePreload && modulePreload . polyfill
196
- ? `'modulepreload'`
197
- : `/* @__PURE__ */ (${ detectScriptRel . toString ( ) } )()`
198
-
199
- // There are two different cases for the preload list format in __vitePreload
200
- //
201
- // __vitePreload(() => import(asyncChunk), [ ...deps... ])
202
- //
203
- // This is maintained to keep backwards compatibility as some users developed plugins
204
- // using regex over this list to workaround the fact that module preload wasn't
205
- // configurable.
206
- const assetsURL =
207
- renderBuiltUrl || isRelativeBase
208
- ? // If `experimental.renderBuiltUrl` is used, the dependencies might be relative to the current chunk.
209
- // If relative base is used, the dependencies are relative to the current chunk.
210
- // The importerUrl is passed as third parameter to __vitePreload in this case
211
- `function(dep, importerUrl) { return new URL(dep, importerUrl).href }`
212
- : // If the base isn't relative, then the deps are relative to the projects `outDir` and the base
213
- // is appended inside __vitePreload too.
214
- `function(dep) { return ${ JSON . stringify ( config . base ) } +dep }`
215
- const preloadCode = `const scriptRel = ${ scriptRel } ;const assetsURL = ${ assetsURL } ;const seen = {};export const ${ preloadMethod } = ${ preload . toString ( ) } `
216
220
return { code : preloadCode , moduleSideEffects : false }
217
221
}
218
222
} ,
@@ -718,5 +722,24 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
718
722
}
719
723
}
720
724
} ,
725
+ } as Plugin
726
+ if ( enableNativePlugin ) {
727
+ delete jsPlugin . transform
728
+ delete jsPlugin . resolveId
729
+ delete jsPlugin . load
721
730
}
731
+ return [
732
+ jsPlugin ,
733
+ enableNativePlugin
734
+ ? nativeBuildImportAnalysisPlugin ( {
735
+ preloadCode : preloadCode ,
736
+ // @ts -expect-error make this environment-specific
737
+ insertPreload : getInsertPreload ( { config : { consumer : 'client' } } ) ,
738
+ /// this field looks redundant, put a dummy value for now
739
+ optimizeModulePreloadRelativePaths : false ,
740
+ renderBuiltUrl : Boolean ( renderBuiltUrl ) ,
741
+ isRelativeBase : isRelativeBase ,
742
+ } )
743
+ : null ,
744
+ ] . filter ( Boolean ) as [ Plugin ]
722
745
}
0 commit comments