Skip to content

Commit aca474a

Browse files
IWANABETHATGUYsapphi-red
authored andcommitted
feat: native build plugins (#45) (#46)
1 parent 014ade6 commit aca474a

File tree

2 files changed

+69
-31
lines changed

2 files changed

+69
-31
lines changed

packages/vite/src/node/build.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
LoggingFunction,
99
ModuleFormat,
1010
OutputOptions,
11+
RolldownPlugin,
1112
RollupBuild,
1213
RollupError,
1314
RollupLog,
@@ -16,6 +17,10 @@ import type {
1617
// RollupWatcher,
1718
// WatcherOptions,
1819
} from 'rolldown'
20+
import {
21+
loadFallbackPlugin as nativeLoadFallbackPlugin,
22+
manifestPlugin as nativeManifestPlugin,
23+
} from 'rolldown/experimental'
1924
import type { RollupCommonJSOptions } from 'dep-types/commonjs'
2025
import type { RollupDynamicImportVarsOptions } from 'dep-types/dynamicImportVars'
2126
import type { TransformOptions } from 'esbuild'
@@ -455,13 +460,15 @@ export function resolveBuildEnvironmentOptions(
455460

456461
export async function resolveBuildPlugins(config: ResolvedConfig): Promise<{
457462
pre: Plugin[]
458-
post: Plugin[]
463+
post: RolldownPlugin[]
459464
}> {
465+
const enableNativePlugin = config.experimental.enableNativePlugin
460466
// TODO: support commonjs options?
461467
return {
462468
pre: [
463469
completeSystemWrapPlugin(),
464-
dataURIPlugin(),
470+
// rolldown has builtin support datauri, use a switch to control it for convenience
471+
...(enableNativePlugin ? [] : [dataURIPlugin()]),
465472
/**
466473
* environment.config.build.rollupOptions.plugins isn't supported
467474
* when builder.sharedConfigBuild or builder.sharedPlugins is enabled.
@@ -478,13 +485,22 @@ export async function resolveBuildPlugins(config: ResolvedConfig): Promise<{
478485
...(config.isWorker ? [webWorkerPostPlugin()] : []),
479486
],
480487
post: [
481-
buildImportAnalysisPlugin(config),
488+
...buildImportAnalysisPlugin(config),
482489
...(config.esbuild !== false ? [buildEsbuildPlugin(config)] : []),
483490
terserPlugin(config),
484491
...(!config.isWorker
485-
? [manifestPlugin(), ssrManifestPlugin(), buildReporterPlugin(config)]
492+
? [
493+
config.build.manifest && enableNativePlugin
494+
? // TODO: make this environment-specific
495+
nativeManifestPlugin()
496+
: manifestPlugin(),
497+
ssrManifestPlugin(),
498+
buildReporterPlugin(config),
499+
]
486500
: []),
487-
buildLoadFallbackPlugin(),
501+
enableNativePlugin
502+
? nativeLoadFallbackPlugin()
503+
: buildLoadFallbackPlugin(),
488504
],
489505
}
490506
}

packages/vite/src/node/plugins/importAnalysisBuild.ts

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { init, parse as parseImports } from 'es-module-lexer'
88
import type { SourceMap } from 'rolldown'
99
import type { RawSourceMap } from '@ampproject/remapping'
1010
import convertSourceMap from 'convert-source-map'
11+
import { buildImportAnalysisPlugin as nativeBuildImportAnalysisPlugin } from 'rolldown/experimental'
1112
import {
1213
combineSourcemaps,
1314
generateCodeFrame,
@@ -169,15 +170,42 @@ function preload(
169170
/**
170171
* Build only. During serve this is performed as part of ./importAnalysis.
171172
*/
172-
export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
173+
export function buildImportAnalysisPlugin(config: ResolvedConfig): [Plugin] {
173174
const ssr = !!config.build.ssr
174175
const isWorker = config.isWorker
176+
const enableNativePlugin = config.experimental.enableNativePlugin
175177
const insertPreload = !(ssr || !!config.build.lib || isWorker)
176178

177179
const renderBuiltUrl = config.experimental.renderBuiltUrl
178180
const isRelativeBase = config.base === './' || config.base === ''
179181

180-
return {
182+
// TODO: make this environment-specific
183+
const { modulePreload } = config.build // this.environment.config.build
184+
185+
const scriptRel =
186+
modulePreload && modulePreload.polyfill
187+
? `'modulepreload'`
188+
: `/* @__PURE__ */ (${detectScriptRel.toString()})()`
189+
190+
// There are two different cases for the preload list format in __vitePreload
191+
//
192+
// __vitePreload(() => import(asyncChunk), [ ...deps... ])
193+
//
194+
// This is maintained to keep backwards compatibility as some users developed plugins
195+
// using regex over this list to workaround the fact that module preload wasn't
196+
// configurable.
197+
const assetsURL =
198+
renderBuiltUrl || isRelativeBase
199+
? // If `experimental.renderBuiltUrl` is used, the dependencies might be relative to the current chunk.
200+
// If relative base is used, the dependencies are relative to the current chunk.
201+
// The importerUrl is passed as third parameter to __vitePreload in this case
202+
`function(dep, importerUrl) { return new URL(dep, importerUrl).href }`
203+
: // If the base isn't relative, then the deps are relative to the projects `outDir` and the base
204+
// is appended inside __vitePreload too.
205+
`function(dep) { return ${JSON.stringify(config.base)}+dep }`
206+
const preloadCode = `const scriptRel = ${scriptRel};const assetsURL = ${assetsURL};const seen = {};export const ${preloadMethod} = ${preload.toString()}`
207+
208+
const jsPlugin = {
181209
name: 'vite:build-import-analysis',
182210
resolveId(id) {
183211
if (id === preloadHelperId) {
@@ -187,30 +215,6 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
187215

188216
load(id) {
189217
if (id === preloadHelperId) {
190-
const { modulePreload } = this.environment.config.build
191-
192-
const scriptRel =
193-
modulePreload && modulePreload.polyfill
194-
? `'modulepreload'`
195-
: `/* @__PURE__ */ (${detectScriptRel.toString()})()`
196-
197-
// There are two different cases for the preload list format in __vitePreload
198-
//
199-
// __vitePreload(() => import(asyncChunk), [ ...deps... ])
200-
//
201-
// This is maintained to keep backwards compatibility as some users developed plugins
202-
// using regex over this list to workaround the fact that module preload wasn't
203-
// configurable.
204-
const assetsURL =
205-
renderBuiltUrl || isRelativeBase
206-
? // If `experimental.renderBuiltUrl` is used, the dependencies might be relative to the current chunk.
207-
// If relative base is used, the dependencies are relative to the current chunk.
208-
// The importerUrl is passed as third parameter to __vitePreload in this case
209-
`function(dep, importerUrl) { return new URL(dep, importerUrl).href }`
210-
: // If the base isn't relative, then the deps are relative to the projects `outDir` and the base
211-
// is appended inside __vitePreload too.
212-
`function(dep) { return ${JSON.stringify(config.base)}+dep }`
213-
const preloadCode = `const scriptRel = ${scriptRel};const assetsURL = ${assetsURL};const seen = {};export const ${preloadMethod} = ${preload.toString()}`
214218
return { code: preloadCode, moduleSideEffects: false }
215219
}
216220
},
@@ -715,5 +719,23 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
715719
}
716720
}
717721
},
722+
} as Plugin
723+
if (enableNativePlugin) {
724+
delete jsPlugin.transform
725+
delete jsPlugin.resolveId
726+
delete jsPlugin.load
718727
}
728+
return [
729+
jsPlugin,
730+
enableNativePlugin
731+
? nativeBuildImportAnalysisPlugin({
732+
preloadCode: preloadCode,
733+
insertPreload: insertPreload,
734+
/// this field looks redundant, put a dummy value for now
735+
optimizeModulePreloadRelativePaths: false,
736+
renderBuiltUrl: Boolean(renderBuiltUrl),
737+
isRelativeBase: isRelativeBase,
738+
})
739+
: null,
740+
].filter(Boolean) as [Plugin]
719741
}

0 commit comments

Comments
 (0)