@intlify/unplugin-vue-i18n 0.2.1 → 0.3.0

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/CHANGELOG.md CHANGED
@@ -1,4 +1,19 @@
1
1
 
2
+ ## @intlify/unplugin-vue-i18n@0.3.0 (2022-07-07)
3
+
4
+ #### :star: Features
5
+ * [#136](https://github.com/intlify/bundle-tools/pull/136) feat(unplugin-vue-i18n): support fullinstall option ([@kazupon](https://github.com/kazupon))
6
+ * [#135](https://github.com/intlify/bundle-tools/pull/135) feat(unplugin-vue-i18n): support composition only option ([@kazupon](https://github.com/kazupon))
7
+ * [#134](https://github.com/intlify/bundle-tools/pull/134) feat(unplugin-vue-i18n): support runtimeOnly option ([@kazupon](https://github.com/kazupon))
8
+
9
+ #### :pencil: Documentation
10
+ * [#133](https://github.com/intlify/bundle-tools/pull/133) docs: consistent plugin name and add Nuxt ([@Atinux](https://github.com/Atinux))
11
+
12
+ #### Committers: 2
13
+ - Sébastien Chopin ([@Atinux](https://github.com/Atinux))
14
+ - kazuya kawaguchi ([@kazupon](https://github.com/kazupon))
15
+
16
+
2
17
  ## @intlify/unplugin-vue-i18n@0.2.1 (2022-05-07)
3
18
 
4
19
  #### :bug: Bug Fixes
package/README.md CHANGED
@@ -28,11 +28,11 @@ npm i @intlify/unplugin-vue-i18n
28
28
 
29
29
  ```ts
30
30
  // vite.config.ts
31
- import vueI18n from '@intlify/unplugin-vue-i18n/vite'
31
+ import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
32
32
 
33
33
  export default defineConfig({
34
34
  plugins: [
35
- vueI18n({ /* options */ }),
35
+ VueI18nPlugin({ /* options */ }),
36
36
  ],
37
37
  })
38
38
  ```
@@ -56,6 +56,32 @@ module.exports = {
56
56
 
57
57
  <br></details>
58
58
 
59
+ <details>
60
+ <summary>Nuxt</summary><br>
61
+
62
+ ```ts
63
+ // nuxt.config.ts
64
+ import { defineNuxtConfig } from 'nuxt'
65
+ import VueI18nPlugin from '@intlify/unplugin-vue-i18n'
66
+
67
+ export default defineNuxtConfig({
68
+ vite: {
69
+ plugins: [
70
+ VueI18nPlugin.vite({ /* options */ }),
71
+ ],
72
+ },
73
+ // When using Webpack
74
+ // builder: '@nuxt/webpack-builder',
75
+ webpack: {
76
+ plugins: [
77
+ VueI18nPlugin.webpack({ /* options */ }),
78
+ ]
79
+ }
80
+ })
81
+ ```
82
+
83
+ <br></details>
84
+
59
85
  ## 🚀 Usage
60
86
 
61
87
  ### i18n resources pre-compilation
@@ -199,6 +225,19 @@ If you want type definition of `@intlify/unplugin-vue-i18n/messages`, add `unplu
199
225
  }
200
226
  ```
201
227
 
228
+
229
+ ## 📦 Automatic bundling
230
+ ### For Vue I18n
231
+ As noted [here](https://vue-i18n.intlify.dev/installation.html#explanation-of-different-builds), NPM provides many different builds of Vue I18n.
232
+
233
+ This plugin will automatically select and bundle Vue I18n build according to the following behavior:
234
+
235
+ - development: `vue-i18n.esm-bundler.js`
236
+ - production: `vue-i18n.runtime.esm-bundler.js`
237
+
238
+ About details, See the [here](https://vue-i18n.intlify.dev/guide/advanced/optimization.html#improve-performance-and-reduce-bundle-size-with-runtime-build-only)
239
+
240
+
202
241
  ## 🔧 Options
203
242
 
204
243
  ### `include`
@@ -217,6 +256,42 @@ If you want type definition of `@intlify/unplugin-vue-i18n/messages`, add `unplu
217
256
 
218
257
  Note `json` resources matches this option, it will be handled **before the internal json plugin of bundler, and will not be processed afterwards**, else the option doesn't match, the bundler side will handle.
219
258
 
259
+ ### `runtimeOnly`
260
+
261
+ - **Type:** `boolean`
262
+ - **Default:** `true`
263
+
264
+ Whether or not to automatically use Vue I18n **runtime-only** in production build, set `vue-i18n.runtime.esm-bundler.js` in the `vue-i18n` field of bundler config, the below:
265
+
266
+ ```
267
+ - vite config: `resolve.alias`
268
+ - webpack config: `resolve.alias`
269
+ ```
270
+
271
+ If `false` is specified, Vue I18n (vue-i18n) package.json `module` field will be used.
272
+
273
+ For more details, See [here](#-automatic-bundling)
274
+
275
+ ### `compositionOnly`
276
+
277
+ - **Type:** `boolean`
278
+ - **Default:** `true`
279
+
280
+ Whether to make vue-i18n API only composition API. **By default the legacy API is tree-shaken.**
281
+
282
+ For more details, See [here](https://vue-i18n.intlify.dev/guide/advanced/optimization.html#reduce-bundle-size-with-feature-build-flags)
283
+
284
+ ### `fullInstall`
285
+
286
+ - **Type:** `boolean`
287
+ - **Default:** `true`
288
+
289
+ Whether to install the full set of APIs, components, etc. provided by Vue I18n. By default, all of them will be installed.
290
+
291
+ If `false` is specified, **buld-in components and directive will not be installed in vue and will be tree-shaken.**
292
+
293
+ For more details, See [here](https://vue-i18n.intlify.dev/guide/advanced/optimization.html#reduce-bundle-size-with-feature-build-flags)
294
+
220
295
  ### `forceStringify`
221
296
 
222
297
  - **Type:** `boolean`
@@ -349,7 +424,6 @@ If you want type definition of `@intlify/unplugin-vue-i18n/messages`, add `unplu
349
424
 
350
425
  ## ✅ TODO
351
426
  - [ ] Bundling optimizations
352
- - [ ] Support nuxt
353
427
 
354
428
  ## 📜 Changelog
355
429
 
package/lib/index.cjs CHANGED
@@ -116,6 +116,12 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
116
116
  const useClassComponent = !!options.useClassComponent;
117
117
  const bridge = !!options.bridge;
118
118
  debug("bridge", bridge);
119
+ const runtimeOnly = shared.isBoolean(options.runtimeOnly) ? options.runtimeOnly : true;
120
+ debug("runtimeOnly", runtimeOnly);
121
+ const compositionOnly = shared.isBoolean(options.compositionOnly) ? options.compositionOnly : true;
122
+ debug("compositionOnly", compositionOnly);
123
+ const fullInstall = shared.isBoolean(options.fullInstall) ? options.fullInstall : true;
124
+ debug("fullInstall", fullInstall);
119
125
  let isProduction = false;
120
126
  let sourceMap = false;
121
127
  return {
@@ -131,6 +137,25 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
131
137
  }
132
138
  },
133
139
  vite: {
140
+ config(config, { command }) {
141
+ normalizeConfigResolveAlias(config.resolve, meta.framework);
142
+ if (command === "build" && runtimeOnly) {
143
+ if (shared.isArray(config.resolve.alias)) {
144
+ config.resolve.alias.push({
145
+ find: "vue-i18n",
146
+ replacement: `vue-i18n/dist/vue-i18n.runtime.esm-bundler.js`
147
+ });
148
+ } else if (shared.isObject(config.resolve.alias)) {
149
+ config.resolve.alias["vue-i18n"] = `vue-i18n/dist/vue-i18n.runtime.esm-bundler.js`;
150
+ }
151
+ }
152
+ config.define = config.define || {};
153
+ config.define["__VUE_I18N_LEGACY_API__"] = !compositionOnly;
154
+ debug(`set __VUE_I18N_LEGACY_API__ is '${config.define["__VUE_I18N_LEGACY_API__"]}'`);
155
+ config.define["__VUE_I18N_FULL_INSTALL__"] = fullInstall;
156
+ debug(`set __VUE_I18N_FULL_INSTALL__ is '${config.define["__VUE_I18N_FULL_INSTALL__"]}'`);
157
+ config.define["__VUE_I18N_PROD_DEVTOOLS__"] = false;
158
+ },
134
159
  configResolved(config) {
135
160
  isProduction = config.isProduction;
136
161
  sourceMap = config.command === "build" ? !!config.build.sourcemap : false;
@@ -156,6 +181,23 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
156
181
  isProduction = compiler.options.mode !== "development";
157
182
  sourceMap = !!compiler.options.devtool;
158
183
  debug(`webpack: isProduction = ${isProduction}, sourceMap = ${sourceMap}`);
184
+ if (isProduction && runtimeOnly) {
185
+ normalizeConfigResolveAlias(compiler.options.resolve, meta.framework);
186
+ compiler.options.resolve.alias["vue-i18n"] = `vue-i18n/dist/vue-i18n.runtime.esm-bundler.js`;
187
+ }
188
+ loadWebpack().then((webpack) => {
189
+ if (webpack) {
190
+ compiler.options.plugins.push(new webpack.DefinePlugin({
191
+ __VUE_I18N_LEGACY_API__: JSON.stringify(compositionOnly),
192
+ __VUE_I18N_FULL_INSTALL__: JSON.stringify(fullInstall),
193
+ __INTLIFY_PROD_DEVTOOLS__: "false"
194
+ }));
195
+ debug(`set __VUE_I18N_LEGACY_API__ is '${compositionOnly}'`);
196
+ debug(`set __VUE_I18N_FULL_INSTALL__ is '${fullInstall}'`);
197
+ } else {
198
+ debug("ignore vue-i18n feature flags with webpack.DefinePlugin");
199
+ }
200
+ });
159
201
  if (compiler.options.module) {
160
202
  compiler.options.module.rules.push({
161
203
  test: /\.(json5?|ya?ml)$/,
@@ -259,6 +301,33 @@ const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
259
301
  }
260
302
  };
261
303
  });
304
+ function normalizeConfigResolveAlias(resolve, framework) {
305
+ if (resolve && resolve.alias) {
306
+ return;
307
+ }
308
+ if (!resolve) {
309
+ if (framework === "vite") {
310
+ resolve = { alias: [] };
311
+ } else if (framework === "webpack") {
312
+ resolve = { alias: {} };
313
+ }
314
+ } else if (!resolve.alias) {
315
+ if (framework === "vite") {
316
+ resolve.alias = [];
317
+ } else if (framework === "webpack") {
318
+ resolve.alias = {};
319
+ }
320
+ }
321
+ }
322
+ async function loadWebpack() {
323
+ let webpack = null;
324
+ try {
325
+ webpack = await import('webpack').then((m) => m.default || m);
326
+ } catch (e) {
327
+ console.warn(`[@intlify/unplugin-vue-i18n] webpack not found, please install webpack.`);
328
+ }
329
+ return webpack;
330
+ }
262
331
  async function generateBundleResources(resources, query, isProduction, {
263
332
  forceStringify = false,
264
333
  isGlobal = false,
package/lib/index.mjs CHANGED
@@ -2,7 +2,7 @@ import { createUnplugin } from 'unplugin';
2
2
  import { normalize, parse } from 'pathe';
3
3
  import createDebug from 'debug';
4
4
  import fg from 'fast-glob';
5
- import { isString, isArray, isEmptyObject, isNumber, assign } from '@intlify/shared';
5
+ import { isString, isArray, isBoolean, isObject, isEmptyObject, isNumber, assign } from '@intlify/shared';
6
6
  import { createFilter } from '@rollup/pluginutils';
7
7
  import { generateJSON, generateYAML } from '@intlify/bundle-utils';
8
8
  import { parse as parse$1 } from '@vue/compiler-sfc';
@@ -105,6 +105,12 @@ const unplugin = createUnplugin((options = {}, meta) => {
105
105
  const useClassComponent = !!options.useClassComponent;
106
106
  const bridge = !!options.bridge;
107
107
  debug("bridge", bridge);
108
+ const runtimeOnly = isBoolean(options.runtimeOnly) ? options.runtimeOnly : true;
109
+ debug("runtimeOnly", runtimeOnly);
110
+ const compositionOnly = isBoolean(options.compositionOnly) ? options.compositionOnly : true;
111
+ debug("compositionOnly", compositionOnly);
112
+ const fullInstall = isBoolean(options.fullInstall) ? options.fullInstall : true;
113
+ debug("fullInstall", fullInstall);
108
114
  let isProduction = false;
109
115
  let sourceMap = false;
110
116
  return {
@@ -120,6 +126,25 @@ const unplugin = createUnplugin((options = {}, meta) => {
120
126
  }
121
127
  },
122
128
  vite: {
129
+ config(config, { command }) {
130
+ normalizeConfigResolveAlias(config.resolve, meta.framework);
131
+ if (command === "build" && runtimeOnly) {
132
+ if (isArray(config.resolve.alias)) {
133
+ config.resolve.alias.push({
134
+ find: "vue-i18n",
135
+ replacement: `vue-i18n/dist/vue-i18n.runtime.esm-bundler.js`
136
+ });
137
+ } else if (isObject(config.resolve.alias)) {
138
+ config.resolve.alias["vue-i18n"] = `vue-i18n/dist/vue-i18n.runtime.esm-bundler.js`;
139
+ }
140
+ }
141
+ config.define = config.define || {};
142
+ config.define["__VUE_I18N_LEGACY_API__"] = !compositionOnly;
143
+ debug(`set __VUE_I18N_LEGACY_API__ is '${config.define["__VUE_I18N_LEGACY_API__"]}'`);
144
+ config.define["__VUE_I18N_FULL_INSTALL__"] = fullInstall;
145
+ debug(`set __VUE_I18N_FULL_INSTALL__ is '${config.define["__VUE_I18N_FULL_INSTALL__"]}'`);
146
+ config.define["__VUE_I18N_PROD_DEVTOOLS__"] = false;
147
+ },
123
148
  configResolved(config) {
124
149
  isProduction = config.isProduction;
125
150
  sourceMap = config.command === "build" ? !!config.build.sourcemap : false;
@@ -145,6 +170,23 @@ const unplugin = createUnplugin((options = {}, meta) => {
145
170
  isProduction = compiler.options.mode !== "development";
146
171
  sourceMap = !!compiler.options.devtool;
147
172
  debug(`webpack: isProduction = ${isProduction}, sourceMap = ${sourceMap}`);
173
+ if (isProduction && runtimeOnly) {
174
+ normalizeConfigResolveAlias(compiler.options.resolve, meta.framework);
175
+ compiler.options.resolve.alias["vue-i18n"] = `vue-i18n/dist/vue-i18n.runtime.esm-bundler.js`;
176
+ }
177
+ loadWebpack().then((webpack) => {
178
+ if (webpack) {
179
+ compiler.options.plugins.push(new webpack.DefinePlugin({
180
+ __VUE_I18N_LEGACY_API__: JSON.stringify(compositionOnly),
181
+ __VUE_I18N_FULL_INSTALL__: JSON.stringify(fullInstall),
182
+ __INTLIFY_PROD_DEVTOOLS__: "false"
183
+ }));
184
+ debug(`set __VUE_I18N_LEGACY_API__ is '${compositionOnly}'`);
185
+ debug(`set __VUE_I18N_FULL_INSTALL__ is '${fullInstall}'`);
186
+ } else {
187
+ debug("ignore vue-i18n feature flags with webpack.DefinePlugin");
188
+ }
189
+ });
148
190
  if (compiler.options.module) {
149
191
  compiler.options.module.rules.push({
150
192
  test: /\.(json5?|ya?ml)$/,
@@ -248,6 +290,33 @@ const unplugin = createUnplugin((options = {}, meta) => {
248
290
  }
249
291
  };
250
292
  });
293
+ function normalizeConfigResolveAlias(resolve, framework) {
294
+ if (resolve && resolve.alias) {
295
+ return;
296
+ }
297
+ if (!resolve) {
298
+ if (framework === "vite") {
299
+ resolve = { alias: [] };
300
+ } else if (framework === "webpack") {
301
+ resolve = { alias: {} };
302
+ }
303
+ } else if (!resolve.alias) {
304
+ if (framework === "vite") {
305
+ resolve.alias = [];
306
+ } else if (framework === "webpack") {
307
+ resolve.alias = {};
308
+ }
309
+ }
310
+ }
311
+ async function loadWebpack() {
312
+ let webpack = null;
313
+ try {
314
+ webpack = await import('webpack').then((m) => m.default || m);
315
+ } catch (e) {
316
+ console.warn(`[@intlify/unplugin-vue-i18n] webpack not found, please install webpack.`);
317
+ }
318
+ return webpack;
319
+ }
251
320
  async function generateBundleResources(resources, query, isProduction, {
252
321
  forceStringify = false,
253
322
  isGlobal = false,
package/lib/types.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  declare type SFCLangFormat = 'json' | 'json5' | 'yml' | 'yaml';
2
2
  interface PluginOptions {
3
3
  include?: string | string[];
4
+ runtimeOnly?: boolean;
5
+ compositionOnly?: boolean;
6
+ fullInstall?: boolean;
4
7
  forceStringify?: boolean;
5
8
  defaultSFCLang?: SFCLangFormat;
6
9
  globalSFCScope?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlify/unplugin-vue-i18n",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "unplugin for Vue I18n",
5
5
  "author": {
6
6
  "name": "kazuya kawaguchi",