update
This commit is contained in:
parent
562c71a0a2
commit
50446a1614
@ -1 +0,0 @@
|
||||
{"type":"module"}
|
@ -1,7 +0,0 @@
|
||||
|
||||
|
||||
const compile = require('@voerkai18n/cli/compile.command');
|
||||
const path = require("path")
|
||||
|
||||
|
||||
compile(path.resolve(__dirname,"./apps/app/languages")).then(()=>{})
|
19
demo/data.js
19
demo/data.js
@ -1,19 +0,0 @@
|
||||
module.exports = {
|
||||
"name" : "张三丰",
|
||||
"age" : 12,
|
||||
"active" : true,
|
||||
"address" : [
|
||||
"北京市",
|
||||
"福建省泉州市\n洛阳镇"
|
||||
],
|
||||
"posts" : {
|
||||
"title" : "标题",
|
||||
"content": "内容"
|
||||
},
|
||||
"产品清单\t{}": 2,
|
||||
"产品价格" : {
|
||||
"手机" : 1299,
|
||||
"电脑\t:": 3999
|
||||
},
|
||||
"产品\\清\\单": 1
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
const gulp = require('gulp');
|
||||
const extract = require('@voerkai18n/cli/extract.plugin');
|
||||
const path = require('path');
|
||||
|
||||
|
||||
const soucePath = path.join(__dirname,'./apps/app')
|
||||
|
||||
|
||||
|
||||
gulp.src([
|
||||
soucePath+ '/**',
|
||||
"!"+ soucePath+ '/languages/**'
|
||||
]).pipe(extract({
|
||||
debug:true,
|
||||
// output: path.join(soucePath , 'languages'),
|
||||
languages: [
|
||||
{name:'en',title:"英文"},
|
||||
{name:'cn',title:"中文",default:true},
|
||||
{name:'de',title:"德语"},
|
||||
{name:'fr',title:"法语"},
|
||||
{name:'es',title:"西班牙语"},
|
||||
{name:'it',title:"意大利语"},
|
||||
{name:'jp',title:"日語"}
|
||||
],
|
||||
// extractor:{
|
||||
// default:[new RegExp()], // 默认匹配器,当文件类型没有对应的提取器时使用
|
||||
// "*" : [new RegExp()], // 所有类型均会执行的提取器
|
||||
// js:new RegExp(), // 只有一个正则表达式,js文件提取正则表达式
|
||||
// html:[new RegExp(),new RegExp()] // 多个表达式可以用数组
|
||||
// "js,jsx":[new RegExp(),(content,file)=>{...})] // 提取器也可以是一个函数,传入文件和文件内容,返回提取结果
|
||||
// },
|
||||
namespaces:{
|
||||
"a":"a",
|
||||
"b":"b",
|
||||
}
|
||||
}))
|
||||
.pipe(gulp.dest(path.join(__dirname,'./apps/app/languages')));
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "@voerkai18n/demo",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "babel.plugin.demo.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@voerkai18n/runtime": "workspace:^1.0.0",
|
||||
"@voerkai18n/cli": "workspace:^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"deepmerge": "^4.2.2",
|
||||
"gulp": "^4.0.2",
|
||||
"vinyl": "^2.2.1"
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
const { objectStringify } = require("@voerkai18n/cli/stringify")
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
const k1 = "产品清单\t{}"
|
||||
const k2 = "产品\\清\\单"
|
||||
|
||||
const newTexts = {
|
||||
[k1]:1,
|
||||
[k2]:2
|
||||
}
|
||||
|
||||
let data = {
|
||||
name:"张三丰",
|
||||
age:12,
|
||||
active:true,
|
||||
address:[
|
||||
"北京市",
|
||||
"福建省泉州市\n洛阳镇"
|
||||
],
|
||||
posts:{
|
||||
title:"标题",
|
||||
content:"内容",
|
||||
//comments:[]
|
||||
},
|
||||
[k1]:[
|
||||
"手机",
|
||||
"电脑"
|
||||
],
|
||||
"产品清单\t{}":2,
|
||||
"产品价格":{
|
||||
"手机":1299,
|
||||
"电脑\t:":3999
|
||||
},
|
||||
"产品\\清\\单":1
|
||||
}
|
||||
|
||||
|
||||
const result = objectStringify(data)
|
||||
|
||||
console.log(result)
|
||||
|
||||
fs.writeFileSync(path.join(__dirname,"./data.js"),`module.exports = ${result}`)
|
||||
|
||||
const loaded = require("./data.js")
|
||||
|
||||
Object.entries(loaded).forEach(([key,value])=>{
|
||||
if(key===k1){
|
||||
console.log("k1=",value)
|
||||
}else if(key===k2){
|
||||
console.log("k2=",value)
|
||||
console.log("k2 in data",k2 in data)
|
||||
}
|
||||
})
|
||||
|
||||
console.log(loaded[k1])
|
||||
console.log(loaded[k2])
|
||||
|
||||
|
32
packages/apps/app/languages/cn.js
Normal file
32
packages/apps/app/languages/cn.js
Normal file
@ -0,0 +1,32 @@
|
||||
module.exports = {
|
||||
"1": "a",
|
||||
"2": "b",
|
||||
"3": "c",
|
||||
"4": "d",
|
||||
"5": "e",
|
||||
"6": "请输入旧密码:",
|
||||
"7": "请再次输入旧密码:",
|
||||
"8": "请输入新密码:",
|
||||
"9": "请再次输入新密码:",
|
||||
"10": "密码至少需要6位,并且至少包含数字、字符或特殊符号中的两种",
|
||||
"11": "密码强度: {strength}",
|
||||
"12": "用户名或密码错误",
|
||||
"13": "请输入用户名:",
|
||||
"14": "请输入密码:",
|
||||
"15": "欢迎您: {}",
|
||||
"16": "数据库类型:{}、{}、{}",
|
||||
"17": "数据库密码:{pwd}",
|
||||
"18": "数据库地址:{url}",
|
||||
"19": "编码:{encode}",
|
||||
"20": "编码",
|
||||
"21": "名称",
|
||||
"22": "描述",
|
||||
"23": "文件名称",
|
||||
"24": "您有{}条未读消息",
|
||||
"25": "消息总数:{$count}",
|
||||
"26": "消息类型:{type}",
|
||||
"27": "登录",
|
||||
"28": "请输入密码:",
|
||||
"29": "头像",
|
||||
"30": "相片"
|
||||
}
|
32
packages/apps/app/languages/en.js
Normal file
32
packages/apps/app/languages/en.js
Normal file
@ -0,0 +1,32 @@
|
||||
module.exports = {
|
||||
"1": "a",
|
||||
"2": "b",
|
||||
"3": "c",
|
||||
"4": "d",
|
||||
"5": "e",
|
||||
"6": "请输入旧密码:",
|
||||
"7": "请再次输入旧密码:",
|
||||
"8": "请输入新密码:",
|
||||
"9": "请再次输入新密码:",
|
||||
"10": "密码至少需要6位,并且至少包含数字、字符或特殊符号中的两种",
|
||||
"11": "密码强度: {strength}",
|
||||
"12": "用户名或密码错误",
|
||||
"13": "请输入用户名:",
|
||||
"14": "请输入密码:",
|
||||
"15": "欢迎您: {}",
|
||||
"16": "数据库类型:{}、{}、{}",
|
||||
"17": "数据库密码:{pwd}",
|
||||
"18": "数据库地址:{url}",
|
||||
"19": "编码:{encode}",
|
||||
"20": "编码",
|
||||
"21": "名称",
|
||||
"22": "描述",
|
||||
"23": "文件名称",
|
||||
"24": "您有{}条未读消息",
|
||||
"25": "消息总数:{$count}",
|
||||
"26": "消息类型:{type}",
|
||||
"27": "登录",
|
||||
"28": "请输入密码:",
|
||||
"29": "头像",
|
||||
"30": "相片"
|
||||
}
|
106
packages/apps/app/languages/formatters.js
Normal file
106
packages/apps/app/languages/formatters.js
Normal file
@ -0,0 +1,106 @@
|
||||
/**
|
||||
|
||||
格式化器用来对翻译文本内容中的插值变量进行格式化,
|
||||
比如将一个数字格式化为货币格式,或者将一个日期格式化为友好的日期格式。
|
||||
|
||||
- 以下定义了一些格式化器,在中文场景下,会启用这些格式化器。
|
||||
import dayjs from "dayjs";
|
||||
const formatters = {
|
||||
"*":{ // 在所有语言下生效的格式化器
|
||||
$types:{...}, // 只作用于特定数据类型的默认格式化器
|
||||
.... // 全局格式化器
|
||||
},
|
||||
cn:{
|
||||
// 只作用于特定数据类型的格式化器
|
||||
$types:{
|
||||
Date:(value)=>dayjs(value).format("YYYY年MM月DD日 HH:mm:ss"),
|
||||
},
|
||||
date:(value)=>dayjs(value).format("YYYY年MM月DD日")
|
||||
bjTime:(value)=>"北京时间"+ value,
|
||||
[格式化器名称]:(value)=>{...},
|
||||
[格式化器名称]:(value)=>{...},
|
||||
[格式化器名称]:(value)=>{...},
|
||||
},
|
||||
en:{
|
||||
$types:{
|
||||
Date:(value)=>dayjs(value).format("YYYY/MM/DD HH:mm:ss"), // 默认的格式化器
|
||||
},
|
||||
date:(value)=>dayjs(value).format("YYYY/MM/DD")
|
||||
bjTime:(value)=>"BeiJing "+ value,
|
||||
[格式化器名称]:(value)=>{...},
|
||||
[格式化器名称]:(value)=>{...},
|
||||
[格式化器名称]:(value)=>{...},
|
||||
}
|
||||
}
|
||||
- 在翻译函数中使用格式化器的方法,示例如下:
|
||||
|
||||
t("Now is { value | date | bjTime }",{value: new Date()})
|
||||
其等效于:
|
||||
t(`Now is ${bjTime(date(value))",{value: new Date()})
|
||||
由于value分别经过两个管道符转换,上一个管道符的输出作为下一个管道符的输入,可以多次使用管道符。
|
||||
|
||||
最终的输出结果:
|
||||
中文: "现在是北京时间2022年3月1日"
|
||||
英文: "Now is BeiJing 2022/03/01"
|
||||
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// 在所有语言下生效的格式化器
|
||||
"*":{
|
||||
//[格式化名称]:(value)=>{...},
|
||||
//[格式化名称]:(value,arg)=>{...},
|
||||
},
|
||||
// 在所有语言下只作用于特定数据类型的格式化器
|
||||
$types:{
|
||||
|
||||
},
|
||||
cn:{
|
||||
$types:{
|
||||
// 所有类型的默认格式化器
|
||||
// "*":{
|
||||
|
||||
// },
|
||||
// Date:{
|
||||
|
||||
// },
|
||||
// Number:{
|
||||
|
||||
// },
|
||||
// String:{
|
||||
|
||||
// },
|
||||
// Array:{
|
||||
|
||||
// },
|
||||
// Object:{
|
||||
|
||||
// }
|
||||
}
|
||||
},
|
||||
en:{
|
||||
$types:{
|
||||
// 所有类型的默认格式化器
|
||||
// "*":{
|
||||
|
||||
// },
|
||||
// Date:{
|
||||
|
||||
// },
|
||||
// Number:{
|
||||
|
||||
// },
|
||||
// String:{
|
||||
|
||||
// },
|
||||
// Array:{
|
||||
|
||||
// },
|
||||
// Object:{
|
||||
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
32
packages/apps/app/languages/idMap.js
Normal file
32
packages/apps/app/languages/idMap.js
Normal file
@ -0,0 +1,32 @@
|
||||
module.exports = {
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3,
|
||||
"d": 4,
|
||||
"e": 5,
|
||||
"请输入旧密码:": 6,
|
||||
"请再次输入旧密码:": 7,
|
||||
"请输入新密码:": 8,
|
||||
"请再次输入新密码:": 9,
|
||||
"密码至少需要6位,并且至少包含数字、字符或特殊符号中的两种": 10,
|
||||
"密码强度: {strength}": 11,
|
||||
"用户名或密码错误": 12,
|
||||
"请输入用户名:": 13,
|
||||
"请输入密码:": 14,
|
||||
"欢迎您: {}": 15,
|
||||
"数据库类型:{}、{}、{}": 16,
|
||||
"数据库密码:{pwd}": 17,
|
||||
"数据库地址:{url}": 18,
|
||||
"编码:{encode}": 19,
|
||||
"编码": 20,
|
||||
"名称": 21,
|
||||
"描述": 22,
|
||||
"文件名称": 23,
|
||||
"您有{}条未读消息": 24,
|
||||
"消息总数:{$count}": 25,
|
||||
"消息类型:{type}": 26,
|
||||
"登录": 27,
|
||||
"请输入密码:": 28,
|
||||
"头像": 29,
|
||||
"相片": 30
|
||||
}
|
45
packages/apps/app/languages/index.js
Normal file
45
packages/apps/app/languages/index.js
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
const messageIds = require("./idMap")
|
||||
const { translate,I18nManager,i18nScope } = require("@voerkai18n/runtime")
|
||||
const formatters = require("./formatters.js")
|
||||
const defaultMessages = require("./cn.js")
|
||||
const activeMessages = defaultMessages
|
||||
|
||||
|
||||
|
||||
// 语言配置文件
|
||||
const scopeSettings = {
|
||||
"languages": [
|
||||
{
|
||||
"name": "cn",
|
||||
"title": "cn"
|
||||
},
|
||||
{
|
||||
"name": "en",
|
||||
"title": "en"
|
||||
}
|
||||
],
|
||||
"defaultLanguage": "cn",
|
||||
"activeLanguage": "cn",
|
||||
"namespaces": {}
|
||||
}
|
||||
|
||||
// 语言作用域
|
||||
const scope = new i18nScope({
|
||||
...scopeSettings, // languages,defaultLanguage,activeLanguage,namespaces,formatters
|
||||
id: "", // 当前作用域的id,自动取当前工程的package.json的name
|
||||
default: defaultMessages, // 默认语言包
|
||||
messages : activeMessages, // 当前语言包
|
||||
idMap:messageIds, // 消息id映射列表
|
||||
formatters, // 当前作用域的格式化函数列表
|
||||
loaders:{
|
||||
"en" : ()=>import("./en.js")
|
||||
}
|
||||
})
|
||||
// 翻译函数
|
||||
const t = translate.bind(scope)
|
||||
|
||||
module.exports.t = t
|
||||
module.exports.scope = scope
|
||||
module.exports.i18nManager = VoerkaI18n
|
||||
|
@ -1,12 +1,12 @@
|
||||
module.exports = {
|
||||
{
|
||||
"languages": [
|
||||
{
|
||||
"name": "cn",
|
||||
"title": "中文"
|
||||
"title": "cn"
|
||||
},
|
||||
{
|
||||
"name": "en",
|
||||
"title": "英文"
|
||||
"title": "en"
|
||||
}
|
||||
],
|
||||
"defaultLanguage": "cn",
|
183
packages/apps/app/languages/translates/default.json
Normal file
183
packages/apps/app/languages/translates/default.json
Normal file
@ -0,0 +1,183 @@
|
||||
{
|
||||
"a": {
|
||||
"en": "a",
|
||||
"$file": [
|
||||
"index.js"
|
||||
]
|
||||
},
|
||||
"b": {
|
||||
"en": "b",
|
||||
"$file": [
|
||||
"index.js"
|
||||
]
|
||||
},
|
||||
"c": {
|
||||
"en": "c",
|
||||
"$file": [
|
||||
"index.js"
|
||||
]
|
||||
},
|
||||
"d": {
|
||||
"en": "d",
|
||||
"$file": [
|
||||
"index.js"
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"en": "e",
|
||||
"$file": [
|
||||
"index.js"
|
||||
]
|
||||
},
|
||||
"请输入旧密码:": {
|
||||
"en": "请输入旧密码:",
|
||||
"$file": [
|
||||
"auth\\changepassword.js"
|
||||
]
|
||||
},
|
||||
"请再次输入旧密码:": {
|
||||
"en": "请再次输入旧密码:",
|
||||
"$file": [
|
||||
"auth\\changepassword.js"
|
||||
]
|
||||
},
|
||||
"请输入新密码:": {
|
||||
"en": "请输入新密码:",
|
||||
"$file": [
|
||||
"auth\\changepassword.js"
|
||||
]
|
||||
},
|
||||
"请再次输入新密码:": {
|
||||
"en": "请再次输入新密码:",
|
||||
"$file": [
|
||||
"auth\\changepassword.js"
|
||||
]
|
||||
},
|
||||
"密码至少需要6位,并且至少包含数字、字符或特殊符号中的两种": {
|
||||
"en": "密码至少需要6位,并且至少包含数字、字符或特殊符号中的两种",
|
||||
"$file": [
|
||||
"auth\\changepassword.js"
|
||||
]
|
||||
},
|
||||
"密码强度: {strength}": {
|
||||
"en": "密码强度: {strength}",
|
||||
"$file": [
|
||||
"auth\\changepassword.js"
|
||||
]
|
||||
},
|
||||
"用户名或密码错误": {
|
||||
"en": "用户名或密码错误",
|
||||
"$file": [
|
||||
"auth\\login.js"
|
||||
]
|
||||
},
|
||||
"请输入用户名:": {
|
||||
"en": "请输入用户名:",
|
||||
"$file": [
|
||||
"auth\\login.js",
|
||||
"auth\\login.html"
|
||||
]
|
||||
},
|
||||
"请输入密码:": {
|
||||
"en": "请输入密码:",
|
||||
"$file": [
|
||||
"auth\\login.js"
|
||||
]
|
||||
},
|
||||
"欢迎您: {}": {
|
||||
"en": "欢迎您: {}",
|
||||
"$file": [
|
||||
"auth\\login.js"
|
||||
]
|
||||
},
|
||||
"数据库类型:{}、{}、{}": {
|
||||
"en": "数据库类型:{}、{}、{}",
|
||||
"$file": [
|
||||
"db\\index.js"
|
||||
]
|
||||
},
|
||||
"数据库密码:{pwd}": {
|
||||
"en": "数据库密码:{pwd}",
|
||||
"$file": [
|
||||
"db\\index.js"
|
||||
]
|
||||
},
|
||||
"数据库地址:{url}": {
|
||||
"en": "数据库地址:{url}",
|
||||
"$file": [
|
||||
"db\\index.js"
|
||||
]
|
||||
},
|
||||
"编码:{encode}": {
|
||||
"en": "编码:{encode}",
|
||||
"$file": [
|
||||
"db\\index.js"
|
||||
]
|
||||
},
|
||||
"编码": {
|
||||
"en": "编码",
|
||||
"$file": [
|
||||
"db\\models.js"
|
||||
]
|
||||
},
|
||||
"名称": {
|
||||
"en": "名称",
|
||||
"$file": [
|
||||
"db\\models.js"
|
||||
]
|
||||
},
|
||||
"描述": {
|
||||
"en": "描述",
|
||||
"$file": [
|
||||
"db\\models.js"
|
||||
]
|
||||
},
|
||||
"文件名称": {
|
||||
"en": "文件名称",
|
||||
"$file": [
|
||||
"db\\models.js"
|
||||
]
|
||||
},
|
||||
"您有{}条未读消息": {
|
||||
"en": "您有{}条未读消息",
|
||||
"$file": [
|
||||
"messages\\index.js"
|
||||
]
|
||||
},
|
||||
"消息总数:{$count}": {
|
||||
"en": "消息总数:{$count}",
|
||||
"$file": [
|
||||
"messages\\index.js"
|
||||
]
|
||||
},
|
||||
"消息类型:{type}": {
|
||||
"en": "消息类型:{type}",
|
||||
"$file": [
|
||||
"messages\\index.js"
|
||||
]
|
||||
},
|
||||
"登录": {
|
||||
"en": "登录",
|
||||
"$file": [
|
||||
"auth\\login.html"
|
||||
]
|
||||
},
|
||||
"请输入密码:": {
|
||||
"en": "请输入密码:",
|
||||
"$file": [
|
||||
"auth\\login.html"
|
||||
]
|
||||
},
|
||||
"头像": {
|
||||
"en": "头像",
|
||||
"$file": [
|
||||
"auth\\login.html"
|
||||
]
|
||||
},
|
||||
"相片": {
|
||||
"en": "相片",
|
||||
"$file": [
|
||||
"auth\\login.html"
|
||||
]
|
||||
}
|
||||
}
|
24
packages/apps/app/package-lock.json
generated
Normal file
24
packages/apps/app/package-lock.json
generated
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "app",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@voerkai18n/runtime": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@voerkai18n/runtime": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@voerkai18n/runtime/-/runtime-1.0.0.tgz",
|
||||
"integrity": "sha512-P3yTmuaGb79LkWmQtLmmN9xGa3A0Lf+9O0ngB6Jr5v+0A7tzh94LGA5KnIaQAL63smc3fpQcf3vQZgnxUoAC1g=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@voerkai18n/runtime": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@voerkai18n/runtime/-/runtime-1.0.0.tgz",
|
||||
"integrity": "sha512-P3yTmuaGb79LkWmQtLmmN9xGa3A0Lf+9O0ngB6Jr5v+0A7tzh94LGA5KnIaQAL63smc3fpQcf3vQZgnxUoAC1g=="
|
||||
}
|
||||
}
|
||||
}
|
1
packages/apps/app/package.json
Normal file
1
packages/apps/app/package.json
Normal file
@ -0,0 +1 @@
|
||||
{"type":"module","dependencies":{"@voerkai18n/cli":"workspace:^1.0.6","@voerkai18n/runtime":"^1.0.0"}}
|
24
packages/apps/vueapp/.gitignore
vendored
Normal file
24
packages/apps/vueapp/.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
3
packages/apps/vueapp/.vscode/extensions.json
vendored
Normal file
3
packages/apps/vueapp/.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["johnsoncodehk.volar"]
|
||||
}
|
7
packages/apps/vueapp/README.md
Normal file
7
packages/apps/vueapp/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Vue 3 + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)
|
13
packages/apps/vueapp/index.html
Normal file
13
packages/apps/vueapp/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
1154
packages/apps/vueapp/package-lock.json
generated
Normal file
1154
packages/apps/vueapp/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
packages/apps/vueapp/package.json
Normal file
18
packages/apps/vueapp/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "vueapp",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@voerkai18n/cli": "workspace:^1.0.6",
|
||||
"vue": "^3.2.25"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^2.2.0",
|
||||
"vite": "^2.8.0"
|
||||
}
|
||||
}
|
BIN
packages/apps/vueapp/public/favicon.ico
Normal file
BIN
packages/apps/vueapp/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
24
packages/apps/vueapp/src/App.vue
Normal file
24
packages/apps/vueapp/src/App.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<script setup>
|
||||
// This starter template is using Vue 3 <script setup> SFCs
|
||||
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
|
||||
import HelloWorld from './components/HelloWorld.vue'
|
||||
console.log(t("Hello world!"))
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<img alt="Vue logo" src="./assets/logo.png" />
|
||||
<HelloWorld msg="Hello Vue 3 + Vite" />
|
||||
</template>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
}
|
||||
</style>
|
BIN
packages/apps/vueapp/src/assets/logo.png
Normal file
BIN
packages/apps/vueapp/src/assets/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
40
packages/apps/vueapp/src/components/HelloWorld.vue
Normal file
40
packages/apps/vueapp/src/components/HelloWorld.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineProps({
|
||||
msg: String
|
||||
})
|
||||
|
||||
const count = ref(0)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ msg }}</h1>
|
||||
|
||||
<p>
|
||||
Recommended IDE setup:
|
||||
<a href="https://code.visualstudio.com/" target="_blank">VSCode</a>
|
||||
+
|
||||
<a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="https://vitejs.dev/guide/features.html" target="_blank">
|
||||
Vite Documentation
|
||||
</a>
|
||||
|
|
||||
<a href="https://v3.vuejs.org/" target="_blank">Vue 3 Documentation</a>
|
||||
</p>
|
||||
|
||||
<button type="button" @click="count++">count is: {{ count }}</button>
|
||||
<p>
|
||||
Edit
|
||||
<code>components/HelloWorld.vue</code> to test hot module replacement.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
3
packages/apps/vueapp/src/languages/cn.js
Normal file
3
packages/apps/vueapp/src/languages/cn.js
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
"1": "Hello world!"
|
||||
}
|
3
packages/apps/vueapp/src/languages/en.js
Normal file
3
packages/apps/vueapp/src/languages/en.js
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
"1": "Hello world!"
|
||||
}
|
108
packages/apps/vueapp/src/languages/formatters.js
Normal file
108
packages/apps/vueapp/src/languages/formatters.js
Normal file
@ -0,0 +1,108 @@
|
||||
/**
|
||||
|
||||
格式化器用来对翻译文本内容中的插值变量进行格式化,
|
||||
比如将一个数字格式化为货币格式,或者将一个日期格式化为友好的日期格式。
|
||||
|
||||
- 以下定义了一些格式化器,在中文场景下,会启用这些格式化器。
|
||||
import dayjs from "dayjs";
|
||||
const formatters = {
|
||||
"*":{ // 在所有语言下生效的格式化器
|
||||
$types:{...}, // 只作用于特定数据类型的默认格式化器
|
||||
.... // 全局格式化器
|
||||
},
|
||||
cn:{
|
||||
// 只作用于特定数据类型的格式化器
|
||||
$types:{
|
||||
Date:(value)=>dayjs(value).format("YYYY年MM月DD日 HH:mm:ss"),
|
||||
},
|
||||
date:(value)=>dayjs(value).format("YYYY年MM月DD日")
|
||||
bjTime:(value)=>"北京时间"+ value,
|
||||
[格式化器名称]:(value)=>{...},
|
||||
[格式化器名称]:(value)=>{...},
|
||||
[格式化器名称]:(value)=>{...},
|
||||
},
|
||||
en:{
|
||||
$types:{
|
||||
Date:(value)=>dayjs(value).format("YYYY/MM/DD HH:mm:ss"), // 默认的格式化器
|
||||
},
|
||||
date:(value)=>dayjs(value).format("YYYY/MM/DD")
|
||||
bjTime:(value)=>"BeiJing "+ value,
|
||||
[格式化器名称]:(value)=>{...},
|
||||
[格式化器名称]:(value)=>{...},
|
||||
[格式化器名称]:(value)=>{...},
|
||||
}
|
||||
}
|
||||
- 在翻译函数中使用格式化器的方法,示例如下:
|
||||
|
||||
t("Now is { value | date | bjTime }",{value: new Date()})
|
||||
其等效于:
|
||||
t(`Now is ${bjTime(date(value))",{value: new Date()})
|
||||
由于value分别经过两个管道符转换,上一个管道符的输出作为下一个管道符的输入,可以多次使用管道符。
|
||||
|
||||
最终的输出结果:
|
||||
中文: "现在是北京时间2022年3月1日"
|
||||
英文: "Now is BeiJing 2022/03/01"
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
export default{
|
||||
// 在所有语言下生效的格式化器
|
||||
"*":{
|
||||
//[格式化名称]:(value)=>{...},
|
||||
//[格式化名称]:(value,arg)=>{...},
|
||||
},
|
||||
// 在所有语言下只作用于特定数据类型的格式化器
|
||||
$types:{
|
||||
|
||||
},
|
||||
cn:{
|
||||
$types:{
|
||||
// 所有类型的默认格式化器
|
||||
// "*":{
|
||||
|
||||
// },
|
||||
// Date:{
|
||||
|
||||
// },
|
||||
// Number:{
|
||||
|
||||
// },
|
||||
// String:{
|
||||
|
||||
// },
|
||||
// Array:{
|
||||
|
||||
// },
|
||||
// Object:{
|
||||
|
||||
// }
|
||||
}
|
||||
},
|
||||
en:{
|
||||
$types:{
|
||||
// 所有类型的默认格式化器
|
||||
// "*":{
|
||||
|
||||
// },
|
||||
// Date:{
|
||||
|
||||
// },
|
||||
// Number:{
|
||||
|
||||
// },
|
||||
// String:{
|
||||
|
||||
// },
|
||||
// Array:{
|
||||
|
||||
// },
|
||||
// Object:{
|
||||
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
3
packages/apps/vueapp/src/languages/idMap.js
Normal file
3
packages/apps/vueapp/src/languages/idMap.js
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
"Hello world!": 1
|
||||
}
|
46
packages/apps/vueapp/src/languages/index.js
Normal file
46
packages/apps/vueapp/src/languages/index.js
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
import messageIds from "./idMap.js"
|
||||
import { translate,I18nManager,i18nScope } from "@voerkai18n/runtime"
|
||||
import formatters from "./formatters.js"
|
||||
import defaultMessages from "./cn.js"
|
||||
const activeMessages = defaultMessages
|
||||
|
||||
|
||||
// 语言配置文件
|
||||
const scopeSettings = {
|
||||
"languages": [
|
||||
{
|
||||
"name": "cn",
|
||||
"title": "cn"
|
||||
},
|
||||
{
|
||||
"name": "en",
|
||||
"title": "en"
|
||||
}
|
||||
],
|
||||
"defaultLanguage": "cn",
|
||||
"activeLanguage": "cn",
|
||||
"namespaces": {}
|
||||
}
|
||||
|
||||
// 语言作用域
|
||||
const scope = new i18nScope({
|
||||
...scopeSettings, // languages,defaultLanguage,activeLanguage,namespaces,formatters
|
||||
id: "vueapp", // 当前作用域的id,自动取当前工程的package.json的name
|
||||
default: defaultMessages, // 默认语言包
|
||||
messages : activeMessages, // 当前语言包
|
||||
idMap:messageIds, // 消息id映射列表
|
||||
formatters, // 当前作用域的格式化函数列表
|
||||
loaders:{
|
||||
"en" : ()=>import("./en.js")
|
||||
}
|
||||
})
|
||||
// 翻译函数
|
||||
const t = translate.bind(scope)
|
||||
|
||||
export {
|
||||
t,
|
||||
i18nScope:scope,
|
||||
i18nManager:VoerkaI18n,
|
||||
}
|
||||
|
15
packages/apps/vueapp/src/languages/settings.json
Normal file
15
packages/apps/vueapp/src/languages/settings.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"languages": [
|
||||
{
|
||||
"name": "cn",
|
||||
"title": "cn"
|
||||
},
|
||||
{
|
||||
"name": "en",
|
||||
"title": "en"
|
||||
}
|
||||
],
|
||||
"defaultLanguage": "cn",
|
||||
"activeLanguage": "cn",
|
||||
"namespaces": {}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"Hello world!": {
|
||||
"en": "Hello world!",
|
||||
"$file": [
|
||||
"App.vue"
|
||||
]
|
||||
}
|
||||
}
|
8
packages/apps/vueapp/src/main.js
Normal file
8
packages/apps/vueapp/src/main.js
Normal file
@ -0,0 +1,8 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import { t, i18nScope } from './languages'
|
||||
|
||||
createApp(App).mount('#app')
|
||||
|
||||
|
||||
|
7
packages/apps/vueapp/vite.config.js
Normal file
7
packages/apps/vueapp/vite.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()]
|
||||
})
|
@ -14,21 +14,19 @@
|
||||
* - cn.json
|
||||
* - ...
|
||||
* idMap.js // id映射列表
|
||||
* settings.js // 配置文件
|
||||
* settings.json // 配置文件
|
||||
* cn.js // 中文语言包
|
||||
* en.js // 英文语言包
|
||||
* [lang].js // 其他语言包
|
||||
* package.json // 包信息,用来指定包类型,以便在nodejs中能够正确加载
|
||||
*
|
||||
* @param {*} opts
|
||||
*/
|
||||
|
||||
const readJson = require("readjson")
|
||||
const glob = require("glob")
|
||||
const createLogger = require("logsets")
|
||||
const path = require("path")
|
||||
const { t,importModule,findModuleType,getCurrentPackageJson} = require("./utils")
|
||||
const fs = require("fs")
|
||||
const { t,findModuleType,getCurrentPackageJson} = require("./utils")
|
||||
const fs = require("fs-extra")
|
||||
const logger = createLogger()
|
||||
const artTemplate = require("art-template")
|
||||
|
||||
@ -36,6 +34,7 @@ function normalizeCompileOptions(opts={}) {
|
||||
let options = Object.assign({
|
||||
moduleType:"auto" // 指定编译后的语言文件的模块类型,取值common,cjs,esm,es
|
||||
}, opts)
|
||||
options.moduleType = options.moduleType.trim()
|
||||
if(options.moduleType==="es") options.moduleType = "esm"
|
||||
if(options.moduleType==="cjs") options.moduleType = "commonjs"
|
||||
if(!["auto","commonjs","cjs","esm","es"].includes(options.moduleType)) options.moduleType = "esm"
|
||||
@ -45,16 +44,16 @@ function normalizeCompileOptions(opts={}) {
|
||||
module.exports =async function compile(langFolder,opts={}){
|
||||
const options = normalizeCompileOptions(opts);
|
||||
let { moduleType } = options;
|
||||
|
||||
// 如果自动则会从当前项目读取,如果没有指定则会是esm
|
||||
if(moduleType==="auto"){
|
||||
moduleType = findModuleType(langFolder)
|
||||
}
|
||||
const projectPackageJson = getCurrentPackageJson(langFolder)
|
||||
// 加载多语言配置文件
|
||||
const settingsFile = path.join(langFolder,"settings.js")
|
||||
const settingsFile = path.join(langFolder,"settings.json")
|
||||
try{
|
||||
// 读取多语言配置文件
|
||||
const langSettings = await importModule(settingsFile)
|
||||
const langSettings = fs.readJSONSync(settingsFile)
|
||||
let { languages,defaultLanguage,activeLanguage,namespaces } = langSettings
|
||||
|
||||
logger.log(t("支持的语言\t: {}"),languages.map(item=>`${item.title}(${item.name})`).join(","))
|
||||
@ -69,7 +68,7 @@ module.exports =async function compile(langFolder,opts={}){
|
||||
let messages = {} ,msgId =1
|
||||
glob.sync(path.join(langFolder,"translates/*.json")).forEach(file=>{
|
||||
try{
|
||||
let msg = readJson.sync(file)
|
||||
let msg = fs.readJSONSync(file)
|
||||
Object.entries(msg).forEach(([msg,langs])=>{
|
||||
if(msg in messages){
|
||||
Object.assign(messages[msg],langs)
|
||||
@ -121,7 +120,8 @@ module.exports =async function compile(langFolder,opts={}){
|
||||
activeLanguage,
|
||||
namespaces,
|
||||
moduleType,
|
||||
JSON
|
||||
JSON,
|
||||
settings:JSON.stringify(langSettings,null,4)
|
||||
}
|
||||
|
||||
// 5 . 生成编译后的格式化函数文件
|
||||
@ -133,11 +133,11 @@ module.exports =async function compile(langFolder,opts={}){
|
||||
}else{ // 格式化器如果存在,则需要更改对应的模块类型
|
||||
let formattersContent = fs.readFileSync(formattersFile,"utf8").toString()
|
||||
if(moduleType == "esm"){
|
||||
formattersContent = formattersContent.replaceAll(/\s*module.exports\s*\=/g,"export default ")
|
||||
formattersContent = formattersContent.replaceAll(/\s*module.exports\./g,"export ")
|
||||
formattersContent = formattersContent.replaceAll(/^[^\n\r\w]*module.exports\s*\=/gm,"export default ")
|
||||
formattersContent = formattersContent.replaceAll(/^[^\n\r\w]*module.exports\./gm,"export ")
|
||||
}else{
|
||||
formattersContent = formattersContent.replaceAll(/^\s*export\s*default\s*/g,"module.exports = ")
|
||||
formattersContent = formattersContent.replaceAll(/^\s*export\s*/g,"module.exports.")
|
||||
formattersContent = formattersContent.replaceAll(/^[^\n\r\w]*export\s*default\s*/gm,"module.exports = ")
|
||||
formattersContent = formattersContent.replaceAll(/^[^\n\r\w]*export\s*/gm,"module.exports.")
|
||||
}
|
||||
fs.writeFileSync(formattersFile,formattersContent)
|
||||
logger.log(t(" - 更新格式化器:{}"),path.basename(formattersFile))
|
||||
@ -149,30 +149,6 @@ module.exports =async function compile(langFolder,opts={}){
|
||||
fs.writeFileSync(entryFile,entryContent)
|
||||
logger.log(t(" - 访问入口文件: {}"),path.basename(entryFile))
|
||||
|
||||
|
||||
|
||||
|
||||
// 7. 重新生成settings ,需要确保settings.js匹配模块类型
|
||||
if(moduleType==="esm"){
|
||||
fs.writeFileSync(settingsFile,`export default ${JSON.stringify(langSettings,null,4)}`)
|
||||
}else{
|
||||
fs.writeFileSync(settingsFile,`module.exports = ${JSON.stringify(langSettings,null,4)}`)
|
||||
}
|
||||
|
||||
// 8. 生成package.json
|
||||
const packageJsonFile = path.join(langFolder,"package.json")
|
||||
let packageJson = {}
|
||||
if(moduleType==="esm"){
|
||||
packageJson = {
|
||||
license:"MIT",
|
||||
type:"module",
|
||||
}
|
||||
}else{
|
||||
packageJson = {
|
||||
license:"MIT",
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(packageJsonFile,JSON.stringify(packageJson,null,4))
|
||||
}catch(e){
|
||||
logger.log(t("加载多语言配置文件<{}>失败: {} "),settingsFile,e.message)
|
||||
}
|
||||
|
@ -7,22 +7,23 @@ const createLogger = require("logsets")
|
||||
const logger = createLogger()
|
||||
|
||||
|
||||
module.exports = function(targetPath,options={}){
|
||||
module.exports = function(srcPath,options={}){
|
||||
let { filetypes,exclude} = options
|
||||
if(!filetypes) filetypes = ["*.js","*.jsx","*.ts","*.tsx","*.vue","*.html"]
|
||||
if(!Array.isArray(filetypes)) filetypes = filetypes.split(",")
|
||||
const folders = filetypes.map(ftype=>{
|
||||
if(ftype.startsWith(".")) ftype = "*"+ftype
|
||||
if(!ftype.startsWith("*.")) ftype = "*."+ftype
|
||||
return path.join(targetPath,"**",ftype)
|
||||
return path.join(srcPath,"**",ftype)
|
||||
})
|
||||
folders.push(`!${path.join(targetPath,"languages","**")}`)
|
||||
folders.push(`!${path.join(targetPath,"node_modules","**")}`)
|
||||
folders.push(`!${path.join(targetPath,"**","node_modules","**")}`)
|
||||
folders.push(`!${path.join(srcPath,"languages","**")}`)
|
||||
folders.push(`!${path.join(srcPath,"node_modules","**")}`)
|
||||
folders.push(`!${path.join(srcPath,"**","node_modules","**")}`)
|
||||
folders.push("!**/babel.config.js")
|
||||
folders.push("!**/gulpfile.js")
|
||||
folders.push("!**/*.test.js")
|
||||
folders.push("!__test__/**/*.js")
|
||||
folders.push("!**/vite.config.js")
|
||||
|
||||
|
||||
if(!Array.isArray(exclude) && exclude){
|
||||
@ -30,11 +31,11 @@ module.exports = function(targetPath,options={}){
|
||||
}
|
||||
if(exclude){
|
||||
exclude.forEach(folder=>{
|
||||
folders.push(`!${path.join(targetPath,folder)}`)
|
||||
folders.push(`!${path.join(srcPath,folder)}`)
|
||||
})
|
||||
}
|
||||
if(!fs.existsSync(targetPath)){
|
||||
logger.log(t("目标文件夹<{}>不存在"),targetPath)
|
||||
if(!fs.existsSync(srcPath)){
|
||||
logger.log(t("目标文件夹<{}>不存在"),srcPath)
|
||||
return
|
||||
}
|
||||
if(options.debug){
|
||||
@ -42,7 +43,7 @@ module.exports = function(targetPath,options={}){
|
||||
logger.format(folders)
|
||||
}
|
||||
|
||||
options.outputPath = path.join(targetPath,"languages")
|
||||
options.outputPath = path.join(srcPath,"languages")
|
||||
gulp.src(folders)
|
||||
.pipe(extractor(options))
|
||||
.pipe(gulp.dest(options.outputPath))
|
||||
|
@ -8,8 +8,7 @@
|
||||
const through2 = require('through2')
|
||||
const deepmerge = require("deepmerge")
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const readJson = require("readjson")
|
||||
const fs = require('fs-extra')
|
||||
const createLogger = require("logsets")
|
||||
const { replaceInterpolateVars,getDataTypeName } = require("@voerkai18n/runtime")
|
||||
const { findModuleType,createPackageJsonFile,t } = require("./utils")
|
||||
@ -27,6 +26,33 @@ const DefaultTranslateExtractor = String.raw`\bt\(\s*("|'){1}(?:((?<namespace>\w
|
||||
// 从html文件标签中提取翻译文本
|
||||
const DefaultHtmlAttrExtractor = String.raw`\<(?<tagName>\w+)(.*?)(?<i18nKey>{attrName}\s*\=\s*)([\"\'']{1})(?<text>.*?)(\4){1}\s*(.*?)(\>|\/\>)`
|
||||
|
||||
// 声明各种语言的注释匹配正则表达式
|
||||
// {"js,jsx"}
|
||||
const commentRegexs ={
|
||||
"js,vue,jsx,ts":[
|
||||
/(^[^\n\r\w\W]*\/\/.*$)|(\/\/.*$)/gm, // 单行注释
|
||||
/\/\*\s*[\W\w|\r|\n|*]*\s*\*\//gm // 多行注释
|
||||
],
|
||||
html:[
|
||||
/\<\!--[\s\r\n-]*[\w\r\n-\W]*?[\s\r\n-]*--\>/gm, // 注释
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配文件中的注释部分
|
||||
*/
|
||||
function removeComments(content,filetype="js"){
|
||||
Object.entries(commentRegexs).forEach(([filetype,regexps])=>{
|
||||
if(filetype.split(",").includes(filetype)){
|
||||
regexps.forEach(regex=>{
|
||||
content = content.replaceAll(regex,"")
|
||||
})
|
||||
}
|
||||
})
|
||||
return content
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 返回filePath是否在nsPaths名称空间内
|
||||
@ -61,6 +87,7 @@ function inNamespace(filePath,nsPath){
|
||||
}
|
||||
return "default"
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 使用正则表达式提取翻译文本
|
||||
@ -73,6 +100,10 @@ function extractTranslateTextUseRegexp(content,namespace,extractor,file,options)
|
||||
|
||||
let { languages,defaultLanguage } = options
|
||||
|
||||
// 移除代码中的注释,以便正则表达式提取翻译文本时排除注释部分
|
||||
const fileExtName = file.extname.substr(1).toLowerCase() // 文件扩展名
|
||||
content = removeComments(content,fileExtName)
|
||||
|
||||
let texts = {}
|
||||
while ((result = extractor.exec(content)) !== null) {
|
||||
// 这对于避免零宽度匹配的无限循环是必要的
|
||||
@ -320,7 +351,7 @@ function updateLanguageFile(newTexts,toLangFile,options){
|
||||
let oldTexts = {}
|
||||
// 读取原始翻译文件
|
||||
try{
|
||||
oldTexts =JSON.parse(fs.readFileSync(toLangFile))// readJson.sync(toLangFile)
|
||||
oldTexts =JSON.parse(fs.readFileSync(toLangFile))
|
||||
}catch(e){
|
||||
logger.log("Error while read language file <{}>: {}",toLangFile,e.message)
|
||||
// 如果读取出错,可能是语言文件不是有效的json文件,则备份一下
|
||||
@ -415,8 +446,8 @@ module.exports = function(options={}){
|
||||
logger.log(" √ 保存语言文件 : {}",path.relative(outputPath,langFile))
|
||||
}
|
||||
}
|
||||
// 生成语言配置文件 settings.js , 仅当不存在时才生成
|
||||
const settingsFile = path.join(outputPath,"settings.js")
|
||||
// 生成语言配置文件 settings.json , 仅当不存在时才生成
|
||||
const settingsFile = path.join(outputPath,"settings.json")
|
||||
if(!fs.existsSync(settingsFile)){
|
||||
const settings = {
|
||||
languages : options.languages,
|
||||
@ -424,15 +455,12 @@ module.exports = function(options={}){
|
||||
activeLanguage : options.activeLanguage,
|
||||
namespaces : options.namespaces
|
||||
}
|
||||
fs.writeFileSync(settingsFile,`module.exports = ${JSON.stringify(settings,null,4)}`)
|
||||
fs.writeFileSync(settingsFile,JSON.stringify(settings,null,4))
|
||||
logger.log(" - 生成语言配置文件: {}",settingsFile)
|
||||
}else{
|
||||
logger.log(" - 已更新语言配置文件: {}",settingsFile)
|
||||
logger.log(" - 应用语言配置文件: {}",settingsFile)
|
||||
}
|
||||
|
||||
// 生成package.json
|
||||
createPackageJsonFile(outputPath)
|
||||
|
||||
logger.log("下一步:")
|
||||
logger.log(" - 运行<{}>编译语言包","voerkai18n compile")
|
||||
logger.log(" - 在源码中导入编译后的语言包[{}]","import './languages'")
|
||||
|
@ -1,36 +1,59 @@
|
||||
const { Command } = require('commander');
|
||||
const createLogger = require("logsets")
|
||||
const path = require("path")
|
||||
const fs = require("fs");
|
||||
const { importModule,t } = require('./utils');
|
||||
const fs = require("fs-extra")
|
||||
const deepmerge = require('deepmerge');
|
||||
const logger = createLogger()
|
||||
const { scope } = require('./languages');
|
||||
const { getCurrentProjectRootFolder,i18nScope ,t } = require("./utils")
|
||||
|
||||
|
||||
|
||||
const program = new Command();
|
||||
|
||||
/**
|
||||
* 根据当前输入的文件夹位置自动确定源码文件夹位置
|
||||
*
|
||||
* - 如果没有指定,则取当前文件夹
|
||||
* - 如果指定是非绝对路径,则以当前文件夹作为base
|
||||
* - 查找pack
|
||||
* - 如果该文件夹中存在src,则取src下的文件夹
|
||||
* -
|
||||
*
|
||||
* @param {*} location
|
||||
* @returns
|
||||
*/
|
||||
function getProjectSourceFolder(location){
|
||||
if(!location) {
|
||||
location = process.cwd()
|
||||
}else{
|
||||
if(!path.isAbsolute(location)){
|
||||
location = path.join(process.cwd(),location)
|
||||
}
|
||||
}
|
||||
let projectRoot = getCurrentProjectRootFolder(location)
|
||||
// 如果当前工程存在src文件夹,则自动使用该文件夹作为源文件夹
|
||||
if(fs.existsSync(path.join(projectRoot,"src"))){
|
||||
projectRoot = path.join(projectRoot,"src")
|
||||
}
|
||||
return projectRoot
|
||||
}
|
||||
|
||||
program
|
||||
.command('init')
|
||||
.argument('[location]', t('工程项目所在目录'))
|
||||
.description(t('初始化项目国际化配置'))
|
||||
.option('-d, --debug', t('输出调试信息'))
|
||||
.option('-D, --debug', t('输出调试信息'))
|
||||
.option('-r, --reset', t('重新生成当前项目的语言配置'))
|
||||
.option('-m, --moduleType [type]', t('生成的js模块类型,取值auto,esm,cjs'),"auto")
|
||||
.option('-lngs, --languages <languages...>', t('支持的语言列表'), ['cn','en'])
|
||||
.option('-default, --defaultLanguage <name>', t('默认语言'), 'cn')
|
||||
.option('-active, --activeLanguage <name>', t('激活语言'), 'cn')
|
||||
.option('-d, --defaultLanguage <name>', t('默认语言'), 'cn')
|
||||
.option('-i, --installRuntime', t('自动安装默认语言'),true)
|
||||
.option('-a, --activeLanguage <name>', t('激活语言'), 'cn')
|
||||
.hook("preAction",async function(location){
|
||||
const lang= process.env.LANGUAGE
|
||||
if(lang){
|
||||
await scope.change(lang)
|
||||
}
|
||||
const lang= process.env.LANGUAGE || "cn"
|
||||
await i18nScope.change(lang)
|
||||
})
|
||||
.action((location,options) => {
|
||||
if(!location) {
|
||||
location = process.cwd()
|
||||
}else{
|
||||
location = path.join(process.cwd(),location)
|
||||
}
|
||||
location = getProjectSourceFolder(location)
|
||||
logger.log(t("工程目录:{}"),location)
|
||||
//
|
||||
if(options.debug){
|
||||
@ -44,45 +67,34 @@ program
|
||||
program
|
||||
.command('extract')
|
||||
.description(t('扫描并提取所有待翻译的字符串到<languages/translates>文件夹中'))
|
||||
.option('-d, --debug', t('输出调试信息'))
|
||||
.option('-lngs, --languages', t('支持的语言'), 'cn,en')
|
||||
.option('-default, --defaultLanguage', t('默认语言'), 'cn')
|
||||
.option('-active, --activeLanguage', t('激活语言'), 'cn')
|
||||
.option('-D, --debug', t('输出调试信息'))
|
||||
.option('-lngs, --languages <languages...>', t('支持的语言'), ['cn','en'])
|
||||
.option('-d, --defaultLanguage', t('默认语言'), 'cn')
|
||||
.option('-a, --activeLanguage', t('激活语言'), 'cn')
|
||||
.option('-ns, --namespaces', t('翻译名称空间'))
|
||||
.option('-e, --exclude <folders>', t('排除要扫描的文件夹,多个用逗号分隔'))
|
||||
.option('-u, --updateMode', t('本次提取内容与已存在内容的数据合并策略,默认取值sync=同步,overwrite=覆盖,merge=合并'), 'sync')
|
||||
.option('-f, --filetypes', t('要扫描的文件类型'), 'js,vue,html,jsx,ts')
|
||||
.option('-f, --filetypes', t('要扫描的文件类型'), 'js,vue,html,jsx,ts,mjs,cjs')
|
||||
.argument('[location]', t('工程项目所在目录'),"./")
|
||||
.hook("preAction",async function(location){
|
||||
const lang= process.env.LANGUAGE
|
||||
if(lang){
|
||||
await scope.change(lang)
|
||||
}
|
||||
const lang= process.env.LANGUAGE || "cn"
|
||||
await i18nScope.change(lang)
|
||||
})
|
||||
.action(async (location,options) => {
|
||||
if(!location) {
|
||||
location = process.cwd()
|
||||
}else{
|
||||
location = path.join(process.cwd(),location)
|
||||
}
|
||||
location = getProjectSourceFolder(location)
|
||||
if(options.languages){
|
||||
options.languages = options.languages.split(",").map(l=>({name:l,title:l}))
|
||||
options.languages = options.languages.map(l=>({name:l,title:l}))
|
||||
}
|
||||
//options = Object.assign({},options)
|
||||
logger.log(t("工程目录:{}"),location)
|
||||
const langSettingsFile = path.join(location,"languages","settings.js")
|
||||
const langSettingsFile = path.join(location,"languages","settings.json")
|
||||
if(fs.existsSync(langSettingsFile)){
|
||||
logger.log(t("语言配置文件<{}>已存在,将优先使用此配置文件中参数来提取文本","./languages/settings.js"))
|
||||
let lngOptions = await importModule(langSettingsFile)
|
||||
logger.log(t("语言配置文件<{}>已存在,将优先使用此配置文件中参数来提取文本","./languages/settings.json"))
|
||||
let lngOptions = fs.readJSONSync(langSettingsFile)
|
||||
options.languages = lngOptions.languages
|
||||
options.defaultLanguage = lngOptions.defaultLanguage
|
||||
options.activeLanguage = lngOptions.activeLanguage
|
||||
options.namespaces = lngOptions.namespaces
|
||||
}
|
||||
//
|
||||
// if(options.debug){
|
||||
// logger.format(options,{compact:true})
|
||||
// }
|
||||
const extractor = require('./extract.command');
|
||||
extractor(location,options)
|
||||
});
|
||||
@ -92,28 +104,19 @@ program
|
||||
.command('compile')
|
||||
.description(t('编译指定项目的语言包'))
|
||||
.option('-d, --debug', t('输出调试信息'))
|
||||
.option('-m, --moduleType [types]', t('输出模块类型,取值auto,esm,cjs'), 'auto')
|
||||
.option('-m, --moduleType [types]', t('输出模块类型,取值auto,esm,cjs'), 'esm')
|
||||
.argument('[location]', t('工程项目所在目录'),"./")
|
||||
.hook("preAction",async function(location){
|
||||
const lang= process.env.LANGUAGE
|
||||
if(lang){
|
||||
await scope.change(lang)
|
||||
}
|
||||
const lang= process.env.LANGUAGE || "cn"
|
||||
await i18nScope.change(lang)
|
||||
})
|
||||
.action(async (location,options) => {
|
||||
if(!location) {
|
||||
location = process.cwd()
|
||||
}else{
|
||||
location = path.join(process.cwd(),location)
|
||||
}
|
||||
location = getProjectSourceFolder(location)
|
||||
const langFolder = path.join(location,"languages")
|
||||
if(!fs.existsSync(langFolder)){
|
||||
logger.error(t("语言包文件夹<{}>不存在",langFolder))
|
||||
return
|
||||
}
|
||||
// if(options.debug){
|
||||
// logger.format(options,{compact:true})
|
||||
// }
|
||||
}
|
||||
compile = require("./compile.command")
|
||||
compile(langFolder,options)
|
||||
});
|
||||
|
@ -28,7 +28,7 @@ const logger = createLogger()
|
||||
}
|
||||
|
||||
|
||||
module.exports = function(srcPath,{debug = true,languages=["cn","en"],defaultLanguage="cn",activeLanguage="cn",moduleType = "auto",reset=false}={}){
|
||||
module.exports = function(srcPath,{debug = true,languages=["cn","en"],defaultLanguage="cn",activeLanguage="cn",reset=false,installRuntime=true}={}){
|
||||
// 语言文件夹名称
|
||||
const langPath = "languages"
|
||||
// 查找当前项目的语言包类型路径
|
||||
@ -38,21 +38,9 @@ module.exports = function(srcPath,{debug = true,languages=["cn","en"],defaultLan
|
||||
if(debug) logger.log(t("创建语言包文件夹: {}"),lngPath)
|
||||
}
|
||||
|
||||
moduleType = createPackageJsonFile(lngPath,moduleType)
|
||||
|
||||
if(moduleType==null) {
|
||||
if(debug){
|
||||
logger.log(t("找不到{}文件,{}只能在js项目工程中使用"),"package.json","voerkai18n")
|
||||
}else{
|
||||
throw new Error(t("找不到package.json文件,voerkai18n只能在js项目工程中使用"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 创建settings.js文件
|
||||
const settingsFile = path.join(lngPath,"settings.js")
|
||||
// 创建settings.json文件
|
||||
const settingsFile = path.join(lngPath,"settings.json")
|
||||
if(fs.existsSync(settingsFile) && !reset){
|
||||
if(debug) logger.log(t("语言配置文件{}文件已存在,跳过创建。\n使用{}可以重新覆盖创建"),settingsFile,"-r")
|
||||
return
|
||||
@ -63,21 +51,21 @@ module.exports = function(srcPath,{debug = true,languages=["cn","en"],defaultLan
|
||||
activeLanguage,
|
||||
namespaces:{}
|
||||
}
|
||||
// 写入配置文件
|
||||
if(["esm","es","module"].includes(moduleType)){
|
||||
fs.writeFileSync(settingsFile,`export default ${JSON.stringify(settings,null,4)}`)
|
||||
}else{
|
||||
fs.writeFileSync(settingsFile,`module.exports = ${JSON.stringify(settings,null,4)}`)
|
||||
}
|
||||
// 自动安装运行时@voerkai18n/runtime
|
||||
logger.log(t("正在安装多语言运行时:{}"),"@voerkai18n/runtime")
|
||||
installVoerkai18nRuntim(srcPath)
|
||||
|
||||
// 写入配置文件
|
||||
fs.writeFileSync(settingsFile,JSON.stringify(settings,null,4))
|
||||
|
||||
// 自动安装运行时@voerkai18n/runtime
|
||||
if(installRuntime){
|
||||
logger.log(t("正在安装多语言运行时:{}"),"@voerkai18n/runtime")
|
||||
installVoerkai18nRuntim(srcPath)
|
||||
}
|
||||
|
||||
if(debug) {
|
||||
logger.log(t("生成语言配置文件:{}"),"./languages/settings.js")
|
||||
logger.log(t("生成语言配置文件:{}"),"./languages/settings.json")
|
||||
logger.log(t("拟支持的语言:{}"),settings.languages.map(l=>l.name).join(","))
|
||||
logger.log(t("初始化成功,下一步:"))
|
||||
logger.log(t(" - 编辑{}确定拟支持的语言种类等参数"),"languages/settings.js")
|
||||
logger.log(t(" - 编辑{}确定拟支持的语言种类等参数"),"languages/settings.json")
|
||||
logger.log(t(" - 运行<{}>扫描提取要翻译的文本"),"voerkai18n extract")
|
||||
logger.log(t(" - 运行<{}>编译语言包"),"voerkai18n compile")
|
||||
}
|
||||
|
@ -3,44 +3,44 @@ module.exports = {
|
||||
"2": "默认语言\\t: {}",
|
||||
"3": "激活语言\\t: {}",
|
||||
"4": "名称空间\\t: {}",
|
||||
"5": "模块类型\\t: {}",
|
||||
"6": "编译结果输出至:{}",
|
||||
"7": "读取语言文件{}失败:{}",
|
||||
"8": " - 共合成{}条语言包文本",
|
||||
"9": " - 语言包文件: {}",
|
||||
"10": " - idMap文件: {}",
|
||||
"11": " - 格式化器:{}",
|
||||
"12": " - 更新格式化器:{}",
|
||||
"13": " - 访问入口文件: {}",
|
||||
"14": "加载多语言配置文件<{}>失败: {} ",
|
||||
"15": "目标文件夹<{}>不存在",
|
||||
"16": "扫描提取范围:",
|
||||
"17": "工程项目所在目录",
|
||||
"18": "初始化项目国际化配置",
|
||||
"19": "输出调试信息",
|
||||
"20": "重新生成当前项目的语言配置",
|
||||
"21": "生成的js模块类型,取值auto,esm,cjs",
|
||||
"22": "支持的语言列表",
|
||||
"23": "工程目录:{}",
|
||||
"24": "扫描并提取所有待翻译的字符串到<languages/translates>文件夹中",
|
||||
"25": "支持的语言",
|
||||
"26": "默认语言",
|
||||
"27": "激活语言",
|
||||
"28": "翻译名称空间",
|
||||
"29": "排除要扫描的文件夹,多个用逗号分隔",
|
||||
"30": "本次提取内容与已存在内容的数据合并策略,默认取值sync=同步,overwrite=覆盖,merge=合并",
|
||||
"31": "要扫描的文件类型",
|
||||
"32": "语言配置文件<{}>已存在,将优先使用此配置文件中参数来提取文本",
|
||||
"33": "编译指定项目的语言包",
|
||||
"34": "输出模块类型,取值auto,esm,cjs",
|
||||
"35": "语言包文件夹<{}>不存在",
|
||||
"36": "找不到{}文件,{}只能在js项目工程中使用",
|
||||
"37": "找不到package.json文件,voerkai18n只能在js项目工程中使用",
|
||||
"38": "语言配置文件{}文件已存在,跳过创建。\\n使用{}可以重新覆盖创建",
|
||||
"39": "生成语言配置文件:{}",
|
||||
"40": "拟支持的语言:{}",
|
||||
"41": "初始化成功,下一步:",
|
||||
"42": " - 编辑{}确定拟支持的语言种类等参数",
|
||||
"43": " - 运行<{}>扫描提取要翻译的文本",
|
||||
"44": " - 运行<{}>编译语言包"
|
||||
"5": " - 更新格式化器:{}",
|
||||
"6": " - 访问入口文件: {}",
|
||||
"7": "加载多语言配置文件<{}>失败: {} ",
|
||||
"8": "目标文件夹<{}>不存在",
|
||||
"9": "扫描提取范围:",
|
||||
"10": "工程项目所在目录",
|
||||
"11": "初始化项目国际化配置",
|
||||
"12": "输出调试信息",
|
||||
"13": "重新生成当前项目的语言配置",
|
||||
"14": "支持的语言列表",
|
||||
"15": "工程目录:{}",
|
||||
"16": "扫描并提取所有待翻译的字符串到<languages/translates>文件夹中",
|
||||
"17": "支持的语言",
|
||||
"18": "默认语言",
|
||||
"19": "激活语言",
|
||||
"20": "翻译名称空间",
|
||||
"21": "排除要扫描的文件夹,多个用逗号分隔",
|
||||
"22": "本次提取内容与已存在内容的数据合并策略,默认取值sync=同步,overwrite=覆盖,merge=合并",
|
||||
"23": "要扫描的文件类型",
|
||||
"24": "语言配置文件<{}>已存在,将优先使用此配置文件中参数来提取文本",
|
||||
"25": "编译指定项目的语言包",
|
||||
"26": "输出模块类型,取值auto,esm,cjs",
|
||||
"27": "语言包文件夹<{}>不存在",
|
||||
"28": "语言配置文件{}文件已存在,跳过创建。\\n使用{}可以重新覆盖创建",
|
||||
"29": "生成语言配置文件:{}",
|
||||
"30": "拟支持的语言:{}",
|
||||
"31": "初始化成功,下一步:",
|
||||
"32": " - 编辑{}确定拟支持的语言种类等参数",
|
||||
"33": " - 运行<{}>扫描提取要翻译的文本",
|
||||
"34": " - 运行<{}>编译语言包",
|
||||
"35": "创建语言包文件夹: {}",
|
||||
"36": "正在安装多语言运行时:{}",
|
||||
"37": "模块类型\\t: {}",
|
||||
"38": "编译结果输出至:{}",
|
||||
"39": "读取语言文件{}失败:{}",
|
||||
"40": " - 共合成{}条语言包文本",
|
||||
"41": " - 语言包文件: {}",
|
||||
"42": " - idMap文件: {}",
|
||||
"43": " - 格式化器:{}",
|
||||
"44": "Now is { value | date | bjTime }"
|
||||
}
|
@ -3,44 +3,44 @@ module.exports = {
|
||||
"2": "Default language\\t: {}",
|
||||
"3": "Active language\\t\\t: {}",
|
||||
"4": "Namespaces\\t\\t: {}",
|
||||
"5": "Module type\\t\\t: {}",
|
||||
"6": "Compile to:{}",
|
||||
"7": "Error while read language of file<{}>:{}",
|
||||
"8": " - Total {} messages",
|
||||
"9": " - language messages: {}",
|
||||
"10": " - idMap file: {}",
|
||||
"11": " - Formatters:{}",
|
||||
"12": " - Update formatters:{}",
|
||||
"13": " - Entry of language: {}",
|
||||
"14": "Failed to load multilingual configuration file <{}>: {}",
|
||||
"15": "The destination folder < {} > does not exist",
|
||||
"16": "Scan for:",
|
||||
"17": "Project directory",
|
||||
"18": "Initialize project i18n configuration",
|
||||
"19": "Output debug information",
|
||||
"20": "Regenerate the language configuration of the current project",
|
||||
"21": "Generated JS module type, with values of auto, esm, cjs",
|
||||
"22": "Supported languages",
|
||||
"23": "Folder of project:{}",
|
||||
"24": "Scan and extract all strings to be translated into the <languages/translations> folder",
|
||||
"25": "Supported languages",
|
||||
"26": "Default language",
|
||||
"27": "Active language",
|
||||
"28": "Namespaces",
|
||||
"29": "Exclude folders to scan, multiple separated by commas",
|
||||
"30": " strategy of messages merge,with value of sync(default),overwrite,merge",
|
||||
"31": "Type of file to scan",
|
||||
"32": "The language configuration file <{}> already exists. It will be used preferentially to extract messages",
|
||||
"33": "Compiles the language messages for project",
|
||||
"34": "Output module type, values: auto, esm, cjs",
|
||||
"35": "The language messages folder <{}> does not exist",
|
||||
"36": "Cannot find {} file, {} can only be used in JS project",
|
||||
"37": "Cannot find <package.json> file, voerkai18n can only be used in JS project",
|
||||
"38": "Language configuration {} file already exists, skipping creation\\n use {} to overwrite the creation",
|
||||
"39": "Generate language configuration: {}",
|
||||
"40": "Languages to be supported:{}",
|
||||
"41": "Initialization succeeded, next step:",
|
||||
"42": " - Edit language parameters in {}",
|
||||
"43": " - Run <{}> scan to extract the messages to be translated",
|
||||
"44": " - Run <{}> compile language messages"
|
||||
"5": " - Update formatters:{}",
|
||||
"6": " - Entry of language: {}",
|
||||
"7": "Failed to load multilingual configuration file <{}>: {}",
|
||||
"8": "The destination folder < {} > does not exist",
|
||||
"9": "Scan for:",
|
||||
"10": "Project directory",
|
||||
"11": "Initialize project i18n configuration",
|
||||
"12": "Output debug information",
|
||||
"13": "Regenerate the language configuration of the current project",
|
||||
"14": "Supported languages",
|
||||
"15": "Folder of project:{}",
|
||||
"16": "Scan and extract all strings to be translated into the <languages/translations> folder",
|
||||
"17": "Supported languages",
|
||||
"18": "Default language",
|
||||
"19": "Active language",
|
||||
"20": "Namespaces",
|
||||
"21": "Exclude folders to scan, multiple separated by commas",
|
||||
"22": " strategy of messages merge,with value of sync(default),overwrite,merge",
|
||||
"23": "Type of file to scan",
|
||||
"24": "The language configuration file <{}> already exists. It will be used preferentially to extract messages",
|
||||
"25": "Compiles the language messages for project",
|
||||
"26": "Output module type, values: auto, esm, cjs",
|
||||
"27": "The language messages folder <{}> does not exist",
|
||||
"28": "Language configuration {} file already exists, skipping creation\\n use {} to overwrite the creation",
|
||||
"29": "Generate language configuration: {}",
|
||||
"30": "Languages to be supported:{}",
|
||||
"31": "Initialization succeeded, next step:",
|
||||
"32": " - Edit language parameters in {}",
|
||||
"33": " - Run <{}> scan to extract the messages to be translated",
|
||||
"34": " - Run <{}> compile language messages",
|
||||
"35": "Create <languages> folder: {}",
|
||||
"36": "Installing @voerkai18n/runtime:{}",
|
||||
"37": "Type of module\\t\\t: {}",
|
||||
"38": "Compile to:{}",
|
||||
"39": "Error while read language file{}: {}",
|
||||
"40": " - Total {} messages",
|
||||
"41": " - Language file: {}",
|
||||
"42": " - idMap file: {}",
|
||||
"43": " - Formatters: {}",
|
||||
"44": "Now is { value | date | bjTime }"
|
||||
}
|
@ -46,7 +46,6 @@
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// 在所有语言下生效的格式化器
|
||||
"*":{
|
||||
|
@ -3,44 +3,44 @@ module.exports = {
|
||||
"默认语言\\t: {}": 2,
|
||||
"激活语言\\t: {}": 3,
|
||||
"名称空间\\t: {}": 4,
|
||||
"模块类型\\t: {}": 5,
|
||||
"编译结果输出至:{}": 6,
|
||||
"读取语言文件{}失败:{}": 7,
|
||||
" - 共合成{}条语言包文本": 8,
|
||||
" - 语言包文件: {}": 9,
|
||||
" - idMap文件: {}": 10,
|
||||
" - 格式化器:{}": 11,
|
||||
" - 更新格式化器:{}": 12,
|
||||
" - 访问入口文件: {}": 13,
|
||||
"加载多语言配置文件<{}>失败: {} ": 14,
|
||||
"目标文件夹<{}>不存在": 15,
|
||||
"扫描提取范围:": 16,
|
||||
"工程项目所在目录": 17,
|
||||
"初始化项目国际化配置": 18,
|
||||
"输出调试信息": 19,
|
||||
"重新生成当前项目的语言配置": 20,
|
||||
"生成的js模块类型,取值auto,esm,cjs": 21,
|
||||
"支持的语言列表": 22,
|
||||
"工程目录:{}": 23,
|
||||
"扫描并提取所有待翻译的字符串到<languages/translates>文件夹中": 24,
|
||||
"支持的语言": 25,
|
||||
"默认语言": 26,
|
||||
"激活语言": 27,
|
||||
"翻译名称空间": 28,
|
||||
"排除要扫描的文件夹,多个用逗号分隔": 29,
|
||||
"本次提取内容与已存在内容的数据合并策略,默认取值sync=同步,overwrite=覆盖,merge=合并": 30,
|
||||
"要扫描的文件类型": 31,
|
||||
"语言配置文件<{}>已存在,将优先使用此配置文件中参数来提取文本": 32,
|
||||
"编译指定项目的语言包": 33,
|
||||
"输出模块类型,取值auto,esm,cjs": 34,
|
||||
"语言包文件夹<{}>不存在": 35,
|
||||
"找不到{}文件,{}只能在js项目工程中使用": 36,
|
||||
"找不到package.json文件,voerkai18n只能在js项目工程中使用": 37,
|
||||
"语言配置文件{}文件已存在,跳过创建。\\n使用{}可以重新覆盖创建": 38,
|
||||
"生成语言配置文件:{}": 39,
|
||||
"拟支持的语言:{}": 40,
|
||||
"初始化成功,下一步:": 41,
|
||||
" - 编辑{}确定拟支持的语言种类等参数": 42,
|
||||
" - 运行<{}>扫描提取要翻译的文本": 43,
|
||||
" - 运行<{}>编译语言包": 44
|
||||
" - 更新格式化器:{}": 5,
|
||||
" - 访问入口文件: {}": 6,
|
||||
"加载多语言配置文件<{}>失败: {} ": 7,
|
||||
"目标文件夹<{}>不存在": 8,
|
||||
"扫描提取范围:": 9,
|
||||
"工程项目所在目录": 10,
|
||||
"初始化项目国际化配置": 11,
|
||||
"输出调试信息": 12,
|
||||
"重新生成当前项目的语言配置": 13,
|
||||
"支持的语言列表": 14,
|
||||
"工程目录:{}": 15,
|
||||
"扫描并提取所有待翻译的字符串到<languages/translates>文件夹中": 16,
|
||||
"支持的语言": 17,
|
||||
"默认语言": 18,
|
||||
"激活语言": 19,
|
||||
"翻译名称空间": 20,
|
||||
"排除要扫描的文件夹,多个用逗号分隔": 21,
|
||||
"本次提取内容与已存在内容的数据合并策略,默认取值sync=同步,overwrite=覆盖,merge=合并": 22,
|
||||
"要扫描的文件类型": 23,
|
||||
"语言配置文件<{}>已存在,将优先使用此配置文件中参数来提取文本": 24,
|
||||
"编译指定项目的语言包": 25,
|
||||
"输出模块类型,取值auto,esm,cjs": 26,
|
||||
"语言包文件夹<{}>不存在": 27,
|
||||
"语言配置文件{}文件已存在,跳过创建。\\n使用{}可以重新覆盖创建": 28,
|
||||
"生成语言配置文件:{}": 29,
|
||||
"拟支持的语言:{}": 30,
|
||||
"初始化成功,下一步:": 31,
|
||||
" - 编辑{}确定拟支持的语言种类等参数": 32,
|
||||
" - 运行<{}>扫描提取要翻译的文本": 33,
|
||||
" - 运行<{}>编译语言包": 34,
|
||||
"创建语言包文件夹: {}": 35,
|
||||
"正在安装多语言运行时:{}": 36,
|
||||
"模块类型\\t: {}": 37,
|
||||
"编译结果输出至:{}": 38,
|
||||
"读取语言文件{}失败:{}": 39,
|
||||
" - 共合成{}条语言包文本": 40,
|
||||
" - 语言包文件: {}": 41,
|
||||
" - idMap文件: {}": 42,
|
||||
" - 格式化器:{}": 43,
|
||||
"Now is { value | date | bjTime }": 44
|
||||
}
|
@ -1,16 +1,32 @@
|
||||
|
||||
const messageIds = require("./idMap")
|
||||
const { translate,I18nManager,i18nScope } = require("@voerkai18n/runtime")
|
||||
const scopeSettings = require("./settings.js")
|
||||
const formatters = require("./formatters.js")
|
||||
const defaultMessages = require("./cn.js")
|
||||
const activeMessages = defaultMessages
|
||||
|
||||
|
||||
// 语言配置文件
|
||||
const scopeSettings = {
|
||||
"languages": [
|
||||
{
|
||||
"name": "cn",
|
||||
"title": "cn"
|
||||
},
|
||||
{
|
||||
"name": "en",
|
||||
"title": "en"
|
||||
}
|
||||
],
|
||||
"defaultLanguage": "cn",
|
||||
"activeLanguage": "cn",
|
||||
"namespaces": {}
|
||||
}
|
||||
|
||||
// 语言作用域
|
||||
const scope = new i18nScope({
|
||||
...scopeSettings, // languages,defaultLanguage,activeLanguage,namespaces,formatters
|
||||
id: "@voerkai18n/cli", // 当前作用域的id,自动取当前工程的package.json的name
|
||||
id: "@voerkai18n/cli", // 当前作用域的id,自动取当前工程的package.json的name
|
||||
default: defaultMessages, // 默认语言包
|
||||
messages : activeMessages, // 当前语言包
|
||||
idMap:messageIds, // 消息id映射列表
|
||||
@ -23,6 +39,6 @@ const scope = new i18nScope({
|
||||
const t = translate.bind(scope)
|
||||
|
||||
module.exports.t = t
|
||||
module.exports.scope = scope
|
||||
module.exports.i18nScope = scope
|
||||
module.exports.i18nManager = VoerkaI18n
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"license": "MIT"
|
||||
}
|
15
packages/cli/languages/settings.json
Normal file
15
packages/cli/languages/settings.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"languages": [
|
||||
{
|
||||
"name": "cn",
|
||||
"title": "cn"
|
||||
},
|
||||
{
|
||||
"name": "en",
|
||||
"title": "en"
|
||||
}
|
||||
],
|
||||
"defaultLanguage": "cn",
|
||||
"activeLanguage": "cn",
|
||||
"namespaces": {}
|
||||
}
|
@ -27,48 +27,6 @@
|
||||
"extract.plugin.js"
|
||||
]
|
||||
},
|
||||
"模块类型\\t: {}": {
|
||||
"en": "Module type\\t\\t: {}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
"编译结果输出至:{}": {
|
||||
"en": "Compile to:{}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
"读取语言文件{}失败:{}": {
|
||||
"en": "Error while read language of file<{}>:{}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
" - 共合成{}条语言包文本": {
|
||||
"en": " - Total {} messages",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
" - 语言包文件: {}": {
|
||||
"en": " - language messages: {}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
" - idMap文件: {}": {
|
||||
"en": " - idMap file: {}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
" - 格式化器:{}": {
|
||||
"en": " - Formatters:{}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
" - 更新格式化器:{}": {
|
||||
"en": " - Update formatters:{}",
|
||||
"$file": [
|
||||
@ -123,12 +81,6 @@
|
||||
"index.js"
|
||||
]
|
||||
},
|
||||
"生成的js模块类型,取值auto,esm,cjs": {
|
||||
"en": "Generated JS module type, with values of auto, esm, cjs",
|
||||
"$file": [
|
||||
"index.js"
|
||||
]
|
||||
},
|
||||
"支持的语言列表": {
|
||||
"en": "Supported languages",
|
||||
"$file": [
|
||||
@ -213,18 +165,6 @@
|
||||
"index.js"
|
||||
]
|
||||
},
|
||||
"找不到{}文件,{}只能在js项目工程中使用": {
|
||||
"en": "Cannot find {} file, {} can only be used in JS project",
|
||||
"$file": [
|
||||
"init.command.js"
|
||||
]
|
||||
},
|
||||
"找不到package.json文件,voerkai18n只能在js项目工程中使用": {
|
||||
"en": "Cannot find <package.json> file, voerkai18n can only be used in JS project",
|
||||
"$file": [
|
||||
"init.command.js"
|
||||
]
|
||||
},
|
||||
"语言配置文件{}文件已存在,跳过创建。\\n使用{}可以重新覆盖创建": {
|
||||
"en": "Language configuration {} file already exists, skipping creation\\n use {} to overwrite the creation",
|
||||
"$file": [
|
||||
@ -266,5 +206,65 @@
|
||||
"$file": [
|
||||
"init.command.js"
|
||||
]
|
||||
},
|
||||
"创建语言包文件夹: {}": {
|
||||
"en": "Create <languages> folder: {}",
|
||||
"$file": [
|
||||
"init.command.js"
|
||||
]
|
||||
},
|
||||
"正在安装多语言运行时:{}": {
|
||||
"en": "Installing @voerkai18n/runtime:{}",
|
||||
"$file": [
|
||||
"init.command.js"
|
||||
]
|
||||
},
|
||||
"模块类型\\t: {}": {
|
||||
"en": "Type of module\\t\\t: {}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
"编译结果输出至:{}": {
|
||||
"en": "Compile to:{}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
"读取语言文件{}失败:{}": {
|
||||
"en": "Error while read language file{}: {}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
" - 共合成{}条语言包文本": {
|
||||
"en": " - Total {} messages",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
" - 语言包文件: {}": {
|
||||
"en": " - Language file: {}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
" - idMap文件: {}": {
|
||||
"en": " - idMap file: {}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
" - 格式化器:{}": {
|
||||
"en": " - Formatters: {}",
|
||||
"$file": [
|
||||
"compile.command.js"
|
||||
]
|
||||
},
|
||||
"Now is { value | date | bjTime }": {
|
||||
"en": "Now is { value | date | bjTime }",
|
||||
"$file": [
|
||||
"templates\\formatters.js"
|
||||
]
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@voerkai18n/cli",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.7",
|
||||
"description": "VoerkaI18n command line interactive tools",
|
||||
"main": "index.js",
|
||||
"homepage": "https://gitee.com/zhangfisher/voerka-i18n",
|
||||
@ -34,10 +34,10 @@
|
||||
"commander": "^9.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"deepmerge": "^4.2.2",
|
||||
"fs-extra": "^10.0.1",
|
||||
"glob": "^7.2.0",
|
||||
"gulp": "^4.0.2",
|
||||
"logsets": "^1.0.8",
|
||||
"readjson": "^2.2.2",
|
||||
"shelljs": "^0.8.5",
|
||||
"through2": "^4.0.2",
|
||||
"vinyl": "^2.2.1"
|
||||
|
@ -1,7 +1,6 @@
|
||||
{{if moduleType === "esm"}}
|
||||
import messageIds from "./idMap.js"
|
||||
import { translate,I18nManager,i18nScope } from "@voerkai18n/runtime"
|
||||
import scopeSettings from "./settings.js"
|
||||
import formatters from "./formatters.js"
|
||||
import defaultMessages from "./{{defaultLanguage}}.js"
|
||||
{{if defaultLanguage === activeLanguage}}const activeMessages = defaultMessages
|
||||
@ -9,12 +8,14 @@ import defaultMessages from "./{{defaultLanguage}}.js"
|
||||
{{else}}
|
||||
const messageIds = require("./idMap")
|
||||
const { translate,I18nManager,i18nScope } = require("@voerkai18n/runtime")
|
||||
const scopeSettings = require("./settings.js")
|
||||
const formatters = require("./formatters.js")
|
||||
const defaultMessages = require("./{{defaultLanguage}}.js")
|
||||
{{if defaultLanguage === activeLanguage}}const activeMessages = defaultMessages
|
||||
{{else}}const activeMessages = require("./{{activeLanguage}}.js"){{/if}}
|
||||
{{/if}}
|
||||
// 语言配置文件
|
||||
const scopeSettings = {{@ settings}}
|
||||
|
||||
// 语言作用域
|
||||
const scope = new i18nScope({
|
||||
...scopeSettings, // languages,defaultLanguage,activeLanguage,namespaces,formatters
|
||||
@ -32,11 +33,11 @@ const t = translate.bind(scope)
|
||||
{{if moduleType === "esm"}}
|
||||
export {
|
||||
t,
|
||||
scope,
|
||||
i18nScope:scope,
|
||||
i18nManager:VoerkaI18n,
|
||||
}
|
||||
{{else}}
|
||||
module.exports.t = t
|
||||
module.exports.scope = scope
|
||||
module.exports.i18nScope = scope
|
||||
module.exports.i18nManager = VoerkaI18n
|
||||
{{/if}}
|
||||
|
@ -42,12 +42,14 @@
|
||||
最终的输出结果:
|
||||
中文: "现在是北京时间2022年3月1日"
|
||||
英文: "Now is BeiJing 2022/03/01"
|
||||
|
||||
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
{{if moduleType === "esm"}}export default {{else}}module.exports = {{/if}}{
|
||||
|
||||
|
||||
{{if moduleType === "esm"}}
|
||||
|
||||
export default{{else}}module.exports = {{/if}}{
|
||||
// 在所有语言下生效的格式化器
|
||||
"*":{
|
||||
//[格式化名称]:(value)=>{...},
|
||||
|
@ -1,18 +1,5 @@
|
||||
const path = require("path")
|
||||
const fs = require("fs")
|
||||
const readJson = require("readjson")
|
||||
|
||||
async function importModule(url,onlyDefault=true) {
|
||||
try{
|
||||
return require(url)
|
||||
}catch(e){
|
||||
const result = await import(`file:///${url}`)
|
||||
return onlyDefault ? result.default : result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const fs = require("fs-extra")
|
||||
|
||||
/**
|
||||
* 返回当前项目根文件夹
|
||||
@ -39,13 +26,13 @@ async function importModule(url,onlyDefault=true) {
|
||||
/**
|
||||
* 读取指定文件夹的package.json文件,如果当前文件夹没有package.json文件,则向上查找
|
||||
* @param {*} folder
|
||||
* @param {*} exclueCurrent =true 排除folder,从folder的父级开始查找
|
||||
* @param {*} exclueCurrent = true 排除folder,从folder的父级开始查找
|
||||
* @returns
|
||||
*/
|
||||
function getCurrentPackageJson(folder,exclueCurrent=true){
|
||||
let projectFolder = getCurrentProjectRootFolder(folder,exclueCurrent)
|
||||
if( projectFolder){
|
||||
return readJson.sync(path.join(projectFolder, "package.json"))
|
||||
if(projectFolder){
|
||||
return fs.readJSONSync(path.join(projectFolder,"package.json"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,26 +155,31 @@ function escape(str){
|
||||
.replaceAll("\\\\",'\\')
|
||||
}
|
||||
|
||||
// 翻译函数
|
||||
// @voerkai18n/cli工程本身使用了voerkai18n,即@voerkai18n/cli的extract和compile依赖于其自己生成的languages运行时
|
||||
// 这样产生了鸡蛋问题,因此在extract与compile调试阶段如果t函数无法使用(即编译的languages无法正常使用),则需要提供t函数
|
||||
// 此函数的目的是提供一种容错方式
|
||||
let t
|
||||
|
||||
let i18nScope,t
|
||||
try{
|
||||
t = require("./languages").t
|
||||
}catch(e){
|
||||
console.warn(e.stack)
|
||||
t = v=>v
|
||||
// @voerkai18n/cli工程本身使用了voerkai18n,即@voerkai18n/cli的extract和compile依赖于其自己生成的languages运行时
|
||||
// 而@voerkai18n/cli又用来编译多语言包,这样产生了鸡生蛋问题
|
||||
// extract与compile调试阶段如果t函数无法使用(即编译的languages无法正常使用),则需要提供t函数
|
||||
const language = require('./languages');
|
||||
t = language.t
|
||||
i18nScope = language.i18nScope
|
||||
}catch{
|
||||
t=v=>v
|
||||
i18nScope={change:()=>{} }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
importModule,
|
||||
findModuleType,
|
||||
createPackageJsonFile,
|
||||
isPlainObject,
|
||||
getCurrentPackageJson,
|
||||
getCurrentProjectRootFolder,
|
||||
escape,
|
||||
i18nScope,
|
||||
t
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
[](https://gitee.com/zhangfisher/voerka-i18n)
|
||||
|
||||
# @voerkai18n/formatters
|
||||
|
||||
|
||||
|
2
packages/runtime/dist/index.cjs
vendored
2
packages/runtime/dist/index.cjs
vendored
File diff suppressed because one or more lines are too long
2
packages/runtime/dist/index.esm.js
vendored
2
packages/runtime/dist/index.esm.js
vendored
File diff suppressed because one or more lines are too long
@ -621,6 +621,7 @@ function translate(message) {
|
||||
* 切换语言
|
||||
*/
|
||||
async change(value){
|
||||
value=value.trim()
|
||||
if(this.languages.findIndex(lang=>lang.name === value)!==-1){
|
||||
// 通知所有作用域刷新到对应的语言包
|
||||
await this._refreshScopes(value)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@voerkai18n/runtime",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.3",
|
||||
"description": "Voerkai18n Runtime",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "dist/index.esm.js",
|
||||
|
27
packages/vue/index.js
Normal file
27
packages/vue/index.js
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import Root from './App.vue'
|
||||
import i18nPlugin from '@voerkai18n/vue'
|
||||
import { t, i18nScope } from './languages'
|
||||
const app = createApp(Root)
|
||||
app.use(i18nPlugin,{ t,i18nScope })
|
||||
app.mount('#app')
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
export default {
|
||||
install: (app, opts={}) => {
|
||||
let options = Object.assign({
|
||||
t:message=>message,
|
||||
}, opts)
|
||||
|
||||
// 全局翻译函数
|
||||
app.config.globalProperties.t = function(){
|
||||
return options.t(...arguments)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
4
packages/vue/readme.md
Normal file
4
packages/vue/readme.md
Normal file
@ -0,0 +1,4 @@
|
||||
[](https://gitee.com/zhangfisher/voerka-i18n)
|
||||
|
||||
# @voerkai18n/vue
|
||||
|
506
pnpm-lock.yaml
generated
506
pnpm-lock.yaml
generated
@ -34,6 +34,27 @@ importers:
|
||||
shelljs: 0.8.5
|
||||
vinyl: 2.2.1
|
||||
|
||||
packages/apps/app:
|
||||
specifiers:
|
||||
'@voerkai18n/cli': workspace:^1.0.6
|
||||
'@voerkai18n/runtime': ^1.0.0
|
||||
dependencies:
|
||||
'@voerkai18n/cli': link:../../cli
|
||||
'@voerkai18n/runtime': link:../../runtime
|
||||
|
||||
packages/apps/vueapp:
|
||||
specifiers:
|
||||
'@vitejs/plugin-vue': ^2.2.0
|
||||
'@voerkai18n/cli': workspace:^1.0.6
|
||||
vite: ^2.8.0
|
||||
vue: ^3.2.25
|
||||
dependencies:
|
||||
'@voerkai18n/cli': link:../../cli
|
||||
vue: 3.2.31
|
||||
devDependencies:
|
||||
'@vitejs/plugin-vue': 2.2.4_vite@2.8.6+vue@3.2.31
|
||||
vite: 2.8.6
|
||||
|
||||
packages/babel:
|
||||
specifiers: {}
|
||||
|
||||
@ -46,10 +67,10 @@ importers:
|
||||
commander: ^9.0.0
|
||||
cross-env: ^7.0.3
|
||||
deepmerge: ^4.2.2
|
||||
fs-extra: ^10.0.1
|
||||
glob: ^7.2.0
|
||||
gulp: ^4.0.2
|
||||
logsets: ^1.0.8
|
||||
readjson: ^2.2.2
|
||||
shelljs: ^0.8.5
|
||||
through2: ^4.0.2
|
||||
vinyl: ^2.2.1
|
||||
@ -61,10 +82,10 @@ importers:
|
||||
commander: 9.0.0
|
||||
cross-env: 7.0.3
|
||||
deepmerge: 4.2.2
|
||||
fs-extra: 10.0.1
|
||||
glob: 7.2.0
|
||||
gulp: 4.0.2
|
||||
logsets: 1.0.8
|
||||
readjson: 2.2.2
|
||||
shelljs: 0.8.5
|
||||
through2: 4.0.2
|
||||
vinyl: 2.2.1
|
||||
@ -1253,6 +1274,14 @@ packages:
|
||||
esutils: 2.0.3
|
||||
dev: true
|
||||
|
||||
/@babel/runtime-corejs3/7.17.2:
|
||||
resolution: {integrity: sha512-NcKtr2epxfIrNM4VOmPKO46TvDMCBhgi2CrSHaEarrz+Plk2K5r9QemmOFTGpZaoKnWoGH5MO+CzeRsih/Fcgg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.2.tgz}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
core-js-pure: 3.21.1
|
||||
regenerator-runtime: 0.13.9
|
||||
dev: false
|
||||
|
||||
/@babel/runtime/7.17.2:
|
||||
resolution: {integrity: sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@ -1686,6 +1715,100 @@ packages:
|
||||
'@types/yargs-parser': 20.2.1
|
||||
dev: true
|
||||
|
||||
/@vitejs/plugin-vue/2.2.4_vite@2.8.6+vue@3.2.31:
|
||||
resolution: {integrity: sha512-ev9AOlp0ljCaDkFZF3JwC/pD2N4Hh+r5srl5JHM6BKg5+99jiiK0rE/XaRs3pVm1wzyKkjUy/StBSoXX5fFzcw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
vite: ^2.5.10
|
||||
vue: ^3.2.25
|
||||
dependencies:
|
||||
vite: 2.8.6
|
||||
vue: 3.2.31
|
||||
dev: true
|
||||
|
||||
/@vue/compiler-core/3.2.31:
|
||||
resolution: {integrity: sha512-aKno00qoA4o+V/kR6i/pE+aP+esng5siNAVQ422TkBNM6qA4veXiZbSe8OTXHXquEi/f6Akc+nLfB4JGfe4/WQ==}
|
||||
dependencies:
|
||||
'@babel/parser': 7.17.3
|
||||
'@vue/shared': 3.2.31
|
||||
estree-walker: 2.0.2
|
||||
source-map: 0.6.1
|
||||
dev: false
|
||||
|
||||
/@vue/compiler-dom/3.2.31:
|
||||
resolution: {integrity: sha512-60zIlFfzIDf3u91cqfqy9KhCKIJgPeqxgveH2L+87RcGU/alT6BRrk5JtUso0OibH3O7NXuNOQ0cDc9beT0wrg==}
|
||||
dependencies:
|
||||
'@vue/compiler-core': 3.2.31
|
||||
'@vue/shared': 3.2.31
|
||||
dev: false
|
||||
|
||||
/@vue/compiler-sfc/3.2.31:
|
||||
resolution: {integrity: sha512-748adc9msSPGzXgibHiO6T7RWgfnDcVQD+VVwYgSsyyY8Ans64tALHZANrKtOzvkwznV/F4H7OAod/jIlp/dkQ==}
|
||||
dependencies:
|
||||
'@babel/parser': 7.17.3
|
||||
'@vue/compiler-core': 3.2.31
|
||||
'@vue/compiler-dom': 3.2.31
|
||||
'@vue/compiler-ssr': 3.2.31
|
||||
'@vue/reactivity-transform': 3.2.31
|
||||
'@vue/shared': 3.2.31
|
||||
estree-walker: 2.0.2
|
||||
magic-string: 0.25.9
|
||||
postcss: 8.4.12
|
||||
source-map: 0.6.1
|
||||
dev: false
|
||||
|
||||
/@vue/compiler-ssr/3.2.31:
|
||||
resolution: {integrity: sha512-mjN0rqig+A8TVDnsGPYJM5dpbjlXeHUm2oZHZwGyMYiGT/F4fhJf/cXy8QpjnLQK4Y9Et4GWzHn9PS8AHUnSkw==}
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.2.31
|
||||
'@vue/shared': 3.2.31
|
||||
dev: false
|
||||
|
||||
/@vue/reactivity-transform/3.2.31:
|
||||
resolution: {integrity: sha512-uS4l4z/W7wXdI+Va5pgVxBJ345wyGFKvpPYtdSgvfJfX/x2Ymm6ophQlXXB6acqGHtXuBqNyyO3zVp9b1r0MOA==}
|
||||
dependencies:
|
||||
'@babel/parser': 7.17.3
|
||||
'@vue/compiler-core': 3.2.31
|
||||
'@vue/shared': 3.2.31
|
||||
estree-walker: 2.0.2
|
||||
magic-string: 0.25.9
|
||||
dev: false
|
||||
|
||||
/@vue/reactivity/3.2.31:
|
||||
resolution: {integrity: sha512-HVr0l211gbhpEKYr2hYe7hRsV91uIVGFYNHj73njbARVGHQvIojkImKMaZNDdoDZOIkMsBc9a1sMqR+WZwfSCw==}
|
||||
dependencies:
|
||||
'@vue/shared': 3.2.31
|
||||
dev: false
|
||||
|
||||
/@vue/runtime-core/3.2.31:
|
||||
resolution: {integrity: sha512-Kcog5XmSY7VHFEMuk4+Gap8gUssYMZ2+w+cmGI6OpZWYOEIcbE0TPzzPHi+8XTzAgx1w/ZxDFcXhZeXN5eKWsA==}
|
||||
dependencies:
|
||||
'@vue/reactivity': 3.2.31
|
||||
'@vue/shared': 3.2.31
|
||||
dev: false
|
||||
|
||||
/@vue/runtime-dom/3.2.31:
|
||||
resolution: {integrity: sha512-N+o0sICVLScUjfLG7u9u5XCjvmsexAiPt17GNnaWHJUfsKed5e85/A3SWgKxzlxx2SW/Hw7RQxzxbXez9PtY3g==}
|
||||
dependencies:
|
||||
'@vue/runtime-core': 3.2.31
|
||||
'@vue/shared': 3.2.31
|
||||
csstype: 2.6.20
|
||||
dev: false
|
||||
|
||||
/@vue/server-renderer/3.2.31_vue@3.2.31:
|
||||
resolution: {integrity: sha512-8CN3Zj2HyR2LQQBHZ61HexF5NReqngLT3oahyiVRfSSvak+oAvVmu8iNLSu6XR77Ili2AOpnAt1y8ywjjqtmkg==}
|
||||
peerDependencies:
|
||||
vue: 3.2.31
|
||||
dependencies:
|
||||
'@vue/compiler-ssr': 3.2.31
|
||||
'@vue/shared': 3.2.31
|
||||
vue: 3.2.31
|
||||
dev: false
|
||||
|
||||
/@vue/shared/3.2.31:
|
||||
resolution: {integrity: sha512-ymN2pj6zEjiKJZbrf98UM2pfDd6F2H7ksKw7NDt/ZZ1fh5Ei39X5tABugtT03ZRlWd9imccoK0hE8hpjpU7irQ==}
|
||||
dev: false
|
||||
|
||||
/abab/2.0.5:
|
||||
resolution: {integrity: sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==}
|
||||
dev: true
|
||||
@ -1779,6 +1902,10 @@ packages:
|
||||
resolution: {integrity: sha1-qCJQ3bABXponyoLoLqYDu/pF768=}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/ansicolor/1.1.100:
|
||||
resolution: {integrity: sha512-Jl0pxRfa9WaQVUX57AB8/V2my6FJxrOR1Pp2qqFbig20QB4HzUoQ48THTKAgHlUCJeQm/s2WoOPcoIDhyCL/kw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/ansicolor/-/ansicolor-1.1.100.tgz}
|
||||
dev: false
|
||||
|
||||
/anymatch/2.0.0:
|
||||
resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==}
|
||||
dependencies:
|
||||
@ -2333,7 +2460,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/color-name/1.1.3:
|
||||
resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=}
|
||||
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
|
||||
|
||||
/color-name/1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
@ -2413,6 +2540,16 @@ packages:
|
||||
semver: 7.0.0
|
||||
dev: true
|
||||
|
||||
/core-js-pure/3.21.1:
|
||||
resolution: {integrity: sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/core-js-pure/-/core-js-pure-3.21.1.tgz}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/core-js/3.21.1:
|
||||
resolution: {integrity: sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig==}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/core-util-is/1.0.3:
|
||||
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
|
||||
|
||||
@ -2447,6 +2584,10 @@ packages:
|
||||
cssom: 0.3.8
|
||||
dev: true
|
||||
|
||||
/csstype/2.6.20:
|
||||
resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==}
|
||||
dev: false
|
||||
|
||||
/d/1.0.1:
|
||||
resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==}
|
||||
dependencies:
|
||||
@ -2491,7 +2632,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/decode-uri-component/0.2.0:
|
||||
resolution: {integrity: sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=}
|
||||
resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==}
|
||||
engines: {node: '>=0.10'}
|
||||
|
||||
/dedent/0.7.0:
|
||||
@ -2630,12 +2771,220 @@ packages:
|
||||
es6-iterator: 2.0.3
|
||||
es6-symbol: 3.1.3
|
||||
|
||||
/esbuild-android-64/0.14.27:
|
||||
resolution: {integrity: sha512-LuEd4uPuj/16Y8j6kqy3Z2E9vNY9logfq8Tq+oTE2PZVuNs3M1kj5Qd4O95ee66yDGb3isaOCV7sOLDwtMfGaQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-android-arm64/0.14.27:
|
||||
resolution: {integrity: sha512-E8Ktwwa6vX8q7QeJmg8yepBYXaee50OdQS3BFtEHKrzbV45H4foMOeEE7uqdjGQZFBap5VAqo7pvjlyA92wznQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-64/0.14.27:
|
||||
resolution: {integrity: sha512-czw/kXl/1ZdenPWfw9jDc5iuIYxqUxgQ/Q+hRd4/3udyGGVI31r29LCViN2bAJgGvQkqyLGVcG03PJPEXQ5i2g==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-arm64/0.14.27:
|
||||
resolution: {integrity: sha512-BEsv2U2U4o672oV8+xpXNxN9bgqRCtddQC6WBh4YhXKDcSZcdNh7+6nS+DM2vu7qWIWNA4JbRG24LUUYXysimQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-64/0.14.27:
|
||||
resolution: {integrity: sha512-7FeiFPGBo+ga+kOkDxtPmdPZdayrSzsV9pmfHxcyLKxu+3oTcajeZlOO1y9HW+t5aFZPiv7czOHM4KNd0tNwCA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-arm64/0.14.27:
|
||||
resolution: {integrity: sha512-8CK3++foRZJluOWXpllG5zwAVlxtv36NpHfsbWS7TYlD8S+QruXltKlXToc/5ZNzBK++l6rvRKELu/puCLc7jA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-32/0.14.27:
|
||||
resolution: {integrity: sha512-qhNYIcT+EsYSBClZ5QhLzFzV5iVsP1YsITqblSaztr3+ZJUI+GoK8aXHyzKd7/CKKuK93cxEMJPpfi1dfsOfdw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-64/0.14.27:
|
||||
resolution: {integrity: sha512-ESjck9+EsHoTaKWlFKJpPZRN26uiav5gkI16RuI8WBxUdLrrAlYuYSndxxKgEn1csd968BX/8yQZATYf/9+/qg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm/0.14.27:
|
||||
resolution: {integrity: sha512-JnnmgUBdqLQO9hoNZQqNHFWlNpSX82vzB3rYuCJMhtkuaWQEmQz6Lec1UIxJdC38ifEghNTBsF9bbe8dFilnCw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm64/0.14.27:
|
||||
resolution: {integrity: sha512-no6Mi17eV2tHlJnqBHRLekpZ2/VYx+NfGxKcBE/2xOMYwctsanCaXxw4zapvNrGE9X38vefVXLz6YCF8b1EHiQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-mips64le/0.14.27:
|
||||
resolution: {integrity: sha512-NolWP2uOvIJpbwpsDbwfeExZOY1bZNlWE/kVfkzLMsSgqeVcl5YMen/cedRe9mKnpfLli+i0uSp7N+fkKNU27A==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-ppc64le/0.14.27:
|
||||
resolution: {integrity: sha512-/7dTjDvXMdRKmsSxKXeWyonuGgblnYDn0MI1xDC7J1VQXny8k1qgNp6VmrlsawwnsymSUUiThhkJsI+rx0taNA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-riscv64/0.14.27:
|
||||
resolution: {integrity: sha512-D+aFiUzOJG13RhrSmZgrcFaF4UUHpqj7XSKrIiCXIj1dkIkFqdrmqMSOtSs78dOtObWiOrFCDDzB24UyeEiNGg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-s390x/0.14.27:
|
||||
resolution: {integrity: sha512-CD/D4tj0U4UQjELkdNlZhQ8nDHU5rBn6NGp47Hiz0Y7/akAY5i0oGadhEIg0WCY/HYVXFb3CsSPPwaKcTOW3bg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-netbsd-64/0.14.27:
|
||||
resolution: {integrity: sha512-h3mAld69SrO1VoaMpYl3a5FNdGRE/Nqc+E8VtHOag4tyBwhCQXxtvDDOAKOUQexBGca0IuR6UayQ4ntSX5ij1Q==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-openbsd-64/0.14.27:
|
||||
resolution: {integrity: sha512-xwSje6qIZaDHXWoPpIgvL+7fC6WeubHHv18tusLYMwL+Z6bEa4Pbfs5IWDtQdHkArtfxEkIZz77944z8MgDxGw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-sunos-64/0.14.27:
|
||||
resolution: {integrity: sha512-/nBVpWIDjYiyMhuqIqbXXsxBc58cBVH9uztAOIfWShStxq9BNBik92oPQPJ57nzWXRNKQUEFWr4Q98utDWz7jg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-32/0.14.27:
|
||||
resolution: {integrity: sha512-Q9/zEjhZJ4trtWhFWIZvS/7RUzzi8rvkoaS9oiizkHTTKd8UxFwn/Mm2OywsAfYymgUYm8+y2b+BKTNEFxUekw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-64/0.14.27:
|
||||
resolution: {integrity: sha512-b3y3vTSl5aEhWHK66ngtiS/c6byLf6y/ZBvODH1YkBM+MGtVL6jN38FdHUsZasCz9gFwYs/lJMVY9u7GL6wfYg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-arm64/0.14.27:
|
||||
resolution: {integrity: sha512-I/reTxr6TFMcR5qbIkwRGvldMIaiBu2+MP0LlD7sOlNXrfqIl9uNjsuxFPGEG4IRomjfQ5q8WT+xlF/ySVkqKg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild/0.14.27:
|
||||
resolution: {integrity: sha512-MZQt5SywZS3hA9fXnMhR22dv0oPGh6QtjJRIYbgL1AeqAoQZE+Qn5ppGYQAoHv/vq827flj4tIJ79Mrdiwk46Q==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
esbuild-android-64: 0.14.27
|
||||
esbuild-android-arm64: 0.14.27
|
||||
esbuild-darwin-64: 0.14.27
|
||||
esbuild-darwin-arm64: 0.14.27
|
||||
esbuild-freebsd-64: 0.14.27
|
||||
esbuild-freebsd-arm64: 0.14.27
|
||||
esbuild-linux-32: 0.14.27
|
||||
esbuild-linux-64: 0.14.27
|
||||
esbuild-linux-arm: 0.14.27
|
||||
esbuild-linux-arm64: 0.14.27
|
||||
esbuild-linux-mips64le: 0.14.27
|
||||
esbuild-linux-ppc64le: 0.14.27
|
||||
esbuild-linux-riscv64: 0.14.27
|
||||
esbuild-linux-s390x: 0.14.27
|
||||
esbuild-netbsd-64: 0.14.27
|
||||
esbuild-openbsd-64: 0.14.27
|
||||
esbuild-sunos-64: 0.14.27
|
||||
esbuild-windows-32: 0.14.27
|
||||
esbuild-windows-64: 0.14.27
|
||||
esbuild-windows-arm64: 0.14.27
|
||||
dev: true
|
||||
|
||||
/escalade/3.1.1:
|
||||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
/escape-string-regexp/1.0.5:
|
||||
resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=}
|
||||
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
|
||||
/escape-string-regexp/2.0.0:
|
||||
@ -2690,7 +3039,6 @@ packages:
|
||||
|
||||
/estree-walker/2.0.2:
|
||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||
dev: true
|
||||
|
||||
/esutils/2.0.3:
|
||||
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
||||
@ -2750,7 +3098,7 @@ packages:
|
||||
type: 2.6.0
|
||||
|
||||
/extend-shallow/2.0.1:
|
||||
resolution: {integrity: sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=}
|
||||
resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
is-extendable: 0.1.1
|
||||
@ -2908,7 +3256,6 @@ packages:
|
||||
graceful-fs: 4.2.9
|
||||
jsonfile: 6.1.0
|
||||
universalify: 2.0.0
|
||||
dev: true
|
||||
|
||||
/fs-mkdirp-stream/1.0.0:
|
||||
resolution: {integrity: sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=}
|
||||
@ -3101,7 +3448,7 @@ packages:
|
||||
glogg: 1.0.2
|
||||
|
||||
/has-flag/3.0.0:
|
||||
resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=}
|
||||
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
/has-flag/4.0.0:
|
||||
@ -3325,7 +3672,7 @@ packages:
|
||||
kind-of: 6.0.3
|
||||
|
||||
/is-extendable/0.1.1:
|
||||
resolution: {integrity: sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=}
|
||||
resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/is-extendable/1.0.1:
|
||||
@ -3335,7 +3682,7 @@ packages:
|
||||
is-plain-object: 2.0.4
|
||||
|
||||
/is-extglob/2.1.1:
|
||||
resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=}
|
||||
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/is-fullwidth-code-point/1.0.0:
|
||||
@ -3446,10 +3793,10 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/isarray/1.0.0:
|
||||
resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=}
|
||||
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
|
||||
|
||||
/isexe/2.0.0:
|
||||
resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=}
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
/isobject/2.1.0:
|
||||
resolution: {integrity: sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=}
|
||||
@ -3458,7 +3805,7 @@ packages:
|
||||
isarray: 1.0.0
|
||||
|
||||
/isobject/3.0.1:
|
||||
resolution: {integrity: sha1-TkMekrEalzFjaqH5yNHMvP2reN8=}
|
||||
resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/istanbul-lib-coverage/3.2.0:
|
||||
@ -3982,10 +4329,6 @@ packages:
|
||||
- utf-8-validate
|
||||
dev: true
|
||||
|
||||
/jju/1.4.0:
|
||||
resolution: {integrity: sha1-o6vicYryQaKykE+EpiWXDzia4yo=}
|
||||
dev: false
|
||||
|
||||
/js-tokens/3.0.2:
|
||||
resolution: {integrity: sha1-mGbfOVECEw449/mWvOtlRDIJwls=}
|
||||
dev: false
|
||||
@ -4073,13 +4416,12 @@ packages:
|
||||
universalify: 2.0.0
|
||||
optionalDependencies:
|
||||
graceful-fs: 4.2.9
|
||||
dev: true
|
||||
|
||||
/just-debounce/1.1.0:
|
||||
resolution: {integrity: sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==}
|
||||
|
||||
/kind-of/3.2.2:
|
||||
resolution: {integrity: sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=}
|
||||
resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
is-buffer: 1.1.6
|
||||
@ -4185,9 +4527,9 @@ packages:
|
||||
/logsets/1.0.8:
|
||||
resolution: {integrity: sha512-9XuCtIjGvAWbi+JgF2+NI5Bb55uvzwgCFvlo/pafXdZjVC0DDri2k+Jzv7hWg0audTrw4FTnIBiSo3yOlEpmHQ==}
|
||||
dependencies:
|
||||
'@babel/runtime-corejs3': registry.npmmirror.com/@babel/runtime-corejs3/7.17.2
|
||||
ansicolor: registry.npmmirror.com/ansicolor/1.1.100
|
||||
core-js: registry.npmmirror.com/core-js/3.21.1
|
||||
'@babel/runtime-corejs3': 7.17.2
|
||||
ansicolor: 1.1.100
|
||||
core-js: 3.21.1
|
||||
deepmerge: 4.2.2
|
||||
dev: false
|
||||
|
||||
@ -4206,7 +4548,6 @@ packages:
|
||||
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
|
||||
dependencies:
|
||||
sourcemap-codec: 1.4.8
|
||||
dev: true
|
||||
|
||||
/make-dir/2.1.0:
|
||||
resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
|
||||
@ -4323,7 +4664,7 @@ packages:
|
||||
is-extendable: 1.0.1
|
||||
|
||||
/ms/2.0.0:
|
||||
resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=}
|
||||
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
|
||||
|
||||
/ms/2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
@ -4337,6 +4678,11 @@ packages:
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/nanoid/3.3.1:
|
||||
resolution: {integrity: sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==}
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
|
||||
/nanomatch/1.2.13:
|
||||
resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -4469,7 +4815,7 @@ packages:
|
||||
make-iterator: 1.0.1
|
||||
|
||||
/once/1.4.0:
|
||||
resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=}
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
|
||||
@ -4652,6 +4998,14 @@ packages:
|
||||
resolution: {integrity: sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/postcss/8.4.12:
|
||||
resolution: {integrity: sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
dependencies:
|
||||
nanoid: 3.3.1
|
||||
picocolors: 1.0.0
|
||||
source-map-js: 1.0.2
|
||||
|
||||
/prelude-ls/1.1.2:
|
||||
resolution: {integrity: sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@ -4763,14 +5117,6 @@ packages:
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/readjson/2.2.2:
|
||||
resolution: {integrity: sha512-PdeC9tsmLWBiL8vMhJvocq+OezQ3HhsH2HrN7YkhfYcTjQSa/iraB15A7Qvt7Xpr0Yd2rDNt6GbFwVQDg3HcAw==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
jju: 1.4.0
|
||||
try-catch: 3.0.0
|
||||
dev: false
|
||||
|
||||
/rechoir/0.6.2:
|
||||
resolution: {integrity: sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=}
|
||||
engines: {node: '>= 0.10'}
|
||||
@ -4790,7 +5136,6 @@ packages:
|
||||
|
||||
/regenerator-runtime/0.13.9:
|
||||
resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==}
|
||||
dev: true
|
||||
|
||||
/regenerator-transform/0.14.5:
|
||||
resolution: {integrity: sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==}
|
||||
@ -4829,7 +5174,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/relateurl/0.2.7:
|
||||
resolution: {integrity: sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=}
|
||||
resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==}
|
||||
engines: {node: '>= 0.10'}
|
||||
dev: false
|
||||
|
||||
@ -4904,7 +5249,7 @@ packages:
|
||||
value-or-function: 3.0.0
|
||||
|
||||
/resolve-url/0.2.1:
|
||||
resolution: {integrity: sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=}
|
||||
resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==}
|
||||
deprecated: https://github.com/lydell/resolve-url#deprecated
|
||||
|
||||
/resolve.exports/1.1.0:
|
||||
@ -5095,6 +5440,10 @@ packages:
|
||||
source-map-resolve: 0.5.3
|
||||
use: 3.1.1
|
||||
|
||||
/source-map-js/1.0.2:
|
||||
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/source-map-resolve/0.5.3:
|
||||
resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==}
|
||||
deprecated: See https://github.com/lydell/source-map-resolve#deprecated
|
||||
@ -5131,7 +5480,6 @@ packages:
|
||||
|
||||
/sourcemap-codec/1.4.8:
|
||||
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
|
||||
dev: true
|
||||
|
||||
/sparkles/1.0.1:
|
||||
resolution: {integrity: sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==}
|
||||
@ -5413,11 +5761,6 @@ packages:
|
||||
punycode: 2.1.1
|
||||
dev: true
|
||||
|
||||
/try-catch/3.0.0:
|
||||
resolution: {integrity: sha512-3uAqUnoemzca1ENvZ72EVimR+E8lqBbzwZ9v4CEbLjkaV3Q+FtdmPUt7jRtoSoTiYjyIMxEkf6YgUpe/voJ1ng==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/type-check/0.3.2:
|
||||
resolution: {integrity: sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@ -5527,7 +5870,6 @@ packages:
|
||||
/universalify/2.0.0:
|
||||
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
dev: true
|
||||
|
||||
/unset-value/1.0.0:
|
||||
resolution: {integrity: sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=}
|
||||
@ -5545,7 +5887,7 @@ packages:
|
||||
dev: false
|
||||
|
||||
/urix/0.1.0:
|
||||
resolution: {integrity: sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=}
|
||||
resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==}
|
||||
deprecated: Please see https://github.com/lydell/urix#deprecated
|
||||
|
||||
/use/3.1.1:
|
||||
@ -5553,7 +5895,7 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/util-deprecate/1.0.2:
|
||||
resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=}
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
/v8-to-istanbul/8.1.1:
|
||||
resolution: {integrity: sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==}
|
||||
@ -5625,6 +5967,40 @@ packages:
|
||||
remove-trailing-separator: 1.1.0
|
||||
replace-ext: 1.0.1
|
||||
|
||||
/vite/2.8.6:
|
||||
resolution: {integrity: sha512-e4H0QpludOVKkmOsRyqQ7LTcMUDF3mcgyNU4lmi0B5JUbe0ZxeBBl8VoZ8Y6Rfn9eFKYtdXNPcYK97ZwH+K2ug==}
|
||||
engines: {node: '>=12.2.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
less: '*'
|
||||
sass: '*'
|
||||
stylus: '*'
|
||||
peerDependenciesMeta:
|
||||
less:
|
||||
optional: true
|
||||
sass:
|
||||
optional: true
|
||||
stylus:
|
||||
optional: true
|
||||
dependencies:
|
||||
esbuild: 0.14.27
|
||||
postcss: 8.4.12
|
||||
resolve: 1.22.0
|
||||
rollup: 2.69.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/vue/3.2.31:
|
||||
resolution: {integrity: sha512-odT3W2tcffTiQCy57nOT93INw1auq5lYLLYtWpPYQQYQOOdHiqFct9Xhna6GJ+pJQaF67yZABraH47oywkJgFw==}
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.2.31
|
||||
'@vue/compiler-sfc': 3.2.31
|
||||
'@vue/runtime-dom': 3.2.31
|
||||
'@vue/server-renderer': 3.2.31_vue@3.2.31
|
||||
'@vue/shared': 3.2.31
|
||||
dev: false
|
||||
|
||||
/w3c-hr-time/1.0.2:
|
||||
resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==}
|
||||
dependencies:
|
||||
@ -5710,7 +6086,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/wrappy/1.0.2:
|
||||
resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=}
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
|
||||
/write-file-atomic/3.0.3:
|
||||
resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==}
|
||||
@ -5798,39 +6174,3 @@ packages:
|
||||
which-module: 1.0.0
|
||||
y18n: 3.2.2
|
||||
yargs-parser: 5.0.1
|
||||
|
||||
registry.npmmirror.com/@babel/runtime-corejs3/7.17.2:
|
||||
resolution: {integrity: sha512-NcKtr2epxfIrNM4VOmPKO46TvDMCBhgi2CrSHaEarrz+Plk2K5r9QemmOFTGpZaoKnWoGH5MO+CzeRsih/Fcgg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/runtime-corejs3/-/runtime-corejs3-7.17.2.tgz}
|
||||
name: '@babel/runtime-corejs3'
|
||||
version: 7.17.2
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
core-js-pure: registry.npmmirror.com/core-js-pure/3.21.1
|
||||
regenerator-runtime: registry.npmmirror.com/regenerator-runtime/0.13.9
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/ansicolor/1.1.100:
|
||||
resolution: {integrity: sha512-Jl0pxRfa9WaQVUX57AB8/V2my6FJxrOR1Pp2qqFbig20QB4HzUoQ48THTKAgHlUCJeQm/s2WoOPcoIDhyCL/kw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansicolor/-/ansicolor-1.1.100.tgz}
|
||||
name: ansicolor
|
||||
version: 1.1.100
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/core-js-pure/3.21.1:
|
||||
resolution: {integrity: sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.21.1.tgz}
|
||||
name: core-js-pure
|
||||
version: 3.21.1
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/core-js/3.21.1:
|
||||
resolution: {integrity: sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/core-js/-/core-js-3.21.1.tgz}
|
||||
name: core-js
|
||||
version: 3.21.1
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/regenerator-runtime/0.13.9:
|
||||
resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz}
|
||||
name: regenerator-runtime
|
||||
version: 0.13.9
|
||||
dev: false
|
||||
|
183
readme.md
183
readme.md
@ -78,12 +78,10 @@
|
||||
```shell
|
||||
myapp
|
||||
|--package.json
|
||||
|--index.js
|
||||
|--index.js
|
||||
```
|
||||
|
||||
## 第一步:使用翻译函数
|
||||
|
||||
在源码文件中直接使用`t`翻译函数对要翻译文本信息进行封装,简单而粗暴。
|
||||
在本项目的所有支持的源码文件中均可以使用`t`函数对要翻译的文本进行包装,简单而粗暴。
|
||||
|
||||
```javascript
|
||||
// index.js
|
||||
@ -93,35 +91,69 @@ console.log(t("中华人民共和国成立于{}",1949))
|
||||
|
||||
`t`翻译函数是从`myapp/languages/index.js`文件导出的翻译函数,但是现在`myapp/languages`还不存在,后续会使用工具自动生成。`voerkai18n`后续会使用正则表达式对提取要翻译的文本。
|
||||
|
||||
## 第二步:提取要翻译的内容
|
||||
## 第一步:初始化工程
|
||||
|
||||
在工程目录中运行`voerkai18n init`命令进行初始化。
|
||||
|
||||
```javascript
|
||||
> voerkai18n init
|
||||
```
|
||||
|
||||
上述命令会在当前工程目录下创建`languages/settings.json`文件。如果您的源代码在`src`子文件夹中,则会创建在`src/languages/settings.json`
|
||||
|
||||
`settings.json`内容如下:
|
||||
|
||||
```json
|
||||
{
|
||||
"languages": [
|
||||
{
|
||||
"name": "cn",
|
||||
"title": "cn"
|
||||
},
|
||||
{
|
||||
"name": "en",
|
||||
"title": "en"
|
||||
}
|
||||
],
|
||||
"defaultLanguage": "cn",
|
||||
"activeLanguage": "cn",
|
||||
"namespaces": {}
|
||||
}
|
||||
```
|
||||
|
||||
上述命令代表了:
|
||||
|
||||
- 本项目拟支持`中文`和`英文`两种语言。
|
||||
- 默认语言是`中文`(即在源代码中直接使用中文)
|
||||
- 激活语言是`中文`
|
||||
|
||||
|
||||
|
||||
**注意:**
|
||||
|
||||
- `voerkai18n init`是可选的,`voerkai18n extract`也可以实现相同的功能。
|
||||
- 一般情况下,您可以手工修改`settings.json`,如定义名称空间。
|
||||
|
||||
## 第二步:提取文本
|
||||
|
||||
接下来我们使用`voerkai18n extract`命令来自动扫描工程源码文件中的需要的翻译的文本信息。
|
||||
|
||||
```shell
|
||||
myapp>voerkai18n extract -d -lngs cn,en,de,jp -default cn -active cn
|
||||
myapp>voerkai18n extract
|
||||
```
|
||||
|
||||
以上命令代表:
|
||||
|
||||
- 扫描当前文件夹下所有源码文件,默认是`js`、`jsx`、`html`、`vue`文件类型,并排除`node_modules`。
|
||||
- 计划支持`cn`、`en`、`de`、`jp`四种语言
|
||||
- 默认语言是中文。(指在源码文件中我们直接使用中文即可)
|
||||
- 激活语言是中文(即默认切换到中文)
|
||||
- `-d`代表显示扫描调试信息
|
||||
|
||||
执行`voerkai18n extract`命令后,就会在`myapp/languages`通过生成`translates/default.json`、`settings.js`等相关文件。
|
||||
执行`voerkai18n extract`命令后,就会在`myapp/languages`通过生成`translates/default.json`、`settings.json`等相关文件。
|
||||
|
||||
- **translates/default.json** : 该文件就是需要进行翻译的文本信息。
|
||||
|
||||
- **settings.js**: 语言环境的基本配置信息,可以进行修改。
|
||||
- **settings.json**: 语言环境的基本配置信息,可以进行修改。
|
||||
|
||||
最后文件结构如下:
|
||||
|
||||
```shell
|
||||
myapp
|
||||
|-- languages
|
||||
|-- settings.js // 语言配置文件
|
||||
|-- package.json
|
||||
|-- settings.json // 语言配置文件
|
||||
|-- translates // 此文件夹是所有需要翻译的内容
|
||||
|-- default.json // 默认名称空间内容
|
||||
|-- package.json
|
||||
@ -129,6 +161,20 @@ myapp
|
||||
|
||||
```
|
||||
|
||||
**如果略过第一步中的`voerkai18n init`,也可以使用以下命令来为创建和更新`settinbgs.json`**
|
||||
|
||||
```javascript
|
||||
myapp>voerkai18n extract -D -lngs cn en de jp -d cn -a cn
|
||||
```
|
||||
|
||||
以上命令代表:
|
||||
|
||||
- 扫描当前文件夹下所有源码文件,默认是`js`、`jsx`、`html`、`vue`文件类型。
|
||||
- 计划支持`cn`、`en`、`de`、`jp`四种语言
|
||||
- 默认语言是中文。(指在源码文件中我们直接使用中文即可)
|
||||
- 激活语言是中文(即默认切换到中文)
|
||||
- `-D`代表显示扫描调试信息
|
||||
|
||||
## 第三步:翻译文本
|
||||
|
||||
接下来就可以分别对`language/translates`文件夹下的所有`JSON`文件进行翻译了。每个`JSON`文件大概如下:
|
||||
@ -160,7 +206,7 @@ myapp
|
||||
|
||||
因此,反复执行`voerkai18n extract`命令是安全的,不会导致进行了一半的翻译内容丢失,可以放心执行。
|
||||
|
||||
## 第三步:编译语言包
|
||||
## 第四步:编译语言包
|
||||
|
||||
当我们完成`myapp/languages/translates`下的所有`JSON语言文件`的翻译后(如果配置了名称空间后,每一个名称空间会对应生成一个文件,详见后续`名称空间`介绍),接下来需要对翻译后的文件进行编译。
|
||||
|
||||
@ -168,12 +214,11 @@ myapp
|
||||
myapp> voerkai18n compile
|
||||
```
|
||||
|
||||
`compile`命令根据`myapp/languages/translates/*.json`和`myapp/languages/settings.js`文件编译生成以下文件:
|
||||
`compile`命令根据`myapp/languages/translates/*.json`和`myapp/languages/settings.json`文件编译生成以下文件:
|
||||
|
||||
```javascript
|
||||
|-- languages
|
||||
|-- package.json
|
||||
|-- settings.js // 语言配置文件
|
||||
|-- settings.json // 语言配置文件
|
||||
|-- idMap.js // 文本信息id映射表
|
||||
|-- index.js // 包含该应用作用域下的翻译函数等
|
||||
|-- cn.js // 语言包
|
||||
@ -187,7 +232,7 @@ myapp> voerkai18n compile
|
||||
|
||||
```
|
||||
|
||||
## 第四步:导入翻译函数
|
||||
## 第五步:导入翻译函数
|
||||
|
||||
第一步中我们在源文件中直接使用了`t`翻译函数包装要翻译的文本信息,该`t`翻译函数就是在编译环节自动生成并声明在`myapp/languages/index.js`中的。
|
||||
|
||||
@ -197,28 +242,28 @@ import { t } from "./languages"
|
||||
|
||||
因此,我们需要在需要进行翻译时导入该函数即可。但是如果源码文件很多,重次重复导入`t`函数也是比较麻烦的,所以我们也提供了一个`babel插件`来自动导入`t`函数。
|
||||
|
||||
## 第五步:切换语言
|
||||
## 第六步:切换语言
|
||||
|
||||
当需要切换语言时,可以通过调用scope方法来切换语言。
|
||||
当需要切换语言时,可以通过调用`change`方法来切换语言。
|
||||
|
||||
```javascript
|
||||
import { scope } from "./languages"
|
||||
import { i18nScope } from "./languages"
|
||||
|
||||
// 切换到英文
|
||||
await scope.change("en")
|
||||
await i18nScope.change("en")
|
||||
// VoerkaI18n是一个全局单例,可以直接访问
|
||||
VoerkaI18n.change("en")
|
||||
```
|
||||
|
||||
`scope.change`与`VoerkaI18n.change`两者是等价的。
|
||||
`i18nScope.change`与`VoerkaI18n.change`两者是等价的。
|
||||
|
||||
一般可能也需要在语言切换后进行界面更新渲染,可以订阅事件来响应语言切换。
|
||||
|
||||
```javascript
|
||||
import { scope } from "./languages"
|
||||
import { i18nScope } from "./languages"
|
||||
|
||||
// 切换到英文
|
||||
scope.on((newLanguage)=>{
|
||||
i18nScope.on((newLanguage)=>{
|
||||
...
|
||||
})
|
||||
//
|
||||
@ -262,7 +307,6 @@ t("中华人民共和国成立于{birthday | year}年",{birthday:new Date()})
|
||||
|
||||
- `voerkai18n`使用正则表达式来提取要翻译的内容,因此`t()`可以使用在任意地方。
|
||||
|
||||
-
|
||||
|
||||
|
||||
## 插值变量
|
||||
@ -705,11 +749,11 @@ t("当前状态:{status | dict(0,'初始化',1,'正在连接',2,'已连接',3,
|
||||
|
||||
因此,引入`名称空间`就是目的就是为了解决此问题。
|
||||
|
||||
配置名称空间,需要配置`languages/settings.js`文件。
|
||||
配置名称空间,需要配置`languages/settings.json`文件。
|
||||
|
||||
```javascript
|
||||
// 工程目录:d:/code/myapp
|
||||
// languages/settings.js
|
||||
// languages/settings.json
|
||||
module.exports = {
|
||||
namespaces:{
|
||||
//"名称":"相对路径",
|
||||
@ -882,10 +926,10 @@ module.expors = {
|
||||
可以通过全局单例或当前作用域实例切换语言。
|
||||
|
||||
```javascript
|
||||
import { scope } from "./languages"
|
||||
import { i18nScope } from "./languages"
|
||||
|
||||
// 切换到英文
|
||||
await scope.change("en")
|
||||
await i18nScope.change("en")
|
||||
// VoerkaI18n是一个全局单例,可以直接访问
|
||||
VoerkaI18n.change("en")
|
||||
```
|
||||
@ -893,10 +937,10 @@ VoerkaI18n.change("en")
|
||||
侦听语言切换事件:
|
||||
|
||||
```javascript
|
||||
import { scope } from "./languages"
|
||||
import { i18nScope } from "./languages"
|
||||
|
||||
// 切换到英文
|
||||
scope.on((newLanguage)=>{
|
||||
i18nScope.on((newLanguage)=>{
|
||||
...
|
||||
})
|
||||
//
|
||||
@ -937,9 +981,9 @@ const scope = new i18nScope({
|
||||
|
||||
然后在`babel.config.js`中使用,详见上节`自动导入翻译函数`介绍。
|
||||
|
||||
## Vue扩展
|
||||
|
||||
|
||||
## VUE扩展
|
||||
|
||||
## React扩展
|
||||
|
||||
@ -985,12 +1029,11 @@ const scope = new i18nScope({
|
||||
Arguments:
|
||||
location 工程项目所在目录
|
||||
Options:
|
||||
-d, --debug 输出调试信息
|
||||
-D, --debug 输出调试信息
|
||||
-r, --reset 重新生成当前项目的语言配置
|
||||
-m, --moduleType [type] 生成的js模块类型,取值auto,esm,cjs (default: "auto")
|
||||
-lngs, --languages <languages...> 支持的语言列表 (default: ["cn","en"])
|
||||
-default, --defaultLanguage 默认语言
|
||||
-active, --activeLanguage 激活语言
|
||||
-d, --defaultLanguage 默认语言
|
||||
-a, --activeLanguage 激活语言
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
@ -1000,7 +1043,7 @@ Options:
|
||||
|
||||
```javascript
|
||||
//- `lngs`参数用来指定拟支持的语言名称列表
|
||||
> voerkai18n init . -lngs cn en jp de -default cn
|
||||
> voerkai18n init . -lngs cn en jp de -d cn
|
||||
```
|
||||
|
||||
运行`voerkai18n init`命令后,会在当前工程中创建相应配置文件。
|
||||
@ -1008,13 +1051,12 @@ Options:
|
||||
```javascript
|
||||
myapp
|
||||
|-- languages
|
||||
|-- settings.js // 语言配置文件
|
||||
|-- package.json
|
||||
|-- settings.json // 语言配置文件
|
||||
|-- package.json
|
||||
|-- index.js
|
||||
```
|
||||
|
||||
`settings.js`文件很简单,主要是用来配置要支持的语言等基本信息。
|
||||
`settings.json`文件很简单,主要是用来配置要支持的语言等基本信息。
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
@ -1040,16 +1082,16 @@ module.exports = {
|
||||
|
||||
**说明:**
|
||||
|
||||
- 您也可以手动自行创建`languages/settings.js`、`languages/package.json`文件。这样就不需运行`voerkai18n init`命令了。
|
||||
- 您也可以手动自行创建`languages/settings.json`文件。这样就不需运行`voerkai18n init`命令了。
|
||||
|
||||
- 如果你的源码放在`src`文件夹,则需要在`src`文件夹下执行`init`命令。
|
||||
- 如果你的源码放在`src`文件夹,则`init`命令会自动在在`src`文件夹下创建`languages`文件夹。
|
||||
|
||||
- `voerkai18n init`是可选的,直接使用`extract`时也会自动创建相应的文件。
|
||||
|
||||
- `-m`参数用来指定生成的`settings.js`的模块类型:
|
||||
- `-m`参数用来指定生成的`settings.json`的模块类型:
|
||||
- 当`-m=auto`时,会自动读取前工程`package.json`中的`type`字段
|
||||
- 当`-m=esm`时,会生成`ESM`模块类型的`settings.js`。
|
||||
- 当`-m=cjs`时,会生成`commonjs`模块类型的`settings.js`。
|
||||
- 当`-m=esm`时,会生成`ESM`模块类型的`settings.json`。
|
||||
- 当`-m=cjs`时,会生成`commonjs`模块类型的`settings.json`。
|
||||
|
||||
- `location`参数是可选的,如果没有指定则采用当前目录。
|
||||
|
||||
@ -1067,10 +1109,10 @@ Arguments:
|
||||
location 工程项目所在目录 (default: "./")
|
||||
|
||||
Options:
|
||||
-d, --debug 输出调试信息
|
||||
-D, --debug 输出调试信息
|
||||
-lngs, --languages 支持的语言
|
||||
-default, --defaultLanguage 默认语言
|
||||
-active, --activeLanguage 激活语言
|
||||
-d, --defaultLanguage 默认语言
|
||||
-a, --activeLanguage 激活语言
|
||||
-ns, --namespaces 翻译名称空间
|
||||
-e, --exclude <folders> 排除要扫描的文件夹,多个用逗号分隔
|
||||
-u, --updateMode 本次提取内容与已存在内容的数据合并策略,默认取值sync=同步,overwrite=覆盖,merge=合并
|
||||
@ -1081,7 +1123,7 @@ Options:
|
||||
**说明:**
|
||||
|
||||
- 启用`-d`参数时会输出提取过程,显示从哪些文件提取了几条信息。
|
||||
- 如果已手动创建或通过`init`命令创建了`languages/settings.js`文件,则可以不指定`-ns`,`-lngs`,`-default`,`-active`参数。`extract`会优先使用`languages/settings.js`文件中的参数来进行提取。
|
||||
- 如果已手动创建或通过`init`命令创建了`languages/settings.json`文件,则可以不指定`-ns`,`-lngs`,`-d`,`-a`参数。`extract`会优先使用`languages/settings.json`文件中的参数来进行提取。
|
||||
- `-u`参数用来指定如何将提取的文本与现存的文件进行合并。因为在国际化流程中,我们经常面临源代码变更时需要更新翻译的问题。支持三种合并策略。
|
||||
- **sync**:同步(默认值),两者自动合并,并且会删除在源码文件中不存在的文本。如果某个翻译已经翻译了一半也会保留。此值适用于大部情况,推荐。
|
||||
- **overwrite**:覆盖现存的翻译内容。这会导致已经进行了一半的翻译数据丢失,**慎用**。
|
||||
@ -1109,8 +1151,8 @@ Arguments:
|
||||
location 工程项目所在目录 (default: "./")
|
||||
|
||||
Options:
|
||||
-d, --debug 输出调试信息
|
||||
-m, --moduleType [types] 输出模块类型,取值auto,esm,cjs (default: "auto")
|
||||
-D, --debug 输出调试信息
|
||||
-m, --moduleType [types] 输出模块类型,取值auto,esm,cjs (default: "esm")
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
@ -1119,7 +1161,6 @@ Options:
|
||||
```javascript
|
||||
myapp
|
||||
|--- langauges
|
||||
|-- package.json
|
||||
|-- index.js // 当前作用域的源码
|
||||
|-- idMap.js // 翻译文本与id的映射文件
|
||||
|-- formatters.js // 自定义格式化器
|
||||
@ -1142,33 +1183,33 @@ myapp
|
||||
每个工程会创建一个`i18nScope`实例。
|
||||
|
||||
```javascript
|
||||
import { scope } from "./languages"
|
||||
import { i18nScope } from "./languages"
|
||||
|
||||
// 订阅语言切换事件
|
||||
scope.on((newLanguage)=>{...})
|
||||
i18nScope.on((newLanguage)=>{...})
|
||||
// 取消语言切换事件订阅
|
||||
scope.off(callback)
|
||||
i18nScope.off(callback)
|
||||
// 当前作用域配置
|
||||
scope.settings
|
||||
i18nScope.settings
|
||||
// 当前语言
|
||||
scope.activeLanguage // 如cn
|
||||
i18nScope.activeLanguage // 如cn
|
||||
|
||||
// 默认语言
|
||||
scope.defaultLanguage
|
||||
i18nScope.defaultLanguage
|
||||
// 返回当前支持的语言列表,可以用来显示
|
||||
scope.languages // [{name:"cn",title:"中文"},{name:"en",title:"英文"},...]
|
||||
i18nScope.languages // [{name:"cn",title:"中文"},{name:"en",title:"英文"},...]
|
||||
// 返回当前作用域的格式化器
|
||||
scope.formatters
|
||||
i18nScope.formatters
|
||||
// 当前作用id
|
||||
scop.id
|
||||
i18nScope.id
|
||||
// 切换语言,异步函数
|
||||
await scope.change(newLanguage)
|
||||
await i18nScope.change(newLanguage)
|
||||
// 当前语言包
|
||||
scope.messages // {1:"...",2:"...","3":"..."}
|
||||
i18nScope.messages // {1:"...",2:"...","3":"..."}
|
||||
// 引用全局VoerkaI18n实例
|
||||
scope.global
|
||||
i18nScope.global
|
||||
// 注册当前作用域格式化器
|
||||
scope.registerFormatter(name,formatter,{language:"*"})
|
||||
i18nScope.registerFormatter(name,formatter,{language:"*"})
|
||||
```
|
||||
|
||||
## VoerkaI18n
|
||||
|
@ -97,9 +97,9 @@ test("初始化工程(esm)",async () =>{
|
||||
let code = shelljs.exec(`node ${CLI_INDEX_FILE} init . -lngs ${SUPPORTED_LANGUAGES.join(" ")} -default ${DEFAULT_LANGUAGE} -active ${ACTIVE_LANGUAGE}`).code
|
||||
expect(code).toEqual(0);
|
||||
expect(fs.existsSync(path.join(LANGUAGE_FOLDER,"package.json"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(LANGUAGE_FOLDER,"settings.js"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(LANGUAGE_FOLDER,"settings.json"))).toBe(true);
|
||||
expect(fs.readJSONSync(path.join(LANGUAGE_FOLDER,"package.json")).type || "commonjs").toEqual(MODULE_TYPE);
|
||||
const langSettings = await importModule(path.join(LANGUAGE_FOLDER,"settings.js"));
|
||||
const langSettings = await importModule(path.join(LANGUAGE_FOLDER,"settings.json"));
|
||||
|
||||
expect(langSettings.languages.map(lng=>lng.name).join(",")).toEqual(SUPPORTED_LANGUAGES.join(","));
|
||||
expect(langSettings.defaultLanguage).toEqual(DEFAULT_LANGUAGE);
|
||||
@ -110,9 +110,9 @@ test("初始化工程(cjs)",async () =>{
|
||||
let code = shelljs.exec(`node ${CLI_INDEX_FILE} init . -lngs ${SUPPORTED_LANGUAGES.join(" ")} -default ${DEFAULT_LANGUAGE} -active ${ACTIVE_LANGUAGE}`).code
|
||||
expect(code).toEqual(0);
|
||||
expect(fs.existsSync(path.join(LANGUAGE_FOLDER,"package.json"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(LANGUAGE_FOLDER,"settings.js"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(LANGUAGE_FOLDER,"settings.json"))).toBe(true);
|
||||
expect(fs.readJSONSync(path.join(LANGUAGE_FOLDER,"package.json")).type || "commonjs").toEqual("commonjs");
|
||||
const langSettings = await importModule(path.join(LANGUAGE_FOLDER,"settings.js"));
|
||||
const langSettings = await importModule(path.join(LANGUAGE_FOLDER,"settings.json"));
|
||||
|
||||
expect(langSettings.languages.map(lng=>lng.name).join(",")).toEqual(SUPPORTED_LANGUAGES.join(","));
|
||||
expect(langSettings.defaultLanguage).toEqual(DEFAULT_LANGUAGE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user