@intlify/unplugin-vue-i18n 7.0.0-beta.0 → 7.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.cjs CHANGED
@@ -6,13 +6,17 @@ const unplugin$1 = require('unplugin');
6
6
  const createDebug = require('debug');
7
7
  const pc = require('picocolors');
8
8
  const path = require('node:path');
9
+ const defu = require('defu');
9
10
  const pathe = require('pathe');
10
- const shared = require('@intlify/shared');
11
11
  const bundleUtils = require('@intlify/bundle-utils');
12
+ const shared = require('@intlify/shared');
12
13
  const pluginutils = require('@rollup/pluginutils');
13
14
  const fg = require('fast-glob');
14
- const node_fs = require('node:fs');
15
+ const fs = require('node:fs');
15
16
  const compilerSfc = require('vue/compiler-sfc');
17
+ const knitwork = require('knitwork');
18
+ const mlly = require('mlly');
19
+ const node_crypto = require('node:crypto');
16
20
  const vueI18nExtensions = require('@intlify/vue-i18n-extensions');
17
21
  const scopeManager = require('@typescript-eslint/scope-manager');
18
22
  const typescriptEstree = require('@typescript-eslint/typescript-estree');
@@ -23,7 +27,9 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
23
27
  const createDebug__default = /*#__PURE__*/_interopDefaultCompat(createDebug);
24
28
  const pc__default = /*#__PURE__*/_interopDefaultCompat(pc);
25
29
  const path__default = /*#__PURE__*/_interopDefaultCompat(path);
30
+ const defu__default = /*#__PURE__*/_interopDefaultCompat(defu);
26
31
  const fg__default = /*#__PURE__*/_interopDefaultCompat(fg);
32
+ const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
27
33
  const eslintUitls__default = /*#__PURE__*/_interopDefaultCompat(eslintUitls);
28
34
 
29
35
  const PKG_NAME = "unplugin-vue-i18n";
@@ -62,54 +68,53 @@ function normalizePath(id) {
62
68
  return path__default.posix.normalize(isWindows ? slash(id) : id);
63
69
  }
64
70
 
71
+ function toArray(value) {
72
+ return Array.isArray(value) ? value : [value];
73
+ }
74
+
75
+ const getVueI18nAliasPath = (opts) => {
76
+ const filename = [
77
+ opts.module,
78
+ opts.runtimeOnly ? "runtime" : "",
79
+ !opts.ssr ? "esm-bundler" : "node",
80
+ "js"
81
+ ].filter(Boolean).join(".");
82
+ return `${opts.module}/dist/${filename}`;
83
+ };
65
84
  function resolveOptions(options) {
66
- const moduleType = options.module || "vue-i18n";
67
- let onlyLocales = [];
68
- if (options.onlyLocales) {
69
- onlyLocales = shared.isArray(options.onlyLocales) ? options.onlyLocales : [options.onlyLocales];
70
- }
71
- let include = options.include;
72
- let exclude = void 0;
73
- if (include) {
74
- if (shared.isArray(include)) {
75
- include = include.map((item) => pathe.normalize(item));
76
- } else if (shared.isString(include)) {
77
- include = pathe.normalize(include);
78
- }
79
- } else {
80
- exclude = "**/**";
81
- }
82
- const forceStringify = !!options.forceStringify;
83
- const defaultSFCLang = shared.isString(options.defaultSFCLang) ? options.defaultSFCLang : "json";
84
- const globalSFCScope = !!options.globalSFCScope;
85
- const runtimeOnly = shared.isBoolean(options.runtimeOnly) ? options.runtimeOnly : true;
86
- const dropMessageCompiler = !!options.dropMessageCompiler;
87
- const fullInstall = moduleType === "vue-i18n" ? shared.isBoolean(options.fullInstall) ? options.fullInstall : true : false;
88
- const ssrBuild = !!options.ssr;
89
- const allowDynamic = !!options.allowDynamic;
90
- const strictMessage = shared.isBoolean(options.strictMessage) ? options.strictMessage : true;
91
- const escapeHtml = !!options.escapeHtml;
92
- const optimizeTranslationDirective = shared.isString(options.optimizeTranslationDirective) || shared.isArray(options.optimizeTranslationDirective) ? options.optimizeTranslationDirective : !!options.optimizeTranslationDirective;
85
+ const res = defu__default(options, {
86
+ ssr: false,
87
+ module: "vue-i18n",
88
+ escapeHtml: false,
89
+ onlyLocales: [],
90
+ fullInstall: true,
91
+ runtimeOnly: true,
92
+ strictMessage: true,
93
+ allowDynamic: false,
94
+ globalSFCScope: false,
95
+ forceStringify: false,
96
+ defaultSFCLang: "json",
97
+ dropMessageCompiler: false,
98
+ transformI18nBlock: void 0,
99
+ optimizeTranslationDirective: false
100
+ });
101
+ const include = res.include ? toArray(res.include).map((item) => pathe.normalize(item)) : void 0;
102
+ const _exclude = res.exclude ? toArray(res.exclude).map((item) => pathe.normalize(item)) : void 0;
103
+ const exclude = res.include ? _exclude : ["**/**"];
104
+ const onlyLocales = toArray(res.onlyLocales);
105
+ const fullInstall = res.module !== "vue-i18n" ? false : res.fullInstall;
106
+ const optimizeTranslationDirective = typeof res.optimizeTranslationDirective === "boolean" ? res.optimizeTranslationDirective : toArray(res.optimizeTranslationDirective);
93
107
  const translationIdentifiers = /* @__PURE__ */ new Map();
94
- const transformI18nBlock = typeof options.transformI18nBlock === "function" ? options.transformI18nBlock : null;
108
+ const vueI18nAliasPath = getVueI18nAliasPath(res);
95
109
  return {
110
+ ...res,
96
111
  include,
97
112
  exclude,
98
- module: moduleType,
99
- onlyLocales,
100
- forceStringify,
101
- defaultSFCLang,
102
- globalSFCScope,
103
- runtimeOnly,
104
- dropMessageCompiler,
105
113
  fullInstall,
106
- ssrBuild,
107
- allowDynamic,
108
- strictMessage,
109
- escapeHtml,
110
- optimizeTranslationDirective,
114
+ onlyLocales,
115
+ vueI18nAliasPath,
111
116
  translationIdentifiers,
112
- transformI18nBlock
117
+ optimizeTranslationDirective
113
118
  };
114
119
  }
115
120
 
@@ -181,52 +186,84 @@ function getDescriptor(filename, code, options) {
181
186
  const INTLIFY_BUNDLE_IMPORT_ID = "@intlify/unplugin-vue-i18n/messages";
182
187
  const VIRTUAL_PREFIX = "\0";
183
188
  const debug$2 = createDebug__default(resolveNamespace("resource"));
184
- function resourcePlugin({
185
- onlyLocales,
186
- include,
187
- exclude,
188
- module,
189
- forceStringify,
190
- defaultSFCLang,
191
- globalSFCScope,
192
- runtimeOnly,
193
- dropMessageCompiler,
194
- fullInstall,
195
- ssrBuild,
196
- strictMessage,
197
- allowDynamic,
198
- escapeHtml,
199
- transformI18nBlock
200
- }, meta) {
201
- const filter = pluginutils.createFilter(include, exclude);
202
- const getVueI18nAliasPath = ({ ssr = false, runtimeOnly: runtimeOnly2 = false }) => {
203
- return `${module}/dist/${module}${runtimeOnly2 ? ".runtime" : ""}.${!ssr ? "esm-bundler.js" : "node.js"}`;
189
+ function resourcePlugin(opts, meta) {
190
+ const _filter = pluginutils.createFilter(opts.include, opts.exclude);
191
+ const importedResources = /* @__PURE__ */ new Set();
192
+ const filter = (val) => _filter(val) || importedResources.has(val);
193
+ debug$2(`vue-i18n alias name: ${opts.module}`);
194
+ const ctx = {
195
+ prod: false,
196
+ sourceMap: false
204
197
  };
205
- let isProduction = false;
206
- let sourceMap = false;
207
- const vueI18nAliasName = module;
208
- debug$2(`vue-i18n alias name: ${vueI18nAliasName}`);
209
198
  let vuePlugin = null;
210
- const getSfcParser = () => {
211
- return vuePlugin ? getVueCompiler(vuePlugin).parse : compilerSfc.parse;
212
- };
199
+ const getSfcParser = () => vuePlugin ? getVueCompiler(vuePlugin).parse : compilerSfc.parse;
200
+ const resourcePaths = /* @__PURE__ */ new Set();
201
+ for (const inc of opts.include || []) {
202
+ for (const resourcePath of fg__default.sync(inc, { ignore: opts.exclude })) {
203
+ resourcePaths.add(resourcePath);
204
+ }
205
+ }
206
+ function result(code) {
207
+ if (meta.framework === "vite") {
208
+ return { code, map: { mappings: "" } };
209
+ }
210
+ return { code };
211
+ }
212
+ function sharedWebpackLikePlugin(compiler) {
213
+ ctx.prod = compiler.options.mode !== "development";
214
+ ctx.sourceMap = !!compiler.options.devtool;
215
+ debug$2(
216
+ `${meta.framework}: isProduction = ${ctx.prod}, sourceMap = ${ctx.sourceMap}`
217
+ );
218
+ compiler.options.resolve.alias = {
219
+ ...compiler.options.resolve.alias,
220
+ [opts.module]: opts.vueI18nAliasPath
221
+ };
222
+ debug$2(`set ${opts.module}: ${opts.vueI18nAliasPath}`);
223
+ const loader = meta.framework === "webpack" ? loadWebpack : loadRspack;
224
+ loader().then((mod) => {
225
+ if (mod) {
226
+ compiler.options.plugins.push(
227
+ // @ts-expect-error type issue
228
+ new mod.DefinePlugin({
229
+ __VUE_I18N_FULL_INSTALL__: JSON.stringify(opts.fullInstall),
230
+ __INTLIFY_PROD_DEVTOOLS__: "false"
231
+ })
232
+ );
233
+ debug$2(`set __VUE_I18N_FULL_INSTALL__ is '${opts.fullInstall}'`);
234
+ } else {
235
+ debug$2(
236
+ `ignore vue-i18n feature flags with ${meta.framework}.DefinePlugin`
237
+ );
238
+ }
239
+ }).catch((_e) => {
240
+ warn(`${meta.framework} not found, please install ${meta.framework}.`);
241
+ });
242
+ compiler.options.module.rules.push({
243
+ test: /\.(json5?|ya?ml)$/,
244
+ type: "javascript/auto",
245
+ include: (resource) => filter(resource)
246
+ });
247
+ }
248
+ const supportedFileExtensionsRE = /\.(json5?|ya?ml|[c|m]?[j|t]s)$/;
213
249
  return {
214
250
  name: resolveNamespace("resource"),
215
251
  /**
216
252
  * NOTE:
253
+ * vite: early ('pre') transform for json and SFC's custom blocks
254
+ * because these are transformed into javascript code by `vite:json` plugin.
217
255
  *
218
- * For vite, If we have json (including SFC's custom block),
219
- * transform it first because it will be transformed into javascript code by `vite:json` plugin.
220
- *
221
- * For webpack, This plugin will handle with ‘post’, because vue-loader generate the request query.
256
+ * webpack/rspack: late ('post') transform because we rely on vue-loader to generate the request queries.
222
257
  */
223
258
  enforce: meta.framework === "vite" ? "pre" : "post",
259
+ rspack: sharedWebpackLikePlugin,
260
+ webpack: sharedWebpackLikePlugin,
224
261
  vite: {
225
262
  config() {
226
263
  const defineConfig = {
227
264
  define: {
228
- __VUE_I18N_FULL_INSTALL__: fullInstall,
229
- __INTLIFY_DROP_MESSAGE_COMPILER__: dropMessageCompiler,
265
+ __VUE_I18N_FULL_INSTALL__: opts.fullInstall,
266
+ __INTLIFY_DROP_MESSAGE_COMPILER__: opts.dropMessageCompiler,
230
267
  __VUE_I18N_PROD_DEVTOOLS__: false
231
268
  }
232
269
  };
@@ -234,10 +271,7 @@ function resourcePlugin({
234
271
  const aliasConfig = {
235
272
  resolve: {
236
273
  alias: {
237
- [vueI18nAliasName]: getVueI18nAliasPath({
238
- ssr: ssrBuild,
239
- runtimeOnly
240
- })
274
+ [opts.module]: opts.vueI18nAliasPath
241
275
  }
242
276
  }
243
277
  };
@@ -249,10 +283,10 @@ function resourcePlugin({
249
283
  if (!checkVuePlugin(vuePlugin)) {
250
284
  return;
251
285
  }
252
- isProduction = config.isProduction;
253
- sourceMap = config.command === "build" ? !!config.build.sourcemap : false;
286
+ ctx.prod = config.isProduction;
287
+ ctx.sourceMap = config.command === "build" ? !!config.build.sourcemap : false;
254
288
  debug$2(
255
- `configResolved: isProduction = ${isProduction}, sourceMap = ${sourceMap}`
289
+ `configResolved: isProduction = ${ctx.prod}, sourceMap = ${ctx.sourceMap}`
256
290
  );
257
291
  const jsonPlugin = getVitePlugin(config, "vite:json");
258
292
  if (jsonPlugin) {
@@ -269,106 +303,6 @@ function resourcePlugin({
269
303
  return orgTransform.apply(this, [code, id]);
270
304
  };
271
305
  }
272
- const esbuildPlugin = getVitePlugin(config, "vite:esbuild");
273
- if (esbuildPlugin) {
274
- const orgTransform = esbuildPlugin.transform;
275
- esbuildPlugin.transform = async function(code, id) {
276
- const result = await orgTransform.apply(this, [
277
- code,
278
- id
279
- ]);
280
- if (result == null) {
281
- return result;
282
- }
283
- const { filename, query } = parseVueRequest(id);
284
- if (!query.vue && filter(id) && /\.[c|m]?ts$/.test(id)) {
285
- const [_code, inSourceMap] = shared.isString(result) ? [result, void 0] : [result.code, result.map];
286
- let langInfo = defaultSFCLang;
287
- langInfo = pathe.parse(filename).ext;
288
- const generate = getGenerator(langInfo);
289
- const parseOptions = getOptions(
290
- filename,
291
- isProduction,
292
- query,
293
- sourceMap,
294
- {
295
- inSourceMap,
296
- isGlobal: globalSFCScope,
297
- allowDynamic,
298
- strictMessage,
299
- escapeHtml,
300
- jit: true,
301
- onlyLocales,
302
- forceStringify
303
- }
304
- );
305
- debug$2("parseOptions", parseOptions);
306
- const { code: generatedCode, map } = generate(_code, parseOptions);
307
- debug$2("generated code", generatedCode);
308
- debug$2("sourcemap", map, sourceMap);
309
- if (_code === generatedCode)
310
- return;
311
- return {
312
- code: generatedCode,
313
- map: { mappings: "" }
314
- };
315
- } else {
316
- return result;
317
- }
318
- };
319
- }
320
- },
321
- async handleHotUpdate({ file, server }) {
322
- if (/\.(json5?|ya?ml)$/.test(file)) {
323
- const module2 = server.moduleGraph.getModuleById(
324
- asVirtualId(INTLIFY_BUNDLE_IMPORT_ID, meta.framework)
325
- );
326
- if (module2) {
327
- server.moduleGraph.invalidateModule(module2);
328
- return [module2];
329
- }
330
- }
331
- }
332
- },
333
- webpack(compiler) {
334
- isProduction = compiler.options.mode !== "development";
335
- sourceMap = !!compiler.options.devtool;
336
- debug$2(`webpack: isProduction = ${isProduction}, sourceMap = ${sourceMap}`);
337
- compiler.options.resolve = normalizeConfigResolveAlias(
338
- compiler.options.resolve,
339
- meta.framework
340
- );
341
- compiler.options.resolve.alias[vueI18nAliasName] = getVueI18nAliasPath({
342
- ssr: ssrBuild,
343
- runtimeOnly
344
- });
345
- debug$2(
346
- `set ${vueI18nAliasName}: ${getVueI18nAliasPath({
347
- ssr: ssrBuild,
348
- runtimeOnly
349
- })}`
350
- );
351
- loadWebpack().then((webpack) => {
352
- if (webpack) {
353
- compiler.options.plugins.push(
354
- new webpack.DefinePlugin({
355
- __VUE_I18N_FULL_INSTALL__: JSON.stringify(fullInstall),
356
- __INTLIFY_PROD_DEVTOOLS__: "false"
357
- })
358
- );
359
- debug$2(`set __VUE_I18N_FULL_INSTALL__ is '${fullInstall}'`);
360
- } else {
361
- debug$2("ignore vue-i18n feature flags with webpack.DefinePlugin");
362
- }
363
- });
364
- if (compiler.options.module) {
365
- compiler.options.module.rules.push({
366
- test: /\.(json5?|ya?ml)$/,
367
- type: "javascript/auto",
368
- include(resource) {
369
- return filter(resource);
370
- }
371
- });
372
306
  }
373
307
  },
374
308
  resolveId(id, importer) {
@@ -377,198 +311,152 @@ function resourcePlugin({
377
311
  return asVirtualId(id, meta.framework);
378
312
  }
379
313
  },
380
- async load(id) {
314
+ loadInclude(id) {
315
+ return INTLIFY_BUNDLE_IMPORT_ID === getVirtualId(id, meta.framework);
316
+ },
317
+ load(id) {
381
318
  debug$2("load", id);
382
- if (INTLIFY_BUNDLE_IMPORT_ID === getVirtualId(id, meta.framework) && include) {
383
- let resourcePaths = [];
384
- const includePaths = shared.isArray(include) ? include : [include];
385
- for (const inc of includePaths) {
386
- resourcePaths = [...resourcePaths, ...await fg__default(inc)];
319
+ if (INTLIFY_BUNDLE_IMPORT_ID === getVirtualId(id, meta.framework) && resourcePaths.size > 0) {
320
+ const code = generateBundleResources(resourcePaths);
321
+ for (const p of resourcePaths) {
322
+ this.addWatchFile(p);
387
323
  }
388
- resourcePaths = resourcePaths.filter(
389
- (el, pos) => resourcePaths.indexOf(el) === pos
390
- );
391
- const code = await generateBundleResources(
392
- resourcePaths,
393
- isProduction,
394
- {
395
- forceStringify,
396
- strictMessage,
397
- escapeHtml
398
- }
399
- );
400
- return {
401
- code,
402
- map: { mappings: "" }
403
- };
324
+ return result(code);
404
325
  }
405
326
  },
406
327
  transformInclude(id) {
407
328
  debug$2("transformInclude", id);
408
329
  if (meta.framework === "vite") {
409
330
  return true;
410
- } else {
411
- const { filename } = parseVueRequest(id);
412
- return filename.endsWith("vue") || filename.endsWith(INTLIFY_BUNDLE_IMPORT_ID) || /\.(json5?|ya?ml)$/.test(filename) && filter(filename);
413
331
  }
332
+ const { filename, query } = parseVueRequest(id);
333
+ if (filename.endsWith("vue") || filename.endsWith(INTLIFY_BUNDLE_IMPORT_ID)) {
334
+ return true;
335
+ }
336
+ let isResourcePath = resourcePaths.has(id);
337
+ if (!isResourcePath && "issuerPath" in query) {
338
+ isResourcePath = resourcePaths.has(query.issuerPath);
339
+ }
340
+ return supportedFileExtensionsRE.test(filename) && filter(filename) && isResourcePath;
414
341
  },
415
342
  async transform(code, id) {
416
343
  const { filename, query } = parseVueRequest(id);
417
344
  debug$2("transform", id, JSON.stringify(query), filename);
418
- let langInfo = defaultSFCLang;
419
- let inSourceMap;
420
- if (!query.vue) {
421
- if (/\.(json5?|ya?ml|[c|m]?js)$/.test(id) && filter(id)) {
422
- langInfo = pathe.parse(filename).ext;
423
- const generate = getGenerator(langInfo);
424
- const parseOptions = getOptions(
425
- filename,
426
- isProduction,
427
- query,
428
- sourceMap,
429
- {
430
- inSourceMap,
431
- isGlobal: globalSFCScope,
432
- allowDynamic,
433
- strictMessage,
434
- escapeHtml,
435
- jit: true,
436
- onlyLocales,
437
- forceStringify
438
- }
439
- );
440
- debug$2("parseOptions", parseOptions);
345
+ let langInfo = opts.defaultSFCLang;
346
+ if (filter(id)) {
347
+ const imports = mlly.findStaticImports(code);
348
+ for (const p of imports) {
349
+ const res = pathe.resolve(pathe.dirname(id), p.specifier);
350
+ importedResources.add(res);
351
+ }
352
+ }
353
+ if (!query.vue && supportedFileExtensionsRE.test(id) && filter(id)) {
354
+ langInfo = pathe.parse(filename).ext;
355
+ const generate = getGenerator(langInfo);
356
+ const parseOptions = getOptions(filename, ctx, query, {
357
+ ...opts,
358
+ transformI18nBlock: void 0
359
+ });
360
+ debug$2("parseOptions", parseOptions);
361
+ try {
441
362
  const { code: generatedCode, map } = generate(code, parseOptions);
442
363
  debug$2("generated code", generatedCode);
443
- debug$2("sourcemap", map, sourceMap);
364
+ debug$2("sourcemap", map, ctx.sourceMap);
444
365
  if (code === generatedCode)
445
366
  return;
446
- return {
447
- code: generatedCode,
448
- // prettier-ignore
449
- map: { mappings: "" }
450
- };
451
- }
452
- } else {
453
- if (isCustomBlock(query)) {
454
- if (shared.isString(query.lang)) {
455
- langInfo = query.src ? query.lang === "i18n" ? defaultSFCLang : query.lang : query.lang;
456
- } else if (defaultSFCLang) {
457
- langInfo = defaultSFCLang;
367
+ return result(generatedCode);
368
+ } catch (err) {
369
+ if (err instanceof bundleUtils.DynamicResourceError) {
370
+ error(
371
+ `Unable to precompile or optimize \`${filename}\` - excluding from virtual bundle \`${INTLIFY_BUNDLE_IMPORT_ID}\`.
372
+ `,
373
+ err
374
+ );
375
+ return `export default {}`;
376
+ } else {
377
+ throw err;
458
378
  }
459
- debug$2("langInfo", langInfo);
460
- const generate = /\.?json5?/.test(langInfo) ? bundleUtils.generateJSON : bundleUtils.generateYAML;
461
- const parseOptions = getOptions(
462
- filename,
463
- isProduction,
464
- query,
465
- sourceMap,
466
- {
467
- inSourceMap,
468
- isGlobal: globalSFCScope,
469
- jit: true,
470
- strictMessage,
471
- escapeHtml,
472
- onlyLocales,
473
- forceStringify
474
- }
475
- );
476
- debug$2("parseOptions", parseOptions);
477
- let source = await getCode(
478
- code,
479
- filename,
480
- sourceMap,
481
- query,
482
- getSfcParser(),
483
- meta.framework
484
- );
485
- if (typeof transformI18nBlock === "function") {
486
- const modifiedSource = transformI18nBlock(source);
487
- if (modifiedSource && typeof modifiedSource === "string") {
488
- source = modifiedSource;
489
- } else {
490
- warn("transformI18nBlock should return a string");
491
- }
379
+ }
380
+ }
381
+ if (isCustomBlock(query)) {
382
+ langInfo = opts.defaultSFCLang;
383
+ if (query.lang && query.lang !== "i18n") {
384
+ langInfo = query.lang;
385
+ }
386
+ debug$2("langInfo", langInfo);
387
+ const parseOptions = getOptions(filename, ctx, query, {
388
+ ...opts,
389
+ allowDynamic: false,
390
+ transformI18nBlock: void 0
391
+ });
392
+ debug$2("parseOptions", parseOptions);
393
+ let source = getCode(
394
+ code,
395
+ filename,
396
+ ctx.sourceMap,
397
+ query,
398
+ getSfcParser(),
399
+ meta
400
+ );
401
+ if (typeof opts.transformI18nBlock === "function") {
402
+ const modifiedSource = opts.transformI18nBlock(source);
403
+ if (modifiedSource && typeof modifiedSource === "string") {
404
+ source = modifiedSource;
405
+ } else {
406
+ warn("transformI18nBlock should return a string");
492
407
  }
493
- const { code: generatedCode, map } = generate(source, parseOptions);
494
- debug$2("generated code", generatedCode);
495
- debug$2("sourcemap", map, sourceMap);
496
- if (code === generatedCode)
497
- return;
498
- return {
499
- code: generatedCode,
500
- // prettier-ignore
501
- map: { mappings: "" }
502
- };
408
+ }
409
+ const generate = getGenerator(langInfo, bundleUtils.generateYAML);
410
+ const { code: generatedCode, map } = generate(source, parseOptions);
411
+ debug$2("generated code", generatedCode);
412
+ debug$2("sourcemap", map, ctx.sourceMap);
413
+ if (code !== generatedCode) {
414
+ return result(generatedCode);
503
415
  }
504
416
  }
505
417
  }
506
418
  };
507
419
  }
508
- function getGenerator(ext, defaultGen = bundleUtils.generateJSON) {
509
- return /\.?json5?$/.test(ext) ? bundleUtils.generateJSON : /\.ya?ml$/.test(ext) ? bundleUtils.generateYAML : /\.([c|m]?js|[c|m]?ts)$/.test(ext) ? bundleUtils.generateJavaScript : defaultGen;
510
- }
511
- function normalizeConfigResolveAlias(resolve, framework) {
512
- if (resolve && resolve.alias) {
513
- return resolve;
420
+ function getGenerator(ext, fallback = bundleUtils.generateJSON) {
421
+ if (/\.?json5?$/.test(ext)) {
422
+ return bundleUtils.generateJSON;
514
423
  }
515
- if (!resolve) {
516
- if (framework === "vite") {
517
- return { alias: [] };
518
- } else if (framework === "webpack") {
519
- return { alias: {} };
520
- }
521
- } else if (!resolve.alias) {
522
- if (framework === "vite") {
523
- resolve.alias = [];
524
- return resolve;
525
- } else if (framework === "webpack") {
526
- resolve.alias = {};
527
- return resolve;
528
- }
424
+ if (/\.ya?ml$/.test(ext)) {
425
+ return bundleUtils.generateYAML;
426
+ }
427
+ if (/\.[c|m]?[j|t]s$/.test(ext)) {
428
+ return bundleUtils.generateJavaScript;
529
429
  }
430
+ return fallback;
530
431
  }
531
432
  async function loadWebpack() {
532
- let webpack = null;
533
- try {
534
- webpack = await import('webpack').then((m) => m.default || m);
535
- } catch (_e) {
536
- warn(`webpack not found, please install webpack.`);
537
- }
538
- return webpack;
539
- }
540
- async function generateBundleResources(resources, isProduction, {
541
- forceStringify = false,
542
- isGlobal = false,
543
- onlyLocales = [],
544
- strictMessage = true,
545
- escapeHtml = false,
546
- jit = true,
547
- transformI18nBlock = void 0
548
- }) {
433
+ const mod = await import('webpack');
434
+ return mod.default || mod;
435
+ }
436
+ async function loadRspack() {
437
+ const { rspack } = await import('@rspack/core');
438
+ return rspack;
439
+ }
440
+ function generateBundleResources(resources) {
549
441
  const codes = [];
550
- for (const res of resources) {
551
- debug$2(`${res} bundle loading ...`);
552
- if (/\.(json5?|ya?ml)$/.test(res)) {
553
- const { ext, name } = pathe.parse(res);
554
- const source = await getRaw(res);
555
- const generate = /json5?/.test(ext) ? bundleUtils.generateJSON : bundleUtils.generateYAML;
556
- const parseOptions = getOptions(res, isProduction, {}, false, {
557
- isGlobal,
558
- jit,
559
- onlyLocales,
560
- strictMessage,
561
- escapeHtml,
562
- forceStringify,
563
- transformI18nBlock
564
- });
565
- parseOptions.type = "bare";
566
- const { code } = generate(source, parseOptions);
567
- debug$2("generated code", code);
568
- codes.push(`${JSON.stringify(name)}: ${code}`);
569
- }
442
+ const imports = [];
443
+ for (const filename of resources) {
444
+ debug$2(`${filename} bundle loading ...`);
445
+ const { name } = pathe.parse(filename);
446
+ const varName = knitwork.genSafeVariableName(
447
+ [
448
+ name,
449
+ node_crypto.createHash("sha256").update(filename).digest("hex").substring(0, 8)
450
+ ].join("_")
451
+ );
452
+ imports.push({ statement: knitwork.genImport(filename, varName), varName });
453
+ codes.push(`${JSON.stringify(name)}: ${varName}`);
570
454
  }
571
- return `const isObject = (item) => item && typeof item === 'object' && !Array.isArray(item);
455
+ const importStatements = imports.map((x) => x.statement).join("\n");
456
+ return `
457
+ ${importStatements}
458
+
459
+ const isObject = (item) => item && typeof item === 'object' && !Array.isArray(item);
572
460
 
573
461
  const mergeDeep = (target, ...sources) => {
574
462
  if (!sources.length) return target;
@@ -589,96 +477,73 @@ const mergeDeep = (target, ...sources) => {
589
477
  }
590
478
 
591
479
  export default mergeDeep({},
592
- ${codes.map((code) => `{${code}}`).join(",\n")}
480
+ ${codes.map((code) => `{ ${code} }`).join(",\n ")}
593
481
  );`;
594
482
  }
595
- async function getCode(source, filename, sourceMap, query, parser, framework = "vite") {
596
- const { index, issuerPath } = query;
597
- if (!shared.isNumber(index)) {
598
- raiseError(`unexpected index: ${index}`);
483
+ function getCode(source, filename, sourceMap, query, parser, meta) {
484
+ if (query.index == null) {
485
+ raiseError(`unexpected index: ${query.index}`);
599
486
  }
600
- if (framework === "webpack") {
601
- if (issuerPath) {
602
- debug$2(`getCode (webpack) ${index} via issuerPath`, issuerPath);
603
- return await getRaw(filename);
604
- } else {
605
- const result = parser(await getRaw(filename), {
606
- sourceMap,
607
- filename
608
- });
609
- const block = result.descriptor.customBlocks[index];
610
- if (block) {
611
- const code = block.src ? await getRaw(block.src) : block.content;
612
- debug$2(`getCode (webpack) ${index} from SFC`, code);
613
- return code;
614
- } else {
615
- return source;
616
- }
617
- }
618
- } else {
487
+ if (meta.framework === "vite") {
619
488
  return source;
620
489
  }
490
+ if (query.issuerPath) {
491
+ debug$2(
492
+ `getCode (${meta.framework}) ${query.index} via issuerPath`,
493
+ query.issuerPath
494
+ );
495
+ return readFile(filename);
496
+ }
497
+ const result = parser(readFile(filename), { sourceMap, filename });
498
+ const block = result.descriptor.customBlocks[query.index];
499
+ if (block) {
500
+ const code = block.src ? readFile(block.src) : block.content;
501
+ debug$2(`getCode (${meta.framework}) ${query.index} from SFC`, code);
502
+ return code;
503
+ }
504
+ return source;
621
505
  }
622
506
  function isCustomBlock(query) {
623
507
  return !shared.isEmptyObject(query) && "vue" in query && (query["type"] === "custom" || // for vite (@vite-plugin-vue)
624
508
  query["type"] === "i18n" || // for webpack (vue-loader)
625
509
  query["blockType"] === "i18n");
626
510
  }
627
- function getOptions(filename, isProduction, query, sourceMap, {
628
- inSourceMap = void 0,
629
- forceStringify = false,
630
- isGlobal = false,
631
- onlyLocales = [],
632
- allowDynamic = false,
633
- strictMessage = true,
634
- escapeHtml = false,
635
- jit = true,
636
- transformI18nBlock = null
637
- }) {
638
- const mode = isProduction ? "production" : "development";
511
+ function getOptions(filename, ctx, query, opts) {
639
512
  const baseOptions = {
513
+ ...opts,
640
514
  filename,
641
- sourceMap,
642
- inSourceMap,
643
- forceStringify,
644
- allowDynamic,
645
- strictMessage,
646
- escapeHtml,
647
- jit,
648
- onlyLocales,
649
- env: mode,
650
- transformI18nBlock,
651
- onWarn: (msg) => {
652
- warn(`${filename} ${msg}`);
653
- },
515
+ jit: true,
516
+ // allow overriding ctx.sourceMap with opts
517
+ sourceMap: opts.sourceMap ?? ctx.sourceMap,
518
+ env: ctx.prod ? "production" : "development",
519
+ onWarn: (msg) => warn(`${filename} ${msg}`),
654
520
  onError: (msg, extra) => {
655
521
  const codeFrame = shared.generateCodeFrame(
656
522
  extra?.source || extra?.location?.source || "",
657
523
  extra?.location?.start.column,
658
524
  extra?.location?.end.column
659
525
  );
660
- const errMssage = `${msg} (error code: ${extra?.code}) in ${filename}
526
+ const errMessage = `${msg} (error code: ${extra?.code}) in ${filename}
661
527
  target message: ${extra?.source}
662
528
  target message path: ${extra?.path}
663
529
 
664
530
  ${codeFrame}
665
531
  `;
666
- error(errMssage);
667
- throw new Error(errMssage);
532
+ error(errMessage);
533
+ throw new Error(errMessage);
668
534
  }
669
535
  };
670
536
  if (isCustomBlock(query)) {
671
537
  return shared.assign(baseOptions, {
672
538
  type: "sfc",
673
- locale: shared.isString(query.locale) ? query.locale : "",
674
- isGlobal: isGlobal || !!query.global
675
- });
676
- } else {
677
- return shared.assign(baseOptions, {
678
- type: "plain",
679
- isGlobal: false
539
+ locale: query.locale ?? "",
540
+ isGlobal: opts.globalSFCScope || !!query.global
680
541
  });
681
542
  }
543
+ return shared.assign(baseOptions, {
544
+ type: "plain",
545
+ isGlobal: false
546
+ });
682
547
  }
683
548
  function getVirtualId(id, framework = "vite") {
684
549
  return framework === "vite" ? id.startsWith(VIRTUAL_PREFIX) ? id.slice(VIRTUAL_PREFIX.length) : "" : id;
@@ -686,8 +551,8 @@ function getVirtualId(id, framework = "vite") {
686
551
  function asVirtualId(id, framework = "vite") {
687
552
  return framework === "vite" ? VIRTUAL_PREFIX + id : id;
688
553
  }
689
- async function getRaw(path) {
690
- return node_fs.promises.readFile(path, { encoding: "utf-8" });
554
+ function readFile(path) {
555
+ return fs__default.readFileSync(path, "utf-8");
691
556
  }
692
557
 
693
558
  const debug$1 = createDebug__default(resolveNamespace("directive"));
@@ -968,17 +833,17 @@ function resolveIdentifier(localVariables, returnVariable) {
968
833
  const debug = createDebug__default(resolveNamespace("root"));
969
834
  const unpluginFactory = (options = {}, meta) => {
970
835
  debug("meta framework", meta.framework);
971
- if (!["vite", "webpack"].includes(meta.framework)) {
972
- raiseError(`This plugin is supported 'vite' and 'webpack' only`);
836
+ if (!["vite", "webpack", "rspack"].includes(meta.framework)) {
837
+ raiseError(`This plugin is supported 'vite', 'webpack' and 'rspack' only`);
973
838
  }
974
839
  debug("plugin options (resolving):", options);
975
840
  const resolvedOptions = resolveOptions(options);
976
841
  debug("plugin options (resolved):", resolvedOptions);
977
842
  const plugins = [resourcePlugin(resolvedOptions, meta)];
978
843
  if (resolvedOptions.optimizeTranslationDirective) {
979
- if (meta.framework === "webpack") {
844
+ if (meta.framework === "webpack" || meta.framework === "rspack") {
980
845
  raiseError(
981
- `The 'optimizeTranslationDirective' option still is not supported for webpack.
846
+ `The 'optimizeTranslationDirective' option still is not supported for ${meta.framework}.
982
847
  We are waiting for your Pull Request \u{1F642}.`
983
848
  );
984
849
  }