nuxt-i18n
Version:
i18n for Nuxt
83 lines (72 loc) • 2.37 kB
JavaScript
import { readFileSync } from 'fs'
import { parse } from '@babel/parser'
import traverse from '@babel/traverse'
// Must not be an explicit dependency to avoid version mismatch issue.
// See https://github.com/nuxt-community/i18n-module/issues/297
import { parseComponent } from 'vue-template-compiler'
import { formatMessage } from '../templates/utils-common'
import { COMPONENT_OPTIONS_KEY } from './constants'
/**
* Extracts nuxtI18n component options for given component file path.
*
* @typedef {Required<Pick<import('../../types/vue').NuxtI18nComponentOptions, 'locales' | 'paths'>>} ComputedPageOptions
*
* @param {import('@nuxt/types/config/router').NuxtRouteConfig['component']} component
* @return {ComputedPageOptions | false}
*/
export function extractComponentOptions (component) {
if (typeof (component) !== 'string') {
return false
}
/** @type {ComputedPageOptions | false} */
let componentOptions = {
locales: [],
paths: {}
}
let contents
try {
contents = readFileSync(component).toString()
} catch (error) {
console.warn(formatMessage(`Couldn't read page component file (${error.message})`))
}
if (!contents) {
return componentOptions
}
const Component = parseComponent(contents)
if (!Component.script || Component.script.content.length < 1) {
return componentOptions
}
const script = Component.script.content
try {
const parsed = parse(script, {
sourceType: 'module',
plugins: [
'nullishCoalescingOperator',
'optionalChaining',
'classProperties',
'decorators-legacy',
'dynamicImport',
'estree',
'exportDefaultFrom',
'typescript'
]
})
traverse(parsed, {
enter (path) {
// @ts-ignore
if (path.node.type === 'Property') {
// @ts-ignore
if (path.node.key.name === COMPONENT_OPTIONS_KEY) {
// @ts-ignore
const data = script.substring(path.node.start, path.node.end)
componentOptions = Function(`return ({${data}})`)()[COMPONENT_OPTIONS_KEY] // eslint-disable-line
}
}
}
})
} catch (error) {
// eslint-disable-next-line no-console
console.warn(formatMessage(`Error parsing "${COMPONENT_OPTIONS_KEY}" component option in file "${component}"`))
}
return componentOptions
}