Skip to content

Commit

Permalink
feat: environment aware native plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
sapphi-red committed Oct 15, 2024
1 parent 504ad37 commit 727e891
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 40 deletions.
27 changes: 18 additions & 9 deletions packages/vite/src/node/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ import {
partialEncodeURIPath,
requireResolveFromRootWithFallback,
} from './utils'
import { resolveEnvironmentPlugins } from './plugin'
import {
createBuiltinPluginWithEnvironmentSupport,
resolveEnvironmentPlugins,
} from './plugin'
import { manifestPlugin } from './plugins/manifest'
import type { Logger } from './logger'
import { dataURIPlugin } from './plugins/dataUri'
Expand Down Expand Up @@ -499,14 +502,20 @@ export async function resolveBuildPlugins(config: ResolvedConfig): Promise<{
...(!config.isWorker
? [
config.build.manifest && enableNativePlugin
? // TODO: make this environment-specific
nativeManifestPlugin({
root: config.root,
outPath:
config.build.manifest === true
? '.vite/manifest.json'
: config.build.manifest,
})
? createBuiltinPluginWithEnvironmentSupport(
'native:manifest',
(environment) => {
if (!environment.config.build.manifest) return false

return nativeManifestPlugin({
root: environment.config.root,
outPath:
environment.config.build.manifest === true
? '.vite/manifest.json'
: environment.config.build.manifest,
})
},
)
: manifestPlugin(),
ssrManifestPlugin(),
...(enableBuildReport ? [buildReporterPlugin(config)] : []),
Expand Down
34 changes: 34 additions & 0 deletions packages/vite/src/node/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,4 +343,38 @@ export function resolveEnvironmentPlugins(environment: Environment): Plugin[] {
(plugin) =>
!plugin.applyToEnvironment || plugin.applyToEnvironment(environment),
)
.map((plugin) =>
plugin.api && 'getBuiltinPlugin' in plugin.api
? plugin.api.getBuiltinPlugin?.(environment)
: plugin,
)
}

export function createBuiltinPluginWithEnvironmentSupport<BP>(
name: string,
plugin: (environment: Environment) => BP | false,
): Plugin<{
getBuiltinPlugin: (environment: Environment) => BP | undefined
}> {
const pluginForEnvironment = new WeakMap<Environment, BP>()

return {
name,
applyToEnvironment(environment) {
if (pluginForEnvironment.has(environment)) {
return true
}

const pluginForEnv = plugin(environment)
if (pluginForEnv) {
pluginForEnvironment.set(environment, pluginForEnv)
}
return !!pluginForEnv
},
api: {
getBuiltinPlugin(environment) {
return pluginForEnvironment.get(environment)
},
},
}
}
77 changes: 50 additions & 27 deletions packages/vite/src/node/plugins/importAnalysisBuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import {
isInNodeModules,
numberToPos,
} from '../utils'
import type { Plugin } from '../plugin'
import {
type Plugin,
createBuiltinPluginWithEnvironmentSupport,
} from '../plugin'
import type { ResolvedConfig } from '../config'
import { toOutputFilePathInJS } from '../build'
import { genSourceMapUrl } from '../server/sourcemap'
Expand Down Expand Up @@ -168,21 +171,12 @@ function preload(
})
}

/**
* Build only. During serve this is performed as part of ./importAnalysis.
*/
export function buildImportAnalysisPlugin(config: ResolvedConfig): [Plugin] {
const getInsertPreload = (environment: Environment) =>
environment.config.consumer === 'client' &&
!config.isWorker &&
!config.build.lib

const enableNativePlugin = config.experimental.enableNativePlugin
const renderBuiltUrl = config.experimental.renderBuiltUrl
const isRelativeBase = config.base === './' || config.base === ''

// TODO: make this environment-specific
const { modulePreload } = config.build // this.environment.config.build
function getPreloadCode(
environment: Environment,
renderBuiltUrlBoolean: boolean,
isRelativeBase: boolean,
) {
const { modulePreload } = environment.config.build

const scriptRel =
modulePreload && modulePreload.polyfill
Expand All @@ -197,15 +191,30 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): [Plugin] {
// using regex over this list to workaround the fact that module preload wasn't
// configurable.
const assetsURL =
renderBuiltUrl || isRelativeBase
renderBuiltUrlBoolean || isRelativeBase
? // If `experimental.renderBuiltUrl` is used, the dependencies might be relative to the current chunk.
// If relative base is used, the dependencies are relative to the current chunk.
// The importerUrl is passed as third parameter to __vitePreload in this case
`function(dep, importerUrl) { return new URL(dep, importerUrl).href }`
: // If the base isn't relative, then the deps are relative to the projects `outDir` and the base
// is appended inside __vitePreload too.
`function(dep) { return ${JSON.stringify(config.base)}+dep }`
`function(dep) { return ${JSON.stringify(environment.config.base)}+dep }`
const preloadCode = `const scriptRel = ${scriptRel};const assetsURL = ${assetsURL};const seen = {};export const ${preloadMethod} = ${preload.toString()}`
return preloadCode
}

/**
* Build only. During serve this is performed as part of ./importAnalysis.
*/
export function buildImportAnalysisPlugin(config: ResolvedConfig): [Plugin] {
const getInsertPreload = (environment: Environment) =>
environment.config.consumer === 'client' &&
!config.isWorker &&
!config.build.lib

const enableNativePlugin = config.experimental.enableNativePlugin
const renderBuiltUrl = config.experimental.renderBuiltUrl
const isRelativeBase = config.base === './' || config.base === ''

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

load(id) {
if (id === preloadHelperId) {
const preloadCode = getPreloadCode(
this.environment,
!!renderBuiltUrl,
isRelativeBase,
)
return { code: preloadCode, moduleSideEffects: false }
}
},
Expand Down Expand Up @@ -731,15 +745,24 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): [Plugin] {
return [
jsPlugin,
enableNativePlugin
? nativeBuildImportAnalysisPlugin({
preloadCode: preloadCode,
// @ts-expect-error make this environment-specific
insertPreload: getInsertPreload({ config: { consumer: 'client' } }),
/// this field looks redundant, put a dummy value for now
optimizeModulePreloadRelativePaths: false,
renderBuiltUrl: Boolean(renderBuiltUrl),
isRelativeBase: isRelativeBase,
})
? createBuiltinPluginWithEnvironmentSupport(
'native:import-analysis-build',
(environment) => {
const preloadCode = getPreloadCode(
environment,
!!renderBuiltUrl,
isRelativeBase,
)
return nativeBuildImportAnalysisPlugin({
preloadCode,
insertPreload: getInsertPreload(environment),
// this field looks redundant, put a dummy value for now
optimizeModulePreloadRelativePaths: false,
renderBuiltUrl: !!renderBuiltUrl,
isRelativeBase,
})
},
)
: null,
].filter(Boolean) as [Plugin]
}
23 changes: 19 additions & 4 deletions packages/vite/src/node/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import {
} from 'rolldown/experimental'
import type { PluginHookUtils, ResolvedConfig } from '../config'
import { isDepOptimizationDisabled } from '../optimizer'
import type { HookHandler, Plugin, PluginWithRequiredHook } from '../plugin'
import {
type HookHandler,
type Plugin,
type PluginWithRequiredHook,
createBuiltinPluginWithEnvironmentSupport,
} from '../plugin'
import { watchPackageDataPlugin } from '../packages'
import { getFsUtils } from '../fsUtils'
import { jsonPlugin } from './json'
Expand Down Expand Up @@ -77,9 +82,19 @@ export async function resolvePlugins(

modulePreload !== false && modulePreload.polyfill
? enableNativePlugin
? nativeModulePreloadPolyfillPlugin({
skip: Boolean(config.command !== 'build' || config.build.ssr),
})
? createBuiltinPluginWithEnvironmentSupport(
'native:modulepreload-polyfill',
(environment) => {
if (
config.command !== 'build' ||
environment.config.consumer !== 'client'
)
return false
return nativeModulePreloadPolyfillPlugin({
skip: false,
})
},
)
: modulePreloadPolyfillPlugin(config)
: null,
enableNativePlugin
Expand Down

0 comments on commit 727e891

Please sign in to comment.