Skip to content

Commit 2908b63

Browse files
authored
fix: auto declare typescript regression (#3777)
1 parent b49fd4a commit 2908b63

2 files changed

Lines changed: 30 additions & 7 deletions

File tree

src/transform/i18n-function-injection.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ const TRANSLATION_FUNCTIONS_MAP: Record<(typeof TRANSLATION_FUNCTIONS)[number],
2222
$te: 'te: $te'
2323
}
2424

25+
const QUERY_RE = /\?.*$/
26+
27+
function withoutQuery(id: string) {
28+
return id.replace(QUERY_RE, '')
29+
}
30+
2531
export const TransformI18nFunctionPlugin = (options: BundlerPluginOptions) =>
2632
createUnplugin(() => {
2733
return {
@@ -37,11 +43,12 @@ export const TransformI18nFunctionPlugin = (options: BundlerPluginOptions) =>
3743
code: { include: TRANSLATION_FUNCTIONS_RE }
3844
},
3945
handler(code, id) {
40-
const scriptContent = extractScriptSetupContent(code)
41-
if (!scriptContent) return
46+
const script = extractScriptSetupContent(code)
47+
if (!script) return
4248

43-
const s = new MagicString(code)
44-
const missing = collectMissingI18nFunctions(scriptContent.code, id)
49+
// replace .vue extension with .ts or .tsx
50+
const filepath = withoutQuery(id).replace(/\.\w+$/, '.' + script.loader)
51+
const missing = collectMissingI18nFunctions(script.code, filepath)
4552
if (!missing.size) return
4653

4754
// only add variables when used without having been declared
@@ -51,7 +58,8 @@ export const TransformI18nFunctionPlugin = (options: BundlerPluginOptions) =>
5158
}
5259

5360
// add variable declaration at the start of <script>, `autoImports` does the rest
54-
s.appendLeft(scriptContent.start, `\nconst { ${assignments.join(', ')} } = useI18n()\n`)
61+
const s = new MagicString(code)
62+
s.appendLeft(script.start, `\nconst { ${assignments.join(', ')} } = useI18n()\n`)
5563

5664
return {
5765
code: s.toString(),
@@ -88,6 +96,10 @@ const SFC_SCRIPT_COMPLEX_RE = /<script(?<attrs>[^>]*)>(?<content>[\s\S]*?)<\/scr
8896
function extractScriptSetupContent(sfc: string) {
8997
const match = sfc.match(SFC_SCRIPT_COMPLEX_RE)
9098
if (match?.groups?.content && match.groups.attrs && match.groups.attrs.indexOf('setup') !== -1) {
91-
return { code: match.groups.content.trim(), start: sfc.indexOf(match.groups.content) }
99+
return {
100+
code: match.groups.content.trim(),
101+
loader: match.groups.attrs && /[tj]sx/.test(match.groups.attrs) ? 'tsx' : 'ts',
102+
start: sfc.indexOf(match.groups.content)
103+
}
92104
}
93105
}

test/fn-injection.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { describe, it, expect } from 'vitest'
22
import { collectMissingI18nFunctions } from '../src/transform/i18n-function-injection'
33

44
describe('collectMissingI18nFunctions', () => {
5-
const id = 'test.vue'
5+
const id = 'test.ts'
66

77
it('collects undeclared i18n function calls', () => {
88
const script = `
@@ -28,4 +28,15 @@ describe('collectMissingI18nFunctions', () => {
2828
`
2929
expect(collectMissingI18nFunctions(script, id)).toEqual(new Set(['$d']))
3030
})
31+
32+
it('collects i18n function calls from typescript', () => {
33+
const script = `
34+
const helloText = $t('hello')
35+
36+
function myFn(val: string) {
37+
return val
38+
}
39+
`
40+
expect(collectMissingI18nFunctions(script, id)).toEqual(new Set(['$t']))
41+
})
3142
})

0 commit comments

Comments
 (0)