Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support variable default export for defineI18nConfig #2792

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions specs/fixtures/issues/2094/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<div>
<NuxtPage />
</div>
</template>
13 changes: 13 additions & 0 deletions specs/fixtures/issues/2094/i18n.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const config = defineI18nConfig(() => {
return {
legacy: false,
locale: 'ja',
messages: {
ja: {
big: 'こんにけは,'.repeat(10)
}
}
}
})

export default config
15 changes: 15 additions & 0 deletions specs/fixtures/issues/2094/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: ['@nuxtjs/i18n'],

i18n: {
defaultLocale: 'ja',
locales: [
{
code: 'ja',
iso: 'ja-JP',
name: 'Japanese'
}
]
}
})
15 changes: 15 additions & 0 deletions specs/fixtures/issues/2094/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "nuxt3-test-issues-2000",
"private": true,
"type": "module",
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"start": "node .output/server/index.mjs"
},
"devDependencies": {
"@nuxtjs/i18n": "latest",
"nuxt": "latest"
}
}
9 changes: 9 additions & 0 deletions specs/fixtures/issues/2094/pages/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'

const { t } = useI18n()
</script>

<template>
<p id="render">{{ t('big') }}</p>
</template>
17 changes: 17 additions & 0 deletions specs/issues/2094.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { test, describe, expect } from 'vitest'
import { fileURLToPath } from 'node:url'
import { setup } from '../utils'
import { getText, renderPage } from '../helper'

describe('#2094', async () => {
await setup({
rootDir: fileURLToPath(new URL(`../fixtures/issues/2094`, import.meta.url)),
browser: true
})

test('vue-i18n messages are loaded from config exported as variable', async () => {
const { page } = await renderPage('/')

expect(await getText(page, '#render')).toEqual('こんにけは,'.repeat(10))
})
})
67 changes: 52 additions & 15 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { NUXT_I18N_MODULE_ID, TS_EXTENSIONS, EXECUTABLE_EXTENSIONS, NULL_HASH }

import type { NuxtI18nOptions, LocaleInfo, VueI18nConfigPathInfo, LocaleType, LocaleFile, LocaleObject } from './types'
import type { Nuxt, NuxtConfigLayer } from '@nuxt/schema'
import type { File } from '@babel/types'
import type { File, Identifier } from '@babel/types'

export function formatMessage(message: string) {
return `[${NUXT_I18N_MODULE_ID}]: ${message}`
Expand Down Expand Up @@ -150,27 +150,64 @@ function parseCode(code: string, path: string) {

function scanProgram(program: File['program'] /*, calleeName: string*/) {
let ret: false | 'object' | 'function' | 'arrow-function' = false
let variableDeclaration: Identifier | undefined

for (const node of program.body) {
if (node.type === 'ExportDefaultDeclaration') {
if (node.declaration.type === 'ObjectExpression') {
ret = 'object'
if (node.type !== 'ExportDefaultDeclaration') continue

if (node.declaration.type === 'ObjectExpression') {
ret = 'object'
break
}

if (node.declaration.type === 'Identifier') {
variableDeclaration = node.declaration
break
}

if (node.declaration.type === 'CallExpression' && node.declaration.callee.type === 'Identifier') {
const [fnNode] = node.declaration.arguments
if (fnNode.type === 'FunctionExpression') {
ret = 'function'
break
} else if (
node.declaration.type === 'CallExpression' &&
node.declaration.callee.type === 'Identifier' // &&
// node.declaration.callee.name === calleeName
) {
const [fnNode] = node.declaration.arguments
if (fnNode.type === 'FunctionExpression') {
ret = 'function'
break
} else if (fnNode.type === 'ArrowFunctionExpression') {
ret = 'arrow-function'
}

if (fnNode.type === 'ArrowFunctionExpression') {
ret = 'arrow-function'
break
}
}
}

if (variableDeclaration) {
for (const node of program.body) {
if (node.type !== 'VariableDeclaration') continue
for (const decl of node.declarations) {
if (decl.type !== 'VariableDeclarator') continue
if (decl.init == null) continue
if ('name' in decl.id === false || decl.id.name !== variableDeclaration!.name) continue

if (decl.init.type === 'ObjectExpression') {
ret = 'object'
break
}

if (decl.init.type === 'CallExpression' && decl.init.callee.type === 'Identifier') {
const [fnNode] = decl.init.arguments
if (fnNode.type === 'FunctionExpression') {
ret = 'function'
break
}

if (fnNode.type === 'ArrowFunctionExpression') {
ret = 'arrow-function'
break
}
}
}
}
}

return ret
}

Expand Down