UNPKG

use-on-demand

Version:
476 lines 22.2 kB
import { __assign, __read, __spread } from "tslib"; import fs from 'fs'; import path from 'path'; import { xX_SObject_Helper, xX_Zepto_TypeDetectE } from '../../symbol-object/SObject_Helper'; import { xX_ExceptionError_Helper } from '../../exception-error/ExceptionError_Helper'; import { xX_SRegexp_Helper } from '../../symbol-regexp/SRegexp_Helper'; /** * 格式化,目录分隔符。 * * 转化【Windows的反斜杠分隔符】为通用格式 * 0.参考资料:https://stackoverflow.com/a/63251716/6264260 */ function formatDirSep(filePath) { // filePath: path.normalize(path.resolve(file)), // 转化【Windows的反斜杠分隔符】为通用格式 // WARN 似乎不起作用 return filePath.split(path.sep).join(path.posix.sep); } /** * 从数组中,根据Value值,移除(遇到的)第一个元素。 * 0.参考资料: * [javascript-如何通过值从数组中删除项目? - 堆栈溢出](https://stackoverflow.com/a/3954451/6264260) * 1.只移除一个。 * 2.如果有多个的情况下,只会移除第一个。 */ function removeOneElement_fisrtOccur_inArray(target, arr) { var index = arr.indexOf(target); if (index !== -1) { arr.splice(index, 1); } } /** * 查找文件: * 1.参考资料:https://stackoverflow.com/a/48665880/6264260 * */ var xX_VueI18N_Cli; (function (xX_VueI18N_Cli) { /** * 文件路径查找器 */ var FilePathSearcher = /** @class */ (function () { function FilePathSearcher() { } // TIP——————————————————————————————————————————————————————公有方法—————————————————————————————————————————————————————————————— /** * 写出【文件路径】的JSON文件。 */ FilePathSearcher.writeOut_filePaths = function (matches, fileName) { if (!fs.existsSync(Logic.GlobalCfg.outDir)) { // 如果目录不存在 fs.mkdirSync(Logic.GlobalCfg.outDir); // 生成目录 } // console.log('输出结果', matches); fs.writeFileSync(Logic.GlobalCfg.outDir + fileName, JSON.stringify(matches, null, 2)); console.log('生成了文件'); }; /** * 处理单个文件的逻辑 */ FilePathSearcher.handleSingleFile_logic = function (filePath, regex) { var fileContent = fs.readFileSync(filePath, { encoding: 'utf8', }); if (regex.test(fileContent)) { // 如果匹配到了文件。 try { return { filePath: formatDirSep(filePath), occurLines: LineHelper.regex_lineNums(fileContent, regex), }; } catch (e) { console.log('filePath', filePath); console.log('fileContent', fileContent); throw new Error(e); } } else { return null; } }; /** * 获取所有的【文件】路径,的列表。 */ FilePathSearcher.allFilesInDirectory = function (dir, __cfg) { if (__cfg === void 0) { __cfg = {}; } var cfg = __assign({ // 默认项 pattern: 'HelloWorld', needBoundary: false, ext: '' }, __cfg); if (cfg.pattern instanceof RegExp) { // 如果是正则,则强行做一个global判断 if (!cfg.pattern.global) { throw new Error(xX_ExceptionError_Helper.throwError_andLog('如果是RegExp类型,则必须加【g】关键字!')); } } /* if (!(cfg.pattern instanceof RegExp)) { console.error('必须要传入正则。因为Node.js的matchAll,似乎有点Bug,两个判断相同的正则,得出的结果不一样'); return; } else { console.log('???'); } */ var regex; if (xX_SObject_Helper.typeDetect_judgeType_inZeptoLib(cfg.pattern) === xX_Zepto_TypeDetectE.regexp) { regex = cfg.pattern; } else { // WARN 此处,必须要考虑Regexp转义 var escapedStr = xX_SRegexp_Helper.escapeRegex(cfg.pattern); console.log('转换后文本', escapedStr); // We want full words, so we use full word boundary in regex. regex = cfg.needBoundary ? new RegExp('\\b' + escapedStr + '\\b', 'g') // 两侧带有边界? : new RegExp(escapedStr, 'g'); // 两侧没必要带边界 } console.log('正则', regex); // 迭代,获取所有的子文件路径。 var files = this.__getFilesInDirectory(dir, cfg.ext); console.log("\u4ECE " + files.length + " \u4E2A\u6587\u4EF6\u4E2D\uFF0C\u8FDB\u884C\u7B5B\u9009"); return files; }; // TIP——————————————————————————————————————————————————————私有方法—————————————————————————————————————————————————————————————— /** * 递归,找到所有的【子文件】。 * 1.包括子文件夹的。 */ FilePathSearcher.__getFilesInDirectory = function (dir, ext) { var _this = this; if (ext === void 0) { ext = ''; } // 判断目录是否存在 if (!fs.existsSync(dir)) { throw new Error(xX_ExceptionError_Helper.throwError_andLog("\u6307\u5B9A\u76EE\u5F55: " + dir + " \u4E0D\u5B58\u5728\uFF01")); } var allFilePaths = []; // 读取子文件夹、子文件 fs.readdirSync(dir).forEach(function (file) { var filePath = path.join(dir, file); var stat = fs.lstatSync(filePath); if (stat.isDirectory()) { // 如果是子文件夹 var nestedFiles = _this.__getFilesInDirectory(filePath, ext); allFilePaths = allFilePaths.concat(nestedFiles); } else { // 如果是子文件 // 后缀匹配,或者,没有后缀限制 var matched = !ext || (path.extname(file) === ext); if (matched) { allFilePaths.push(filePath); } } }); return allFilePaths; }; return FilePathSearcher; }()); xX_VueI18N_Cli.FilePathSearcher = FilePathSearcher; /** * 【行数】处理工具。 */ var LineHelper = /** @class */ (function () { function LineHelper() { } // TIP——————————————————————————————————————————————————————公有方法—————————————————————————————————————————————————————————————— LineHelper.regex_lineNums = function (rawContent, regex) { // var string = "This\nstring\nhas\nmultiple\nlines.", var astring = rawContent.split('\n'); // WARN 此处,对于【\r\n】应该也是匹配的? var foundon; var lines = []; astring.forEach(function (line, number) { // const results = regex.exec(line); // FIXME 此处,不适宜用【exec】! /** * 使用matchAll,才能达到目标 * 1.FIXME 是否Node.js的【matchAll】,实现方式和ES不一样??????同样的输入,结果却不同。 */ // console.log('行', line); var testRegexp = /\$t\(/g; /** * FIXME 此处,有个非常蛋疼的Bug。两个正则完全相等,但最后匹配出的结果,却不一样。 * ???????????????????????????????????????? * ???????????????????????????????????????? */ // console.log('两个正则,是否相等', __regexSame(testRegexp, regex)); var results = new (Array.bind.apply(Array, __spread([void 0], (line.matchAll(regex)))))(); /** * FIXME 这个修复Bug的方法,非常诡异????????????????????????? * [js相同的正则多次调用test()返回的值却不同的问题_现在学习也不晚-CSDN博客](https://blog.csdn.net/qq_30100043/article/details/80092012) * 1.去掉【g】或【重置lastIndex】??? * 2. * 另外一个解释:https://stackoverflow.com/a/38910413/6264260 */ regex.lastIndex = 0; // const results = new Array(...(line.matchAll(testRegexp))); if (results && results.length > 0) { foundon = number + 1; // console.log('匹配结果', foundon, results); results.forEach(function (r) { lines.push(foundon); }); } }); return lines; }; /** * * @param targetStr 需要查找的字符串 * @param rawContent 大段文本 * @return {[]} */ LineHelper.str_lineNumbers = function (targetStr, rawContent) { if (targetStr !== '') { var i = 0, a = []; var index = -1; while ((index = rawContent.indexOf(targetStr, index + 1)) !== -1) { a.push(this.__str_lineNumberByIndex(index, rawContent)); } return a; } else { throw new Error(xX_ExceptionError_Helper.throwError_andLog('没有找到任何匹配内容!')); } }; // TIP——————————————————————————————————————————————————————私有方法—————————————————————————————————————————————————————————————— LineHelper.__str_lineNumberByIndex = function (index, string) { var line = 0; var match; var re = /(^)[\S\s]/gm; while (match = re.exec(string)) { if (match.index > index) break; line++; } return line; }; return LineHelper; }()); var KeyMap_Helper = /** @class */ (function () { function KeyMap_Helper() { } KeyMap_Helper.fromPath = function (fPath) { var str = fs.readFileSync(fPath, { encoding: 'utf-8' }); console.log('str', str); }; KeyMap_Helper.extractMap = function (obj) { // console.log('obj', obj); var resultMap = xX_SObject_Helper.flatJson_toKeyChain(obj, { superDeep: false, needRemainValue: false, }); // console.log('resultMap', resultMap); fs.writeFileSync(Logic.GlobalCfg.outDir + Logic.GlobalCfg.keyMapJsonFname, JSON.stringify(resultMap, function (k, v) { return (v === undefined ? null : v); }, 2)); }; return KeyMap_Helper; }()); xX_VueI18N_Cli.KeyMap_Helper = KeyMap_Helper; })(xX_VueI18N_Cli || (xX_VueI18N_Cli = {})); // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // var xX_VueI18N_simplifySlim_Helper; (function (xX_VueI18N_simplifySlim_Helper) { function searchOnce(pattern, outName) { if (outName === void 0) { outName = undefined; } var allFiles = xX_VueI18N_Cli.FilePathSearcher.allFilesInDirectory(Logic.GlobalCfg.targetDir, { pattern: pattern, }); var matches = []; allFiles.forEach(function (f) { var item = xX_VueI18N_Cli.FilePathSearcher.handleSingleFile_logic(f, pattern); if (item) { matches.push(item); } }); console.log('完成了所有匹配'); if (outName) { xX_VueI18N_Cli.FilePathSearcher.writeOut_filePaths(matches, outName); } return matches; } function getSurroundReg(middle) { /* return '\\$t\\([\'\"\`]' + middle + '[\'\"\`]\\)'; */ return '[$.]t\\([\'\"\`]' + middle + '[\'\"\`]\\)'; } function getBaseReg() { return /[$.]t\(/g; } function readJson_fromFileSync(path) { /* return require(Logic.GlobalCfg.outDir + path); */ return JSON.parse(fs.readFileSync(path, 'utf8')); } // TIP—————————————————————————————————————————————————————————————————————————————————————————————————————————————— var Step1_findAll = /** @class */ (function () { function Step1_findAll() { } Step1_findAll.run = function () { searchOnce(getBaseReg(), Logic.GlobalCfg.allOccurFname); }; return Step1_findAll; }()); xX_VueI18N_simplifySlim_Helper.Step1_findAll = Step1_findAll; var Step2_genKeyMap = /** @class */ (function () { function Step2_genKeyMap() { } Step2_genKeyMap.run = function () { xX_VueI18N_Cli.KeyMap_Helper.extractMap(Logic.GlobalCfg.langObj); }; return Step2_genKeyMap; }()); xX_VueI18N_simplifySlim_Helper.Step2_genKeyMap = Step2_genKeyMap; var Step3_findMap_Occur = /** @class */ (function () { function Step3_findMap_Occur() { } Step3_findMap_Occur.run = function () { // const keyMapJson = require(Logic.GlobalCfg.outDir + Logic.GlobalCfg.keyMapJsonFname); var keyMapJson = readJson_fromFileSync(Logic.GlobalCfg.outDir + Logic.GlobalCfg.keyMapJsonFname); var middleStr = "(" + Object.keys(keyMapJson).map(function (k) { return xX_SRegexp_Helper.escapeRegex(k); }).join('|') + ")"; var regExp = new RegExp(getSurroundReg(middleStr), 'g'); console.log('正则', regExp); searchOnce( // /\$t\(['"`]form.Enable['"`]\)/, regExp, Logic.GlobalCfg.keyOccurFname); }; return Step3_findMap_Occur; }()); xX_VueI18N_simplifySlim_Helper.Step3_findMap_Occur = Step3_findMap_Occur; var Step4_InCp_NotInMap = /** @class */ (function () { function Step4_InCp_NotInMap() { } Step4_InCp_NotInMap.run = function ( // needRun_Step_1_2 = false, ) { /* if (needRun_Step_1_2) { console.log('执行第一步'); Step1_findAll.run(); console.log('执行第二步'); Step2_genKeyMap.run(); } */ // const all: Array<MatchItem> = require(Logic.GlobalCfg.outDir + Logic.GlobalCfg.allOccurFname); var all = readJson_fromFileSync(Logic.GlobalCfg.outDir + Logic.GlobalCfg.allOccurFname); // console.log('all', all); // const exact: Array<MatchItem> = require(Logic.GlobalCfg.outDir + Logic.GlobalCfg.keyOccurFname); var exact = readJson_fromFileSync(Logic.GlobalCfg.outDir + Logic.GlobalCfg.keyOccurFname); // console.log('exact', exact); var reduce = all .map(function (preItem) { var preKey = preItem.filePath; var exactItem = exact.find(function (e) { return e.filePath === preKey; }); if (!exactItem) { console.log('key不存在', 'preKey', preKey); console.error('exactItem 元素不存在'); return undefined; } return { filePath: preKey, /** * FIXME 此处,必须考虑一个问题 * 1.一行中,出现了多个【$t】,则不应该都移除掉。 * 2.应该按照【出现次数】,一次一次的移除。 */ /* occurLines: preItem.occurLines.filter(preLine => { return !exactItem.occurLines.includes(preLine); // 只有不再包含的,才保留。 }), */ occurLines: function () { // TIP 此处,Exact行号数字的集合,必然是【ALL的行号数字的集合】的子集。 exactItem.occurLines.forEach(function (line) { // 开始移除 removeOneElement_fisrtOccur_inArray(line, preItem.occurLines); }); return preItem.occurLines; }(), }; }) .filter(function (e) { return !!e; }) .filter(function (e) { return e.occurLines.length > 0; }); console.log('已经做了,同一行出现多个【$t】,的判断处理。 (测试通过)'); xX_VueI18N_Cli.FilePathSearcher.writeOut_filePaths(reduce, Logic.GlobalCfg.InCp_NoInMap_FName); console.log('【组件用到 $t】比【国际化定义 $t】多的部分,已经处理完毕。'); }; return Step4_InCp_NotInMap; }()); xX_VueI18N_simplifySlim_Helper.Step4_InCp_NotInMap = Step4_InCp_NotInMap; var Step5_NotInCp_InMap = /** @class */ (function () { function Step5_NotInCp_InMap() { } Step5_NotInCp_InMap.run = function () { var keys = Object.keys( // require(Logic.GlobalCfg.outDir + Logic.GlobalCfg.keyMapJsonFname), readJson_fromFileSync(Logic.GlobalCfg.outDir + Logic.GlobalCfg.keyMapJsonFname)); var noOccurKeys = []; keys.forEach(function (k) { var regExp = new RegExp(getSurroundReg(k), 'g'); // console.log('正则', regExp); var matches = searchOnce(regExp); if (matches.length === 0) { // throw new Error(xX_ExceptionError_Helper.throwError_andLog(`${k} 未匹配到任何项`)); // console.error(`${k} 未匹配到任何项`); noOccurKeys.push(k); } }); // console.log('未出现的key', noOccurKeys); xX_VueI18N_Cli.FilePathSearcher.writeOut_filePaths(noOccurKeys, Logic.GlobalCfg.NotInCp_InMap_FName); }; return Step5_NotInCp_InMap; }()); xX_VueI18N_simplifySlim_Helper.Step5_NotInCp_InMap = Step5_NotInCp_InMap; // TIP—————————————————————————————————————————————————————————————————————————————————————————————————————————————— })(xX_VueI18N_simplifySlim_Helper || (xX_VueI18N_simplifySlim_Helper = {})); var Logic = /** @class */ (function () { function Logic() { } // Logic.search = function (cfg) { if (cfg) { Logic.GlobalCfg = __assign(__assign({}, Logic.GlobalCfg), cfg); } xX_VueI18N_simplifySlim_Helper.Step1_findAll.run(); xX_VueI18N_simplifySlim_Helper.Step2_genKeyMap.run(); xX_VueI18N_simplifySlim_Helper.Step3_findMap_Occur.run(); xX_VueI18N_simplifySlim_Helper.Step4_InCp_NotInMap.run(); xX_VueI18N_simplifySlim_Helper.Step5_NotInCp_InMap.run(); }; // Logic.GlobalCfg = { targetDir: '../../../../fgex_admin/src', outDir: './build/', keyMapJsonFname: 'map-key.json', allOccurFname: 'i18n_all_occur.json', keyOccurFname: 'i18n_key_occur.json', InCp_NoInMap_FName: 'i18n_InCp_NoInMap.json', NotInCp_InMap_FName: 'i18n_NotInCp_InMap', langObj: {}, }; return Logic; }()); /* Logic.search( require('../../../../fgex_admin/src/project-config/i18n/zh').zhCN, ); */ export var xX_VueI18N_simplifySlim_Helper_Logic = Logic; //# sourceMappingURL=VueI18N_simplifySlim_Helper.js.map