add typescript supports
This commit is contained in:
parent
350012a113
commit
cdc732ada7
@ -1,32 +0,0 @@
|
|||||||
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": "相片"
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
export default {
|
|
||||||
"1": "a",
|
|
||||||
"2": "b",
|
|
||||||
"3": "c",
|
|
||||||
"4": "d",
|
|
||||||
"5": "e",
|
|
||||||
"6": "Please enter your old password:",
|
|
||||||
"7": "Please enter your old password again:",
|
|
||||||
"8": "Please enter a new password:",
|
|
||||||
"9": "Please enter the new password again:",
|
|
||||||
"10": "The password needs at least 6 digits and contains at least two of numbers, characters or special symbols",
|
|
||||||
"11": "Password strength: {strength}",
|
|
||||||
"12": "Wrong user name or password",
|
|
||||||
"13": "Please enter user name:",
|
|
||||||
"14": "Please input a password:",
|
|
||||||
"15": "Welcome: {}",
|
|
||||||
"16": "Database type: {}, {}, {}",
|
|
||||||
"17": "Database password: {PWD}",
|
|
||||||
"18": "Database address: {URL}",
|
|
||||||
"19": "Code: {encode}",
|
|
||||||
"20": "code",
|
|
||||||
"21": "name",
|
|
||||||
"22": "describe",
|
|
||||||
"23": "File name",
|
|
||||||
"24": "You have {} unread messages",
|
|
||||||
"25": "Total messages: {$count}",
|
|
||||||
"26": "Message type: {type}",
|
|
||||||
"27": "Sign in",
|
|
||||||
"28": "Please input a password:",
|
|
||||||
"29": "head portrait",
|
|
||||||
"30": "photo"
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
/**
|
|
||||||
|
|
||||||
格式化器用来对翻译文本内容中的插值变量进行格式化,
|
|
||||||
比如将一个数字格式化为货币格式,或者将一个日期格式化为友好的日期格式。
|
|
||||||
|
|
||||||
- 以下定义了一些格式化器,在中文场景下,会启用这些格式化器。
|
|
||||||
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:{
|
|
||||||
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
export default {
|
|
||||||
"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
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
|
|
||||||
import messageIds from "./idMap.js"
|
|
||||||
import runtime from "./runtime.js"
|
|
||||||
const { translate,i18nScope } = runtime
|
|
||||||
|
|
||||||
import formatters from "./formatters.js"
|
|
||||||
import defaultMessages from "./zh.js"
|
|
||||||
const activeMessages = defaultMessages
|
|
||||||
|
|
||||||
|
|
||||||
// 语言配置文件
|
|
||||||
const scopeSettings = {
|
|
||||||
"languages": [
|
|
||||||
{
|
|
||||||
"name": "zh",
|
|
||||||
"title": "中文"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "en",
|
|
||||||
"title": "英语"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "de",
|
|
||||||
"title": "德语"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "jp",
|
|
||||||
"title": "日语"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"defaultLanguage": "zh",
|
|
||||||
"activeLanguage": "zh",
|
|
||||||
"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"),
|
|
||||||
"de" : ()=>import("./de.js"),
|
|
||||||
"jp" : ()=>import("./jp.js")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 翻译函数
|
|
||||||
const scopedTtranslate = translate.bind(scope)
|
|
||||||
|
|
||||||
export {
|
|
||||||
scopedTtranslate as t,
|
|
||||||
scope as i18nScope
|
|
||||||
}
|
|
||||||
|
|
108
packages/apps/app/tsconfig.json
Normal file
108
packages/apps/app/tsconfig.json
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||||
|
|
||||||
|
/* Projects */
|
||||||
|
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||||
|
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||||
|
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||||
|
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||||
|
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||||
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||||
|
//"suppressImplicitAnyIndexErrors":true,
|
||||||
|
/* Language and Environment */
|
||||||
|
"target": "ES2015", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||||
|
"lib": ["ES2015"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||||
|
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||||
|
"experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||||
|
"emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||||
|
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||||
|
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||||
|
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||||
|
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||||
|
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||||
|
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||||
|
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||||
|
//"moduleResolution": "node16",
|
||||||
|
/* Modules */
|
||||||
|
"module": "commonjs", /* Specify what module code is generated. */
|
||||||
|
// "baseUrl": ".",
|
||||||
|
// "rootDir": "./src",
|
||||||
|
// "outDir": "./dist",
|
||||||
|
// "paths": {
|
||||||
|
// },
|
||||||
|
//"rootDir": "./src", /* Specify the root folder within your source files. */
|
||||||
|
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||||
|
//"baseUrl": "./dist", /* Specify the base directory to resolve non-relative module names. */
|
||||||
|
//"paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||||
|
//"rootDirs": ["src"], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||||
|
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||||
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||||
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||||
|
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||||
|
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||||
|
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||||
|
|
||||||
|
/* JavaScript Support */
|
||||||
|
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||||
|
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||||
|
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||||
|
|
||||||
|
/* Emit */
|
||||||
|
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||||
|
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||||
|
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||||
|
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||||
|
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||||
|
// "outDir": "./dist", /* Specify an output folder for all emitted files. */
|
||||||
|
// "removeComments": true, /* Disable emitting comments. */
|
||||||
|
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||||
|
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||||
|
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||||
|
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||||
|
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||||
|
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||||
|
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||||
|
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||||
|
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||||
|
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||||
|
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||||
|
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||||
|
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||||
|
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||||
|
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||||
|
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||||
|
|
||||||
|
/* Interop Constraints */
|
||||||
|
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||||
|
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||||
|
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||||
|
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||||
|
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||||
|
|
||||||
|
/* Type Checking */
|
||||||
|
"strict": true, /* Enable all strict type-checking options. */
|
||||||
|
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||||
|
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||||
|
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||||
|
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||||
|
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||||
|
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||||
|
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||||
|
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||||
|
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||||
|
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||||
|
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||||
|
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||||
|
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||||
|
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||||
|
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||||
|
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||||
|
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||||
|
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||||
|
|
||||||
|
/* Completeness */
|
||||||
|
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||||
|
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,8 @@ const artTemplate = require("art-template")
|
|||||||
|
|
||||||
function normalizeCompileOptions(opts={}) {
|
function normalizeCompileOptions(opts={}) {
|
||||||
let options = Object.assign({
|
let options = Object.assign({
|
||||||
moduleType:"auto" // 指定编译后的语言文件的模块类型,取值common,cjs,esm,es
|
moduleType:"auto", // 指定编译后的语言文件的模块类型,取值common,cjs,esm,es
|
||||||
|
isTypeScript:false
|
||||||
}, opts)
|
}, opts)
|
||||||
options.moduleType = options.moduleType.trim()
|
options.moduleType = options.moduleType.trim()
|
||||||
if(options.moduleType==="es") options.moduleType = "esm"
|
if(options.moduleType==="es") options.moduleType = "esm"
|
||||||
@ -42,15 +43,15 @@ function normalizeCompileOptions(opts={}) {
|
|||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateFormatterFile(langName,{formattersFolder,templateContext,moduleType}={}){
|
function generateFormatterFile(langName,{isTypeScript,formattersFolder,templateContext,moduleType}={}){
|
||||||
const formattersFile = path.join(formattersFolder,`${langName}.js`)
|
const formattersFile = path.join(formattersFolder,`${langName}.${isTypeScript ? 'ts' : 'js'}`)
|
||||||
if(!fs.existsSync(formattersFile)){
|
if(!fs.existsSync(formattersFile)){
|
||||||
const formattersContent = artTemplate(path.join(__dirname,"templates","formatters.js"), templateContext )
|
const formattersContent = artTemplate(path.join(__dirname,"templates",`formatters.${isTypeScript ? 'ts' : 'js'}`), templateContext )
|
||||||
fs.writeFileSync(formattersFile,formattersContent)
|
fs.writeFileSync(formattersFile,formattersContent)
|
||||||
logger.log(t(" - 格式化器:{}"),path.basename(formattersFile))
|
logger.log(t(" - 格式化器:{}"),path.basename(formattersFile))
|
||||||
}else{ // 格式化器如果存在,则需要更改对应的模块类型
|
}else{ // 格式化器如果存在,则需要更改对应的模块类型
|
||||||
let formattersContent = fs.readFileSync(formattersFile,"utf8").toString()
|
let formattersContent = fs.readFileSync(formattersFile,"utf8").toString()
|
||||||
if(moduleType == "esm"){
|
if(moduleType == "esm" || isTypeScript){
|
||||||
formattersContent = formattersContent.replaceAll(/^[^\n\r\w]*module.exports\s*\=/gm,"export default ")
|
formattersContent = formattersContent.replaceAll(/^[^\n\r\w]*module.exports\s*\=/gm,"export default ")
|
||||||
formattersContent = formattersContent.replaceAll(/^[^\n\r\w]*module.exports\./gm,"export ")
|
formattersContent = formattersContent.replaceAll(/^[^\n\r\w]*module.exports\./gm,"export ")
|
||||||
}else{
|
}else{
|
||||||
@ -65,7 +66,7 @@ function generateFormatterFile(langName,{formattersFolder,templateContext,module
|
|||||||
|
|
||||||
module.exports =async function compile(langFolder,opts={}){
|
module.exports =async function compile(langFolder,opts={}){
|
||||||
const options = normalizeCompileOptions(opts);
|
const options = normalizeCompileOptions(opts);
|
||||||
let { moduleType,inlineRuntime } = options;
|
let { moduleType,inlineRuntime,isTypeScript } = options;
|
||||||
// 如果自动则会从当前项目读取,如果没有指定则会是esm
|
// 如果自动则会从当前项目读取,如果没有指定则会是esm
|
||||||
if(moduleType==="auto"){
|
if(moduleType==="auto"){
|
||||||
moduleType = findModuleType(langFolder)
|
moduleType = findModuleType(langFolder)
|
||||||
@ -85,6 +86,7 @@ module.exports =async function compile(langFolder,opts={}){
|
|||||||
logger.log(t("激活语言\t: {}"),activeLanguage)
|
logger.log(t("激活语言\t: {}"),activeLanguage)
|
||||||
logger.log(t("名称空间\t: {}"),Object.keys(namespaces).join(","))
|
logger.log(t("名称空间\t: {}"),Object.keys(namespaces).join(","))
|
||||||
logger.log(t("模块类型\t: {}"),moduleType)
|
logger.log(t("模块类型\t: {}"),moduleType)
|
||||||
|
logger.log(t("TypeScript\t: {}"),isTypeScript)
|
||||||
logger.log("")
|
logger.log("")
|
||||||
logger.log(t("编译结果输出至:{}"),langFolder)
|
logger.log(t("编译结果输出至:{}"),langFolder)
|
||||||
|
|
||||||
@ -118,9 +120,9 @@ module.exports =async function compile(langFolder,opts={}){
|
|||||||
Object.entries(messages).forEach(([message,translatedMsgs])=>{
|
Object.entries(messages).forEach(([message,translatedMsgs])=>{
|
||||||
langMessages[translatedMsgs.$id] = lang.name in translatedMsgs ? translatedMsgs[lang.name] : message
|
langMessages[translatedMsgs.$id] = lang.name in translatedMsgs ? translatedMsgs[lang.name] : message
|
||||||
})
|
})
|
||||||
const langFile = path.join(langFolder,`${lang.name}.js`)
|
const langFile = path.join(langFolder,`${lang.name}.${isTypeScript ? 'ts' : 'js'}`)
|
||||||
// 为每一种语言生成一个语言文件
|
// 为每一种语言生成一个语言文件
|
||||||
if(moduleType==="esm"){
|
if(moduleType==="esm" || isTypeScript){
|
||||||
fs.writeFileSync(langFile,`export default ${JSON.stringify(langMessages,null,4)}`)
|
fs.writeFileSync(langFile,`export default ${JSON.stringify(langMessages,null,4)}`)
|
||||||
}else{
|
}else{
|
||||||
fs.writeFileSync(langFile,`module.exports = ${JSON.stringify(langMessages,null,4)}`)
|
fs.writeFileSync(langFile,`module.exports = ${JSON.stringify(langMessages,null,4)}`)
|
||||||
@ -129,16 +131,15 @@ module.exports =async function compile(langFolder,opts={}){
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 4. 生成id映射文件
|
// 4. 生成id映射文件
|
||||||
const idMapFile = path.join(langFolder,"idMap.js")
|
const idMapFile = path.join(langFolder,`idMap.${isTypeScript ? 'ts' : 'js'}`)
|
||||||
if(moduleType==="esm"){
|
if(moduleType==="esm" || isTypeScript){
|
||||||
fs.writeFileSync(idMapFile,`export default ${JSON.stringify(messageIds,null,4)}`)
|
fs.writeFileSync(idMapFile,`export default ${JSON.stringify(messageIds,null,4)}`)
|
||||||
}else{
|
}else{
|
||||||
fs.writeFileSync(idMapFile,`module.exports = ${JSON.stringify(messageIds,null,4)}`)
|
fs.writeFileSync(idMapFile,`module.exports = ${JSON.stringify(messageIds,null,4)}`)
|
||||||
}
|
}
|
||||||
logger.log(t(" - idMap文件: {}"),path.basename(idMapFile))
|
logger.log(t(" - idMap文件: {}"),path.basename(idMapFile))
|
||||||
|
|
||||||
// 嵌入运行时源码
|
// 嵌入运行时源码
|
||||||
if(inlineRuntime){
|
if(inlineRuntime && !isTypeScript ){
|
||||||
const runtimeSourceFolder = path.join(require.resolve("@voerkai18n/runtime"),"../..")
|
const runtimeSourceFolder = path.join(require.resolve("@voerkai18n/runtime"),"../..")
|
||||||
fs.copyFileSync(
|
fs.copyFileSync(
|
||||||
path.join(runtimeSourceFolder,"dist",`runtime.${moduleType === 'esm' ? 'mjs' : 'cjs'}`),
|
path.join(runtimeSourceFolder,"dist",`runtime.${moduleType === 'esm' ? 'mjs' : 'cjs'}`),
|
||||||
@ -154,6 +155,7 @@ module.exports =async function compile(langFolder,opts={}){
|
|||||||
logger.log(t(" - 更新运行时:{}"),"@voerkai18n/runtime")
|
logger.log(t(" - 更新运行时:{}"),"@voerkai18n/runtime")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateContext = {
|
const templateContext = {
|
||||||
scopeId:projectPackageJson.name,
|
scopeId:projectPackageJson.name,
|
||||||
inlineRuntime,
|
inlineRuntime,
|
||||||
@ -162,6 +164,7 @@ module.exports =async function compile(langFolder,opts={}){
|
|||||||
activeLanguage,
|
activeLanguage,
|
||||||
namespaces,
|
namespaces,
|
||||||
moduleType,
|
moduleType,
|
||||||
|
isTypeScript,
|
||||||
JSON,
|
JSON,
|
||||||
settings:JSON.stringify(langSettings,null,4)
|
settings:JSON.stringify(langSettings,null,4)
|
||||||
}
|
}
|
||||||
@ -170,16 +173,16 @@ module.exports =async function compile(langFolder,opts={}){
|
|||||||
if(!fs.existsSync(formattersFolder)) fs.mkdirSync(formattersFolder)
|
if(!fs.existsSync(formattersFolder)) fs.mkdirSync(formattersFolder)
|
||||||
// 为每一个语言生成一个对应的式化器
|
// 为每一个语言生成一个对应的式化器
|
||||||
languages.forEach(lang=>{
|
languages.forEach(lang=>{
|
||||||
generateFormatterFile(lang.name,{formattersFolder,templateContext,moduleType})
|
generateFormatterFile(lang.name,{isTypeScript,formattersFolder,templateContext,moduleType})
|
||||||
})
|
})
|
||||||
|
|
||||||
// 6. 生成编译后的访问入口文件
|
// 6. 生成编译后的访问入口文件
|
||||||
const entryFile = path.join(langFolder,"index.js")
|
const entryFile = path.join(langFolder,`index.${isTypeScript ? 'ts' : 'js'}`)
|
||||||
const entryContent = artTemplate(path.join(__dirname,"templates","entry.js"), templateContext )
|
const entryContent = artTemplate(path.join(__dirname,"templates",`entry.${isTypeScript ? 'ts' : 'js'}`), templateContext )
|
||||||
fs.writeFileSync(entryFile,entryContent)
|
fs.writeFileSync(entryFile,entryContent)
|
||||||
logger.log(t(" - 访问入口文件: {}"),path.basename(entryFile))
|
logger.log(t(" - 访问入口文件: {}"),path.basename(entryFile))
|
||||||
|
|
||||||
}catch(e){
|
}catch(e){
|
||||||
logger.log(t("加载多语言配置文件<{}>失败: {} "),settingsFile,e.message)
|
logger.log(t("加载多语言配置文件<{}>失败: {} "),settingsFile,e.stack)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,7 +6,7 @@ const path = require("path")
|
|||||||
const fs = require("fs-extra")
|
const fs = require("fs-extra")
|
||||||
const logger = createLogger()
|
const logger = createLogger()
|
||||||
const { i18nScope ,t } = require("./i18nProxy")
|
const { i18nScope ,t } = require("./i18nProxy")
|
||||||
const { getProjectSourceFolder } = require("@voerkai18n/utils");
|
const { getProjectSourceFolder,isTypeScriptProject } = require("@voerkai18n/utils");
|
||||||
|
|
||||||
logger.use(bannerPluin)
|
logger.use(bannerPluin)
|
||||||
|
|
||||||
@ -100,6 +100,7 @@ program
|
|||||||
})
|
})
|
||||||
.action(async (location,options) => {
|
.action(async (location,options) => {
|
||||||
location = getProjectSourceFolder(location)
|
location = getProjectSourceFolder(location)
|
||||||
|
options.isTypeScript = isTypeScriptProject()
|
||||||
const langFolder = path.join(location,"languages")
|
const langFolder = path.join(location,"languages")
|
||||||
if(!fs.existsSync(langFolder)){
|
if(!fs.existsSync(langFolder)){
|
||||||
logger.error(t("语言包文件夹<{}>不存在",langFolder))
|
logger.error(t("语言包文件夹<{}>不存在",langFolder))
|
||||||
|
41
packages/cli/templates/entry.ts
Normal file
41
packages/cli/templates/entry.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import messageIds from "./idMap" // 语言ID映射文件
|
||||||
|
{{if inlineRuntime && !isTypeScript }}import runtime from "./runtime" // 运行时
|
||||||
|
const { translate,i18nScope } = runtime
|
||||||
|
import defaultFormatters from "./formatters/{{defaultLanguage}}" // 默认语言格式化器
|
||||||
|
{{if defaultLanguage === activeLanguage}}const activeFormatters = defaultFormatters{{else}}import activeFormatters from "./formatters/{{activeLanguage}}"{{/if}} // 激活语言格式化器
|
||||||
|
{{else}}import { translate,i18nScope } from "@voerkai18n/runtime"
|
||||||
|
import defaultFormatters from "./formatters/{{defaultLanguage}}" // 默认语言格式化器
|
||||||
|
{{if defaultLanguage === activeLanguage}}const activeFormatters = defaultFormatters{{else}}import activeFormatters from "@voerkai18n/runtime/formatters/{{activeLanguage}}"{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
import defaultMessages from "./{{defaultLanguage}}"
|
||||||
|
{{if defaultLanguage === activeLanguage}}const activeMessages = defaultMessages{{else}}import activeMessages from "./{{activeLanguage}}"{{/if}}
|
||||||
|
|
||||||
|
// 语言配置文件
|
||||||
|
const scopeSettings = {{@ settings}}
|
||||||
|
const formatters = {
|
||||||
|
{{each languages}}{{if $value.name == defaultLanguage}}'{{defaultLanguage}}' : defaultFormatters{{if $index !== languages.length - 1}},{{/if}}
|
||||||
|
{{else if $value.name == activeLanguage}}{{if defaultLanguage !== activeLanguage}}'{{activeLanguage}}':activeFormatters{{/if}}{{if $index !== languages.length - 1}},{{/if}}
|
||||||
|
{{else}}'{{$value.name}}' : ()=>import("./formatters/{{$value.name}}"){{if $index !== languages.length - 1}},{{'\n\t'}}{{/if}}{{/if}}{{/each}}
|
||||||
|
}
|
||||||
|
// 语言包加载器
|
||||||
|
const loaders = { {{each languages}}{{if $value.name !== defaultLanguage}}
|
||||||
|
{{if $value.name == activeLanguage}}"{{$value.name}}" : activeMessages{{else}}"{{$value.name}}" : ()=>import("./{{$value.name}}"){{/if}}{{if $index !== languages.length - 1}},{{/if}}{{/if}}{{/each}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 语言作用域
|
||||||
|
const scope = new i18nScope({
|
||||||
|
...scopeSettings, // languages,defaultLanguage,activeLanguage,namespaces,formatters
|
||||||
|
id : "{{scopeId}}", // 当前作用域的id,自动取当前工程的package.json的name
|
||||||
|
debug : false, // 是否在控制台输出高度信息
|
||||||
|
default : defaultMessages, // 默认语言包
|
||||||
|
messages : activeMessages, // 当前语言包
|
||||||
|
idMap : messageIds, // 消息id映射列表
|
||||||
|
formatters, // 扩展自定义格式化器
|
||||||
|
loaders // 语言包加载器
|
||||||
|
})
|
||||||
|
// 翻译函数
|
||||||
|
const scopedTtranslate = translate.bind(scope)
|
||||||
|
export {
|
||||||
|
scopedTtranslate as t,
|
||||||
|
scope as i18nScope
|
||||||
|
}
|
112
packages/cli/templates/formatters.ts
Normal file
112
packages/cli/templates/formatters.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/**
|
||||||
|
|
||||||
|
格式化器用来对翻译文本内容中的插值变量进行处理
|
||||||
|
|
||||||
|
如何编写格式器请参阅官网!
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// import { Formatter,FlexFormatter } from "./runtime"
|
||||||
|
export default {
|
||||||
|
// global : true, // 简单地设置为true,代表当前所有格式化器均注册到全局,false只在当前scope生效
|
||||||
|
// global : { // 仅将里面的格式化器注册到全局
|
||||||
|
// $config:{... }
|
||||||
|
// xxxx : value => { ... },
|
||||||
|
// xxxx : (value,$config) => { ... },
|
||||||
|
// xxxx : (value,...args,$config) => { ... },
|
||||||
|
// xxxx : Formatter(value,...args,$config) => { ... },
|
||||||
|
// xxxx : FlexFormatter(value,params,$config) => { ... },
|
||||||
|
//}, // 是否注册到全局,false只在当前scope生效
|
||||||
|
// 直接对内置格式化器进行配置,请参阅官网文档
|
||||||
|
// $config:{
|
||||||
|
// datetime : {
|
||||||
|
// units : ["Year","Quarter","Month","Week","Day","Hour","Minute","Second","Millisecond","Microsecond"],
|
||||||
|
// date :{
|
||||||
|
// long : 'YYYY/MM/DD HH:mm:ss',
|
||||||
|
// short : "YYYY/MM/DD",
|
||||||
|
// format : "local"
|
||||||
|
// },
|
||||||
|
// quarter : {
|
||||||
|
// long : ["First Quarter","Second Quarter","Third Quarter","Fourth Quarter"],
|
||||||
|
// short : ["Q1","Q2","Q3","Q4"],
|
||||||
|
// format : "short"
|
||||||
|
// },
|
||||||
|
// month:{
|
||||||
|
// long : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||||||
|
// short : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"],
|
||||||
|
// format : "long" // 0-长名称,1-短名称,2-数字
|
||||||
|
// },
|
||||||
|
// weekday:{
|
||||||
|
// long : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
|
||||||
|
// short : ["Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"],
|
||||||
|
// format : "long", // 0-长名称,1-短名称,2-数字
|
||||||
|
// },
|
||||||
|
// time : {
|
||||||
|
// long : "HH:mm:ss",
|
||||||
|
// short : "HH:mm:ss",
|
||||||
|
// format : 'local'
|
||||||
|
// },
|
||||||
|
// timeSlots : {
|
||||||
|
// slots : [12],
|
||||||
|
// lowerCases : ["am","pm"],
|
||||||
|
// upperCases : ["AM","PM"]
|
||||||
|
// },
|
||||||
|
// relativeTime : {
|
||||||
|
// units : ["seconds","minutes","hours","days","weeks","months","years"],
|
||||||
|
// now : "Now",
|
||||||
|
// before : "{value} {unit} ago",
|
||||||
|
// after : "after {value} {unit}"
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// currency : {
|
||||||
|
// default : "{symbol}{value}{unit}",
|
||||||
|
// long : "{prefix} {symbol}{value}{unit}{suffix}",
|
||||||
|
// short : "{symbol}{value}{unit}",
|
||||||
|
// custom : "{prefix} {symbol}{value}{unit}{suffix}",
|
||||||
|
// format : "default",
|
||||||
|
// //--
|
||||||
|
// units : [""," thousands"," millions"," billions"," trillions"], //千,百万,十亿,万亿
|
||||||
|
// radix : 3, // 进制,即三位一进,中文是4位一进
|
||||||
|
// symbol : "$", // 符号
|
||||||
|
// prefix : "USD", // 前缀
|
||||||
|
// suffix : "", // 后缀
|
||||||
|
// division : 3, // ,分割位
|
||||||
|
// precision : 2, // 精度
|
||||||
|
|
||||||
|
// },
|
||||||
|
// number : {
|
||||||
|
// division : 3, // , 分割位,3代表每3位添加一个,
|
||||||
|
// precision : 0 // 精度,即保留小数点位置,0代表不限
|
||||||
|
// },
|
||||||
|
// empty:{
|
||||||
|
// //values : [], // 可选,定义空值,如果想让0,''也为空值,可以指定values=[0,'']
|
||||||
|
// escape : "", // 当空值时显示的备用值
|
||||||
|
// next : 'break' // 当空值时下一步的行为: break=中止;skip=跳过
|
||||||
|
// },
|
||||||
|
// error : {
|
||||||
|
// //当错误时显示的内容,支持的插值变量有message=错误信息,error=错误类名,也可以是一个返回上面内容的同步函数
|
||||||
|
// escape : null, // 默认当错误时显示空内容
|
||||||
|
// next : 'break' // 当出错时下一步的行为: break=中止;skip=忽略
|
||||||
|
// },
|
||||||
|
// fileSize:{
|
||||||
|
// brief : ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB","NB","DB"],
|
||||||
|
// whole : ["Bytes", "Kilobytes", "Megabytes", "Gigabytes", "TeraBytes", "PetaBytes", "ExaBytes", "ZetaBytes", "YottaBytes","DoggaBytes"],
|
||||||
|
// precision: 2 // 小数精度
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// 改变特定数据类型的默认格式化器
|
||||||
|
// $types:{
|
||||||
|
// Date : dateFormatter,
|
||||||
|
// Null : value =>"",
|
||||||
|
// Undefined: value =>"",
|
||||||
|
// Error : value => "ERROR",
|
||||||
|
// Boolean : value =>value ? "True":"False",
|
||||||
|
// Number : numberFormartter
|
||||||
|
// }
|
||||||
|
// 以下可以自定义编写格式化器
|
||||||
|
// xxxx : value => { ... },
|
||||||
|
// xxxx : (value,$config) => { ... },
|
||||||
|
// xxxx : (value,...args,$config) => { ... },
|
||||||
|
// xxxx : Formatter(value,...args,$config) => { ... },
|
||||||
|
// xxxx : FlexFormatter(value,params,$config) => { ... },
|
||||||
|
}
|
130
packages/runtime/index.d.ts
vendored
Normal file
130
packages/runtime/index.d.ts
vendored
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export type VoerkaLanguageMessages = Record<string,string>
|
||||||
|
export interface VoerkaLanguagePack {
|
||||||
|
[key: string]: VoerkaLanguageMessages
|
||||||
|
}
|
||||||
|
export interface VoerkaI18nManagerSettings {
|
||||||
|
debug?:boolean
|
||||||
|
defaultLanguage: string
|
||||||
|
activeLanguage : string
|
||||||
|
formatters : VoerkI18nFormatters
|
||||||
|
languages :VoerkaI18nLanguage[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export class I18nManager{
|
||||||
|
constructor(settings:VoerkaI18nManagerSettings)
|
||||||
|
get settings():Required<VoerkaI18nManagerSettings> // 配置参数
|
||||||
|
get scopes():i18nScope[] // 注册的报有i18nScope实例q
|
||||||
|
get activeLanguage():string // 当前激活语言名称
|
||||||
|
get defaultLanguage():string // 默认语言名称
|
||||||
|
get languages():VoerkaI18nSupportedLanguages // 支持的语言列表
|
||||||
|
get formatters():VoerkI18nFormatters // 内置格式化器{*:{$config,$types,...},zh:{$config,$types,...},en:{$config,$types,...}}
|
||||||
|
get defaultMessageLoader():VoerkI18nLoader // 默认语言包加载器
|
||||||
|
// 通过默认加载器加载文件
|
||||||
|
loadMessagesFromDefaultLoader(newLanguage:string,scope:i18nScope):Promise<VoerkaLanguageMessages>
|
||||||
|
change(language:string):Promise<void>
|
||||||
|
register(scope:i18nScope):Promise<void>
|
||||||
|
registerFormatter(name:string,formatter:VoerkI18nFormatter,options?:{language:string | string[]}):void
|
||||||
|
registerDefaultLoader(fn:VoerkI18nLoader):void
|
||||||
|
refresh():Promise<void>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Voerkai18nIdMap = Record<string,number>
|
||||||
|
|
||||||
|
export interface VoerkaI18nLanguage{
|
||||||
|
name:string
|
||||||
|
title?:string
|
||||||
|
default?:boolean
|
||||||
|
fallback?:string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VoerkaI18nSupportedLanguages {
|
||||||
|
[key :string]:VoerkaI18nLanguage
|
||||||
|
}
|
||||||
|
|
||||||
|
export type VoerkI18nFormatter = (value:string,...args:any[]) => string
|
||||||
|
export type VoerkI18nFormatterConfigs = Record<string,any>
|
||||||
|
|
||||||
|
export type VoerkI18nFormatters = Record<string,({
|
||||||
|
$types?:Record<string,VoerkI18nFormatter>
|
||||||
|
$config?:Record<string,string>
|
||||||
|
} & {
|
||||||
|
[key:string]:VoerkI18nFormatter
|
||||||
|
}) | (() => Awaited<Promise<any>>)>
|
||||||
|
|
||||||
|
export type VoerkI18nLoader = ()=>Awaited<Promise<any>>
|
||||||
|
export interface VoerkI18nLoaders {
|
||||||
|
[key :string]:VoerkI18nLoader
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface I18nScopeOptions{
|
||||||
|
id?:string
|
||||||
|
debug?:boolean
|
||||||
|
languages:VoerkaI18nLanguage[]
|
||||||
|
defaultLanguage:string // 默认语言名称
|
||||||
|
activeLanguage:string // 当前语言名称
|
||||||
|
default:VoerkaLanguageMessages // 默认语言包
|
||||||
|
messages:VoerkaLanguageMessages // 当前语言包
|
||||||
|
idMap:Voerkai18nIdMap // 消息id映射列表
|
||||||
|
formatters:VoerkI18nFormatters // 当前作用域的格式化函数列表{<lang>: {$types,$config,[格式化器名称]: () => {},[格式化器名称]: () => {}}}
|
||||||
|
loaders:VoerkI18nLoaders; // 异步加载语言文件的函数列表
|
||||||
|
}
|
||||||
|
|
||||||
|
export class i18nScope {
|
||||||
|
constructor(options:I18nScopeOptions, callback?:Function)
|
||||||
|
get id():string // 作用域唯一id
|
||||||
|
get debug():boolean // 调试开关
|
||||||
|
get defaultLanguage():string // 默认语言名称
|
||||||
|
get activeLanguage():string // 默认语言名称
|
||||||
|
get default():VoerkaLanguageMessages // 默认语言包
|
||||||
|
get messages(): VoerkaLanguageMessages // 当前语言包
|
||||||
|
get idMap():Voerkai18nIdMap // 消息id映射列表
|
||||||
|
get languages():VoerkaI18nSupportedLanguages // 当前作用域支持的语言列表[{name,title,fallback}]
|
||||||
|
get loaders() :VoerkI18nLoaders // 异步加载语言文件的函数列表
|
||||||
|
get global():I18nManager // 引用全局VoerkaI18n配置,注册后自动引用
|
||||||
|
get formatters():VoerkI18nFormatters // 当前作用域的所有格式化器定义 {<语言名称>: {$types,$config,[格式化器名称]: () = >{},[格式化器名称]: () => {}}}
|
||||||
|
get activeFormatters():VoerkI18nFormatters // 当前作用域激活的格式化器定义 {$types,$config,[格式化器名称]: () = >{},[格式化器名称]: () = >{}}
|
||||||
|
get activeFormatterConfig():VoerkI18nFormatterConfigs // 当前格式化器合并后的配置参数,参数已经合并了全局格式化器中的参数
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在全局注册作用域当前作用域
|
||||||
|
* @param {*} callback 注册成功后的回调
|
||||||
|
*/
|
||||||
|
register(callback:Function):void
|
||||||
|
/**
|
||||||
|
* 注册格式化器
|
||||||
|
*/
|
||||||
|
registerFormatter(name:string, formatter:VoerkI18nFormatter, { language , global }:{language:string | string[] , global:boolean}):void
|
||||||
|
/**
|
||||||
|
* 注册多种格式化器
|
||||||
|
*/
|
||||||
|
registerFormatters(formatters:VoerkI18nFormatters,asGlobal?:boolean):void
|
||||||
|
/**
|
||||||
|
* 注册默认文本信息加载器
|
||||||
|
*/
|
||||||
|
registerDefaultLoader(fn:Function):void
|
||||||
|
/**
|
||||||
|
* 获取指定语言信息
|
||||||
|
* @param {*} language
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getLanguage(language:string):VoerkaLanguageMessages
|
||||||
|
hasLanguage(language:string):boolean
|
||||||
|
refresh(newLanguage:string):Promise<void>
|
||||||
|
on():void
|
||||||
|
off():void
|
||||||
|
offAll():void
|
||||||
|
change(language:string):Promise<void>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export declare type translate =((message:string,...args:(string | Function)[])=>string)
|
||||||
|
| ((message:string,vars:Record<string,any>)=>string)
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
var VoerkaI18n:I18nManager
|
||||||
|
var t:((message:string,...args:(string | Function)[])=>string)
|
||||||
|
| ((message:string,vars:Record<string,any>)=>string)
|
||||||
|
}
|
@ -3,7 +3,8 @@
|
|||||||
"version": "1.1.6",
|
"version": "1.1.6",
|
||||||
"description": "核心运行时",
|
"description": "核心运行时",
|
||||||
"main": "./dist/index.cjs",
|
"main": "./dist/index.cjs",
|
||||||
"module": "dist/index.esm.js",
|
"module": "./dist/index.esm.js",
|
||||||
|
"types":"./index.d.ts",
|
||||||
"homepage": "https://gitee.com/zhangfisher/voerka-i18n",
|
"homepage": "https://gitee.com/zhangfisher/voerka-i18n",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -128,6 +128,14 @@ function getProjectRootFolder(folder="./",exclueCurrent=false){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fileIsExists(filename){
|
||||||
|
try{
|
||||||
|
fs.statSync(filename)
|
||||||
|
return true
|
||||||
|
}catch(e){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动获取当前项目的languages
|
* 自动获取当前项目的languages
|
||||||
@ -202,6 +210,19 @@ function getProjectRootFolder(folder="./",exclueCurrent=false){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断当前是否是Typescript工程
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function isTypeScriptProject(){
|
||||||
|
let projectFolder = getProjectRootFolder(process.cwd(),false)
|
||||||
|
if(projectFolder){
|
||||||
|
return fileIsExists(path.join(projectFolder,"tsconfig.json"))
|
||||||
|
|| fileIsExists(path.join(projectFolder,"Src","tsconfig.json"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 返回当前项目的模块类型
|
* 返回当前项目的模块类型
|
||||||
@ -228,7 +249,7 @@ function getProjectRootFolder(folder="./",exclueCurrent=false){
|
|||||||
function isInstallDependent(url){
|
function isInstallDependent(url){
|
||||||
try{
|
try{
|
||||||
// 简单判断是否存在该文件夹node_modules/@voerkai18n/runtime
|
// 简单判断是否存在该文件夹node_modules/@voerkai18n/runtime
|
||||||
let projectFolder = getCurrentProjectRootFolder(process.cwd())
|
let projectFolder = getProjectRootFolder(process.cwd())
|
||||||
if(fs.existsSync(path.join(projectFolder,"node_modules","@voerkai18n/runtime"))){
|
if(fs.existsSync(path.join(projectFolder,"node_modules","@voerkai18n/runtime"))){
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -377,7 +398,7 @@ function deepMerge(toObj,formObj,options={}){
|
|||||||
* @param {*} opts
|
* @param {*} opts
|
||||||
*/
|
*/
|
||||||
function installVoerkai18nRuntime(srcPath){
|
function installVoerkai18nRuntime(srcPath){
|
||||||
const projectFolder = getCurrentProjectRootFolder(srcPath || process.cwd())
|
const projectFolder = getProjectRootFolder(srcPath || process.cwd())
|
||||||
if(fs.existsSync("pnpm-lock.yaml")){
|
if(fs.existsSync("pnpm-lock.yaml")){
|
||||||
shelljs.exec("pnpm add @voerkai18n/runtime")
|
shelljs.exec("pnpm add @voerkai18n/runtime")
|
||||||
}else if(fs.existsSync("yarn.lock")){
|
}else if(fs.existsSync("yarn.lock")){
|
||||||
@ -392,9 +413,9 @@ function deepMerge(toObj,formObj,options={}){
|
|||||||
* @param {*} opts
|
* @param {*} opts
|
||||||
*/
|
*/
|
||||||
function updateVoerkai18nRuntime(srcPath){
|
function updateVoerkai18nRuntime(srcPath){
|
||||||
const projectFolder = getCurrentProjectRootFolder(srcPath || process.cwd())
|
const projectFolder = getProjectRootFolder(srcPath || process.cwd())
|
||||||
if(fs.existsSync("pnpm-lock.yaml")){
|
if(fs.existsSync("pnpm-lock.yaml")){
|
||||||
shelljs.exec("pnpm update --latest @voerkai18n/runtime")
|
shelljs.exec("pnpm upgrade --latest @voerkai18n/runtime")
|
||||||
}else if(fs.existsSync("yarn.lock")){
|
}else if(fs.existsSync("yarn.lock")){
|
||||||
shelljs.exec("yarn upgrade @voerkai18n/runtime")
|
shelljs.exec("yarn upgrade @voerkai18n/runtime")
|
||||||
}else{
|
}else{
|
||||||
@ -442,4 +463,6 @@ module.exports = {
|
|||||||
deepMerge, // 深度合并对象
|
deepMerge, // 深度合并对象
|
||||||
getDataTypeName, // 获取指定变量类型名称
|
getDataTypeName, // 获取指定变量类型名称
|
||||||
isGitRepo, // 判断当前工程是否是git工程
|
isGitRepo, // 判断当前工程是否是git工程
|
||||||
|
fileIsExists,
|
||||||
|
isTypeScriptProject
|
||||||
}
|
}
|
11
versions.test.md
Normal file
11
versions.test.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# 版本信息
|
||||||
|
| 包| 版本 | 最新发布 | 说明|
|
||||||
|
| --- | :---: | :---: | --- |
|
||||||
|
|**@voerkai18n/utils**|1.0.13|2022/08/20|公共工具库|
|
||||||
|
|**@voerkai18n/runtime**|1.1.6|2022/08/26|核心运行时|
|
||||||
|
|**@voerkai18n/formatters**|1.0.7|2022/04/15|格式化器,提供对要翻译文本的转换功能|
|
||||||
|
|**@voerkai18n/react**|1.0.4|2022/04/16|React支持,提供语言切换等功能|
|
||||||
|
|**@voerkai18n/cli**|1.0.39|2022/08/26|命令行工具,用来初始化/提取/编译/自动翻译等工具链|
|
||||||
|
|**@voerkai18n/babel**|1.0.24|2022/08/20|Babel插件,实现自动导入t函数和自动文本映射|
|
||||||
|
|**@voerkai18n/vite**|1.0.13|2022/08/20|Vite插件,提供自动插入翻译函数和文本映射等功能|
|
||||||
|
|**@voerkai18n/vue**|1.0.6|2022/08/20|Vue3插件,提供自动插件翻译函数和语言切换功能|
|
Loading…
x
Reference in New Issue
Block a user