增加stringify
This commit is contained in:
parent
ae65d1bf97
commit
a594b51cb6
28
packages/demo/utils.demo.js
Normal file
28
packages/demo/utils.demo.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const { objectToString } = require("../tools/stringify")
|
||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
name:"张三丰",
|
||||||
|
age:12,
|
||||||
|
active:true,
|
||||||
|
address:[
|
||||||
|
"北京市",
|
||||||
|
"福建省泉州市"
|
||||||
|
],
|
||||||
|
posts:{
|
||||||
|
title:"标题",
|
||||||
|
content:"内容",
|
||||||
|
//comments:[]
|
||||||
|
},
|
||||||
|
"产品清单":[
|
||||||
|
"手机",
|
||||||
|
"电脑"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = objectToString(data)
|
||||||
|
|
||||||
|
console.log(result)
|
||||||
|
|
@ -279,7 +279,7 @@ function getFormatter(scope,activeLanguage,name){
|
|||||||
// 缓存格式化器引用,避免重复检索
|
// 缓存格式化器引用,避免重复检索
|
||||||
if(!scope.$cache) resetScopeCache(scope)
|
if(!scope.$cache) resetScopeCache(scope)
|
||||||
if(scope.$cache.activeLanguage === activeLanguage) {
|
if(scope.$cache.activeLanguage === activeLanguage) {
|
||||||
if(dataType in scope.$cache.formatters) return scope.$cache.formatters[dataType]
|
if(name in scope.$cache.formatters) return scope.$cache.formatters[name]
|
||||||
}else{// 当语言切换时清空缓存
|
}else{// 当语言切换时清空缓存
|
||||||
resetScopeCache(scope,activeLanguage)
|
resetScopeCache(scope,activeLanguage)
|
||||||
}
|
}
|
||||||
@ -300,7 +300,7 @@ function getFormatter(scope,activeLanguage,name){
|
|||||||
/**
|
/**
|
||||||
* 执行格式化器并返回结果
|
* 执行格式化器并返回结果
|
||||||
* @param {*} value
|
* @param {*} value
|
||||||
* @param {*} formatters
|
* @param {*} formatters 多个格式化器顺序执行,前一个输出作为下一个格式化器的输入
|
||||||
*/
|
*/
|
||||||
function executeFormatter(value,formatters){
|
function executeFormatter(value,formatters){
|
||||||
if(formatters.length===0) return value
|
if(formatters.length===0) return value
|
||||||
@ -309,7 +309,7 @@ function executeFormatter(value,formatters){
|
|||||||
for(let formatter of formatters){
|
for(let formatter of formatters){
|
||||||
if(typeof(formatter) === "function") {
|
if(typeof(formatter) === "function") {
|
||||||
result = formatter(result)
|
result = formatter(result)
|
||||||
}else{
|
}else{// 如果碰到无效的格式化器,则跳过过续的格式化器
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -504,19 +504,13 @@ function translate(message) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
// 由于在编译语言时会使用JSON.stringify进行保存,而JSON.stringify会将\t\n\r转换为\\t\\n\\r的形式
|
// 2. 取得翻译文本模板字符串
|
||||||
// 这会导致在翻译时,如果消息中有\t\n\r则会出现翻译错误
|
|
||||||
// 所以需要将message再次使用JSON.stringify进行转换才可以匹配
|
|
||||||
content = JSON.stringify(content)
|
|
||||||
content = content.substr(1,content.length-2)
|
|
||||||
|
|
||||||
// 2. 取得翻译文本模板字符串
|
|
||||||
if(activeLanguage === scope.defaultLanguage){
|
if(activeLanguage === scope.defaultLanguage){
|
||||||
// 2.1 从默认语言中取得翻译文本模板字符串
|
// 2.1 从默认语言中取得翻译文本模板字符串
|
||||||
// 如果当前语言就是默认语言,不需要查询加载,只需要做插值变换即可
|
// 如果当前语言就是默认语言,不需要查询加载,只需要做插值变换即可
|
||||||
// 当源文件运用了babel插件后会将原始文本内容转换为msgId
|
// 当源文件运用了babel插件后会将原始文本内容转换为msgId
|
||||||
// 如果是msgId则从scope.default中读取,scope.default=默认语言包={<id>:<message>}
|
// 如果是msgId则从scope.default中读取,scope.default=默认语言包={<id>:<message>}
|
||||||
if(isMessageId(text)){
|
if(isMessageId(content)){
|
||||||
content = scope.default[content] || message
|
content = scope.default[content] || message
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const { isPlainObject } = require("../runtime/utils");
|
const { isPlainObject } = require("./utils");
|
||||||
|
|
||||||
const DefaultI18nPluginOptions = {
|
const DefaultI18nPluginOptions = {
|
||||||
translateFunctionName:"t", // 默认的翻译函数名称
|
translateFunctionName:"t", // 默认的翻译函数名称
|
||||||
|
111
packages/tools/stringify.js
Normal file
111
packages/tools/stringify.js
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
|
||||||
|
const { isPlainObject } = require("./utils")
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* JSON.stringify在将一个JSON转化为字符串时会对字符串里面的\t等转义符进行再次转义
|
||||||
|
* 导致在使用包含\t等转义符为key时会出现问题
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param {*} obj
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function escape(str){
|
||||||
|
return str.replaceAll("\t","\\t")
|
||||||
|
.replaceAll("\n","\\n")
|
||||||
|
.replaceAll("\b","\\b")
|
||||||
|
.replaceAll("\r","\\r")
|
||||||
|
.replaceAll("\f","\\f")
|
||||||
|
.replaceAll("\\","\\\\")
|
||||||
|
.replaceAll("\'","\\'")
|
||||||
|
.replaceAll('\"','\\"')
|
||||||
|
.replaceAll('\v','\\v')
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取字符串的长度,中文算两个字符
|
||||||
|
* @param {*} s
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function getStringWidth(s){
|
||||||
|
let str = String(s)
|
||||||
|
var realLength = 0, len = str.length, charCode = -1;
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
charCode = str.charCodeAt(i);
|
||||||
|
if (charCode >= 0 && charCode <= 128) realLength += 1;
|
||||||
|
else realLength += 2;
|
||||||
|
}
|
||||||
|
return realLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
function objectToString(obj,{indent=4,alignKey=true}={}){
|
||||||
|
function nodeToString(node,level,last=false){
|
||||||
|
let results = [],beginChar = "",endChar = ""
|
||||||
|
level++
|
||||||
|
if(Array.isArray(node)){
|
||||||
|
beginChar = "[\n"
|
||||||
|
node.forEach((value,index)=>{
|
||||||
|
const isLastItem = index ===node.length-1
|
||||||
|
let item = value
|
||||||
|
if(Array.isArray(value) || isPlainObject(value)){
|
||||||
|
item = nodeToString(value, level,isLastItem)
|
||||||
|
}else if(typeof(value)==="string"){
|
||||||
|
item = `"${escape(value)}"`
|
||||||
|
}else if(typeof(value)==="number"){
|
||||||
|
item = value.toString()
|
||||||
|
}else if(typeof(value)==="boolean"){
|
||||||
|
item = value.toString()
|
||||||
|
}
|
||||||
|
// 如果最后一项
|
||||||
|
if(!isLastItem){
|
||||||
|
item = item+","
|
||||||
|
}else{
|
||||||
|
item = item+"\n"
|
||||||
|
}
|
||||||
|
results.push(item)
|
||||||
|
})
|
||||||
|
endChar =" ".repeat((level-1) * indent) + ( last ? "]" : "]")
|
||||||
|
return beginChar + results.map(item=>{
|
||||||
|
return `${" ".repeat(level * indent)}${item}`
|
||||||
|
}).join("\n") + endChar
|
||||||
|
}else if(isPlainObject(node)){
|
||||||
|
beginChar = "{\n"
|
||||||
|
const length = Object.keys(node).length
|
||||||
|
const indentSpace = " ".repeat(level * indent)
|
||||||
|
let alignIndent = 0
|
||||||
|
Object.entries(node).forEach(([key,value],index)=>{
|
||||||
|
const isLastItem = index ===length-1
|
||||||
|
alignIndent = Math.max(getStringWidth(key),alignIndent)
|
||||||
|
let item = [`${indentSpace}"${escape(key)}"`,value]
|
||||||
|
if(Array.isArray(value) || isPlainObject(value)){
|
||||||
|
item[1] = nodeToString(value, level,isLastItem)
|
||||||
|
}else if(typeof(value)==="string"){
|
||||||
|
item[1] = `"${escape(value)}"`
|
||||||
|
}else if(typeof(value)==="number"){
|
||||||
|
item[1] = `${value.toString()}`
|
||||||
|
}else if(typeof(value)==="boolean"){
|
||||||
|
item[1] = `${value.toString()}`
|
||||||
|
}
|
||||||
|
// 如果最后一项
|
||||||
|
if(!isLastItem){
|
||||||
|
item[1] = item[1]+","
|
||||||
|
}else{
|
||||||
|
item[1] = item[1]+"\n"
|
||||||
|
}
|
||||||
|
results.push(item)
|
||||||
|
})
|
||||||
|
endChar =" ".repeat((level-1) * indent) + ( last ? "}" : "}")
|
||||||
|
return beginChar + results.map(item=>{
|
||||||
|
if(alignKey){
|
||||||
|
return `${item[0]}${ " ".repeat(alignIndent-getStringWidth(item[0].trim())+2)}: ${item[1]}`
|
||||||
|
}else{
|
||||||
|
return `${item[0]}: ${item[1]}`
|
||||||
|
}
|
||||||
|
}).join("\n") + endChar
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return nodeToString(obj,0,true)
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
objectToString,
|
||||||
|
getStringWidth
|
||||||
|
}
|
@ -111,74 +111,12 @@ function createJsModuleFile(filename,defaultExports={},namedExports={},moduleTyp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* JSON.stringify在将一个JSON转化为字符串时会对字符串里面的\t等转义符进行再次转义
|
|
||||||
* 导致在使用包含\t等转义符为key时会出现问题
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param {*} obj
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
function escape(str){
|
|
||||||
return str.replaceAll("\t","\\t")
|
|
||||||
}
|
|
||||||
|
|
||||||
function ObjectToString(obj,{indent=4,alignKey=true}={}){
|
|
||||||
function nodeToString(node,level,last=false){
|
|
||||||
let results = [],beginChar = "",endChar = ""
|
|
||||||
level++
|
|
||||||
if(Array.isArray(node)){
|
|
||||||
beginChar = "[\n"
|
|
||||||
node.forEach((value,index)=>{
|
|
||||||
|
|
||||||
})
|
|
||||||
endChar =" ".repeat((level-1) * indent) + ( last ? "]" : "]\n")
|
|
||||||
}else if(isPlainObject(node)){
|
|
||||||
beginChar = "{\n"
|
|
||||||
const length = Object.keys(node).length
|
|
||||||
const indentSpace = " ".repeat(level * indent)
|
|
||||||
let alignIndent = 0
|
|
||||||
Object.entries(node).forEach(([key,value],index)=>{
|
|
||||||
const isLastItem = index ===length-1
|
|
||||||
alignIndent = Math.max(getStringWidth(key),alignIndent)
|
|
||||||
let item = [`${indentSpace}"${key}"`,value]
|
|
||||||
if(Array.isArray(value) || isPlainObject(value)){
|
|
||||||
item[1] = nodeToString(value, level,isLastItem)
|
|
||||||
}else if(typeof(value)==="string"){
|
|
||||||
item[1] = `"${value.toString()}"`
|
|
||||||
}else if(typeof(value)==="number"){
|
|
||||||
item[1] = `${value.toString()}`
|
|
||||||
}else if(typeof(value)==="boolean"){
|
|
||||||
item[1] = `${value.toString()}`
|
|
||||||
}
|
|
||||||
// 如果最后一项
|
|
||||||
if(!isLastItem){
|
|
||||||
item[1] = item[1]+","
|
|
||||||
}else{
|
|
||||||
item[1] = item[1]+"\n"
|
|
||||||
}
|
|
||||||
results.push(item)
|
|
||||||
})
|
|
||||||
endChar =" ".repeat((level-1) * indent) + ( last ? "}" : "}\n")
|
|
||||||
return beginChar + results.map(item=>{
|
|
||||||
if(alignKey){
|
|
||||||
return `${escape(item[0])}${ " ".repeat(alignIndent-getStringWidth(item[0].trim())+2)}: ${escape(item[1])}`
|
|
||||||
}else{
|
|
||||||
return `${escape(item[0])}: ${escape(item[1])}`
|
|
||||||
}
|
|
||||||
}).join("\n") + endChar
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return nodeToString(obj,0,true)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
importModule,
|
importModule,
|
||||||
findModuleType,
|
findModuleType,
|
||||||
createPackageJsonFile
|
createPackageJsonFile,
|
||||||
|
isPlainObject
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
* 测试demp app的语言运行环境
|
* 测试demp app的语言运行环境
|
||||||
*/
|
*/
|
||||||
const compile = require('../packages/tools/compile.command');
|
const i18n = require('../packages/tools/languages');
|
||||||
const path = require("path")
|
const path = require("path")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
test("导入多语言包",async ()=>{
|
test("导入多语言包",done=>{
|
||||||
await compile(path.resolve(__dirname,'../packages/demo/apps/app/languages'),{moduleType:"commonjs"})
|
|
||||||
const { t,scope,languages } = require(path.join(__dirname,'../packages/demo/apps/app/languages/index.js'));
|
|
||||||
expect(t).toBeFunction()
|
expect(t).toBeFunction()
|
||||||
})
|
})
|
Loading…
x
Reference in New Issue
Block a user