Skip to content

Commit 09863d2

Browse files
authored
fix(unplugin-vue-i18n): preserve vite:json ObjectHook shape for Vite 8 compatibility (#554)
* fix(unplugin-vue-i18n): preserve vite:json ObjectHook shape for Vite 8 compatibility * chore: fix knip errors * fix(unplugin-vue-i18n): detect vite:json from config.plugins instead of import(vite) * fix
1 parent 7b39a15 commit 09863d2

4 files changed

Lines changed: 53 additions & 74 deletions

File tree

knip.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ export default {
55
'scripts/playwright.ts' // jiti
66
],
77
ignore: ['**/fixtures/**', '.unmaintained/**'],
8-
ignoreDependencies: ['ts-loader', 'lint-staged']
8+
ignoreDependencies: ['ts-loader', 'lint-staged'],
9+
exclude: ['optionalPeerDependencies']
910
} satisfies KnipConfig

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
},
4646
"onlyBuiltDependencies": [
4747
"esbuild",
48-
"oxc-resolver"
48+
"oxc-resolver",
49+
"unrs-resolver"
4950
]
5051
},
5152
"license": "MIT",

packages/unplugin-vue-i18n/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@
1111
},
1212
"peerDependencies": {
1313
"petite-vue-i18n": "*",
14+
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
1415
"vue": "^3.2.25",
1516
"vue-i18n": "*"
1617
},
1718
"peerDependenciesMeta": {
1819
"petite-vue-i18n": {
1920
"optional": true
2021
},
22+
"vite": {
23+
"optional": true
24+
},
2125
"vue-i18n": {
2226
"optional": true
2327
}

packages/unplugin-vue-i18n/src/core/resource.ts

Lines changed: 45 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ import type { ResolvedOptions } from '../core/options'
2121
import type { PluginOptions } from '../types'
2222
import type { VueQuery } from '../vue'
2323

24-
type ViteCompaibleModule = {
25-
rolldownVersion?: boolean
26-
}
27-
2824
const INTLIFY_BUNDLE_IMPORT_ID = '@intlify/unplugin-vue-i18n/messages'
2925
const VIRTUAL_PREFIX = '\0'
3026
const RE_INTLIFY_BUNDLE_IMPORT_ID = new RegExp(`^${INTLIFY_BUNDLE_IMPORT_ID}$`)
@@ -59,20 +55,6 @@ export function resourcePlugin(
5955
meta: UnpluginContextMeta,
6056
collector?: import('./collector').UsedKeysCollector | null
6157
): UnpluginOptions {
62-
let viteModule: ViteCompaibleModule | null = null
63-
async function getViteModule() {
64-
if (viteModule != null) {
65-
return viteModule
66-
}
67-
try {
68-
viteModule = (await import('vite')) as unknown as ViteCompaibleModule
69-
} catch (e) {
70-
error(`vite not found, please install vite.`, (e as Error).message)
71-
throw e
72-
}
73-
return viteModule
74-
}
75-
7658
function resolveIncludeExclude() {
7759
const customBlockInclude =
7860
meta.framework === 'vite' ? RE_SFC_I18N_CUSTOM_BLOCK : RE_SFC_I18N_WEBPACK_CUSTOM_BLOCK
@@ -99,15 +81,12 @@ export function resourcePlugin(
9981
if (meta.framework == 'webpack') {
10082
debug('Using filter for webpack')
10183
_filter = createFilter(...resolveIncludeExclude())
84+
} else if (hasViteJsonPlugin) {
85+
debug('Using filter for rollup-vite')
86+
_filter = createFilter(...resolveIncludeExcludeForLegacy())
10287
} else {
103-
const viteModule = await getViteModule()
104-
if (viteModule.rolldownVersion) {
105-
debug('Using filter for rolldown-vite')
106-
_filter = createFilter(...resolveIncludeExclude())
107-
} else {
108-
debug('Using filter for rollup-vite')
109-
_filter = createFilter(...resolveIncludeExcludeForLegacy())
110-
}
88+
debug('Using filter for rolldown-vite')
89+
_filter = createFilter(...resolveIncludeExclude())
11190
}
11291

11392
return _filter
@@ -119,6 +98,7 @@ export function resourcePlugin(
11998

12099
let isProduction = false
121100
let sourceMap = false
101+
let hasViteJsonPlugin = false
122102
const vueI18nAliasName = module
123103
debug(`vue-i18n alias name: ${vueI18nAliasName}`)
124104

@@ -179,61 +159,54 @@ export function resourcePlugin(
179159
sourceMap = config.command === 'build' ? !!config.build.sourcemap : false
180160
debug(`configResolved: isProduction = ${isProduction}, sourceMap = ${sourceMap}`)
181161

182-
// Check if we're using rolldown-vite
183-
const isRolldownVite = !!(await getViteModule()).rolldownVersion
184-
debug(`Using ${isRolldownVite ? 'rolldown-vite' : 'vite'} for the build`)
185-
186162
/**
187163
* NOTE(kazupon):
188-
* For the native rolldown plugin, we need to change to another solution from the current workaround.
189-
* Currently, the rolldown team and vite team are discussing this issue.
190-
* https://github.com/vitejs/rolldown-vite/issues/120
164+
* Override `vite:json` plugin transform to prevent it from processing
165+
* JSON files that unplugin-vue-i18n has already compiled.
166+
*
167+
* We detect the builder by checking whether `vite:json` exists in
168+
* `config.plugins` — rolldown-based Vite (v8+) uses
169+
* `builtin:vite-json` instead, so `getVitePlugin` returns null and
170+
* this block is naturally skipped. This is more reliable than
171+
* `import('vite').rolldownVersion` which can resolve to the wrong
172+
* copy in multi-vite setups (e.g. Nuxt 4 + UnoCSS).
173+
* ref: https://github.com/intlify/bundle-tools/issues/553
191174
*/
192-
193-
// json transform handling for normal Vite (not rolldown-vite)
194-
if (!isRolldownVite) {
195-
const jsonPlugin = getVitePlugin(config, 'vite:json')
196-
if (jsonPlugin) {
197-
// saving `vite:json` plugin instance
198-
const orgTransform =
199-
'handler' in jsonPlugin.transform!
200-
? jsonPlugin.transform!.handler
201-
: jsonPlugin.transform!
202-
203-
// override json transform
204-
async function overrideJson(code: string, id: string) {
205-
const filter = await getFilter()
206-
if (!/\.json$/.test(id) || filter(id)) {
207-
return
208-
}
209-
210-
/**
211-
* NOTE(kazupon):
212-
* `vite:json` plugin will be handled if the query generated from the result of parse SFC
213-
* with `vite:vue` plugin contains json as follows.
214-
* e.g src/components/HelloI18n.vue?vue&type=i18n&index=1&lang.json
215-
*
216-
* To avoid this, return the result that has already been processed (`enforce: 'pre'`) in the wrapped json plugin.
217-
*/
218-
const { query } = parseVueRequest(id)
219-
if (query.vue) {
220-
return
221-
}
222-
223-
debug('org json plugin')
224-
// @ts-expect-error
225-
return orgTransform.apply(this, [code, id])
175+
const jsonPlugin = getVitePlugin(config, 'vite:json')
176+
hasViteJsonPlugin = !!jsonPlugin
177+
if (jsonPlugin && jsonPlugin.transform) {
178+
const transform = jsonPlugin.transform
179+
const isObjectHook = typeof transform !== 'function' && 'handler' in transform
180+
const orgTransform = isObjectHook ? transform.handler : transform
181+
182+
async function overrideJson(this: unknown, code: string, id: string) {
183+
const filter = await getFilter()
184+
if (!/\.json$/.test(id) || filter(id)) {
185+
return
226186
}
227187

228188
/**
229189
* NOTE(kazupon):
230-
* We need to override the transform function of the `vite:json` plugin for `transform` and `transform.handler`.
231-
* ref: https://github.com/vitejs/vite/pull/19878/files#diff-2cfbd4f4d8c32727cd8e1a561cffbde0b384a3ce0789340440e144f9d64c10f6R1086-R1088
190+
* `vite:json` plugin will be handled if the query generated from the result of parse SFC
191+
* with `vite:vue` plugin contains json as follows.
192+
* e.g src/components/HelloI18n.vue?vue&type=i18n&index=1&lang.json
193+
*
194+
* To avoid this, return the result that has already been processed (`enforce: 'pre'`) in the wrapped json plugin.
232195
*/
233-
jsonPlugin.transform = overrideJson
234-
if ('handler' in jsonPlugin.transform!) {
235-
jsonPlugin.transform.handler = overrideJson
196+
const { query } = parseVueRequest(id)
197+
if (query.vue) {
198+
return
236199
}
200+
201+
debug('org json plugin')
202+
// @ts-expect-error
203+
return orgTransform.apply(this, [code, id])
204+
}
205+
206+
if (isObjectHook) {
207+
transform.handler = overrideJson as typeof transform.handler
208+
} else {
209+
jsonPlugin.transform = overrideJson as typeof jsonPlugin.transform
237210
}
238211
}
239212
},

0 commit comments

Comments
 (0)