Skip to content

Commit

Permalink
fix: support variable default export for defineI18nConfig (#2792)
Browse files Browse the repository at this point in the history
* fix: support variable default export for `defineI18nConfig`

* test: add variable export `defineI18nConfig` test
  • Loading branch information
BobbieGoede committed Feb 15, 2024
1 parent cba5c3a commit cf8cd25
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 15 deletions.
5 changes: 5 additions & 0 deletions specs/fixtures/issues/2094/app.vue
@@ -0,0 +1,5 @@
<template>
<div>
<NuxtPage />
</div>
</template>
13 changes: 13 additions & 0 deletions specs/fixtures/issues/2094/i18n.config.ts
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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

0 comments on commit cf8cd25

Please sign in to comment.