diff --git a/packages/auto-command/README.md b/packages/auto-command/README.md index 0d6b1d8..82976c2 100644 --- a/packages/auto-command/README.md +++ b/packages/auto-command/README.md @@ -33,6 +33,8 @@ ```js exports.default = { translate: { + // 文件的分隔符号,默认是'-',如果你的文件命名不是这样请加上这个选项,例如你的文件是en_US.tsx,separator应该是_ + separator: '-', // 可以是文件也可以是文件夹,但是必须符合规范的文件 type: 'dir', // locales文件路径 diff --git a/packages/auto-command/package.json b/packages/auto-command/package.json index c0bd842..22f8834 100644 --- a/packages/auto-command/package.json +++ b/packages/auto-command/package.json @@ -18,8 +18,12 @@ "inquirer": "^7.3.0", "md5": "^2.3.0", "signale": "^1.4.0", + "txp-utils": "^1.1.2", "yargs-parser": "^21.0.1" }, + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, "repository": { "type": "git", "url": "https://github.com/txp1035/txp/tree/master/packages/auto-command" diff --git a/packages/auto-command/src/translate/index.js b/packages/auto-command/src/translate/index.ts similarity index 86% rename from packages/auto-command/src/translate/index.js rename to packages/auto-command/src/translate/index.ts index 71b49da..cfc7693 100644 --- a/packages/auto-command/src/translate/index.js +++ b/packages/auto-command/src/translate/index.ts @@ -1,17 +1,18 @@ -const fs = require('fs-extra'); -const path = require('path'); -const signale = require('signale'); -const babel = require('@babel/core'); -const traverse = require('@babel/traverse').default; -const generate = require('@babel/generator').default; -const translate = require('./translate'); +import fs from 'fs-extra'; +import path from 'path'; +import signale from 'signale'; +import * as babel from '@babel/core'; +import traverse from '@babel/traverse'; +import generate from '@babel/generator'; +import utils from 'txp-utils'; + +import translate from './translate'; function getter(obj, arr) { return arr.length === 0 ? obj : getter(typeof obj === 'undefined' ? undefined : obj[arr[0]], arr.slice(1)); } - function contrastDir(before, after) { const arr = after.map(element => { const { dirName, dirContent } = element; @@ -51,8 +52,7 @@ function contrastDir(before, after) { function contrastFile(before, after) { const arr = after.map(element => { const { fileName, fileContent } = element; - const beforeContent = before.find(item => new RegExp(fileName).test(item.fileName)) - ?.fileContent; + const beforeContent = before.find(item => fileName === item.fileName)?.fileContent; if (!beforeContent) { return { fileName, fileContent }; } @@ -73,7 +73,6 @@ function contrastFile(before, after) { }); return arr; } - // 递归对象 function recursiveObj(obj, fc, nodeStrs) { const curNode = JSON.parse(JSON.stringify(nodeStrs || [])); @@ -83,12 +82,10 @@ function recursiveObj(obj, fc, nodeStrs) { Object.prototype.toString.call(obj[item]) === '[object Object]' || Object.prototype.toString.call(obj[item]) === '[object Array]' ) { - curNode.push(item); - recursiveObj(obj[item], fc, curNode); + recursiveObj(obj[item], fc, [...curNode, item]); } } } - function writeFile(path, text) { try { fs.outputFileSync(path, text); @@ -123,13 +120,20 @@ function getObj(str) { }, }); // 生成可序列号的字符串 - const ret = generate(ast).code; + const ret = generate(ast, { jsescOption: { minimal: true } }).code; + // 拿到想要的对象 - const obj = JSON.parse(ret); + let obj; + try { + obj = JSON.parse(ret); + } catch (error) { + utils.node.logger.error(ret); + throw error; + } return obj; } // 传入一个对象,替换里面的value值 -async function replaceValue(params, { from, to }) { +async function replaceValue(params, { from, to }, separator) { // 遍历对象value值成扁平数组 const newParams = JSON.parse(JSON.stringify(params)); let isLog = false; @@ -152,7 +156,7 @@ async function replaceValue(params, { from, to }) { // 数组转换成字符串,翻译,再转换成数组 const str = arr.join('\n'); - const newStr = await translate(str, { from, to }); + const newStr = await translate(str, { from, to }, separator); const newArr = newStr.split('\n'); // 新数组重新赋值给对象 let index = 0; @@ -179,13 +183,13 @@ async function replaceValue(params, { from, to }) { ); return newParams; } - // 核心翻译流程 async function core({ keep = true, type = 'dir', outDir, language = { from: 'zh-CN', to: ['en-US'] }, + separator, }) { signale.time('translate'); // 判断input是路径还是文件 @@ -215,13 +219,16 @@ async function core({ .filter(item => item); // 拿到输入文件数据 const inputFileData = outFileArr.find(item => item.dirName === language.from); - // 翻译 const allRequst = language.to.map(item => - replaceValue(inputFileData.dirContent, { - from: language.from, - to: item, - }), + replaceValue( + inputFileData.dirContent, + { + from: language.from, + to: item, + }, + separator, + ), ); const resData = await Promise.all(allRequst); const transData = language.to.map((item, index) => ({ @@ -258,16 +265,21 @@ async function core({ }); // 拿到输入文件数据 const inputFileData = outFileArr.find(item => new RegExp(language.from).test(item.fileName)); + const suffix = path.extname(inputFileData.fileName); // 翻译 const allRequst = language.to.map(item => - replaceValue(inputFileData.fileContent, { - from: language.from, - to: item, - }), + replaceValue( + inputFileData.fileContent, + { + from: language.from, + to: item, + }, + separator, + ), ); const resData = await Promise.all(allRequst); const transData = language.to.map((item, index) => ({ - fileName: item, + fileName: item + suffix, fileContent: resData[index], })); let lastData; @@ -279,12 +291,11 @@ async function core({ lastData.forEach(element => { const { fileName, fileContent } = element; writeFile( - path.join(outDir, `/${fileName}.ts`), + path.join(outDir, `/${fileName}`), `export default ${JSON.stringify(fileContent)};`, ); }); } signale.timeEnd('translate'); } - -module.exports = core; +export default core; diff --git a/packages/auto-command/src/translate/translate.js b/packages/auto-command/src/translate/translate.ts similarity index 97% rename from packages/auto-command/src/translate/translate.js rename to packages/auto-command/src/translate/translate.ts index 2d8bc7a..b11721e 100644 --- a/packages/auto-command/src/translate/translate.js +++ b/packages/auto-command/src/translate/translate.ts @@ -1,5 +1,5 @@ -const md5 = require('md5'); -const axios = require('axios'); +import md5 from 'md5'; +import axios from 'axios'; /* const umiSelectLang = { @@ -384,7 +384,18 @@ const axios = require('axios'); }; */ -async function translate(word, options = {}) { +function handelOptions(options, separator) { + if (separator) { + return { + ...options, + from: options.from.replace(separator, '-'), + to: options.to.replace(separator, '-'), + }; + } + return options; +} + +async function translate(word, options = {}, separator) { // 和umi库的SelectLang对标 import {SelectLang} from 'umi'; const defaultLangUConfigMap = { 'zh-CN': { memo: '中文', keyYouDao: 'zh-CHS' }, @@ -512,7 +523,7 @@ async function translate(word, options = {}) { // 参数 from = 'zh-CHS', to = 'EN', - } = options; + } = handelOptions(options, separator); // 随机数 const salt = Math.random(); // 生成签名 @@ -532,4 +543,5 @@ async function translate(word, options = {}) { const result = res?.data?.translation[0]; return result; } -module.exports = translate; + +export default translate; diff --git a/packages/txp-utils/package.json b/packages/txp-utils/package.json index 7bfcd90..50df045 100644 --- a/packages/txp-utils/package.json +++ b/packages/txp-utils/package.json @@ -17,5 +17,10 @@ "bugs": { "url": "https://github.com/txp1035/txp/issues" }, - "license": "MIT" + "license": "MIT", + "dependencies": { + "chalk": "^5.0.1", + "fs-extra": "^10.1.0", + "pino": "^8.1.0" + } } diff --git a/packages/txp-utils/src/index.ts b/packages/txp-utils/src/index.ts index 49b76b0..736f620 100644 --- a/packages/txp-utils/src/index.ts +++ b/packages/txp-utils/src/index.ts @@ -1,3 +1,5 @@ +import * as logger from './node/logger'; + /** 对象类 start */ /** * 描述:过滤对象,过滤掉值为null、undefined、NaN的键 @@ -144,4 +146,7 @@ export default { removal, contrast, getValidValues, + node: { + logger, + }, }; diff --git a/packages/txp-utils/src/node/logger.ts b/packages/txp-utils/src/node/logger.ts new file mode 100644 index 0000000..72c4ead --- /dev/null +++ b/packages/txp-utils/src/node/logger.ts @@ -0,0 +1,114 @@ +import { join } from 'path'; +import pino, { type Logger } from 'pino'; +// import chalk from 'chalk'; +import fsExtra from 'fs-extra'; + +const loggerDir = join(process.cwd(), 'node_modules/.cache/logger'); +const loggerPath = join(loggerDir, 'txp.log'); + + +const customLevels = { + ready: 31, + event: 32, + wait: 55, + // 虽然这里设置了 debug 为 30,但日志中还是 20,符合预期 + // 这里不加会不生成到 txp.log,transport 的 level 配置没有生效,原因不明 + debug: 30, +}; + +let logger: Logger<{ customLevels: typeof customLevels }>; +function init() { + // 不存在目录就创建它 + if (!logger) { + fsExtra.mkdirpSync(loggerDir); + logger = pino( + { + customLevels, + }, + pino.transport({ + targets: [ + { + target: require.resolve('pino/file'), + options: { + destination: loggerPath, + }, + level: 'trace', + }, + ], + }), + ); + } +} +const prefixesBase = { + wait: 'wait -', + error: 'error-', + fatal: 'fatal-', + warn: 'warn -', + ready: 'ready-', + info: 'info -', + event: 'event-', + debug: 'debug-', +}; +// const prefixesBase = { +// wait: chalk.cyan('wait') + ' -', +// error: chalk.red('error') + ' -', +// fatal: chalk.red('fatal') + ' -', +// warn: chalk.yellow('warn') + ' -', +// ready: chalk.green('ready') + ' -', +// info: chalk.cyan('info') + ' -', +// event: chalk.magenta('event') + ' -', +// debug: chalk.gray('debug') + ' -', +// }; + +const prefixes = new Proxy(prefixesBase, { + get(target, key, receiver) { + init(); + return Reflect.get(target, key, receiver); + }, +}); + +export function wait(...message: any[]) { + console.log(prefixes.wait, ...message); + logger.wait(message[0]); +} + +export function error(...message: any[]) { + console.error(prefixes.error, ...message); + logger.error(message[0]); +} + +export function warn(...message: any[]) { + console.warn(prefixes.warn, ...message); + logger.warn(message[0]); +} + +export function ready(...message: any[]) { + console.log(prefixes.ready, ...message); + logger.ready(message[0]); +} + +export function info(...message: any[]) { + console.log(prefixes.info, ...message); + logger.info(message[0]); +} + +export function event(...message: any[]) { + console.log(prefixes.event, ...message); + logger.event(message[0]); +} + +export function debug(...message: any[]) { + if (process.env.DEBUG) { + console.log(prefixes.debug, ...message); + } + logger.debug(message[0]); +} + +export function fatal(...message: any[]) { + console.error(prefixes.fatal, ...message); + logger.fatal(message[0]); +} + +export function getLatestLogFilePath() { + return loggerPath; +}