Skip to content

Commit db78a58

Browse files
committed
test: run tests with all native plugins
1 parent 38f0c09 commit db78a58

File tree

18 files changed

+236
-44
lines changed

18 files changed

+236
-44
lines changed

docs/guide/rolldown.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,9 @@ export default {
141141

142142
### Enabling Native Plugins
143143

144-
Thanks to Rolldown and Oxc, various internal Vite plugins, such as the alias or resolve plugin, have been converted to Rust. At the time of writing, using these plugins is not enabled by default, as their behavior may differ from the JavaScript versions.
144+
Thanks to Rolldown and Oxc, various internal Vite plugins, such as the alias or resolve plugin, have been converted to Rust. Native plugins are now enabled by default, with the default value set to `'v1'`.
145145

146-
To test them, you can set the `experimental.enableNativePlugin` option to `true` in your Vite config.
146+
If you encounter any issues, you can change the `experimental.enableNativePlugin` option in your Vite config to `'resolver'` or `false`.
147147

148148
### Utilizing Oxc's React refresh transform
149149

packages/vite/src/node/__tests__/plugins/define.spec.ts

Lines changed: 157 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { describe, expect, test } from 'vitest'
2+
import { rolldown } from 'rolldown'
23
import { definePlugin } from '../../plugins/define'
34
import { resolveConfig } from '../../config'
45
import { PartialEnvironment } from '../../baseEnvironment'
@@ -16,17 +17,48 @@ async function createDefinePluginTransform(
1617
const environment = new PartialEnvironment(ssr ? 'ssr' : 'client', config)
1718

1819
return async (code: string) => {
19-
// @ts-expect-error transform.handler should exist
20-
const result = await instance.transform.handler.call(
21-
{ environment },
22-
code,
23-
'foo.ts',
24-
)
25-
return result?.code || result
20+
if (process.env._VITE_TEST_JS_PLUGIN) {
21+
// @ts-expect-error transform.handler should exist
22+
const result = await instance.transform.handler.call(
23+
{ environment },
24+
code,
25+
'foo.ts',
26+
)
27+
return result?.code || result
28+
} else {
29+
const bundler = await rolldown({
30+
input: 'entry.js',
31+
plugins: [
32+
{
33+
name: 'test',
34+
resolveId(id) {
35+
if (id === 'entry.js') {
36+
return '\0' + id
37+
}
38+
},
39+
load(id) {
40+
if (id === '\0entry.js') {
41+
return code
42+
}
43+
},
44+
},
45+
{
46+
name: 'native:define',
47+
options: (definePlugin(config).options! as any).bind({
48+
environment,
49+
}),
50+
},
51+
],
52+
experimental: {
53+
attachDebugInfo: 'none',
54+
},
55+
})
56+
return (await bundler.generate()).output[0].code
57+
}
2658
}
2759
}
2860

29-
describe('definePlugin', () => {
61+
describe.skipIf(!process.env._VITE_TEST_JS_PLUGIN)('definePlugin', () => {
3062
test('replaces custom define', async () => {
3163
const transform = await createDefinePluginTransform({
3264
__APP_VERSION__: JSON.stringify('1.0'),
@@ -146,3 +178,120 @@ describe('definePlugin', () => {
146178
)
147179
})
148180
})
181+
182+
describe.skipIf(process.env._VITE_TEST_JS_PLUGIN)('native definePlugin', () => {
183+
test('replaces custom define', async () => {
184+
const transform = await createDefinePluginTransform({
185+
__APP_VERSION__: JSON.stringify('1.0'),
186+
})
187+
expect(await transform('export const version = __APP_VERSION__;')).toBe(
188+
'const version = "1.0";\n\nexport { version };',
189+
)
190+
expect(await transform('export const version = __APP_VERSION__ ;')).toBe(
191+
'const version = "1.0";\n\nexport { version };',
192+
)
193+
})
194+
195+
test('should not replace if not defined', async () => {
196+
const transform = await createDefinePluginTransform({
197+
__APP_VERSION__: JSON.stringify('1.0'),
198+
})
199+
expect(await transform('export const version = "1.0";')).toBe(
200+
'const version = "1.0";\n\nexport { version };',
201+
)
202+
expect(
203+
await transform('export const version = import.meta.SOMETHING'),
204+
).toBe('const version = import.meta.SOMETHING;\n\nexport { version };')
205+
})
206+
207+
test('replaces import.meta.env.SSR with false', async () => {
208+
const transform = await createDefinePluginTransform()
209+
expect(await transform('export const isSSR = import.meta.env.SSR;')).toBe(
210+
'const isSSR = false;\n\nexport { isSSR };',
211+
)
212+
})
213+
214+
test('preserve import.meta.hot with override', async () => {
215+
// assert that the default behavior is to replace import.meta.hot with undefined
216+
const transform = await createDefinePluginTransform()
217+
expect(await transform('export const hot = import.meta.hot;')).toBe(
218+
'const hot = void 0;\n\nexport { hot };',
219+
)
220+
// assert that we can specify a user define to preserve import.meta.hot
221+
const overrideTransform = await createDefinePluginTransform({
222+
'import.meta.hot': 'import.meta.hot',
223+
})
224+
expect(await overrideTransform('export const hot = import.meta.hot;')).toBe(
225+
'const hot = import.meta.hot;\n\nexport { hot };',
226+
)
227+
})
228+
229+
test('replace import.meta.env.UNKNOWN with undefined', async () => {
230+
const transform = await createDefinePluginTransform()
231+
expect(await transform('export const foo = import.meta.env.UNKNOWN;')).toBe(
232+
'const foo = void 0;\n\nexport { foo };',
233+
)
234+
})
235+
236+
test('leave import.meta.env["UNKNOWN"] to runtime', async () => {
237+
const transform = await createDefinePluginTransform()
238+
expect(
239+
await transform('export const foo = import.meta.env["UNKNOWN"];'),
240+
).toMatch(/const foo = .*\["UNKNOWN"\];\n\nexport \{ foo \};/s)
241+
})
242+
243+
test('preserve import.meta.env.UNKNOWN with override', async () => {
244+
const transform = await createDefinePluginTransform({
245+
'import.meta.env.UNKNOWN': 'import.meta.env.UNKNOWN',
246+
})
247+
expect(await transform('export const foo = import.meta.env.UNKNOWN;')).toBe(
248+
'const foo = import.meta.env.UNKNOWN;\n\nexport { foo };',
249+
)
250+
})
251+
252+
test('replace import.meta.env when it is a invalid json', async () => {
253+
const transform = await createDefinePluginTransform({
254+
'import.meta.env.LEGACY': '__VITE_IS_LEGACY__',
255+
})
256+
257+
expect(
258+
await transform(
259+
'export const isLegacy = import.meta.env.LEGACY;\nimport.meta.env.UNDEFINED && console.log(import.meta.env.UNDEFINED);',
260+
),
261+
).toMatchInlineSnapshot(
262+
`"const isLegacy = __VITE_IS_LEGACY__;\n\nexport { isLegacy };"`,
263+
)
264+
})
265+
266+
test('replace bare import.meta.env', async () => {
267+
const transform = await createDefinePluginTransform()
268+
expect(await transform('export const env = import.meta.env;')).toMatch(
269+
/const env = .*;\n\nexport \{ env \};/s,
270+
)
271+
})
272+
273+
test('already has marker', async () => {
274+
const transform = await createDefinePluginTransform()
275+
expect(
276+
await transform(
277+
'console.log(__vite_import_meta_env__);\nexport const env = import.meta.env;',
278+
),
279+
).toMatch(/console.log\(__vite_import_meta_env__\);\nconst env = .*/)
280+
281+
expect(
282+
await transform(
283+
'console.log(__vite_import_meta_env__, __vite_import_meta_env__1);\n export const env = import.meta.env;',
284+
),
285+
).toMatch(
286+
/console.log\(__vite_import_meta_env__, __vite_import_meta_env__1\);\nconst env = .*/,
287+
)
288+
289+
expect(
290+
await transform(
291+
'console.log(__vite_import_meta_env__);\nexport const env = import.meta.env;\nconsole.log(import.meta.env.UNDEFINED);',
292+
),
293+
).toMatch(
294+
/console.log\(__vite_import_meta_env__\);\nconst env = .*;\nconsole.log\(void 0\);/s,
295+
)
296+
})
297+
})

packages/vite/src/node/build.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,8 @@ export async function resolveBuildPlugins(config: ResolvedConfig): Promise<{
505505
],
506506
post: [
507507
...buildImportAnalysisPlugin(config),
508-
...(config.experimental.enableNativePlugin !== true
508+
...(config.experimental.enableNativePlugin === false ||
509+
config.experimental.enableNativePlugin === 'resolver'
509510
? [
510511
buildOxcPlugin(),
511512
...(config.build.minify === 'esbuild'

packages/vite/src/node/config.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -542,10 +542,13 @@ export interface ExperimentalOptions {
542542
/**
543543
* Enable builtin plugin that written by rust, which is faster than js plugin.
544544
*
545+
* - 'resolver': Enable only the native resolver plugin.
546+
* - 'v1': Enable the first stable set of native plugins (including resolver).
547+
*
545548
* @experimental
546-
* @default 'resolver'
549+
* @default 'v1'
547550
*/
548-
enableNativePlugin?: boolean | 'resolver'
551+
enableNativePlugin?: boolean | 'resolver' | 'v1'
549552
}
550553

551554
export interface LegacyOptions {
@@ -746,7 +749,7 @@ export const configDefaults = Object.freeze({
746749
importGlobRestoreExtension: false,
747750
renderBuiltUrl: undefined,
748751
hmrPartialAccept: false,
749-
enableNativePlugin: process.env._VITE_TEST_JS_PLUGIN ? false : 'resolver',
752+
enableNativePlugin: process.env._VITE_TEST_JS_PLUGIN ? false : 'v1',
750753
},
751754
future: {
752755
removePluginHookHandleHotUpdate: undefined,

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ export function definePlugin(config: ResolvedConfig): Plugin {
115115
return pattern
116116
}
117117

118-
if (config.experimental.enableNativePlugin === true && isBuild) {
118+
if (
119+
isBuild &&
120+
(config.experimental.enableNativePlugin === true ||
121+
config.experimental.enableNativePlugin === 'v1')
122+
) {
119123
return {
120124
name: 'vite:define',
121125
options(option) {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,9 @@ export function dynamicImportVarsPlugin(config: ResolvedConfig): Plugin {
174174
})
175175

176176
if (
177-
config.experimental.enableNativePlugin === true &&
178-
config.command === 'build'
177+
config.command === 'build' &&
178+
(config.experimental.enableNativePlugin === true ||
179+
config.experimental.enableNativePlugin === 'v1')
179180
) {
180181
return perEnvironmentPlugin('native:dynamic-import-vars', (environment) => {
181182
const { include, exclude } =

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,10 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin[] {
749749
},
750750
}
751751

752-
if (config.experimental.enableNativePlugin === true) {
752+
if (
753+
config.experimental.enableNativePlugin === true ||
754+
config.experimental.enableNativePlugin === 'v1'
755+
) {
753756
delete plugin.transform
754757
delete plugin.resolveId
755758
delete plugin.load

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ interface ParsedGeneralImportGlobOptions extends GeneralImportGlobOptions {
4343

4444
export function importGlobPlugin(config: ResolvedConfig): Plugin {
4545
if (
46-
config.experimental.enableNativePlugin === true &&
47-
config.command === 'build'
46+
config.command === 'build' &&
47+
(config.experimental.enableNativePlugin === true ||
48+
config.experimental.enableNativePlugin === 'v1')
4849
) {
4950
return nativeImportGlobPlugin({
5051
root: config.root,

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ export async function resolvePlugins(
4646
? await (await import('../build')).resolveBuildPlugins(config)
4747
: { pre: [], post: [] }
4848
const { modulePreload } = config.build
49-
const enableNativePlugin = config.experimental.enableNativePlugin
49+
const enableNativePlugin =
50+
config.experimental.enableNativePlugin === true ||
51+
config.experimental.enableNativePlugin === 'v1'
5052

5153
return [
5254
!isBuild ? optimizedDepsPlugin() : null,
5355
!isWorker ? watchPackageDataPlugin(config.packageCache) : null,
5456
!isBuild ? preAliasPlugin(config) : null,
55-
enableNativePlugin === true &&
57+
enableNativePlugin &&
5658
isBuild &&
5759
!config.resolve.alias.some((v) => v.customResolver)
5860
? nativeAliasPlugin({
@@ -74,7 +76,7 @@ export async function resolvePlugins(
7476
modulePreload !== false && modulePreload.polyfill
7577
? modulePreloadPolyfillPlugin(config)
7678
: null,
77-
...(enableNativePlugin
79+
...(config.experimental.enableNativePlugin
7880
? oxcResolvePlugin(
7981
{
8082
root: config.root,
@@ -104,7 +106,7 @@ export async function resolvePlugins(
104106
cssPlugin(config),
105107
esbuildBannerFooterCompatPlugin(config),
106108
config.oxc !== false ? oxcPlugin(config) : null,
107-
jsonPlugin(config.json, isBuild, enableNativePlugin === true),
109+
jsonPlugin(config.json, isBuild, enableNativePlugin),
108110
wasmHelperPlugin(config),
109111
webWorkerPlugin(config),
110112
assetPlugin(config),

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ export function manifestPlugin(config: ResolvedConfig): Plugin {
3737
})
3838
if (
3939
config.build.manifest &&
40-
config.experimental.enableNativePlugin === true
40+
(config.experimental.enableNativePlugin === true ||
41+
config.experimental.enableNativePlugin === 'v1')
4142
) {
4243
return perEnvironmentPlugin('native:manifest', (environment) => {
4344
if (!environment.config.build.manifest) return false

0 commit comments

Comments
 (0)