Skip to content

Commit 9fad4d8

Browse files
committed
feat: environment aware native plugins
1 parent bb7988b commit 9fad4d8

File tree

4 files changed

+121
-40
lines changed

4 files changed

+121
-40
lines changed

packages/vite/src/node/build.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ import {
5454
normalizePath,
5555
partialEncodeURIPath,
5656
} from './utils'
57-
import { resolveEnvironmentPlugins } from './plugin'
57+
import {
58+
createBuiltinPluginWithEnvironmentSupport,
59+
resolveEnvironmentPlugins,
60+
} from './plugin'
5861
import { manifestPlugin } from './plugins/manifest'
5962
import type { Logger } from './logger'
6063
import { dataURIPlugin } from './plugins/dataUri'
@@ -511,14 +514,20 @@ export async function resolveBuildPlugins(config: ResolvedConfig): Promise<{
511514
...(!config.isWorker
512515
? [
513516
config.build.manifest && enableNativePlugin
514-
? // TODO: make this environment-specific
515-
nativeManifestPlugin({
516-
root: config.root,
517-
outPath:
518-
config.build.manifest === true
519-
? '.vite/manifest.json'
520-
: config.build.manifest,
521-
})
517+
? createBuiltinPluginWithEnvironmentSupport(
518+
'native:manifest',
519+
(environment) => {
520+
if (!environment.config.build.manifest) return false
521+
522+
return nativeManifestPlugin({
523+
root: environment.config.root,
524+
outPath:
525+
environment.config.build.manifest === true
526+
? '.vite/manifest.json'
527+
: environment.config.build.manifest,
528+
})
529+
},
530+
)
522531
: manifestPlugin(),
523532
ssrManifestPlugin(),
524533
...(enableBuildReport ? [buildReporterPlugin(config)] : []),

packages/vite/src/node/plugin.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,4 +343,38 @@ export function resolveEnvironmentPlugins(environment: Environment): Plugin[] {
343343
(plugin) =>
344344
!plugin.applyToEnvironment || plugin.applyToEnvironment(environment),
345345
)
346+
.map((plugin) =>
347+
plugin.api && 'getBuiltinPlugin' in plugin.api
348+
? plugin.api.getBuiltinPlugin?.(environment)
349+
: plugin,
350+
)
351+
}
352+
353+
export function createBuiltinPluginWithEnvironmentSupport<BP>(
354+
name: string,
355+
plugin: (environment: Environment) => BP | false,
356+
): Plugin<{
357+
getBuiltinPlugin: (environment: Environment) => BP | undefined
358+
}> {
359+
const pluginForEnvironment = new WeakMap<Environment, BP>()
360+
361+
return {
362+
name,
363+
applyToEnvironment(environment) {
364+
if (pluginForEnvironment.has(environment)) {
365+
return true
366+
}
367+
368+
const pluginForEnv = plugin(environment)
369+
if (pluginForEnv) {
370+
pluginForEnvironment.set(environment, pluginForEnv)
371+
}
372+
return !!pluginForEnv
373+
},
374+
api: {
375+
getBuiltinPlugin(environment) {
376+
return pluginForEnvironment.get(environment)
377+
},
378+
},
379+
}
346380
}

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

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import {
1515
isInNodeModules,
1616
numberToPos,
1717
} from '../utils'
18-
import type { Plugin } from '../plugin'
18+
import {
19+
type Plugin,
20+
createBuiltinPluginWithEnvironmentSupport,
21+
} from '../plugin'
1922
import type { ResolvedConfig } from '../config'
2023
import { toOutputFilePathInJS } from '../build'
2124
import { genSourceMapUrl } from '../server/sourcemap'
@@ -168,21 +171,12 @@ function preload(
168171
})
169172
}
170173

171-
/**
172-
* Build only. During serve this is performed as part of ./importAnalysis.
173-
*/
174-
export function buildImportAnalysisPlugin(config: ResolvedConfig): [Plugin] {
175-
const getInsertPreload = (environment: Environment) =>
176-
environment.config.consumer === 'client' &&
177-
!config.isWorker &&
178-
!config.build.lib
179-
180-
const enableNativePlugin = config.experimental.enableNativePlugin
181-
const renderBuiltUrl = config.experimental.renderBuiltUrl
182-
const isRelativeBase = config.base === './' || config.base === ''
183-
184-
// TODO: make this environment-specific
185-
const { modulePreload } = config.build // this.environment.config.build
174+
function getPreloadCode(
175+
environment: Environment,
176+
renderBuiltUrlBoolean: boolean,
177+
isRelativeBase: boolean,
178+
) {
179+
const { modulePreload } = environment.config.build
186180

187181
const scriptRel =
188182
modulePreload && modulePreload.polyfill
@@ -197,15 +191,30 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): [Plugin] {
197191
// using regex over this list to workaround the fact that module preload wasn't
198192
// configurable.
199193
const assetsURL =
200-
renderBuiltUrl || isRelativeBase
194+
renderBuiltUrlBoolean || isRelativeBase
201195
? // If `experimental.renderBuiltUrl` is used, the dependencies might be relative to the current chunk.
202196
// If relative base is used, the dependencies are relative to the current chunk.
203197
// The importerUrl is passed as third parameter to __vitePreload in this case
204198
`function(dep, importerUrl) { return new URL(dep, importerUrl).href }`
205199
: // If the base isn't relative, then the deps are relative to the projects `outDir` and the base
206200
// is appended inside __vitePreload too.
207-
`function(dep) { return ${JSON.stringify(config.base)}+dep }`
201+
`function(dep) { return ${JSON.stringify(environment.config.base)}+dep }`
208202
const preloadCode = `const scriptRel = ${scriptRel};const assetsURL = ${assetsURL};const seen = {};export const ${preloadMethod} = ${preload.toString()}`
203+
return preloadCode
204+
}
205+
206+
/**
207+
* Build only. During serve this is performed as part of ./importAnalysis.
208+
*/
209+
export function buildImportAnalysisPlugin(config: ResolvedConfig): [Plugin] {
210+
const getInsertPreload = (environment: Environment) =>
211+
environment.config.consumer === 'client' &&
212+
!config.isWorker &&
213+
!config.build.lib
214+
215+
const enableNativePlugin = config.experimental.enableNativePlugin
216+
const renderBuiltUrl = config.experimental.renderBuiltUrl
217+
const isRelativeBase = config.base === './' || config.base === ''
209218

210219
const jsPlugin = {
211220
name: 'vite:build-import-analysis',
@@ -217,6 +226,11 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): [Plugin] {
217226

218227
load(id) {
219228
if (id === preloadHelperId) {
229+
const preloadCode = getPreloadCode(
230+
this.environment,
231+
!!renderBuiltUrl,
232+
isRelativeBase,
233+
)
220234
return { code: preloadCode, moduleSideEffects: false }
221235
}
222236
},
@@ -731,15 +745,24 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): [Plugin] {
731745
return [
732746
jsPlugin,
733747
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-
})
748+
? createBuiltinPluginWithEnvironmentSupport(
749+
'native:import-analysis-build',
750+
(environment) => {
751+
const preloadCode = getPreloadCode(
752+
environment,
753+
!!renderBuiltUrl,
754+
isRelativeBase,
755+
)
756+
return nativeBuildImportAnalysisPlugin({
757+
preloadCode,
758+
insertPreload: getInsertPreload(environment),
759+
// this field looks redundant, put a dummy value for now
760+
optimizeModulePreloadRelativePaths: false,
761+
renderBuiltUrl: !!renderBuiltUrl,
762+
isRelativeBase,
763+
})
764+
},
765+
)
743766
: null,
744767
].filter(Boolean) as [Plugin]
745768
}

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ import {
1212
} from 'rolldown/experimental'
1313
import type { PluginHookUtils, ResolvedConfig } from '../config'
1414
import { isDepOptimizationDisabled } from '../optimizer'
15-
import type { HookHandler, Plugin, PluginWithRequiredHook } from '../plugin'
15+
import {
16+
type HookHandler,
17+
type Plugin,
18+
type PluginWithRequiredHook,
19+
createBuiltinPluginWithEnvironmentSupport,
20+
} from '../plugin'
1621
import { watchPackageDataPlugin } from '../packages'
1722
import { jsonPlugin } from './json'
1823
import { filteredResolvePlugin, resolvePlugin } from './resolve'
@@ -76,9 +81,19 @@ export async function resolvePlugins(
7681

7782
modulePreload !== false && modulePreload.polyfill
7883
? enableNativePlugin
79-
? nativeModulePreloadPolyfillPlugin({
80-
skip: Boolean(config.command !== 'build' || config.build.ssr),
81-
})
84+
? createBuiltinPluginWithEnvironmentSupport(
85+
'native:modulepreload-polyfill',
86+
(environment) => {
87+
if (
88+
config.command !== 'build' ||
89+
environment.config.consumer !== 'client'
90+
)
91+
return false
92+
return nativeModulePreloadPolyfillPlugin({
93+
skip: false,
94+
})
95+
},
96+
)
8297
: modulePreloadPolyfillPlugin(config)
8398
: null,
8499
enableNativePlugin

0 commit comments

Comments
 (0)