@intlify/unplugin-vue-i18n 0.0.0 → 0.1.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 +9 -0
- package/README.md +209 -2
- package/lib/index.cjs +352 -0
- package/lib/index.d.ts +7 -3
- package/lib/index.mjs +340 -0
- package/lib/types.cjs +2 -0
- package/lib/types.d.ts +10 -1
- package/lib/types.mjs +1 -0
- package/lib/vite.cjs +18 -0
- package/lib/vite.d.ts +6 -0
- package/lib/vite.mjs +16 -0
- package/lib/webpack.cjs +18 -0
- package/lib/webpack.d.ts +6 -0
- package/lib/webpack.mjs +16 -0
- package/package.json +38 -11
- package/index.mjs +0 -1
- package/lib/index.js +0 -11
- package/lib/types.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
## @intlify/unplugin-vue-i18n@0.1.0 (2022-05-06)
|
|
3
|
+
|
|
4
|
+
#### :star: Features
|
|
5
|
+
* [#113](https://github.com/intlify/bundle-tools/pull/113) feat: unplugin basic implementation for vue-i18n ([@kazupon](https://github.com/kazupon))
|
|
6
|
+
|
|
7
|
+
#### Committers: 1
|
|
8
|
+
- kazuya kawaguchi ([@kazupon](https://github.com/kazupon))
|
|
9
|
+
|
|
1
10
|
## @intlify/unplugin-vue-i18n@0.0.0 (2022-05-02)
|
|
2
11
|
|
|
3
12
|
:tada: Initial release.
|
package/README.md
CHANGED
|
@@ -1,8 +1,215 @@
|
|
|
1
|
-
# @intlify/
|
|
1
|
+
# @intlify/unplugin-vue-i18n
|
|
2
|
+
|
|
3
|
+
[](https://github.com/intlify/bundle-tools/actions/workflows/lint.yml)
|
|
4
|
+
[](https://github.com/intlify/bundle-tools/actions/workflows/test.yml)
|
|
5
|
+
[](https://www.npmjs.com/package/@intlify/unplugin-vue-i18n)
|
|
6
|
+
|
|
2
7
|
|
|
3
8
|
unplugin for Vue I18n
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## 🌟 Features
|
|
11
|
+
- i18n resource pre-compilation
|
|
12
|
+
- i18n custom block
|
|
13
|
+
- i18n resource definition
|
|
14
|
+
- i18n resource importing
|
|
15
|
+
- Locale of i18n resource definition
|
|
16
|
+
- Locale of i18n resource definition for global scope
|
|
17
|
+
- i18n resource formatting
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## 💿 Installation
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
npm i @intlify/unplugin-vue-i18n
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
<details>
|
|
27
|
+
<summary>Vite</summary><br>
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
// vite.config.ts
|
|
31
|
+
import vueI18n from 'unplugin-vue-i18n/vite'
|
|
32
|
+
|
|
33
|
+
export default defineConfig({
|
|
34
|
+
plugins: [
|
|
35
|
+
vueI18n({ /* options */ }),
|
|
36
|
+
],
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
<br></details>
|
|
41
|
+
|
|
42
|
+
<details>
|
|
43
|
+
<summary>Webpack</summary><br>
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
const VueI18nPlugin = require('unplugin-vue-i18n/webpack')
|
|
47
|
+
|
|
48
|
+
// webpack.config.js
|
|
49
|
+
module.exports = {
|
|
50
|
+
/* ... */
|
|
51
|
+
plugins: [
|
|
52
|
+
VueI18nPlugin({ /* options */ })
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
<br></details>
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## 🔧 Options
|
|
61
|
+
|
|
62
|
+
### `include`
|
|
63
|
+
|
|
64
|
+
- **Type:** `string | string[] | undefined`
|
|
65
|
+
- **Default:** `undefined`
|
|
66
|
+
|
|
67
|
+
A [minimatch](https://github.com/isaacs/minimatch) pattern, or array of patterns, you can specify a path to pre-compile i18n resources files. The extensions of i18n resources to be precompiled are as follows:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
- json
|
|
71
|
+
- json5
|
|
72
|
+
- yaml
|
|
73
|
+
- yml
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Note `json` resources matches this option, it will be handled **before the internal json plugin of Vite, and will not be processed afterwards**, else the option doesn't match, the Vite side will handle.
|
|
77
|
+
|
|
78
|
+
### `forceStringify`
|
|
79
|
+
|
|
80
|
+
- **Type:** `boolean`
|
|
81
|
+
- **Default:** `false`
|
|
82
|
+
|
|
83
|
+
Whether pre-compile number and boolean values as message functions that return the string value.
|
|
84
|
+
|
|
85
|
+
For example, the following json resources:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"trueValue": true,
|
|
90
|
+
"falseValue": false,
|
|
91
|
+
"nullValue": null,
|
|
92
|
+
"numberValue": 1
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
after pre-compiled (development):
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
export default {
|
|
100
|
+
"trueValue": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize(["true"])};fn.source="true";return fn;})(),
|
|
101
|
+
"falseValue": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize(["false"])};fn.source="false";return fn;})(),
|
|
102
|
+
"nullValue": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize(["null"])};fn.source="null";return fn;})(),
|
|
103
|
+
"numberValue": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize(["1"])};fn.source="1";return fn;})()
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### `defaultSFCLang`
|
|
108
|
+
|
|
109
|
+
- **Type:** `string`
|
|
110
|
+
- **Default:** `'json'`
|
|
111
|
+
|
|
112
|
+
Specify the content for all your inlined `i18n` custom blocks on your `SFC`.
|
|
113
|
+
|
|
114
|
+
`defaultSFCLang` must have one of the following values:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
- json
|
|
118
|
+
- json5
|
|
119
|
+
- yaml
|
|
120
|
+
- yml
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
On inlined `i18n` custom blocks that have specified the `lang` attribute, the `defaultSFCLang` is not applied.
|
|
124
|
+
|
|
125
|
+
For example, with `defaultSFCLang: "yaml"` or `defaultSFCLang: "yml"`, this custom block:
|
|
126
|
+
```html
|
|
127
|
+
<i18n lang="yaml">
|
|
128
|
+
en:
|
|
129
|
+
hello: Hello
|
|
130
|
+
es:
|
|
131
|
+
hello: Hola
|
|
132
|
+
</i18n>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
and this another one, are equivalent:
|
|
136
|
+
```html
|
|
137
|
+
<i18n>
|
|
138
|
+
en:
|
|
139
|
+
hello: Hello
|
|
140
|
+
es:
|
|
141
|
+
hello: Hola
|
|
142
|
+
</i18n>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### `globalSFCScope`
|
|
146
|
+
|
|
147
|
+
- **Type:** `boolean`
|
|
148
|
+
- **Default:** `undefined`
|
|
149
|
+
|
|
150
|
+
Whether to include all `i18n` custom blocks on your `SFC` on `global` scope.
|
|
151
|
+
|
|
152
|
+
If `true`, it will be applied to all inlined `i18n` or `imported` custom blocks.
|
|
153
|
+
|
|
154
|
+
**Warning**: beware enabling `globalSFCScope: true`, all `i18n` custom blocks in all your `SFC` will be on `global` scope.
|
|
155
|
+
|
|
156
|
+
For example, with `globalSFCScope: true`, this custom block:
|
|
157
|
+
|
|
158
|
+
```html
|
|
159
|
+
<i18n lang="yaml" global>
|
|
160
|
+
en:
|
|
161
|
+
hello: Hello
|
|
162
|
+
es:
|
|
163
|
+
hello: Hola
|
|
164
|
+
</i18n>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
and this another one, are equivalent:
|
|
168
|
+
|
|
169
|
+
```html
|
|
170
|
+
<i18n lang="yaml">
|
|
171
|
+
en:
|
|
172
|
+
hello: Hello
|
|
173
|
+
es:
|
|
174
|
+
hello: Hola
|
|
175
|
+
</i18n>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
You can also use `defaultSFCLang: "yaml"`, following with previous example, this another is also equivalent to previous ones:
|
|
179
|
+
|
|
180
|
+
```html
|
|
181
|
+
<i18n>
|
|
182
|
+
en:
|
|
183
|
+
hello: Hello
|
|
184
|
+
es:
|
|
185
|
+
hello: Hola
|
|
186
|
+
</i18n>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### `bridge`
|
|
190
|
+
|
|
191
|
+
- **Type:** `boolean`
|
|
192
|
+
- **Default:** `false`
|
|
193
|
+
|
|
194
|
+
The mode to birdge the i18n custom block to work in both vue-i18n@v8.x and vue-i18n@v9.x environments.
|
|
195
|
+
|
|
196
|
+
To support in a smooth transition from vue-i18n@v8.x to vue-i18n@v9.x, we provide a mode that bundles the i18n custom block to be available in either version.
|
|
197
|
+
|
|
198
|
+
> ⚠️ Note that if you set `bridge: true`, the bundle size will increase. It is recommended to disable this mode after the migration from vue-i18n@v8.26 to vue-i18n@v9.x is completed.
|
|
199
|
+
|
|
200
|
+
### `useClassComponent`
|
|
201
|
+
|
|
202
|
+
- **Type:** `boolean`
|
|
203
|
+
- **Default:** `false`
|
|
204
|
+
|
|
205
|
+
This option that to use i18n custom blocks in `vue-class-component`.
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
## ✅ TODO
|
|
209
|
+
- [ ] Virtual resource importing
|
|
210
|
+
- [ ] Bundling optimizations
|
|
211
|
+
- [ ] i18n custom block birdge mode (for vite)
|
|
212
|
+
- [ ] Support nuxt
|
|
6
213
|
|
|
7
214
|
## 📜 Changelog
|
|
8
215
|
|
package/lib/index.cjs
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const unplugin$1 = require('unplugin');
|
|
6
|
+
const pathe = require('pathe');
|
|
7
|
+
const createDebug = require('debug');
|
|
8
|
+
const fg = require('fast-glob');
|
|
9
|
+
const shared = require('@intlify/shared');
|
|
10
|
+
const pluginutils = require('@rollup/pluginutils');
|
|
11
|
+
const bundleUtils = require('@intlify/bundle-utils');
|
|
12
|
+
const compilerSfc = require('@vue/compiler-sfc');
|
|
13
|
+
const JSON5 = require('json5');
|
|
14
|
+
const yaml = require('js-yaml');
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
|
|
17
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
|
|
18
|
+
|
|
19
|
+
const createDebug__default = /*#__PURE__*/_interopDefaultLegacy(createDebug);
|
|
20
|
+
const fg__default = /*#__PURE__*/_interopDefaultLegacy(fg);
|
|
21
|
+
const JSON5__default = /*#__PURE__*/_interopDefaultLegacy(JSON5);
|
|
22
|
+
const yaml__default = /*#__PURE__*/_interopDefaultLegacy(yaml);
|
|
23
|
+
|
|
24
|
+
function parseVueRequest(id) {
|
|
25
|
+
const [filename, rawQuery] = id.split(`?`, 2);
|
|
26
|
+
const params = new URLSearchParams(rawQuery);
|
|
27
|
+
const ret = {};
|
|
28
|
+
const langPart = Object.keys(Object.fromEntries(params)).find((key) => /lang\./i.test(key));
|
|
29
|
+
ret.vue = params.has("vue");
|
|
30
|
+
ret.global = params.has("global");
|
|
31
|
+
ret.src = params.has("src");
|
|
32
|
+
ret.raw = params.has("raw");
|
|
33
|
+
if (params.has("type")) {
|
|
34
|
+
ret.type = params.get("type");
|
|
35
|
+
}
|
|
36
|
+
if (params.has("blockType")) {
|
|
37
|
+
ret.blockType = params.get("blockType");
|
|
38
|
+
}
|
|
39
|
+
if (params.has("index")) {
|
|
40
|
+
ret.index = Number(params.get("index"));
|
|
41
|
+
}
|
|
42
|
+
if (params.has("locale")) {
|
|
43
|
+
ret.locale = params.get("locale");
|
|
44
|
+
}
|
|
45
|
+
if (langPart) {
|
|
46
|
+
const [, lang] = langPart.split(".");
|
|
47
|
+
ret.lang = lang;
|
|
48
|
+
} else if (params.has("lang")) {
|
|
49
|
+
ret.lang = params.get("lang");
|
|
50
|
+
}
|
|
51
|
+
if (params.has("issuerPath")) {
|
|
52
|
+
ret.issuerPath = params.get("issuerPath");
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
filename,
|
|
56
|
+
query: ret
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function createBridgeCodeGenerator(source, query) {
|
|
61
|
+
return () => {
|
|
62
|
+
const data = convert(source, query.lang);
|
|
63
|
+
let value = JSON.parse(data);
|
|
64
|
+
if (shared.isString(query.locale)) {
|
|
65
|
+
value = Object.assign({}, { [query.locale]: value });
|
|
66
|
+
}
|
|
67
|
+
return JSON.stringify(value).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/\\/g, "\\\\").replace(/\u0027/g, "\\u0027");
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function convert(source, lang) {
|
|
71
|
+
switch (lang) {
|
|
72
|
+
case "yaml":
|
|
73
|
+
case "yml":
|
|
74
|
+
const data = yaml__default.load(source);
|
|
75
|
+
return JSON.stringify(data, void 0, " ");
|
|
76
|
+
case "json5":
|
|
77
|
+
return JSON.stringify(JSON5__default.parse(source));
|
|
78
|
+
default:
|
|
79
|
+
return source;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function warn(...args) {
|
|
84
|
+
console.warn(`[unplugin-vue-i18n] `, ...args);
|
|
85
|
+
}
|
|
86
|
+
function error(...args) {
|
|
87
|
+
console.error(`[unplugin-vue-i18n] `, ...args);
|
|
88
|
+
}
|
|
89
|
+
async function getRaw(path) {
|
|
90
|
+
return fs.promises.readFile(path, { encoding: "utf-8" });
|
|
91
|
+
}
|
|
92
|
+
function raiseError(message) {
|
|
93
|
+
throw new Error(`[unplugin-vue-i18n] ${message}`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const INTLIFY_BUNDLE_IMPORT_ID = "@intlify/unplugin-vue-i18n/messages";
|
|
97
|
+
const INTLIFY_BUNDLE_IMPORT_DEPRECTED_ID = "@intlify/vite-plugin-vue-i18n/messages";
|
|
98
|
+
const debug = createDebug__default("unplugin-vue-i18n");
|
|
99
|
+
const unplugin = unplugin$1.createUnplugin((options = {}, meta) => {
|
|
100
|
+
debug("plugin options:", options, meta.framework);
|
|
101
|
+
if (!["vite", "webpack"].includes(meta.framework)) {
|
|
102
|
+
raiseError(`This plugin is supported 'vite' and 'webpack' only`);
|
|
103
|
+
}
|
|
104
|
+
let include = options.include;
|
|
105
|
+
if (include) {
|
|
106
|
+
if (shared.isArray(include)) {
|
|
107
|
+
include = include.map((item) => pathe.normalize(item));
|
|
108
|
+
} else if (shared.isString(include)) {
|
|
109
|
+
include = pathe.normalize(include);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const filter = pluginutils.createFilter(include);
|
|
113
|
+
const forceStringify = !!options.forceStringify;
|
|
114
|
+
const defaultSFCLang = shared.isString(options.defaultSFCLang) ? options.defaultSFCLang : "json";
|
|
115
|
+
const globalSFCScope = !!options.globalSFCScope;
|
|
116
|
+
const useClassComponent = !!options.useClassComponent;
|
|
117
|
+
const bridge = !!options.bridge;
|
|
118
|
+
debug("bridge", bridge);
|
|
119
|
+
let isProduction = false;
|
|
120
|
+
let sourceMap = false;
|
|
121
|
+
return {
|
|
122
|
+
name: "unplugin-vue-i18n",
|
|
123
|
+
enforce: meta.framework === "vite" ? "pre" : "post",
|
|
124
|
+
vite: {
|
|
125
|
+
configResolved(config) {
|
|
126
|
+
isProduction = config.isProduction;
|
|
127
|
+
sourceMap = config.command === "build" ? !!config.build.sourcemap : false;
|
|
128
|
+
debug(`configResolved: isProduction = ${isProduction}, sourceMap = ${sourceMap}`);
|
|
129
|
+
const jsonPlugin = config.plugins.find((p) => p.name === "vite:json");
|
|
130
|
+
if (jsonPlugin) {
|
|
131
|
+
const orgTransform = jsonPlugin.transform;
|
|
132
|
+
jsonPlugin.transform = async function(code, id) {
|
|
133
|
+
if (!/\.json$/.test(id) || filter(id)) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const { query } = parseVueRequest(id);
|
|
137
|
+
if (query.vue) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
debug("org json plugin");
|
|
141
|
+
return orgTransform.apply(this, [code, id]);
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
webpack(compiler) {
|
|
147
|
+
isProduction = compiler.options.mode !== "development";
|
|
148
|
+
sourceMap = !!compiler.options.devtool;
|
|
149
|
+
debug(`webpack: isProduction = ${isProduction}, sourceMap = ${sourceMap}`);
|
|
150
|
+
if (compiler.options.module) {
|
|
151
|
+
compiler.options.module.rules.push({
|
|
152
|
+
test: /\.(json5?|ya?ml)$/,
|
|
153
|
+
type: "javascript/auto",
|
|
154
|
+
exclude: include
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
resolveId(id, importer) {
|
|
159
|
+
debug("resolveId", id, importer);
|
|
160
|
+
if (id === INTLIFY_BUNDLE_IMPORT_DEPRECTED_ID) {
|
|
161
|
+
warn(`deprected '${INTLIFY_BUNDLE_IMPORT_DEPRECTED_ID}', you should switch to '${INTLIFY_BUNDLE_IMPORT_ID}'`);
|
|
162
|
+
return id;
|
|
163
|
+
}
|
|
164
|
+
if (id === INTLIFY_BUNDLE_IMPORT_ID) {
|
|
165
|
+
return id;
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
async load(id) {
|
|
169
|
+
debug("load", id);
|
|
170
|
+
const { query } = parseVueRequest(id);
|
|
171
|
+
if ([INTLIFY_BUNDLE_IMPORT_DEPRECTED_ID, INTLIFY_BUNDLE_IMPORT_ID].includes(id) && include) {
|
|
172
|
+
let resourcePaths = [];
|
|
173
|
+
const includePaths = shared.isArray(include) ? include : [include];
|
|
174
|
+
for (const inc of includePaths) {
|
|
175
|
+
resourcePaths = [...resourcePaths, ...await fg__default(inc)];
|
|
176
|
+
}
|
|
177
|
+
resourcePaths = resourcePaths.filter((el, pos) => resourcePaths.indexOf(el) === pos);
|
|
178
|
+
const code = await generateBundleResources(resourcePaths, query, isProduction, {
|
|
179
|
+
forceStringify,
|
|
180
|
+
bridge,
|
|
181
|
+
useClassComponent
|
|
182
|
+
});
|
|
183
|
+
return {
|
|
184
|
+
code,
|
|
185
|
+
map: { mappings: "" }
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
async transform(code, id) {
|
|
190
|
+
const { filename, query } = parseVueRequest(id);
|
|
191
|
+
debug("transform", id, JSON.stringify(query), filename);
|
|
192
|
+
debug("transform (code)", code);
|
|
193
|
+
let langInfo = defaultSFCLang;
|
|
194
|
+
let inSourceMap;
|
|
195
|
+
if (!query.vue) {
|
|
196
|
+
if (/\.(json5?|ya?ml)$/.test(id) && filter(id)) {
|
|
197
|
+
langInfo = pathe.parse(filename).ext;
|
|
198
|
+
const generate = /\.?json5?/.test(langInfo) ? bundleUtils.generateJSON : bundleUtils.generateYAML;
|
|
199
|
+
const parseOptions = getOptions(filename, isProduction, query, sourceMap, {
|
|
200
|
+
inSourceMap,
|
|
201
|
+
isGlobal: globalSFCScope,
|
|
202
|
+
useClassComponent,
|
|
203
|
+
bridge,
|
|
204
|
+
forceStringify
|
|
205
|
+
});
|
|
206
|
+
debug("parseOptions", parseOptions);
|
|
207
|
+
const { code: generatedCode, map } = generate(code, parseOptions, bridge ? createBridgeCodeGenerator(code, query) : void 0);
|
|
208
|
+
debug("generated code", generatedCode);
|
|
209
|
+
debug("sourcemap", map, sourceMap);
|
|
210
|
+
if (code === generatedCode)
|
|
211
|
+
return;
|
|
212
|
+
return {
|
|
213
|
+
code: generatedCode,
|
|
214
|
+
map: sourceMap ? map : { mappings: "" }
|
|
215
|
+
};
|
|
216
|
+
} else {
|
|
217
|
+
return {
|
|
218
|
+
code,
|
|
219
|
+
map: { mappings: "", version: "3", sources: [] }
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
} else {
|
|
223
|
+
if (isCustomBlock(query)) {
|
|
224
|
+
if (shared.isString(query.lang)) {
|
|
225
|
+
langInfo = query.src ? query.lang === "i18n" ? "json" : query.lang : query.lang;
|
|
226
|
+
} else if (defaultSFCLang) {
|
|
227
|
+
langInfo = defaultSFCLang;
|
|
228
|
+
}
|
|
229
|
+
debug("langInfo", langInfo);
|
|
230
|
+
const generate = /\.?json5?/.test(langInfo) ? bundleUtils.generateJSON : bundleUtils.generateYAML;
|
|
231
|
+
const parseOptions = getOptions(filename, isProduction, query, sourceMap, {
|
|
232
|
+
inSourceMap,
|
|
233
|
+
isGlobal: globalSFCScope,
|
|
234
|
+
useClassComponent,
|
|
235
|
+
bridge,
|
|
236
|
+
forceStringify
|
|
237
|
+
});
|
|
238
|
+
debug("parseOptions", parseOptions);
|
|
239
|
+
const source = await getCode(code, filename, sourceMap, query, meta.framework);
|
|
240
|
+
const { code: generatedCode, map } = generate(source, parseOptions, bridge ? createBridgeCodeGenerator(source, query) : void 0);
|
|
241
|
+
debug("generated code", generatedCode);
|
|
242
|
+
debug("sourcemap", map, sourceMap);
|
|
243
|
+
if (code === generatedCode)
|
|
244
|
+
return;
|
|
245
|
+
return {
|
|
246
|
+
code: generatedCode,
|
|
247
|
+
map: sourceMap ? map : { mappings: "" }
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
});
|
|
254
|
+
async function generateBundleResources(resources, query, isProduction, {
|
|
255
|
+
forceStringify = false,
|
|
256
|
+
isGlobal = false,
|
|
257
|
+
bridge = false,
|
|
258
|
+
useClassComponent = false
|
|
259
|
+
}) {
|
|
260
|
+
const codes = [];
|
|
261
|
+
for (const res of resources) {
|
|
262
|
+
debug(`${res} bundle loading ...`);
|
|
263
|
+
if (/\.(json5?|ya?ml)$/.test(res)) {
|
|
264
|
+
const { ext, name } = pathe.parse(res);
|
|
265
|
+
const source = await getRaw(res);
|
|
266
|
+
const generate = /json5?/.test(ext) ? bundleUtils.generateJSON : bundleUtils.generateYAML;
|
|
267
|
+
const parseOptions = getOptions(res, isProduction, {}, false, {
|
|
268
|
+
isGlobal,
|
|
269
|
+
useClassComponent,
|
|
270
|
+
bridge,
|
|
271
|
+
forceStringify
|
|
272
|
+
});
|
|
273
|
+
parseOptions.type = "bare";
|
|
274
|
+
const { code } = generate(source, parseOptions, bridge ? createBridgeCodeGenerator(source, query) : void 0);
|
|
275
|
+
debug("generated code", code);
|
|
276
|
+
codes.push(`${JSON.stringify(name)}: ${code}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return `export default {
|
|
280
|
+
${codes.join(`,
|
|
281
|
+
`)}
|
|
282
|
+
}`;
|
|
283
|
+
}
|
|
284
|
+
async function getCode(source, filename, sourceMap, query, framework = "vite") {
|
|
285
|
+
const { index, issuerPath } = query;
|
|
286
|
+
if (!shared.isNumber(index)) {
|
|
287
|
+
raiseError(`unexpected index: ${index}`);
|
|
288
|
+
}
|
|
289
|
+
if (framework === "webpack") {
|
|
290
|
+
if (issuerPath) {
|
|
291
|
+
debug(`getCode (webpack) ${index} via issuerPath`, issuerPath);
|
|
292
|
+
return await getRaw(filename);
|
|
293
|
+
} else {
|
|
294
|
+
const result = compilerSfc.parse(await getRaw(filename), {
|
|
295
|
+
sourceMap,
|
|
296
|
+
filename
|
|
297
|
+
});
|
|
298
|
+
const block = result.descriptor.customBlocks[index];
|
|
299
|
+
if (block) {
|
|
300
|
+
const code = block.src ? await getRaw(block.src) : block.content;
|
|
301
|
+
debug(`getCode (webpack) ${index} from SFC`, code);
|
|
302
|
+
return code;
|
|
303
|
+
} else {
|
|
304
|
+
return source;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
} else {
|
|
308
|
+
return source;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function isCustomBlock(query) {
|
|
312
|
+
return !shared.isEmptyObject(query) && "vue" in query && (query["type"] === "custom" || query["type"] === "i18n" || query["blockType"] === "i18n");
|
|
313
|
+
}
|
|
314
|
+
function getOptions(filename, isProduction, query, sourceMap, {
|
|
315
|
+
inSourceMap = void 0,
|
|
316
|
+
forceStringify = false,
|
|
317
|
+
isGlobal = false,
|
|
318
|
+
bridge = false,
|
|
319
|
+
useClassComponent = false
|
|
320
|
+
}) {
|
|
321
|
+
const mode = isProduction ? "production" : "development";
|
|
322
|
+
const baseOptions = {
|
|
323
|
+
filename,
|
|
324
|
+
sourceMap,
|
|
325
|
+
inSourceMap,
|
|
326
|
+
forceStringify,
|
|
327
|
+
useClassComponent,
|
|
328
|
+
bridge,
|
|
329
|
+
env: mode,
|
|
330
|
+
onWarn: (msg) => {
|
|
331
|
+
warn(`${filename} ${msg}`);
|
|
332
|
+
},
|
|
333
|
+
onError: (msg) => {
|
|
334
|
+
error(`${filename} ${msg}`);
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
if (isCustomBlock(query)) {
|
|
338
|
+
return shared.assign(baseOptions, {
|
|
339
|
+
type: "sfc",
|
|
340
|
+
locale: shared.isString(query.locale) ? query.locale : "",
|
|
341
|
+
isGlobal: isGlobal || !!query.global
|
|
342
|
+
});
|
|
343
|
+
} else {
|
|
344
|
+
return shared.assign(baseOptions, {
|
|
345
|
+
type: "plain",
|
|
346
|
+
isGlobal: false
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
exports["default"] = unplugin;
|
|
352
|
+
exports.unplugin = unplugin;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export
|
|
1
|
+
import * as _unplugin from 'unplugin';
|
|
2
|
+
import { PluginOptions } from './types.js';
|
|
3
|
+
export { PluginOptions, SFCLangFormat } from './types.js';
|
|
4
|
+
|
|
5
|
+
declare const unplugin: _unplugin.UnpluginInstance<PluginOptions>;
|
|
6
|
+
|
|
7
|
+
export { unplugin as default, unplugin };
|
package/lib/index.mjs
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { createUnplugin } from 'unplugin';
|
|
2
|
+
import { normalize, parse } from 'pathe';
|
|
3
|
+
import createDebug from 'debug';
|
|
4
|
+
import fg from 'fast-glob';
|
|
5
|
+
import { isString, isArray, isEmptyObject, isNumber, assign } from '@intlify/shared';
|
|
6
|
+
import { createFilter } from '@rollup/pluginutils';
|
|
7
|
+
import { generateJSON, generateYAML } from '@intlify/bundle-utils';
|
|
8
|
+
import { parse as parse$1 } from '@vue/compiler-sfc';
|
|
9
|
+
import JSON5 from 'json5';
|
|
10
|
+
import yaml from 'js-yaml';
|
|
11
|
+
import { promises } from 'fs';
|
|
12
|
+
|
|
13
|
+
function parseVueRequest(id) {
|
|
14
|
+
const [filename, rawQuery] = id.split(`?`, 2);
|
|
15
|
+
const params = new URLSearchParams(rawQuery);
|
|
16
|
+
const ret = {};
|
|
17
|
+
const langPart = Object.keys(Object.fromEntries(params)).find((key) => /lang\./i.test(key));
|
|
18
|
+
ret.vue = params.has("vue");
|
|
19
|
+
ret.global = params.has("global");
|
|
20
|
+
ret.src = params.has("src");
|
|
21
|
+
ret.raw = params.has("raw");
|
|
22
|
+
if (params.has("type")) {
|
|
23
|
+
ret.type = params.get("type");
|
|
24
|
+
}
|
|
25
|
+
if (params.has("blockType")) {
|
|
26
|
+
ret.blockType = params.get("blockType");
|
|
27
|
+
}
|
|
28
|
+
if (params.has("index")) {
|
|
29
|
+
ret.index = Number(params.get("index"));
|
|
30
|
+
}
|
|
31
|
+
if (params.has("locale")) {
|
|
32
|
+
ret.locale = params.get("locale");
|
|
33
|
+
}
|
|
34
|
+
if (langPart) {
|
|
35
|
+
const [, lang] = langPart.split(".");
|
|
36
|
+
ret.lang = lang;
|
|
37
|
+
} else if (params.has("lang")) {
|
|
38
|
+
ret.lang = params.get("lang");
|
|
39
|
+
}
|
|
40
|
+
if (params.has("issuerPath")) {
|
|
41
|
+
ret.issuerPath = params.get("issuerPath");
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
filename,
|
|
45
|
+
query: ret
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function createBridgeCodeGenerator(source, query) {
|
|
50
|
+
return () => {
|
|
51
|
+
const data = convert(source, query.lang);
|
|
52
|
+
let value = JSON.parse(data);
|
|
53
|
+
if (isString(query.locale)) {
|
|
54
|
+
value = Object.assign({}, { [query.locale]: value });
|
|
55
|
+
}
|
|
56
|
+
return JSON.stringify(value).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/\\/g, "\\\\").replace(/\u0027/g, "\\u0027");
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function convert(source, lang) {
|
|
60
|
+
switch (lang) {
|
|
61
|
+
case "yaml":
|
|
62
|
+
case "yml":
|
|
63
|
+
const data = yaml.load(source);
|
|
64
|
+
return JSON.stringify(data, void 0, " ");
|
|
65
|
+
case "json5":
|
|
66
|
+
return JSON.stringify(JSON5.parse(source));
|
|
67
|
+
default:
|
|
68
|
+
return source;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function warn(...args) {
|
|
73
|
+
console.warn(`[unplugin-vue-i18n] `, ...args);
|
|
74
|
+
}
|
|
75
|
+
function error(...args) {
|
|
76
|
+
console.error(`[unplugin-vue-i18n] `, ...args);
|
|
77
|
+
}
|
|
78
|
+
async function getRaw(path) {
|
|
79
|
+
return promises.readFile(path, { encoding: "utf-8" });
|
|
80
|
+
}
|
|
81
|
+
function raiseError(message) {
|
|
82
|
+
throw new Error(`[unplugin-vue-i18n] ${message}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const INTLIFY_BUNDLE_IMPORT_ID = "@intlify/unplugin-vue-i18n/messages";
|
|
86
|
+
const INTLIFY_BUNDLE_IMPORT_DEPRECTED_ID = "@intlify/vite-plugin-vue-i18n/messages";
|
|
87
|
+
const debug = createDebug("unplugin-vue-i18n");
|
|
88
|
+
const unplugin = createUnplugin((options = {}, meta) => {
|
|
89
|
+
debug("plugin options:", options, meta.framework);
|
|
90
|
+
if (!["vite", "webpack"].includes(meta.framework)) {
|
|
91
|
+
raiseError(`This plugin is supported 'vite' and 'webpack' only`);
|
|
92
|
+
}
|
|
93
|
+
let include = options.include;
|
|
94
|
+
if (include) {
|
|
95
|
+
if (isArray(include)) {
|
|
96
|
+
include = include.map((item) => normalize(item));
|
|
97
|
+
} else if (isString(include)) {
|
|
98
|
+
include = normalize(include);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const filter = createFilter(include);
|
|
102
|
+
const forceStringify = !!options.forceStringify;
|
|
103
|
+
const defaultSFCLang = isString(options.defaultSFCLang) ? options.defaultSFCLang : "json";
|
|
104
|
+
const globalSFCScope = !!options.globalSFCScope;
|
|
105
|
+
const useClassComponent = !!options.useClassComponent;
|
|
106
|
+
const bridge = !!options.bridge;
|
|
107
|
+
debug("bridge", bridge);
|
|
108
|
+
let isProduction = false;
|
|
109
|
+
let sourceMap = false;
|
|
110
|
+
return {
|
|
111
|
+
name: "unplugin-vue-i18n",
|
|
112
|
+
enforce: meta.framework === "vite" ? "pre" : "post",
|
|
113
|
+
vite: {
|
|
114
|
+
configResolved(config) {
|
|
115
|
+
isProduction = config.isProduction;
|
|
116
|
+
sourceMap = config.command === "build" ? !!config.build.sourcemap : false;
|
|
117
|
+
debug(`configResolved: isProduction = ${isProduction}, sourceMap = ${sourceMap}`);
|
|
118
|
+
const jsonPlugin = config.plugins.find((p) => p.name === "vite:json");
|
|
119
|
+
if (jsonPlugin) {
|
|
120
|
+
const orgTransform = jsonPlugin.transform;
|
|
121
|
+
jsonPlugin.transform = async function(code, id) {
|
|
122
|
+
if (!/\.json$/.test(id) || filter(id)) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const { query } = parseVueRequest(id);
|
|
126
|
+
if (query.vue) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
debug("org json plugin");
|
|
130
|
+
return orgTransform.apply(this, [code, id]);
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
webpack(compiler) {
|
|
136
|
+
isProduction = compiler.options.mode !== "development";
|
|
137
|
+
sourceMap = !!compiler.options.devtool;
|
|
138
|
+
debug(`webpack: isProduction = ${isProduction}, sourceMap = ${sourceMap}`);
|
|
139
|
+
if (compiler.options.module) {
|
|
140
|
+
compiler.options.module.rules.push({
|
|
141
|
+
test: /\.(json5?|ya?ml)$/,
|
|
142
|
+
type: "javascript/auto",
|
|
143
|
+
exclude: include
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
resolveId(id, importer) {
|
|
148
|
+
debug("resolveId", id, importer);
|
|
149
|
+
if (id === INTLIFY_BUNDLE_IMPORT_DEPRECTED_ID) {
|
|
150
|
+
warn(`deprected '${INTLIFY_BUNDLE_IMPORT_DEPRECTED_ID}', you should switch to '${INTLIFY_BUNDLE_IMPORT_ID}'`);
|
|
151
|
+
return id;
|
|
152
|
+
}
|
|
153
|
+
if (id === INTLIFY_BUNDLE_IMPORT_ID) {
|
|
154
|
+
return id;
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
async load(id) {
|
|
158
|
+
debug("load", id);
|
|
159
|
+
const { query } = parseVueRequest(id);
|
|
160
|
+
if ([INTLIFY_BUNDLE_IMPORT_DEPRECTED_ID, INTLIFY_BUNDLE_IMPORT_ID].includes(id) && include) {
|
|
161
|
+
let resourcePaths = [];
|
|
162
|
+
const includePaths = isArray(include) ? include : [include];
|
|
163
|
+
for (const inc of includePaths) {
|
|
164
|
+
resourcePaths = [...resourcePaths, ...await fg(inc)];
|
|
165
|
+
}
|
|
166
|
+
resourcePaths = resourcePaths.filter((el, pos) => resourcePaths.indexOf(el) === pos);
|
|
167
|
+
const code = await generateBundleResources(resourcePaths, query, isProduction, {
|
|
168
|
+
forceStringify,
|
|
169
|
+
bridge,
|
|
170
|
+
useClassComponent
|
|
171
|
+
});
|
|
172
|
+
return {
|
|
173
|
+
code,
|
|
174
|
+
map: { mappings: "" }
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
async transform(code, id) {
|
|
179
|
+
const { filename, query } = parseVueRequest(id);
|
|
180
|
+
debug("transform", id, JSON.stringify(query), filename);
|
|
181
|
+
debug("transform (code)", code);
|
|
182
|
+
let langInfo = defaultSFCLang;
|
|
183
|
+
let inSourceMap;
|
|
184
|
+
if (!query.vue) {
|
|
185
|
+
if (/\.(json5?|ya?ml)$/.test(id) && filter(id)) {
|
|
186
|
+
langInfo = parse(filename).ext;
|
|
187
|
+
const generate = /\.?json5?/.test(langInfo) ? generateJSON : generateYAML;
|
|
188
|
+
const parseOptions = getOptions(filename, isProduction, query, sourceMap, {
|
|
189
|
+
inSourceMap,
|
|
190
|
+
isGlobal: globalSFCScope,
|
|
191
|
+
useClassComponent,
|
|
192
|
+
bridge,
|
|
193
|
+
forceStringify
|
|
194
|
+
});
|
|
195
|
+
debug("parseOptions", parseOptions);
|
|
196
|
+
const { code: generatedCode, map } = generate(code, parseOptions, bridge ? createBridgeCodeGenerator(code, query) : void 0);
|
|
197
|
+
debug("generated code", generatedCode);
|
|
198
|
+
debug("sourcemap", map, sourceMap);
|
|
199
|
+
if (code === generatedCode)
|
|
200
|
+
return;
|
|
201
|
+
return {
|
|
202
|
+
code: generatedCode,
|
|
203
|
+
map: sourceMap ? map : { mappings: "" }
|
|
204
|
+
};
|
|
205
|
+
} else {
|
|
206
|
+
return {
|
|
207
|
+
code,
|
|
208
|
+
map: { mappings: "", version: "3", sources: [] }
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
if (isCustomBlock(query)) {
|
|
213
|
+
if (isString(query.lang)) {
|
|
214
|
+
langInfo = query.src ? query.lang === "i18n" ? "json" : query.lang : query.lang;
|
|
215
|
+
} else if (defaultSFCLang) {
|
|
216
|
+
langInfo = defaultSFCLang;
|
|
217
|
+
}
|
|
218
|
+
debug("langInfo", langInfo);
|
|
219
|
+
const generate = /\.?json5?/.test(langInfo) ? generateJSON : generateYAML;
|
|
220
|
+
const parseOptions = getOptions(filename, isProduction, query, sourceMap, {
|
|
221
|
+
inSourceMap,
|
|
222
|
+
isGlobal: globalSFCScope,
|
|
223
|
+
useClassComponent,
|
|
224
|
+
bridge,
|
|
225
|
+
forceStringify
|
|
226
|
+
});
|
|
227
|
+
debug("parseOptions", parseOptions);
|
|
228
|
+
const source = await getCode(code, filename, sourceMap, query, meta.framework);
|
|
229
|
+
const { code: generatedCode, map } = generate(source, parseOptions, bridge ? createBridgeCodeGenerator(source, query) : void 0);
|
|
230
|
+
debug("generated code", generatedCode);
|
|
231
|
+
debug("sourcemap", map, sourceMap);
|
|
232
|
+
if (code === generatedCode)
|
|
233
|
+
return;
|
|
234
|
+
return {
|
|
235
|
+
code: generatedCode,
|
|
236
|
+
map: sourceMap ? map : { mappings: "" }
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
});
|
|
243
|
+
async function generateBundleResources(resources, query, isProduction, {
|
|
244
|
+
forceStringify = false,
|
|
245
|
+
isGlobal = false,
|
|
246
|
+
bridge = false,
|
|
247
|
+
useClassComponent = false
|
|
248
|
+
}) {
|
|
249
|
+
const codes = [];
|
|
250
|
+
for (const res of resources) {
|
|
251
|
+
debug(`${res} bundle loading ...`);
|
|
252
|
+
if (/\.(json5?|ya?ml)$/.test(res)) {
|
|
253
|
+
const { ext, name } = parse(res);
|
|
254
|
+
const source = await getRaw(res);
|
|
255
|
+
const generate = /json5?/.test(ext) ? generateJSON : generateYAML;
|
|
256
|
+
const parseOptions = getOptions(res, isProduction, {}, false, {
|
|
257
|
+
isGlobal,
|
|
258
|
+
useClassComponent,
|
|
259
|
+
bridge,
|
|
260
|
+
forceStringify
|
|
261
|
+
});
|
|
262
|
+
parseOptions.type = "bare";
|
|
263
|
+
const { code } = generate(source, parseOptions, bridge ? createBridgeCodeGenerator(source, query) : void 0);
|
|
264
|
+
debug("generated code", code);
|
|
265
|
+
codes.push(`${JSON.stringify(name)}: ${code}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return `export default {
|
|
269
|
+
${codes.join(`,
|
|
270
|
+
`)}
|
|
271
|
+
}`;
|
|
272
|
+
}
|
|
273
|
+
async function getCode(source, filename, sourceMap, query, framework = "vite") {
|
|
274
|
+
const { index, issuerPath } = query;
|
|
275
|
+
if (!isNumber(index)) {
|
|
276
|
+
raiseError(`unexpected index: ${index}`);
|
|
277
|
+
}
|
|
278
|
+
if (framework === "webpack") {
|
|
279
|
+
if (issuerPath) {
|
|
280
|
+
debug(`getCode (webpack) ${index} via issuerPath`, issuerPath);
|
|
281
|
+
return await getRaw(filename);
|
|
282
|
+
} else {
|
|
283
|
+
const result = parse$1(await getRaw(filename), {
|
|
284
|
+
sourceMap,
|
|
285
|
+
filename
|
|
286
|
+
});
|
|
287
|
+
const block = result.descriptor.customBlocks[index];
|
|
288
|
+
if (block) {
|
|
289
|
+
const code = block.src ? await getRaw(block.src) : block.content;
|
|
290
|
+
debug(`getCode (webpack) ${index} from SFC`, code);
|
|
291
|
+
return code;
|
|
292
|
+
} else {
|
|
293
|
+
return source;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
} else {
|
|
297
|
+
return source;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function isCustomBlock(query) {
|
|
301
|
+
return !isEmptyObject(query) && "vue" in query && (query["type"] === "custom" || query["type"] === "i18n" || query["blockType"] === "i18n");
|
|
302
|
+
}
|
|
303
|
+
function getOptions(filename, isProduction, query, sourceMap, {
|
|
304
|
+
inSourceMap = void 0,
|
|
305
|
+
forceStringify = false,
|
|
306
|
+
isGlobal = false,
|
|
307
|
+
bridge = false,
|
|
308
|
+
useClassComponent = false
|
|
309
|
+
}) {
|
|
310
|
+
const mode = isProduction ? "production" : "development";
|
|
311
|
+
const baseOptions = {
|
|
312
|
+
filename,
|
|
313
|
+
sourceMap,
|
|
314
|
+
inSourceMap,
|
|
315
|
+
forceStringify,
|
|
316
|
+
useClassComponent,
|
|
317
|
+
bridge,
|
|
318
|
+
env: mode,
|
|
319
|
+
onWarn: (msg) => {
|
|
320
|
+
warn(`${filename} ${msg}`);
|
|
321
|
+
},
|
|
322
|
+
onError: (msg) => {
|
|
323
|
+
error(`${filename} ${msg}`);
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
if (isCustomBlock(query)) {
|
|
327
|
+
return assign(baseOptions, {
|
|
328
|
+
type: "sfc",
|
|
329
|
+
locale: isString(query.locale) ? query.locale : "",
|
|
330
|
+
isGlobal: isGlobal || !!query.global
|
|
331
|
+
});
|
|
332
|
+
} else {
|
|
333
|
+
return assign(baseOptions, {
|
|
334
|
+
type: "plain",
|
|
335
|
+
isGlobal: false
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export { unplugin as default, unplugin };
|
package/lib/types.cjs
ADDED
package/lib/types.d.ts
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
declare type SFCLangFormat = 'json' | 'json5' | 'yml' | 'yaml';
|
|
2
|
+
interface PluginOptions {
|
|
3
|
+
include?: string | string[];
|
|
4
|
+
forceStringify?: boolean;
|
|
5
|
+
defaultSFCLang?: SFCLangFormat;
|
|
6
|
+
globalSFCScope?: boolean;
|
|
7
|
+
bridge?: boolean;
|
|
8
|
+
useClassComponent?: boolean;
|
|
2
9
|
}
|
|
10
|
+
|
|
11
|
+
export { PluginOptions, SFCLangFormat };
|
package/lib/types.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/lib/vite.cjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const index = require('./index.cjs');
|
|
4
|
+
require('unplugin');
|
|
5
|
+
require('pathe');
|
|
6
|
+
require('debug');
|
|
7
|
+
require('fast-glob');
|
|
8
|
+
require('@intlify/shared');
|
|
9
|
+
require('@rollup/pluginutils');
|
|
10
|
+
require('@intlify/bundle-utils');
|
|
11
|
+
require('@vue/compiler-sfc');
|
|
12
|
+
require('json5');
|
|
13
|
+
require('js-yaml');
|
|
14
|
+
require('fs');
|
|
15
|
+
|
|
16
|
+
const vite = index.unplugin.vite;
|
|
17
|
+
|
|
18
|
+
module.exports = vite;
|
package/lib/vite.d.ts
ADDED
package/lib/vite.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { unplugin } from './index.mjs';
|
|
2
|
+
import 'unplugin';
|
|
3
|
+
import 'pathe';
|
|
4
|
+
import 'debug';
|
|
5
|
+
import 'fast-glob';
|
|
6
|
+
import '@intlify/shared';
|
|
7
|
+
import '@rollup/pluginutils';
|
|
8
|
+
import '@intlify/bundle-utils';
|
|
9
|
+
import '@vue/compiler-sfc';
|
|
10
|
+
import 'json5';
|
|
11
|
+
import 'js-yaml';
|
|
12
|
+
import 'fs';
|
|
13
|
+
|
|
14
|
+
const vite = unplugin.vite;
|
|
15
|
+
|
|
16
|
+
export { vite as default };
|
package/lib/webpack.cjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const index = require('./index.cjs');
|
|
4
|
+
require('unplugin');
|
|
5
|
+
require('pathe');
|
|
6
|
+
require('debug');
|
|
7
|
+
require('fast-glob');
|
|
8
|
+
require('@intlify/shared');
|
|
9
|
+
require('@rollup/pluginutils');
|
|
10
|
+
require('@intlify/bundle-utils');
|
|
11
|
+
require('@vue/compiler-sfc');
|
|
12
|
+
require('json5');
|
|
13
|
+
require('js-yaml');
|
|
14
|
+
require('fs');
|
|
15
|
+
|
|
16
|
+
const webpack = index.unplugin.webpack;
|
|
17
|
+
|
|
18
|
+
module.exports = webpack;
|
package/lib/webpack.d.ts
ADDED
package/lib/webpack.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { unplugin } from './index.mjs';
|
|
2
|
+
import 'unplugin';
|
|
3
|
+
import 'pathe';
|
|
4
|
+
import 'debug';
|
|
5
|
+
import 'fast-glob';
|
|
6
|
+
import '@intlify/shared';
|
|
7
|
+
import '@rollup/pluginutils';
|
|
8
|
+
import '@intlify/bundle-utils';
|
|
9
|
+
import '@vue/compiler-sfc';
|
|
10
|
+
import 'json5';
|
|
11
|
+
import 'js-yaml';
|
|
12
|
+
import 'fs';
|
|
13
|
+
|
|
14
|
+
const webpack = unplugin.webpack;
|
|
15
|
+
|
|
16
|
+
export { webpack as default };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlify/unplugin-vue-i18n",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "unplugin for Vue I18n",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "kazuya kawaguchi",
|
|
@@ -24,38 +24,59 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@intlify/bundle-utils": "next",
|
|
26
26
|
"@intlify/shared": "next",
|
|
27
|
+
"@rollup/pluginutils": "^4.2.0",
|
|
28
|
+
"@vue/compiler-sfc": "^3.2.23",
|
|
27
29
|
"debug": "^4.3.1",
|
|
28
30
|
"fast-glob": "^3.2.5",
|
|
31
|
+
"js-yaml": "^4.1.0",
|
|
32
|
+
"json5": "^2.2.0",
|
|
33
|
+
"pathe": "^0.2.0",
|
|
29
34
|
"source-map": "0.6.1",
|
|
30
35
|
"unplugin": "^0.6.2"
|
|
31
36
|
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"mlly": "^0.5.2",
|
|
39
|
+
"unbuild": "^0.7.4"
|
|
40
|
+
},
|
|
32
41
|
"engines": {
|
|
33
42
|
"node": ">= 12"
|
|
34
43
|
},
|
|
35
44
|
"files": [
|
|
36
|
-
"lib"
|
|
37
|
-
"index.mjs"
|
|
45
|
+
"lib"
|
|
38
46
|
],
|
|
39
47
|
"homepage": "https://github.com/intlify/bundle-tools/blob/main/packages/unplugin-vue-i18n/README.md",
|
|
40
48
|
"keywords": [
|
|
41
49
|
"i18n",
|
|
42
50
|
"plugin",
|
|
43
51
|
"unplugin",
|
|
44
|
-
"
|
|
52
|
+
"transform",
|
|
53
|
+
"webpack",
|
|
54
|
+
"vite",
|
|
45
55
|
"vue",
|
|
46
56
|
"vue-i18n"
|
|
47
57
|
],
|
|
48
58
|
"license": "MIT",
|
|
49
|
-
"main": "lib/index.
|
|
50
|
-
"module": "./index.mjs",
|
|
59
|
+
"main": "lib/index.cjs",
|
|
60
|
+
"module": "./lib/index.mjs",
|
|
51
61
|
"types": "lib/index.d.ts",
|
|
52
62
|
"exports": {
|
|
53
63
|
".": {
|
|
54
|
-
"
|
|
55
|
-
"
|
|
64
|
+
"require": "./lib/index.cjs",
|
|
65
|
+
"import": "./lib/index.mjs"
|
|
66
|
+
},
|
|
67
|
+
"./vite": {
|
|
68
|
+
"require": "./lib/vite.cjs",
|
|
69
|
+
"import": "./lib/vite.mjs"
|
|
70
|
+
},
|
|
71
|
+
"./webpack": {
|
|
72
|
+
"require": "./lib/webpack.cjs",
|
|
73
|
+
"import": "./lib/webpack.mjs"
|
|
74
|
+
},
|
|
75
|
+
"./types": {
|
|
76
|
+
"require": "./lib/types.cjs",
|
|
77
|
+
"import": "./lib/types.mjs"
|
|
56
78
|
},
|
|
57
79
|
"./lib/*": "./lib/*",
|
|
58
|
-
"./index.mjs": "./index.mjs",
|
|
59
80
|
"./package.json": "./package.json"
|
|
60
81
|
},
|
|
61
82
|
"repository": {
|
|
@@ -64,10 +85,16 @@
|
|
|
64
85
|
"directory": "packages/unplugin-vue-i18n"
|
|
65
86
|
},
|
|
66
87
|
"scripts": {
|
|
67
|
-
"
|
|
88
|
+
"dev:vite": "vite examples/vite --config ./examples/vite/vite.config.ts",
|
|
89
|
+
"dev:webpack": "yarn build && webpack-dev-server --config ./examples/webpack/webpack.config.js --inline --hot",
|
|
90
|
+
"build": "unbuild",
|
|
91
|
+
"build:example": "npm-run-all \"build:example:*\"",
|
|
92
|
+
"build:example:vite": "vite build --config ./examples/vite/vite.config.ts --outDir ./examples/vite/dist",
|
|
93
|
+
"build:example:webpack": "yarn build && webpack --config ./examples/webpack/webpack.config.js",
|
|
68
94
|
"clean": "npm-run-all \"clean:*\"",
|
|
69
95
|
"clean:lib": "rm -rf ./lib",
|
|
70
|
-
"
|
|
96
|
+
"test": "yarn test:e2e",
|
|
97
|
+
"test:e2e": "jest --runInBand --config ./jest.e2e.config.js",
|
|
71
98
|
"changelog": "jiti ../../scripts/changelog.ts",
|
|
72
99
|
"release": "jiti ../../scripts/release.ts"
|
|
73
100
|
}
|
package/index.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lib/index.js'
|
package/lib/index.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.unplugin = void 0;
|
|
4
|
-
const unplugin_1 = require("unplugin");
|
|
5
|
-
exports.unplugin = (0, unplugin_1.createUnplugin)((options = {}) => {
|
|
6
|
-
console.log("I've borned in the world!");
|
|
7
|
-
return {
|
|
8
|
-
name: 'unplugin-vue-i18n'
|
|
9
|
-
};
|
|
10
|
-
});
|
|
11
|
-
exports.default = exports.unplugin;
|
package/lib/types.js
DELETED