Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"picocolors": "^1.1.1",
"playwright-chromium": "^1.57.0",
"prettier": "3.7.3",
"rolldown": "1.0.0-beta.53",
"rolldown": "https://pkg.pr.new/rolldown@127a02b",
"rollup": "^4.43.0",
"simple-git-hooks": "^2.13.1",
"tsx": "^4.21.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
"lightningcss": "^1.30.2",
"picomatch": "^4.0.3",
"postcss": "^8.5.6",
"rolldown": "1.0.0-beta.53",
"rolldown": "https://pkg.pr.new/rolldown@127a02b",
"tinyglobby": "^0.2.15"
},
"optionalDependencies": {
Expand Down
7 changes: 4 additions & 3 deletions packages/vite/src/node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ export interface ExperimentalOptions {
*
* - 'resolver' (deprecated, will be removed in v8 stable): Enable only the native resolver plugin.
* - 'v1' (will be deprecated, will be removed in v8 stable): Enable the first stable set of native plugins (including resolver).
* - true: Enable all native plugins (currently an alias of 'v1', it will map to a newer one in the future versions).
* - true: Enable all native plugins (including newly added ones beyond 'v1').
*
* @experimental
* @default 'v1'
Expand Down Expand Up @@ -768,7 +768,7 @@ const configDefaults = Object.freeze({
importGlobRestoreExtension: false,
renderBuiltUrl: undefined,
hmrPartialAccept: false,
enableNativePlugin: process.env._VITE_TEST_JS_PLUGIN ? false : 'v1',
enableNativePlugin: process.env._VITE_TEST_JS_PLUGIN ? false : true,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It needs to be reverted before merging.

},
future: {
removePluginHookHandleHotUpdate: undefined,
Expand Down Expand Up @@ -2060,8 +2060,9 @@ function resolveNativePluginEnabledLevel(
case 'resolver':
return 0
case 'v1':
case true:
return 1
case true:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
case true:
case 'v2':
case true:

We should also update the jsdoc of enableNativePlugin option.

Copy link
Member Author

@shulaoda shulaoda Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm considering not adding the v2 option since the v2 implementation is still experimental and not fully stable. My current idea is to treat enableNativePlugin: true as enabling v2, while keeping v1 as the default behavior. 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think? @sapphi-red

return 2
case false:
return -1
default:
Expand Down
20 changes: 19 additions & 1 deletion packages/vite/src/node/plugins/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import path from 'node:path'
import fsp from 'node:fs/promises'
import { Buffer } from 'node:buffer'
import * as mrmime from 'mrmime'
import { viteAssetPlugin as nativeAssetPlugin } from 'rolldown/experimental'
import type {
NormalizedOutputOptions,
PluginContext,
Expand All @@ -15,7 +16,7 @@ import {
createToImportMetaURLBasedRelativeRuntime,
toOutputFilePathInJS,
} from '../build'
import type { Plugin } from '../plugin'
import { type Plugin, perEnvironmentPlugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import { checkPublicFile } from '../publicDir'
import {
Expand Down Expand Up @@ -148,6 +149,23 @@ export function renderAssetUrlInJS(
* Also supports loading plain strings with import text from './foo.txt?raw'
*/
export function assetPlugin(config: ResolvedConfig): Plugin {
if (config.command === 'build' && config.nativePluginEnabledLevel >= 2) {
return perEnvironmentPlugin('native:asset', (env) => {
return nativeAssetPlugin({
root: env.config.root,
isLib: !!env.config.build.lib,
isSsr: !!env.config.build.ssr,
isWorker: env.config.isWorker,
urlBase: env.config.base,
publicDir: env.config.publicDir,
decodedBase: env.config.decodedBase,
isSkipAssets: !env.config.build.emitAssets,
assetInlineLimit: env.config.build.assetsInlineLimit,
assetsInclude: env.config.rawAssetsInclude,
})
})
}

registerCustomMime()

return {
Expand Down
27 changes: 26 additions & 1 deletion packages/vite/src/node/plugins/assetImportMetaUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import path from 'node:path'
import MagicString from 'magic-string'
import { stripLiteral } from 'strip-literal'
import { exactRegex } from '@rolldown/pluginutils'
import type { Plugin } from '../plugin'
import { viteAssetImportMetaUrlPlugin } from 'rolldown/experimental'
import { type Plugin, perEnvironmentPlugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import {
injectQuery,
Expand Down Expand Up @@ -44,6 +45,30 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
asSrc: true,
}

if (config.command === 'build' && config.nativePluginEnabledLevel >= 2) {
return perEnvironmentPlugin('vite:native-asset-import-meta-url', (env) => {
if (env.config.consumer === 'client') {
return viteAssetImportMetaUrlPlugin({
root: env.config.root,
isLib: !!env.config.build.lib,
publicDir: env.config.publicDir,
clientEntry: CLIENT_ENTRY,
assetInlineLimit: env.config.build.assetsInlineLimit,
tryFsResolve: (file) => tryFsResolve(file, fsResolveOptions),
assetResolver: (url, importer) => {
assetResolver ??= createBackCompatIdResolver(env.config, {
extensions: [],
mainFields: [],
tryIndex: false,
preferRelative: true,
})
return assetResolver(env, url, importer)
},
})
}
})
}

return {
name: 'vite:asset-import-meta-url',

Expand Down
83 changes: 82 additions & 1 deletion packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import type {
TransformAttributeResult as LightningCssTransformAttributeResult,
TransformResult as LightningCssTransformResult,
} from 'lightningcss'
import { viteCSSPlugin, viteCSSPostPlugin } from 'rolldown/experimental'
import type { LightningCSSOptions } from '#types/internal/lightningcssOptions'
import type {
LessPreprocessorBaseOptions,
Expand Down Expand Up @@ -89,7 +90,7 @@ import type { ResolveIdFn } from '../idResolver'
import { PartialEnvironment } from '../baseEnvironment'
import type { TransformPluginContext } from '../server/pluginContainer'
import { searchForWorkspaceRoot } from '../server/searchRoot'
import { type DevEnvironment } from '..'
import { type DevEnvironment, perEnvironmentPlugin } from '..'
import type { PackageCache } from '../packages'
import { findNearestMainPackageData } from '../packages'
import { nodeResolveWithVite } from '../nodeResolve'
Expand Down Expand Up @@ -311,6 +312,49 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
})
}

if (isBuild && config.nativePluginEnabledLevel >= 2) {
return perEnvironmentPlugin('vite:native-css', (env) => {
return [
{
name: 'vite:css-compat',
buildStart() {
preprocessorWorkerController = createPreprocessorWorkerController(
normalizeMaxWorkers(config.css.preprocessorMaxWorkers),
)
preprocessorWorkerControllerCache.set(
config,
preprocessorWorkerController,
)
},

buildEnd() {
preprocessorWorkerController?.close()
},
},
viteCSSPlugin({
root: env.config.root,
isLib: !!env.config.build.lib,
publicDir: env.config.publicDir,
async compileCSS(url, importer, resolver) {
return compileCSS(
env,
url,
importer,
preprocessorWorkerController!,
(url, importer) => {
return resolver.call(url, importer)
},
)
},
resolveUrl(url, importer) {
return idResolver(env, url, importer)
},
assetInlineLimit: env.config.build.assetsInlineLimit,
}),
]
})
}

return {
name: 'vite:css',

Expand Down Expand Up @@ -506,6 +550,43 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
return cssBundleName
}

if (config.command === 'build' && config.nativePluginEnabledLevel >= 2) {
return perEnvironmentPlugin('native:css-post', (env) => {
let libCssFilename: string | undefined
if (env.config.build.lib) {
const libOptions = env.config.build.lib
if (typeof libOptions.cssFileName === 'string') {
libCssFilename = `${libOptions.cssFileName}.css`
} else if (typeof libOptions.fileName === 'string') {
libCssFilename = `${libOptions.fileName}.css`
}
}
return [
viteCSSPostPlugin({
root: env.config.root,
isLib: !!env.config.build.lib,
isSsr: !!env.config.build.ssr,
isWorker: env.config.isWorker,
isClient: env.config.consumer === 'client',
cssCodeSplit: env.config.build.cssCodeSplit,
sourcemap: !!env.config.build.sourcemap,
assetsDir: env.config.build.assetsDir,
urlBase: env.config.base,
decodedBase: env.config.decodedBase,
libCssFilename,
cssMinify: env.config.build.cssMinify
? async (content, inline) => {
return await minifyCSS(content, env.config, inline)
}
: undefined,
renderBuiltUrl: env.config.experimental.renderBuiltUrl,
isOutputOptionsForLegacyChunks:
env.config.isOutputOptionsForLegacyChunks,
}),
]
})
}

return {
name: 'vite:css-post',

Expand Down
6 changes: 6 additions & 0 deletions packages/vite/src/node/plugins/dynamicImportVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ export function dynamicImportVarsPlugin(config: ResolvedConfig): Plugin {
resolver(id, importer) {
return resolve(environment, id, importer)
},
isV2:
config.nativePluginEnabledLevel >= 2
? {
sourcemap: !!environment.config.build.sourcemap,
}
: undefined,
})
})
}
Expand Down
45 changes: 44 additions & 1 deletion packages/vite/src/node/plugins/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@ import type {
} from 'parse5'
import { stripLiteral } from 'strip-literal'
import escapeHtml from 'escape-html'
import type { MinimalPluginContextWithoutEnvironment, Plugin } from '../plugin'
import {
viteHtmlInlineProxyPlugin as nativeHtmlInlineProxyPlugin,
viteHtmlPlugin,
} from 'rolldown/experimental'
import {
type MinimalPluginContextWithoutEnvironment,
type Plugin,
perEnvironmentPlugin,
} from '../plugin'
import type { ViteDevServer } from '../server'
import {
decodeURIIfPossible,
Expand All @@ -41,6 +49,7 @@ import { cleanUrl } from '../../shared/utils'
import { perEnvironmentState } from '../environment'
import { getNodeAssetAttributes } from '../assetSource'
import type { Logger } from '../logger'
import { VERSION } from '../constants'
import {
assetUrlRE,
getPublicAssetFilename,
Expand Down Expand Up @@ -101,6 +110,12 @@ export const htmlProxyMap: WeakMap<
export const htmlProxyResult: Map<string, string> = new Map()

export function htmlInlineProxyPlugin(config: ResolvedConfig): Plugin {
if (config.command === 'build' && config.nativePluginEnabledLevel >= 2) {
return nativeHtmlInlineProxyPlugin({
root: config.root,
})
}

// Should do this when `constructor` rather than when `buildStart`,
// `buildStart` will be triggered multiple times then the cached result will be emptied.
// https://github.com/vitejs/vite/issues/6372
Expand Down Expand Up @@ -366,6 +381,34 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
// Same reason with `htmlInlineProxyPlugin`
isAsyncScriptMap.set(config, new Map())

if (config.command === 'build' && config.nativePluginEnabledLevel >= 2) {
return perEnvironmentPlugin('native:vite-html', (env) => {
return viteHtmlPlugin({
root: env.config.root,
isLib: !!env.config.build.lib,
isSsr: !!env.config.build.ssr,
urlBase: env.config.base,
publicDir: env.config.publicDir,
decodedBase: env.config.decodedBase,
modulePreload: env.config.build.modulePreload,
cssCodeSplit: env.config.build.cssCodeSplit,
assetInlineLimit: env.config.build.assetsInlineLimit,
preHooks,
normalHooks,
postHooks,
async applyHtmlTransforms(html, hooks, pluginContext, ctx) {
pluginContext.meta.viteVersion = VERSION
return applyHtmlTransforms(
html,
hooks as IndexHtmlTransformHook[],
pluginContext,
ctx,
)
},
})
})
}

return {
name: 'vite:build-html',

Expand Down
27 changes: 27 additions & 0 deletions packages/vite/src/node/plugins/importAnalysisBuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,33 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin[] {
},
}

if (config.nativePluginEnabledLevel >= 2) {
return [
perEnvironmentPlugin('native:import-analysis-build', (env) => {
const preloadCode = getPreloadCode(
env,
!!renderBuiltUrl,
isRelativeBase,
)
return nativeBuildImportAnalysisPlugin({
preloadCode,
insertPreload: getInsertPreload(env),
// this field looks redundant, put a dummy value for now
optimizeModulePreloadRelativePaths: false,
renderBuiltUrl: !!renderBuiltUrl,
isRelativeBase,
v2: {
isSsr: !!env.config.build.ssr,
urlBase: env.config.base,
decodedBase: env.config.decodedBase,
modulePreload: env.config.build.modulePreload,
renderBuiltUrl: env.config.experimental.renderBuiltUrl,
},
})
}),
]
}

if (config.nativePluginEnabledLevel >= 1) {
delete plugin.transform
delete plugin.resolveId
Expand Down
6 changes: 6 additions & 0 deletions packages/vite/src/node/plugins/importMetaGlob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ export function importGlobPlugin(config: ResolvedConfig): Plugin {
return nativeImportGlobPlugin({
root: config.root,
restoreQueryExtension: config.experimental.importGlobRestoreExtension,
isV2:
config.nativePluginEnabledLevel >= 2
? {
sourcemap: !!config.build.sourcemap,
}
: undefined,
})
}

Expand Down
Loading
Loading