This commit is contained in:
msojocs 2022-09-03 21:02:36 +08:00
parent 787474ec08
commit 17339ac0f9
4 changed files with 363 additions and 105 deletions

View File

@ -7,9 +7,9 @@ const fs = require("fs");
const args = process.argv.slice(2); const args = process.argv.slice(2);
const funcName = args[args.indexOf("-gn") + 1]; const funcName = args[args.indexOf("-gn") + 1];
const debugWXS = args.includes("-ds"); const debugWXS = args.includes("-ds");
let hasDeps = false;
const wccPath = path.resolve(__dirname, "./wcc.bin"); const wccPath = path.resolve(__dirname, "./wcc.bin");
const DEBUG_OUTPUT = process.env["WX_DEBUG_COMPILER_OUTPUT"]; const DEBUG_OUTPUT = process.env["WX_DEBUG_COMPILER_OUTPUT"];
const globalData = {};
// 向错误输出流写入信息 // 向错误输出流写入信息
process.stderr.write(`环境及执行信息: process.stderr.write(`环境及执行信息:
@ -25,44 +25,26 @@ const COMMON_PREFIX =
const FUNC_PREFIX = `=function(_,_v,_n,_p,_s,_wp,_wl,$gwn,$gwl,$gwh,wh,$gstack,$gwrt,gra,grb,TestTest,wfor,_ca,_da,_r,_rz,_o,_oz,_1,_1z,_2,_2z,_m,_mz,nv_getDate,nv_getRegExp,nv_console,nv_parseInt,nv_parseFloat,nv_isNaN,nv_isFinite,nv_decodeURI,nv_decodeURIComponent,nv_encodeURI,nv_encodeURIComponent,$gdc,nv_JSON,_af,_gv,_ai,_grp,_gd,_gapi,$ixc,_ic,_w,_ev,_tsd){return function(path,global){\u000aif(typeof global==='undefined'){if (typeof __GWX_GLOBAL__==='undefined')global={};else global=__GWX_GLOBAL__;}if(typeof __WXML_GLOBAL__ === 'undefined') {__WXML_GLOBAL__={};\u000a}__WXML_GLOBAL__.modules = __WXML_GLOBAL__.modules || {};\u000avar e_={}\u000aif(typeof(global.entrys)==='undefined')global.entrys={};e_=global.entrys;\u000avar d_={}\u000aif(typeof(global.defines)==='undefined')global.defines={};d_=global.defines;\u000avar f_={}\u000aif(typeof(global.modules)==='undefined')global.modules={};f_=global.modules || {};\u000avar p_={}\u000a`; const FUNC_PREFIX = `=function(_,_v,_n,_p,_s,_wp,_wl,$gwn,$gwl,$gwh,wh,$gstack,$gwrt,gra,grb,TestTest,wfor,_ca,_da,_r,_rz,_o,_oz,_1,_1z,_2,_2z,_m,_mz,nv_getDate,nv_getRegExp,nv_console,nv_parseInt,nv_parseFloat,nv_isNaN,nv_isFinite,nv_decodeURI,nv_decodeURIComponent,nv_encodeURI,nv_encodeURIComponent,$gdc,nv_JSON,_af,_gv,_ai,_grp,_gd,_gapi,$ixc,_ic,_w,_ev,_tsd){return function(path,global){\u000aif(typeof global==='undefined'){if (typeof __GWX_GLOBAL__==='undefined')global={};else global=__GWX_GLOBAL__;}if(typeof __WXML_GLOBAL__ === 'undefined') {__WXML_GLOBAL__={};\u000a}__WXML_GLOBAL__.modules = __WXML_GLOBAL__.modules || {};\u000avar e_={}\u000aif(typeof(global.entrys)==='undefined')global.entrys={};e_=global.entrys;\u000avar d_={}\u000aif(typeof(global.defines)==='undefined')global.defines={};d_=global.defines;\u000avar f_={}\u000aif(typeof(global.modules)==='undefined')global.modules={};f_=global.modules || {};\u000avar p_={}\u000a`;
function parseDeps(source, x, pageConfig){ function parseDeps(source, x, pageConfig){
DEBUG_OUTPUT && process.stderr.write(`parseDeps - x:${x}\r\n${JSON.stringify(pageConfig, null, 4)}`); DEBUG_OUTPUT && process.stderr.write(`\r\nunNeedFiles:${x}\r\n${JSON.stringify(globalData.unNeedFiles, null, 4)}`);
// DEBUG_OUTPUT && process.stderr.write(`\r\nparseDeps - x:${x}\r\n${JSON.stringify(pageConfig, null, 4)}`);
// 插入引用信息 // 插入引用信息
let dep_x = `var x=[`; let dep_x = `var x=[`;
let dep_gz = ""; let dep_gz = "";
let dep_d_ = ""; let dep_d_ = "";
let t_x = []; let t_x = globalData.unNeedFiles.filter(e=>!globalData.depFiles[e]);
if (funcName !== "$gwx") {
// TODO: 可能存在自定义目录无法识别的问题? DEBUG_OUTPUT && process.stderr.write(`\r\nt_x:${x}\r\n${JSON.stringify(t_x, null, 4)}`);
// 非标准函数名
t_x = x.filter(
(ele) =>
ele.startsWith("./miniprogram_npm") ||
ele.startsWith("../") ||
ele.startsWith("./page")
);
}
for (let key in pageConfig) {
if (pageConfig[key].deps.length > 0) {
for (let dep of pageConfig[key].deps) {
let index = x.indexOf(dep);
if (index < 0) {
continue;
}
// x
if (!t_x.includes(dep)) t_x.push(dep);
}
}
}
let i = 1; let i = 1;
for (let dep of t_x) { for (let dep of globalData.unNeedFiles) {
if (dep.startsWith("../")) continue; if(dep.startsWith('../'))continue;
const idx = x.indexOf(dep)
// 处理../../
// TODO: 不同目录的文件,引用不同文件,但是引用路径形式相同
// if(globalData.depFiles[dep])
// dep = globalData.depFiles[dep]
// d_ // d_
const d_Exp = `d_\\[x\\[${x.indexOf( const d_Exp = `d_\\[x\\[${idx}\\]\\]={}\n[\\s\\S]*?e_\\[x\\[${idx}\\]\\]={f:m\\d+,j:\\[.*?\\],i:\\[.*?\\],ti:\\[(.*?)\\],ic:\\[.*?\\]}\n`;
dep
)}\\]\\]={}\n[\\s\\S]*?e_\\[x\\[${x.indexOf(
dep
)}\\]\\]={f:m\\d+,j:\\[.*?\\],i:\\[.*?\\],ti:\\[(.*?)\\],ic:\\[.*?\\]}\n`;
let m0 = source.match(new RegExp(d_Exp)); let m0 = source.match(new RegExp(d_Exp));
let m0_str = m0[0]; let m0_str = m0[0];
@ -79,7 +61,7 @@ function parseDeps(source, x, pageConfig){
dep_d_ += dep_d_ +=
m0_str m0_str
.replace( .replace(
new RegExp(`x\\[${x.indexOf(dep)}\\]`, "g"), new RegExp(`x\\[${idx}\\]`, "g"),
`x[${t_x.indexOf(dep)}]` `x[${t_x.indexOf(dep)}]`
) )
.replace( .replace(
@ -200,12 +182,12 @@ function genCommonContent_LLW(source, pageConfig, x = []) {
const depsData = parseDeps(source, x, pageConfig) const depsData = parseDeps(source, x, pageConfig)
common += depsData.dep_gz; common += depsData.dep_gz;
// nv_require // nv_require
const nv_require = source.match( // const nv_require = source.match(
new RegExp( // new RegExp(
`(__WXML_GLOBAL__\\.ops_set\\.\\${funcName}=[\\s\\S]*)var x=\\[` // `(__WXML_GLOBAL__\\.ops_set\\.\\${funcName}=[\\s\\S]*)var x=\\[`
) // )
); // );
common += nv_require[1]; common += globalData.nv_require;
common += depsData.dep_x + depsData.dep_d_; common += depsData.dep_x + depsData.dep_d_;
common += common +=
@ -232,20 +214,18 @@ function genFunctionContent_LLA(wxmlName, config = {}, source, x) {
let content = `var cs = cs || [];\u000a${config.funcName}${FUNC_PREFIX}`; let content = `var cs = cs || [];\u000a${config.funcName}${FUNC_PREFIX}`;
// cs // cs
const cs = source.match(/var cs([\s\S]*?)function gz/);
content += content +=
"var cs = cs || [];" + "var cs = cs || [];" +
cs[1].replace(new RegExp(`\\${funcName}`, "g"), config.funcName); globalData.cs.replace(new RegExp(`\\${funcName}`, "g"), config.funcName);
// template 检测 模板处理位于二者之间: d_[x[index]]={} ---{template}-- var m0; x[index]中index为wxml在x数组中的索引, m0中数字为当前函数代码 // template 检测 模板处理位于二者之间: d_[x[index]]={} ---{template}-- var m0; x[index]中index为wxml在x数组中的索引, m0中数字为当前函数代码
const templateReg = source.match(new RegExp(`d_\\[x\\[${x.indexOf(`./${wxmlName}.wxml`)}\\]\\]=\\{\\}\n([\\s\\S]*?)\nvar m${config.index}=`)) const templateReg = source.match(new RegExp(`d_\\[x\\[${x.indexOf(`./${wxmlName}.wxml`)}\\]\\]=\\{\\}\n([\\s\\S]*?)\nvar m${config.num}=`))
DEBUG_OUTPUT && process.stderr.write(`genFunctionContent_LLA - wxmlName: ${wxmlName} debugWXS: ${!!debugWXS}, hasDeps: ${!!hasDeps}, templateReg: ${!!templateReg}\n${JSON.stringify(x)} ${JSON.stringify(config)}\n\n`)
// gz函数 // gz函数
let gz; let gz;
if (!debugWXS && !hasDeps && !templateReg) { if (!debugWXS && globalData.depFiles.length === 0 && !templateReg) {
const exp = `function gz\\${funcName}_${ const exp = `function gz\\${funcName}_${
config.index + 1 config.num + 1
}\\(\\)\\{[\\s\\S]*?\\)\\}`; }\\(\\)\\{[\\s\\S]*?\\)\\}`;
gz = source.match(new RegExp(exp)); gz = source.match(new RegExp(exp));
gz = gz =
@ -257,9 +237,9 @@ function genFunctionContent_LLA(wxmlName, config = {}, source, x) {
} else { } else {
// gz函数2 // gz函数2
const exp = `function gz\\${funcName}_${ const exp = `function gz\\${funcName}_${
config.index + 1 config.num + 1
}\\(\\)\\{[\\s\\S]*?__WXML_GLOBAL__\\.ops_cached\\.\\${funcName}_${ }\\(\\)\\{[\\s\\S]*?__WXML_GLOBAL__\\.ops_cached\\.\\${funcName}_${
config.index + 1 config.num + 1
}\n}`; }\n}`;
gz = source.match(new RegExp(exp)); gz = source.match(new RegExp(exp));
gz = gz[0].replace( gz = gz[0].replace(
@ -280,40 +260,56 @@ function genFunctionContent_LLA(wxmlName, config = {}, source, x) {
.replace(new RegExp(`\\${funcName}`, "g"), config.funcName); .replace(new RegExp(`\\${funcName}`, "g"), config.funcName);
content += debug; content += debug;
// m0 --- m{index} // m0 --- m{num}
content += `var x=['./${wxmlName}.wxml'`; content += `var x=['./${wxmlName}.wxml'`;
if (!debugWXS && !hasDeps && !templateReg) { if (!debugWXS && globalData.depFiles.length === 0 && !templateReg) {
content += `];d_[x[0]]={}\u000a`; content += `];d_[x[0]]={}\u000a`;
// e_[x[0]]|| // e_[x[0]]||
content += `var m0=function(e,s,r,gg){\u000avar z=gz${config.funcName}_1()\u000areturn r\u000a}\u000ae_[x[0]]={f:m0,j:[],i:[],ti:[],ic:[]}`; content += `var m0=function(e,s,r,gg){\u000avar z=gz${config.funcName}_1()\u000areturn r\u000a}\u000ae_[x[0]]={f:m0,j:[],i:[],ti:[],ic:[]}`;
} else { } else {
// m0 --- m{index} // m0 --- m{num}
const m0Exp = `var m${config.index}=function\\(e,s,r,gg\\){[\\s\\S]*e_\\[x\\[(\\d+)\\]\\]={f:m${config.index},j:\\[.*?\\],i:\\[.*?\\],ti:\\[(.*?)\\],ic:\\[.*?\\]}`; const m0Exp = `var m${config.num}=function\\(e,s,r,gg\\){[\\s\\S]*e_\\[x\\[(\\d+)\\]\\]={f:m${config.num},j:\\[.*?\\],i:\\[.*?\\],ti:\\[(.*?)\\],ic:\\[.*?\\]}`;
let m0 = source.match(new RegExp(m0Exp)); let m0 = source.match(new RegExp(m0Exp));
let m0_str = m0[0].replace(new RegExp(`m${config.index}`, "g"), "m0"); let m0_str = m0[0].replace(new RegExp(`m${config.num}`, "g"), "m0");
const cur_x = m0[1]; // cur_x与config.index不一定相同 const aiDataM = m0_str.match(/_ai\([\s\S]*?cs\.push/)
const cur_x = m0[1]; // cur_x与config.num不一定相同
m0_str = m0_str.replace(new RegExp(`x\\[${cur_x}\\]`, "g"), "x[0]"); m0_str = m0_str.replace(new RegExp(`x\\[${cur_x}\\]`, "g"), "x[0]");
// _ai引用处理
const depIndex = m0[2].match(/\d+/g); const depIndex = m0[2].match(/\d+/g);
let aiArr,tiArr = []
if (depIndex) { if (depIndex) {
let i = 1; // process.stderr.write(`\r\n-----\r\n`)
for (let index of depIndex) { // process.stderr.write(m0_str)
content += `,'${x[index]}'`; aiArr = aiDataM[0].split('\n');
m0_str = m0_str.replace( depIndex.forEach((v, i)=>{
new RegExp(`x\\[${index}\\]`, "g"), content += `,'${x[v]}'`;
`x[${i++}]` aiArr[i] = aiArr[i].replace(`x[${v}]`, `x[${i + 1}]`).replace(`x[${cur_x}]`, `x[0]`)
); tiArr.push(`x[${i + 1}]`)
} })
} }
content += `];d_[x[0]]={}\u000a`; content += `];d_[x[0]]={}\u000a`;
templateReg && (content += templateReg[1].replace( templateReg && (content += templateReg[1].replace(
new RegExp(`\\${funcName}\\_\\d+`, "g"), new RegExp(`\\${funcName}\\_\\d+`, "g"),
`${config.funcName}_1` `${config.funcName}_1`
) + '\n') ) + '\n')
m0_str = m0_str.replace( m0_str = m0_str.replace(
new RegExp(`x\\[${config.index}\\]`, "g"), new RegExp(`x\\[${config.num}\\]`, "g"),
"x[0]" "x[0]"
) )
// .replace('={f', '=e_[x[0]]||{f');
// _ai引用处理
if (depIndex) {
m0_str = m0_str.replace(
new RegExp(`_ai\\([\\s\\S]*?cs\\.push`, "g"),
`${aiArr.join('\n')}`
)
// fix ti
m0_str = m0_str.replace(/ti:\[.*?\]\],/, `ti:[${tiArr.join(',')}],`);
}
content += m0_str.replace( content += m0_str.replace(
new RegExp(`\\${funcName}\\_\\d+`, "g"), new RegExp(`\\${funcName}\\_\\d+`, "g"),
`${config.funcName}_1` `${config.funcName}_1`
@ -345,12 +341,12 @@ function genCommonContent_LLA(source, pageConfig, x) {
common += depsData.dep_gz; common += depsData.dep_gz;
// nv_require // nv_require
const nv_require = source.match( // const nv_require = source.match(
new RegExp( // new RegExp(
`(__WXML_GLOBAL__\\.ops_set\\.\\${funcName}=[\\s\\S]*)var x=\\[` // `(__WXML_GLOBAL__\\.ops_set\\.\\${funcName}=[\\s\\S]*)var x=\\[`
) // )
); // );
common += nv_require[1]; common += globalData.nv_require;
common += depsData.dep_x + depsData.dep_d_; common += depsData.dep_x + depsData.dep_d_;
common += common +=
@ -372,6 +368,88 @@ function genCommonContent_LLA(source, pageConfig, x) {
return common; return common;
} }
// genCommonContent_LLA END // genCommonContent_LLA END
const wxmlParser = (()=>{
const getFileArr = (code)=>{
// 获取x数组并解析
const indexArr = eval(code.match(/var x=(\[.*\]);/)[1]);
return indexArr;
}
const parseGZFuncMap = (code)=>{
const exp = `function gz\\$(.*?)\\(\\)\\{[\\s\\S]*?__WXML_GLOBAL__\\.ops_cached\\.\\$.*?\n}`;
const gzs = code.matchAll(new RegExp(exp, 'g'));
const gzFunc = {}
for (const gz of gzs) {
gzFunc[`gz$${gz[1]}`] = gz[0];
}
return gzFunc;
}
const parseDepsMap = (code, fileArr)=>{
// 获取所有依赖 _ai函数 被引入的文件, 文件
// _ai(i, depPath, e, mainPath, r, c)
const deps = code.matchAll(
/_ai\(.*?,x\[(\d+)\],.*?,x\[(\d+)\],\d+,\d+\)/g
);
// 处理依赖
const depsResult = {}
const depsFiles = {}
for (let dep of deps) {
// if(depsResult[dep[2]]){
// depsResult[dep[2]].push(deps[1])
// }else{
// depsResult[dep[2]] = [deps[1]]
// }
const file = fileArr[dep[2]]
let depFile = fileArr[dep[1]]
depsFiles[depFile] = file
depFile = `./${path.join(path.dirname(file), depFile)}`
if(depsResult[file]){
depsResult[file].unshift(depFile)
// depsResult[file].push(dep[1])
}else{
depsResult[file] = [depFile]
// depsResult[file] = [dep[1]]
}
}
return {
relation: depsResult,
depsFiles
}
}
const parseDMEMap = (code)=>{
// ti: import依赖引入
const regExp = /d_\[x\[(\d+)\]\]={}[\s\S]*?e_\[x\[\d+\]\]={f:m\d+,j:\[.*?\],i:\[.*?\],ti:\[(.*?)\],ic:\[.*?\]}/g;
const ms = code.matchAll(regExp);
const mFunc = {}
for (const m of ms) {
mFunc[`x[${m[1]}]`] = m[0]
}
return mFunc
}
const parseNvRequireCode = (code)=>{
const ret = code.match(/(__WXML_GLOBAL__\.ops_set\.\$.*?=[\s\S]*)var x=\[/)
return ret[1]
}
const parseCSCode = (code)=>{
const cs = code.match(/var cs([\s\S]*?)function gz/);
return cs[1];
}
const parse = (data, code)=>{
data.nv_require = parseNvRequireCode(code)
data.cs = parseCSCode(code)
data.gz = parseGZFuncMap(code)
data.fileArr = getFileArr(code);
const dep_t = parseDepsMap(code, data.fileArr)
data.deps = dep_t.relation
data.depFiles = dep_t.depsFiles
data.dme = parseDMEMap(code)
}
return {
parse
}
})()
if (args.includes("-llw")) { if (args.includes("-llw")) {
// 参数预处理 // 参数预处理
const split_mark = args[args.indexOf("--split") + 1]; const split_mark = args[args.indexOf("--split") + 1];
@ -483,7 +561,7 @@ if (args.includes("-llw")) {
// 参数预处理 // 参数预处理
const split_mark = args[args.indexOf("--split") + 1]; const split_mark = args[args.indexOf("--split") + 1];
const needArrStr = args[args.indexOf("-lla") + 1] const needArrStr = args[args.indexOf("-lla") + 1]
const needArr = needArrStr.split(split_mark); const needArr = needArrStr.split(split_mark).sort();
const argss = args.filter((e) => e != "-lla" && e != needArrStr); const argss = args.filter((e) => e != "-lla" && e != needArrStr);
const wcc = spawn(wccPath, argss, { const wcc = spawn(wccPath, argss, {
cwd: process.cwd(), cwd: process.cwd(),
@ -510,38 +588,38 @@ if (args.includes("-llw")) {
__COMMON__: funcName, __COMMON__: funcName,
}, },
}; };
const indexArr = eval(str.match(/var x=(\[.*\]);/)[1]); wxmlParser.parse(globalData, str);
const indexArr = globalData.fileArr;
const pageConfig = {}; const pageConfig = {};
globalData.unNeedFiles = indexArr.filter(e=>!needArr.includes(e.substring(0, e.length - 5)))
// for (let i = 0; i < globalData.unNeedFiles.length; i++) {
// const subFile = globalData.unNeedFiles[i];
// if(globalData.depFiles[subFile]){
// globalData.unNeedFiles[i] = globalData.depFiles[subFile]
// }
// }
process.stderr.write('\r\ndepFiles: ' + JSON.stringify(globalData.depFiles, null, 4))
process.stderr.write('\r\depTree: ' + JSON.stringify(globalData.deps, null, 4))
process.stderr.write('\r\indexArr: ' + JSON.stringify(indexArr, null, 4))
process.stderr.write('\r\nneedArr:' + JSON.stringify(needArr, null, 4))
let i = 0; let i = 0;
indexArr.forEach((ele, index) => { indexArr.forEach((ele) => {
if (!ele.startsWith("../")) { if(!globalData.depFiles[ele]){
pageConfig[ele.substring(2, ele.length - 5)] = { pageConfig[ele.substring(2, ele.length - 5)] = {
funcName: `${funcName}_XC_`, funcName: `${funcName}_XC_`,
num: 0, num: i++,
index: i, deps: globalData.deps[ele] || [],
deps: [],
}; };
i++;
} }
}); });
// 引入解析
const deps = str.matchAll(
/_ai\(.*?,x\[(\d+)\],.*?,x\[(\d+)\],\d+,\d+\)/g
);
for (let dep of deps) {
hasDeps = true;
// console.log(dep[1]) // 被引用文件下标
// console.log(dep[2]) // 引用文件下标
const target = indexArr[dep[2]];
pageConfig[target.substring(2, target.length - 5)].deps.unshift(
"./" + path.join(path.dirname(target), indexArr[dep[1]])
);
}
i = 0; i = 0;
for (let key in pageConfig) { for (let key in pageConfig) {
if (needArr.includes("./" + key)) { if (needArr.includes("./" + key)) {
pageConfig[key].funcName += i++; pageConfig[key].funcName += i++;
// pageConfig[key].num = i++;
resultObj.generateFunctionName[key] = resultObj.generateFunctionName[key] =
pageConfig[key].funcName; pageConfig[key].funcName;
resultObj.generateFunctionContent[key] = resultObj.generateFunctionContent[key] =

View File

@ -11,7 +11,7 @@ describe("wcc - lla", function () {
// console.error('failed', this.currentTest) // console.error('failed', this.currentTest)
// } // }
// }) // })
it("初次加载1", async function () { it("初次加载1 #变量名不同导致比较不通过,需要手动检查", async function () {
const projectPath = path.resolve( const projectPath = path.resolve(
__dirname, __dirname,
"../../examples/miniprogram-demo/miniprogram" "../../examples/miniprogram-demo/miniprogram"
@ -47,11 +47,11 @@ describe("wcc - lla", function () {
__dirname, __dirname,
`miniprogram-demo/${this.test.title}` `miniprogram-demo/${this.test.title}`
); );
const n = JSON.parse(await node.wcc(args, projectPath, storagePath));
const w = JSON.parse(await wine.wcc(args, projectPath));
try { try {
fs.mkdirSync(storagePath, { recursive: true }); fs.mkdirSync(storagePath, { recursive: true });
} catch (error) {} } catch (error) {}
const n = JSON.parse(await node.wcc(args, projectPath, storagePath));
const w = JSON.parse(await wine.wcc(args, projectPath));
fs.writeFileSync( fs.writeFileSync(
`${storagePath}/wine-output.json`, `${storagePath}/wine-output.json`,
JSON.stringify(w, null, 4) JSON.stringify(w, null, 4)
@ -115,8 +115,6 @@ describe("wcc - lla", function () {
"-gn", "-gn",
"$7061636b616765436f6d706f6e656e742f", "$7061636b616765436f6d706f6e656e742f",
]; ];
const w = JSON.parse(await wine.wcc(args, projectPath));
const n = JSON.parse(await node.wcc(args, projectPath));
const storagePath = path.resolve( const storagePath = path.resolve(
__dirname, __dirname,
`miniprogram-demo/${this.test.title}` `miniprogram-demo/${this.test.title}`
@ -124,6 +122,8 @@ describe("wcc - lla", function () {
try { try {
fs.mkdirSync(storagePath, { recursive: true }); fs.mkdirSync(storagePath, { recursive: true });
} catch (error) {} } catch (error) {}
const w = JSON.parse(await wine.wcc(args, projectPath));
const n = JSON.parse(await node.wcc(args, projectPath, storagePath));
fs.writeFileSync( fs.writeFileSync(
`${storagePath}/wine-output.json`, `${storagePath}/wine-output.json`,
JSON.stringify(w, null, 4) JSON.stringify(w, null, 4)
@ -157,8 +157,6 @@ describe("wcc - lla", function () {
"-gn", "-gn",
"$7061636b616765536b796c696e652f", "$7061636b616765536b796c696e652f",
]; ];
const w = JSON.parse(await wine.wcc(args, projectPath));
const n = JSON.parse(await node.wcc(args, projectPath));
const storagePath = path.resolve( const storagePath = path.resolve(
__dirname, __dirname,
`miniprogram-demo/${this.test.title}` `miniprogram-demo/${this.test.title}`
@ -166,6 +164,8 @@ describe("wcc - lla", function () {
try { try {
fs.mkdirSync(storagePath, { recursive: true }); fs.mkdirSync(storagePath, { recursive: true });
} catch (error) {} } catch (error) {}
const w = JSON.parse(await wine.wcc(args, projectPath));
const n = JSON.parse(await node.wcc(args, projectPath, storagePath));
fs.writeFileSync( fs.writeFileSync(
`${storagePath}/wine-output.json`, `${storagePath}/wine-output.json`,
JSON.stringify(w, null, 4) JSON.stringify(w, null, 4)
@ -176,7 +176,7 @@ describe("wcc - lla", function () {
); );
assert.deepEqual(w, n); assert.deepEqual(w, n);
}); });
it("组件 - skyline - 自定义路由", async function () { it("组件 - skyline - 自定义路由 #变量名不同导致比较不通过,需要手动检查", async function () {
const projectPath = path.resolve( const projectPath = path.resolve(
__dirname, __dirname,
"../../examples/miniprogram-demo/miniprogram/" "../../examples/miniprogram-demo/miniprogram/"
@ -208,8 +208,6 @@ describe("wcc - lla", function () {
"-gn", "-gn",
"$gwx", "$gwx",
]; ];
const w = JSON.parse(await wine.wcc(args, projectPath));
const n = JSON.parse(await node.wcc(args, projectPath));
const storagePath = path.resolve( const storagePath = path.resolve(
__dirname, __dirname,
`miniprogram-demo/${this.test.title}` `miniprogram-demo/${this.test.title}`
@ -217,6 +215,8 @@ describe("wcc - lla", function () {
try { try {
fs.mkdirSync(storagePath, { recursive: true }); fs.mkdirSync(storagePath, { recursive: true });
} catch (error) {} } catch (error) {}
const w = JSON.parse(await wine.wcc(args, projectPath));
const n = JSON.parse(await node.wcc(args, projectPath, storagePath));
fs.writeFileSync( fs.writeFileSync(
`${storagePath}/wine-output.json`, `${storagePath}/wine-output.json`,
JSON.stringify(w, null, 4) JSON.stringify(w, null, 4)
@ -301,8 +301,6 @@ describe("wcc - lla", function () {
"-gn", "-gn",
"$7061636b616765457874656e642f", "$7061636b616765457874656e642f",
]; ];
const w = JSON.parse(await wine.wcc(args, projectPath));
const n = JSON.parse(await node.wcc(args, projectPath));
const storagePath = path.resolve( const storagePath = path.resolve(
__dirname, __dirname,
`miniprogram-demo/${this.test.title}` `miniprogram-demo/${this.test.title}`
@ -310,6 +308,8 @@ describe("wcc - lla", function () {
try { try {
fs.mkdirSync(storagePath, { recursive: true }); fs.mkdirSync(storagePath, { recursive: true });
} catch (error) {} } catch (error) {}
const w = JSON.parse(await wine.wcc(args, projectPath));
const n = JSON.parse(await node.wcc(args, projectPath, storagePath));
fs.writeFileSync( fs.writeFileSync(
`${storagePath}/wine-output.json`, `${storagePath}/wine-output.json`,
JSON.stringify(w, null, 4) JSON.stringify(w, null, 4)
@ -416,8 +416,6 @@ describe("wcc - lla", function () {
"-gn", "-gn",
"$7061636b6167654150492f", "$7061636b6167654150492f",
]; ];
const w = JSON.parse(await wine.wcc(args, projectPath));
const n = JSON.parse(await node.wcc(args, projectPath));
const storagePath = path.resolve( const storagePath = path.resolve(
__dirname, __dirname,
`miniprogram-demo/${this.test.title}` `miniprogram-demo/${this.test.title}`
@ -425,6 +423,8 @@ describe("wcc - lla", function () {
try { try {
fs.mkdirSync(storagePath, { recursive: true }); fs.mkdirSync(storagePath, { recursive: true });
} catch (error) {} } catch (error) {}
const w = JSON.parse(await wine.wcc(args, projectPath));
const n = JSON.parse(await node.wcc(args, projectPath, storagePath));
fs.writeFileSync( fs.writeFileSync(
`${storagePath}/wine-output.json`, `${storagePath}/wine-output.json`,
JSON.stringify(w, null, 4) JSON.stringify(w, null, 4)

84
test/wcc/lla/raw-parse.js Normal file
View File

@ -0,0 +1,84 @@
const path = require("path");
const fs = require("fs");
const { spawn } = require("child_process");
const wxmlParser = (()=>{
const getFileArr = (code)=>{
// 获取x数组并解析
const indexArr = eval(code.match(/var x=(\[.*\]);/)[1]);
return indexArr;
}
const parseGZFuncMap = (code)=>{
const exp = `function gz\\$(.*?)\\(\\)\\{[\\s\\S]*?__WXML_GLOBAL__\\.ops_cached\\.\\$.*?\n}`;
const gzs = code.matchAll(new RegExp(exp, 'g'));
const gzFunc = {}
for (const gz of gzs) {
gzFunc[`gz$${gz[1]}`] = gz[0];
}
return gzFunc;
}
const parseDepsMap = (code, fileArr)=>{
// 获取所有依赖 _ai函数 被引入的文件, 文件
// _ai(i, depPath, e, mainPath, r, c)
const deps = code.matchAll(
/_ai\(.*?,x\[(\d+)\],.*?,x\[(\d+)\],\d+,\d+\)/g
);
// 处理依赖
const depsResult = {}
for (let dep of deps) {
const file = fileArr[dep[2]]
let depFile = fileArr[dep[1]]
depFile = `./${path.join(path.dirname(file), depFile)}`
if(depsResult[file]){
depsResult[file].push(depFile)
}else{
depsResult[file] = [depFile]
}
}
return depsResult
}
const parseDMEMap = (code)=>{
// ti: import依赖引入
const regExp = /d_\[x\[(\d+)\]\]={}[\s\S]*?e_\[x\[\d+\]\]={f:m\d+,j:\[.*?\],i:\[.*?\],ti:\[(.*?)\],ic:\[.*?\]}/g;
const ms = code.matchAll(regExp);
const mFunc = {}
for (const m of ms) {
mFunc[`x[${m[1]}]`] = m[0]
}
return mFunc
}
const parseNvRequireCode = (code)=>{
const ret = code.match(/(__WXML_GLOBAL__\.ops_set\.\$.*?=[\s\S]*)var x=\[/)
return ret[1]
}
const parseCSCode = (code)=>{
const cs = code.match(/var cs([\s\S]*?)function gz/);
return cs[1];
}
const parse = (data, code)=>{
data.nv_require = parseNvRequireCode(code)
data.cs = parseCSCode(code)
data.gz = parseGZFuncMap(code)
data.fileArr = getFileArr(code);
data.deps = parseDepsMap(code, data.fileArr)
data.dme = parseDMEMap(code)
}
return {
parse
}
})()
const data = fs.readFileSync('/home/msojocs/Documents/Work/compiler/test/wcc/lla/miniprogram-demo/初次加载1/linux_output.js')
const code = data.toString();
const fileArr = wxmlParser.getFileArr(code)
// console.log(fileArr)
const gzFunc = wxmlParser.parseGZFuncMap(code)
// console.log(gzFunc)
const deps = wxmlParser.parseDepsMap(code, fileArr)
// console.log(deps)
const mFunc = wxmlParser.parseDMEMap(code)
const nvRequire = wxmlParser.parseNvRequireCode(code)
console.log(nvRequire)

96
test/wcc/lla/wcc.js Normal file
View File

@ -0,0 +1,96 @@
const path = require("path");
const fs = require("fs");
const { spawn } = require("child_process");
const wcc = (args, projectPath, outputPath = undefined) => {
const node_exec = spawn(
path.resolve(__dirname, "../../../nodejs/wcc"),
args,
{
cwd: projectPath,
env: {
WX_DEBUG_COMPILER_OUTPUT: outputPath,
},
// stdio: 'inherit'
}
);
const spwanData = [],
errData = [];
node_exec.stdout.on("data", (e) => {
spwanData.push(e);
// console.log(e.toString())
});
node_exec.stderr.on("data", (e) => {
errData.push(e);
// console.log(e.toString())
});
return new Promise((resolve, reject) => {
node_exec.on("close", (n) => {
// console.log("node n: ", n);
outputPath && require('fs').writeFileSync(`${outputPath}/linux_err.js`, Buffer.concat(errData).toString())
if (0 === n) {
let result = Buffer.concat(spwanData).toString();
// process.stdout.write(result);
// result = JSON.parse(result);
resolve(result);
} else {
process.stderr.write(Buffer.concat(errData).toString());
// process.stderr.write(Buffer.concat(spwanData).toString());
reject(n);
}
});
});
};
const test = async () => {
const projectPath = path.resolve(
__dirname,
"../../examples/miniprogram-demo/miniprogram"
);
const args = [
"-d",
"--split",
">_<1989",
"-xc",
"12>_<1989./component/navigation-bar/navigation-bar.wxml>_<19891>_<1989mp-navigation-bar>_<1989./components/navigation-bar/index.wxml>_<19891>_<1989mp-navigation-bar>_<1989./components/page-scroll/index.wxml>_<19891>_<1989mp-navigation-bar>_<1989./miniprogram_npm/miniprogram-barrage/index.wxml>_<19890>_<1989./miniprogram_npm/miniprogram-recycle-view/recycle-item.wxml>_<19890>_<1989./miniprogram_npm/miniprogram-recycle-view/recycle-view.wxml>_<19890>_<1989./miniprogram_npm/wxml-to-canvas/index.wxml>_<19890>_<1989./page/API/index.wxml>_<19892>_<1989set-tab-bar>_<1989mp-navigation-bar>_<1989./page/API/components/set-tab-bar/set-tab-bar.wxml>_<19891>_<1989mp-navigation-bar>_<1989./page/cloud/index.wxml>_<19891>_<1989mp-navigation-bar>_<1989./page/component/index.wxml>_<19891>_<1989mp-navigation-bar>_<1989./page/extend/index.wxml>_<19891>_<1989mp-navigation-bar",
"-lla",
"./component/navigation-bar/navigation-bar>_<1989./components/navigation-bar/index>_<1989./components/page-scroll/index>_<1989./miniprogram_npm/miniprogram-barrage/index>_<1989./miniprogram_npm/miniprogram-recycle-view/recycle-item>_<1989./miniprogram_npm/miniprogram-recycle-view/recycle-view>_<1989./miniprogram_npm/wxml-to-canvas/index>_<1989./page/API/index>_<1989./page/API/components/set-tab-bar/set-tab-bar>_<1989./page/cloud/index>_<1989./page/component/index>_<1989./page/extend/index",
"./common/foot.wxml",
"./common/head.wxml",
"./component/navigation-bar/navigation-bar.wxml",
"./components/navigation-bar/index.wxml",
"./components/page-scroll/index.wxml",
"./miniprogram_npm/miniprogram-barrage/index.wxml",
"./miniprogram_npm/miniprogram-recycle-view/recycle-item.wxml",
"./miniprogram_npm/miniprogram-recycle-view/recycle-view.wxml",
"./miniprogram_npm/wxml-to-canvas/index.wxml",
"./page/API/index.wxml",
"./page/API/components/set-tab-bar/set-tab-bar.wxml",
"./page/cloud/index.wxml",
"./page/common/foot.wxml",
"./page/common/head.wxml",
"./page/component/index.wxml",
"./page/extend/index.wxml",
"-gn",
"$gwx",
];
const storagePath = path.resolve(
__dirname,
`miniprogram-demo/tmp`
);
try {
fs.mkdirSync(storagePath, { recursive: true });
} catch (error) {}
const n = JSON.parse(await wcc(args, projectPath, storagePath));
// const w = JSON.parse(await wine.wcc(args, projectPath));
// fs.writeFileSync(
// `${storagePath}/wine-output.json`,
// JSON.stringify(w, null, 4)
// );
fs.writeFileSync(
`${storagePath}/node-output.json`,
JSON.stringify(n, null, 4)
);
};
test();