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

breaking: drop useVueI18nImportName option #372

Merged
merged 1 commit into from
May 20, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/unplugin-vue-i18n/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ If do you will use this option, you need to enable `jitCompilation` option.
This option that to use i18n custom blocks in `vue-class-component`.

> [!IMPORTANT]
'useClassComponent' option is deprecated in v5.
`useClassComponent` option is deprecated in v5.
This option will be supported with vue-i18n until v9 latest version.

### `onlyLocales`
Expand All @@ -567,6 +567,9 @@ If do you will use this option, you need to enable `jitCompilation` option.

This option allows a smooth migration from `petite-vue-i18n` to `vue-i18n` and allows progressive enhacement.

> [!IMPORTANT]
`useVueI18nImportName` option is deprecated in v5.
This option will be supported with vue-i18n until v9 latest version.

## 📜 Changelog

Expand Down
142 changes: 37 additions & 105 deletions packages/unplugin-vue-i18n/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import createDebug from 'debug'
import fg from 'fast-glob'
import {
isArray,
isObject,
isEmptyObject,
isString,
isNumber,
Expand All @@ -16,12 +15,11 @@ import { createFilter } from '@rollup/pluginutils'
import {
generateJSON,
generateYAML,
generateJavaScript,
checkInstallPackage
generateJavaScript
} from '@intlify/bundle-utils'
import { parse } from '@vue/compiler-sfc'
import { parseVueRequest, VueQuery } from './query'
import { getRaw, warn, error, raiseError } from './utils'
import { getRaw, warn, error, raiseError, checkInstallPackage } from './utils'

import type { RawSourceMap } from 'source-map-js'
import type {
Expand All @@ -37,7 +35,7 @@ const VIRTUAL_PREFIX = '\0'

const debug = createDebug('unplugin-vue-i18n')

const installedPkg = checkInstallPackage('@intlify/unplugin-vue-i18n', debug)
const installedPkgInfo = checkInstallPackage(debug)

export const unplugin = createUnplugin<PluginOptions>((options = {}, meta) => {
debug('plugin options:', options, meta.framework)
Expand Down Expand Up @@ -84,15 +82,15 @@ export const unplugin = createUnplugin<PluginOptions>((options = {}, meta) => {
debug('dropMessageCompiler', dropMessageCompiler)

// prettier-ignore
const compositionOnly = installedPkg === 'vue-i18n'
const compositionOnly = installedPkgInfo.pkg === 'vue-i18n'
? isBoolean(options.compositionOnly)
? options.compositionOnly
: true
: true
debug('compositionOnly', compositionOnly)

// prettier-ignore
const fullInstall = installedPkg === 'vue-i18n'
const fullInstall = installedPkgInfo.pkg === 'vue-i18n'
? isBoolean(options.fullInstall)
? options.fullInstall
: true
Expand All @@ -102,20 +100,8 @@ export const unplugin = createUnplugin<PluginOptions>((options = {}, meta) => {
const ssrBuild = !!options.ssr
debug('ssr', ssrBuild)

const useVueI18nImportName = options.useVueI18nImportName
if (useVueI18nImportName != null) {
warn(`'useVueI18nImportName' option is experimental`)
}
debug('useVueI18nImportName', useVueI18nImportName)

// prettier-ignore
const getVueI18nAliasName = () =>
installedPkg === 'petite-vue-i18n' && isBoolean(useVueI18nImportName) && useVueI18nImportName
? 'vue-i18n'
: installedPkg

const getVueI18nAliasPath = ({ ssr = false, runtimeOnly = false }) => {
return `${installedPkg}/dist/${installedPkg}${runtimeOnly ? '.runtime' : ''}.${
return `${installedPkgInfo.alias}/dist/${installedPkgInfo.pkg}${runtimeOnly ? '.runtime' : ''}.${
!ssr ? 'esm-bundler.js' /* '.mjs' */ : 'node.mjs'
}`
}
Expand All @@ -134,7 +120,8 @@ export const unplugin = createUnplugin<PluginOptions>((options = {}, meta) => {
let isProduction = false
let sourceMap = false

const vueI18nAliasName = getVueI18nAliasName()
const vueI18nAliasName = installedPkgInfo.alias
debug(`vue-i18n alias name: ${vueI18nAliasName}`)

return {
name: 'unplugin-vue-i18n',
Expand All @@ -150,73 +137,30 @@ export const unplugin = createUnplugin<PluginOptions>((options = {}, meta) => {
enforce: meta.framework === 'vite' ? 'pre' : 'post',

vite: {
config(config, { command }) {
config.resolve = normalizeConfigResolveAlias(
config.resolve,
meta.framework
)
config() {
const defineConfig = {
define: {
__VUE_I18N_LEGACY_API__: !compositionOnly,
__VUE_I18N_FULL_INSTALL__: fullInstall,
__INTLIFY_DROP_MESSAGE_COMPILER__: dropMessageCompiler,
__VUE_I18N_PROD_DEVTOOLS__: false
}
}
debug('define Config:', defineConfig)

if (command === 'build') {
debug(`vue-i18n alias name: ${vueI18nAliasName}`)
if (isArray(config.resolve!.alias)) {
config.resolve!.alias.push({
find: vueI18nAliasName,
replacement: getVueI18nAliasPath({
ssr: ssrBuild,
runtimeOnly
})
})
} else if (isObject(config.resolve!.alias)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(config.resolve!.alias as any)[vueI18nAliasName] =
getVueI18nAliasPath({
const aliasConfig = {
resolve: {
alias: {
[vueI18nAliasName]: getVueI18nAliasPath({
ssr: ssrBuild,
runtimeOnly
})
}
}
debug(
`set ${vueI18nAliasName} runtime only: ${getVueI18nAliasPath({
ssr: ssrBuild,
runtimeOnly
})}`
)
} else if (
command === 'serve' &&
installedPkg === 'petite-vue-i18n' &&
useVueI18nImportName
) {
config.resolve = normalizeConfigResolveAlias(
config.resolve,
meta.framework
)
if (isArray(config.resolve!.alias)) {
config.resolve!.alias.push({
find: vueI18nAliasName,
replacement: `petite-vue-i18n/dist/petite-vue-i18n.esm-bundler.js`
})
} else {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(config.resolve!.alias as any)[vueI18nAliasName] =
`petite-vue-i18n/dist/petite-vue-i18n.esm-bundler.js`
}
debug(`petite-vue-i18n alias name: ${vueI18nAliasName}`)
}
debug('alias Config:', aliasConfig)

config.define = config.define || {}
config.define['__VUE_I18N_LEGACY_API__'] = !compositionOnly
debug(
`set __VUE_I18N_LEGACY_API__ is '${config.define['__VUE_I18N_LEGACY_API__']}'`
)
config.define['__VUE_I18N_FULL_INSTALL__'] = fullInstall
debug(
`set __VUE_I18N_FULL_INSTALL__ is '${config.define['__VUE_I18N_FULL_INSTALL__']}'`
)
config.define['__INTLIFY_DROP_MESSAGE_COMPILER__'] = dropMessageCompiler
debug(
`set __INTLIFY_DROP_MESSAGE_COMPILER__ is '${config.define['__INTLIFY_DROP_MESSAGE_COMPILER__']}'`
)

config.define['__VUE_I18N_PROD_DEVTOOLS__'] = false
return assign(defineConfig, aliasConfig)
},

configResolved(config) {
Expand Down Expand Up @@ -346,30 +290,18 @@ export const unplugin = createUnplugin<PluginOptions>((options = {}, meta) => {
compiler.options.resolve,
meta.framework
)

if (isProduction) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(compiler.options.resolve!.alias as any)[vueI18nAliasName] =
getVueI18nAliasPath({
ssr: ssrBuild,
runtimeOnly
})
debug(
`set ${vueI18nAliasName}: ${getVueI18nAliasPath({
ssr: ssrBuild,
runtimeOnly
})}`
)
} else if (
!isProduction &&
installedPkg === 'petite-vue-i18n' &&
useVueI18nImportName
) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(compiler.options.resolve!.alias as any)[vueI18nAliasName] =
`petite-vue-i18n/dist/petite-vue-i18n.esm-bundler.js`
debug(`petite-vue-i18n alias name: ${vueI18nAliasName}`)
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(compiler.options.resolve!.alias as any)[vueI18nAliasName] =
getVueI18nAliasPath({
ssr: ssrBuild,
runtimeOnly
})
debug(
`set ${vueI18nAliasName}: ${getVueI18nAliasPath({
ssr: ssrBuild,
runtimeOnly
})}`
)

loadWebpack().then(webpack => {
if (webpack) {
Expand Down
1 change: 0 additions & 1 deletion packages/unplugin-vue-i18n/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export interface PluginOptions {
forceStringify?: boolean
defaultSFCLang?: SFCLangFormat
globalSFCScope?: boolean
useVueI18nImportName?: boolean
strictMessage?: boolean
escapeHtml?: boolean
}
62 changes: 60 additions & 2 deletions packages/unplugin-vue-i18n/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,63 @@
import { promises as fs } from 'fs'
import fs from 'node:fs'
import { promises as fsp } from 'node:fs'
import createDebug from 'debug'
import pc from 'picocolors'
import module from 'node:module'
import path from 'node:path'

const SUPPORT_PACKAGES = ['vue-i18n', 'petite-vue-i18n'] as const

type SupportPackage = (typeof SUPPORT_PACKAGES)[number]

type InstalledPackageInfo = {
alias: string
pkg: SupportPackage
}

const _require = module.createRequire(import.meta.url)

export function checkInstallPackage(
debug: createDebug.Debugger
): InstalledPackageInfo {
const pkgInfo =
resolvePkgPath('vue-i18n', debug) ||
resolvePkgPath('petite-vue-i18n', debug)
if (!pkgInfo) {
throw new Error(
`requires 'vue-i18n' or 'petite-vue-i18n' to be present in the dependency tree.`
)
}

debug('installed package info:', pkgInfo)
return pkgInfo
}

function resolvePkgPath(
id: string,
debug: createDebug.Debugger
): InstalledPackageInfo | null {
try {
/**
* NOTE:
* Assuming the case of using npm alias `npm:`,
* get the installed package name from `package.json`
*/
const resolvedPath = _require.resolve(id)
const pkgPath = path.dirname(resolvedPath)
const pkgJson = JSON.parse(
fs.readFileSync(path.join(pkgPath, 'package.json'), 'utf-8')
) as { name: string }
const pkgName: string = pkgJson.name.startsWith('vue-i18n')
? 'vue-i18n'
: pkgJson.name.startsWith('petite-vue-i18n')
? 'petite-vue-i18n'
: ''
return pkgJson ? { alias: id, pkg: pkgName as SupportPackage } : null
} catch (e) {
debug(`cannot find '${id}'`, e)
return null
}
}

export function warn(...args: unknown[]) {
console.warn(pc.yellow(pc.bold(`[unplugin-vue-i18n] `)), ...args)
Expand All @@ -10,7 +68,7 @@ export function error(...args: unknown[]) {
}

export async function getRaw(path: string): Promise<string> {
return fs.readFile(path, { encoding: 'utf-8' })
return fsp.readFile(path, { encoding: 'utf-8' })
}

export function raiseError(message: string) {
Expand Down
Loading