Skip to content

Commit b9e008c

Browse files
authoredMar 21, 2025··
fix: transform ts locale files with esbuild (#3428)
* fix: transform ts locale files including their imports using `esbuild` * test: add ts locale file with type annotation
1 parent 258b179 commit b9e008c

File tree

6 files changed

+138
-60
lines changed

6 files changed

+138
-60
lines changed
 

‎build.config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export default defineBuildConfig({
77
'node:url',
88
'webpack',
99
'@rspack/core',
10+
'oxc-parser',
1011
'@babel/parser',
1112
'unplugin-vue-router',
1213
'unplugin-vue-router/options'

‎package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,13 @@
108108
"@vue/compiler-sfc": "^3.5.13",
109109
"debug": "^4.3.5",
110110
"defu": "^6.1.4",
111+
"esbuild": "^0.25.1",
111112
"estree-walker": "^3.0.3",
112113
"is-https": "^4.0.0",
113114
"knitwork": "^1.2.0",
114115
"magic-string": "^0.30.17",
115116
"mlly": "^1.7.4",
116-
"oxc-parser": "^0.53.0",
117+
"oxc-parser": "^0.61.0",
117118
"pathe": "^2.0.3",
118119
"ufo": "^1.5.4",
119120
"unplugin": "^2.2.1",

‎pnpm-lock.yaml

+98-58
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default defineI18nLocale(
2+
() =>
3+
({
4+
'server-key': 'Hello!'
5+
}) as Record<string, string> // types should be stripped during transformation
6+
)

‎specs/fixtures/layers/layer-server/nuxt.config.ts

+6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ export default defineNuxtConfig({
1818
language: 'ja-JP',
1919
file: 'ja.yaml',
2020
name: 'Japanese'
21+
},
22+
{
23+
code: 'nl',
24+
language: 'nl-NL',
25+
file: 'nl.ts',
26+
name: 'Nederlands'
2127
}
2228
]
2329
}

‎src/transform/resource.ts

+25-1
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,22 @@ import {
88
NUXT_I18N_COMPOSABLE_DEFINE_CONFIG,
99
NUXT_I18N_VIRTUAL_PREFIX
1010
} from '../constants'
11+
import { resolve, dirname } from 'pathe'
12+
import { parseSync } from '../utils/parse'
13+
import { resolvePath, tryUseNuxt } from '@nuxt/kit'
14+
import { transform as esbuildTransform } from 'esbuild'
15+
import type { SameShape, TransformOptions, TransformResult } from 'esbuild'
1116

1217
import type { BundlerPluginOptions } from './utils'
1318
import type { I18nNuxtContext } from '../context'
1419

20+
async function transform<T extends TransformOptions>(
21+
input: string | Uint8Array,
22+
options?: SameShape<TransformOptions, T>
23+
): Promise<TransformResult<T>> {
24+
return await esbuildTransform(input, { ...tryUseNuxt()?.options.esbuild.options, ...options })
25+
}
26+
1527
const debug = createDebug('@nuxtjs/i18n:transform:resource')
1628

1729
export const ResourcePlugin = (options: BundlerPluginOptions, ctx: I18nNuxtContext) =>
@@ -61,8 +73,20 @@ export const ResourcePlugin = (options: BundlerPluginOptions, ctx: I18nNuxtConte
6173
/**
6274
* Match and replace `defineI18nX(<content>)` with its `<content>`
6375
*/
64-
transform(code, id) {
76+
async transform(_code, id) {
6577
debug('transform', id)
78+
let code = _code
79+
80+
const parsed = parseSync(id, _code)
81+
// ensure imported resources are transformed as well
82+
for (const x of parsed.module.staticImports) {
83+
i18nPathSet.add(await resolvePath(resolve(dirname(id), x.moduleRequest.value)))
84+
}
85+
86+
// transform typescript
87+
if (/(c|m)?ts$/.test(id)) {
88+
code = (await transform(_code, { loader: 'ts' })).code
89+
}
6690

6791
const s = new MagicString(code)
6892
const matches = code.matchAll(DEFINE_I18N_FN_RE)

0 commit comments

Comments
 (0)
Please sign in to comment.