Skip to content

Commit 6f82e61

Browse files
committed
fix: virtual bundle for webpack and rspack
1 parent d1f0e16 commit 6f82e61

File tree

8 files changed

+70
-72
lines changed

8 files changed

+70
-72
lines changed

examples/rspack/rspack.config.js examples/rspack/rspack.config.mjs

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
// @ts-check
2-
const path = require('path')
3-
const { VueLoaderPlugin } = require('vue-loader')
4-
const VueI18nPlugin = require('../../packages/unplugin-vue-i18n/lib/rspack.cjs')
2+
import { dirname, resolve, join } from 'path'
3+
import { VueLoaderPlugin } from 'vue-loader'
4+
import VueI18nPlugin from '../../packages/unplugin-vue-i18n/lib/rspack.mjs'
5+
import { fileURLToPath } from 'url'
6+
7+
const __filename = fileURLToPath(import.meta.url)
8+
const __dirname = dirname(__filename)
59

610
function transformI18nBlock(source) {
711
const sourceCopy = source
@@ -27,26 +31,23 @@ function transformI18nBlock(source) {
2731
/**
2832
* @type {import('@rspack/core').RspackOptions}
2933
**/
30-
module.exports = {
34+
export default {
3135
mode: 'development',
3236
devtool: 'source-map',
33-
entry: path.resolve(__dirname, './src/main.js'),
37+
entry: resolve(__dirname, './src/main.js'),
3438
output: {
35-
path: path.resolve(__dirname, 'dist'),
39+
path: resolve(__dirname, 'dist'),
3640
filename: '[name].js',
3741
publicPath: '/dist/'
3842
},
3943
resolve: {
4044
alias: {
41-
vue: path.resolve(
42-
__dirname,
43-
'../../node_modules/vue/dist/vue.esm-bundler.js'
44-
)
45+
vue: resolve(__dirname, '../../node_modules/vue/dist/vue.esm-bundler.js')
4546
}
4647
},
4748
devServer: {
4849
static: {
49-
directory: path.join(__dirname, './')
50+
directory: join(__dirname, './')
5051
}
5152
},
5253
module: {
@@ -64,7 +65,7 @@ module.exports = {
6465
plugins: [
6566
new VueLoaderPlugin(),
6667
VueI18nPlugin({
67-
include: [path.resolve(__dirname, './src/locales/**')],
68+
include: [resolve(__dirname, './src/locales/**')],
6869
transformI18nBlock: transformI18nBlock
6970
})
7071
]

examples/rspack/src/main.js

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
import { createApp } from 'vue'
22
import { createI18n } from 'vue-i18n'
33
import App from './App.vue'
4-
5-
import ja from './locales/ja.json'
6-
import en from './locales/en.yaml'
4+
import messages from '@intlify/unplugin-vue-i18n/messages'
75

86
const i18n = createI18n({
97
locale: 'ja',
10-
messages: {
11-
en,
12-
ja
13-
}
8+
messages
149
})
1510

1611
const app = createApp(App)

examples/vite/vite.config.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import path from 'path'
1+
import path, { dirname } from 'path'
22
import { defineConfig } from 'vite'
33
import vue from '@vitejs/plugin-vue'
44
import vueI18n from '../../packages/unplugin-vue-i18n/src/vite'
5+
import { fileURLToPath } from 'url'
6+
const __filename = fileURLToPath(import.meta.url)
7+
const __dirname = dirname(__filename)
58

69
function transformI18nBlock(source) {
710
const sourceCopy = source

examples/webpack/src/main.js

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
import { createApp } from 'vue'
22
import { createI18n } from 'vue-i18n'
33
import App from './App.vue'
4-
5-
import ja from './locales/ja.json'
6-
import en from './locales/en.yaml'
4+
import messages from '@intlify/unplugin-vue-i18n/messages'
75

86
const i18n = createI18n({
97
locale: 'ja',
10-
messages: {
11-
en,
12-
ja
13-
}
8+
messages
149
})
1510

1611
const app = createApp(App)

examples/webpack/webpack.config.js examples/webpack/webpack.config.mjs

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
const path = require('path')
2-
const { VueLoaderPlugin } = require('vue-loader')
3-
const VueI18nPlugin = require('../../packages/unplugin-vue-i18n/lib/webpack.cjs')
1+
import { dirname, resolve, join } from 'path'
2+
import { fileURLToPath } from 'url'
3+
import { VueLoaderPlugin } from 'vue-loader'
4+
import VueI18nPlugin from '../../packages/unplugin-vue-i18n/lib/webpack.mjs'
5+
6+
const __filename = fileURLToPath(import.meta.url)
7+
const __dirname = dirname(__filename)
48

59
function transformI18nBlock(source) {
610
const sourceCopy = source
@@ -23,26 +27,23 @@ function transformI18nBlock(source) {
2327
return source
2428
}
2529

26-
module.exports = {
30+
export default {
2731
mode: 'development',
2832
devtool: 'source-map',
29-
entry: path.resolve(__dirname, './src/main.js'),
33+
entry: resolve(__dirname, './src/main.js'),
3034
output: {
31-
path: path.resolve(__dirname, 'dist'),
35+
path: resolve(__dirname, 'dist'),
3236
filename: '[name].js',
3337
publicPath: '/dist/'
3438
},
3539
resolve: {
3640
alias: {
37-
vue: path.resolve(
38-
__dirname,
39-
'../../node_modules/vue/dist/vue.esm-bundler.js'
40-
)
41+
vue: resolve(__dirname, '../../node_modules/vue/dist/vue.esm-bundler.js')
4142
}
4243
},
4344
devServer: {
4445
static: {
45-
directory: path.join(__dirname, './')
46+
directory: join(__dirname, './')
4647
}
4748
},
4849
module: {
@@ -60,7 +61,7 @@ module.exports = {
6061
plugins: [
6162
new VueLoaderPlugin(),
6263
VueI18nPlugin({
63-
include: [path.resolve(__dirname, './src/locales/**')],
64+
include: [resolve(__dirname, './src/locales/**')],
6465
transformI18nBlock: transformI18nBlock
6566
})
6667
]

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@
113113
"build:example:webpack": "pnpm build && webpack --config ./examples/webpack/webpack.config.js",
114114
"build:example:rspack": "pnpm build && rspack --config ./examples/rspack/rsbuild.config.js",
115115
"play:vite": "vite examples/vite -c examples/vite/vite.config.ts",
116-
"play:webpack": "pnpm run build:unplugin && webpack serve --config ./examples/webpack/webpack.config.js",
117-
"play:rspack": "rspack dev --config ./examples/rspack/rspack.config.js",
116+
"play:webpack": "pnpm run build:unplugin && webpack serve --config ./examples/webpack/webpack.config.mjs",
117+
"play:rspack": "rspack dev --config ./examples/rspack/rspack.config.mjs",
118118
"preview:vite": "vite preview examples/vite --outDir dist",
119119
"check-install": "jiti scripts/playwright.ts",
120120
"clean": "run-p \"clean:*\"",

packages/unplugin-vue-i18n/src/core/resource.ts

+32-29
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
assign,
88
generateCodeFrame,
99
isEmptyObject,
10-
isNumber,
1110
isString
1211
} from '@intlify/shared'
1312
import { createFilter } from '@rollup/pluginutils'
@@ -61,6 +60,15 @@ export function resourcePlugin(
6160
return vuePlugin ? getVueCompiler(vuePlugin).parse : parse
6261
}
6362

63+
const resourcePaths = new Set<string>()
64+
if (opts.include) {
65+
for (const inc of opts.include) {
66+
for (const resourcePath of fg.sync(inc)) {
67+
resourcePaths.add(resourcePath)
68+
}
69+
}
70+
}
71+
6472
return {
6573
name: resolveNamespace('resource'),
6674

@@ -221,27 +229,26 @@ export function resourcePlugin(
221229
return INTLIFY_BUNDLE_IMPORT_ID === getVirtualId(id, meta.framework)
222230
},
223231

224-
async load(id: string) {
232+
load(id: string) {
225233
debug('load', id)
226234
if (
227235
INTLIFY_BUNDLE_IMPORT_ID === getVirtualId(id, meta.framework) &&
228-
opts.include
236+
resourcePaths.size > 0
229237
) {
230-
const resourcePaths = new Set<string>()
231-
for (const inc of opts.include) {
232-
for (const resourcePath of await fg(inc)) {
233-
resourcePaths.add(resourcePath)
234-
}
235-
}
236-
237238
const code = generateBundleResources(resourcePaths, prod, opts)
238239

239240
// TODO: support virtual import identifier
240241
// for virtual import identifier (@intlify/unplugin-vue-i18n/messages)
241-
return {
242-
code,
243-
map: { mappings: '' }
242+
if (meta.framework === 'vite') {
243+
return { code, map: { mappings: '' } }
244+
}
245+
246+
// watch resources to invalidate on change (webpack)
247+
for (const p of resourcePaths) {
248+
this.addWatchFile(p)
244249
}
250+
251+
return { code }
245252
}
246253
},
247254

@@ -285,11 +292,10 @@ export function resourcePlugin(
285292

286293
if (code === generatedCode) return
287294

288-
return {
289-
code: generatedCode,
290-
// prettier-ignore
291-
map: { mappings: '' }
295+
if (meta.framework === 'vite') {
296+
return { code: generatedCode, map: { mappings: '' } }
292297
}
298+
return { code: generatedCode }
293299
} else {
294300
// TODO: support virtual import identifier
295301
// for virtual import identifier (@intlify/unplugin-vue-i18n/messages)
@@ -347,11 +353,10 @@ export function resourcePlugin(
347353

348354
if (code === generatedCode) return
349355

350-
return {
351-
code: generatedCode,
352-
// prettier-ignore
353-
map: { mappings: '' }
356+
if (meta.framework === 'vite') {
357+
return { code: generatedCode, map: { mappings: '' } }
354358
}
359+
return { code: generatedCode }
355360
}
356361
}
357362
}
@@ -518,7 +523,7 @@ function getCode(
518523
parser: ReturnType<typeof getVueCompiler>['parse'],
519524
framework: UnpluginContextMeta['framework'] = 'vite'
520525
): string {
521-
if (!isNumber(index)) {
526+
if (index == null) {
522527
raiseError(`unexpected index: ${index}`)
523528
}
524529

@@ -566,30 +571,28 @@ function getOptions(
566571
filename,
567572
jit: true,
568573
env: mode,
569-
onWarn: msg => {
570-
warn(`${filename} ${msg}`)
571-
},
574+
onWarn: msg => warn(`${filename} ${msg}`),
572575
onError: (msg, extra) => {
573576
const codeFrame = generateCodeFrame(
574577
extra?.source || extra?.location?.source || '',
575578
extra?.location?.start.column,
576579
extra?.location?.end.column
577580
)
578-
const errMssage = `${msg} (error code: ${extra?.code}) in ${filename}
581+
const errMessage = `${msg} (error code: ${extra?.code}) in ${filename}
579582
target message: ${extra?.source}
580583
target message path: ${extra?.path}
581584
582585
${codeFrame}
583586
`
584-
error(errMssage)
585-
throw new Error(errMssage)
587+
error(errMessage)
588+
throw new Error(errMessage)
586589
}
587590
}
588591

589592
if (isCustomBlock(query)) {
590593
return assign(baseOptions, {
591594
type: 'sfc' as const,
592-
locale: isString(query.locale) ? query.locale : '',
595+
locale: query.locale ?? '',
593596
isGlobal: opts.globalSFCScope || !!query.global
594597
})
595598
}

packages/unplugin-vue-i18n/test/bundle-import.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { resolve } from 'pathe'
2-
import { bundleAndRun, getCurrentTestBundler, isTestFramework } from './utils'
2+
import { bundleAndRun, getCurrentTestBundler } from './utils'
33
import { createMessageContext, compile } from '@intlify/core-base'
44
import { expect, test } from 'vitest'
55
import type { MessageCompilerContext } from '@intlify/core-base'
@@ -10,7 +10,7 @@ import type { MessageCompilerContext } from '@intlify/core-base'
1010
fixture: '@intlify/unplugin-vue-i18n/messages'
1111
}
1212
].forEach(({ testcase, input, fixture }) => {
13-
test.skipIf(!isTestFramework('vite'))(testcase, async () => {
13+
test(testcase, async () => {
1414
const options = {
1515
input,
1616
strictMessage: false,

0 commit comments

Comments
 (0)