diff --git a/bin/wechat-devtools b/bin/wechat-devtools index 7ab1911..1d1621b 100755 --- a/bin/wechat-devtools +++ b/bin/wechat-devtools @@ -37,6 +37,7 @@ clean_cache() { echo "清理缓存"; rm -rf "$APPDATA/WeappCache"; rm -rf "$APPDATA/WeappVendor"; + rm -rf "$DATA_DIR/wechat_devtools" } # 检测是否有清除缓存的必要 diff --git a/compiler/wcc_node/lib/index.js b/compiler/wcc_node/lib/index.js new file mode 100644 index 0000000..4ddb516 --- /dev/null +++ b/compiler/wcc_node/lib/index.js @@ -0,0 +1,4 @@ +module.exports = { + wcc: require('./wcc'), + wcsc: require('./wcsc') +} \ No newline at end of file diff --git a/compiler/wcc_node/util.js b/compiler/wcc_node/lib/util.js similarity index 100% rename from compiler/wcc_node/util.js rename to compiler/wcc_node/lib/util.js diff --git a/compiler/wcc_node/lib/wcc.js b/compiler/wcc_node/lib/wcc.js new file mode 100644 index 0000000..b828648 --- /dev/null +++ b/compiler/wcc_node/lib/wcc.js @@ -0,0 +1,95 @@ +const util = require('./util') +const path = require('path') + +let wcc + +function loadWccAddon() { + if (wcc) return + // wcc = require('../build/Release/wcc.node') + wcc = require('../src/wcc') +} + +const fs = util.fs + +exports = async function (options) { + + loadWccAddon() + + if (!options) throw Error('options is required') + + const lazyload = !!options.lazyloadConfig + + options = Object.assign( + { + files: [], + contents: [], + replaceContent: {}, + verbose: false, + debug: false, + debugWXS: false, + showNewTree: false, + isPlugin: false, + addTestAttre: false, + independent: false, + genfuncname: '$gwx', + isCut: false, + cwd: process.cwd, + debug: false, + lazyload, + lazyloadConfig: '', + }, + options, + ) + + return new Promise(async (resolve, reject) => { + let st = Date.now() + + // 获取文件内容 + if (!options.contents.length) { + const tasks = options.files.map((file) => { + if (typeof options.replaceContent[file] === 'string') { + return options.replaceContent[file] + } + return fs.readFile(path.resolve(options.cwd, file), 'utf8') + }) + options.contents = await Promise.all(tasks) || [] + } + // console.log('wcc get files', Date.now() - st, options.contents) + let result + try { + result = wcc(options) + } catch(errmsg) { + reject(new Error(errmsg)) + return + } + + console.log('wcc get compile', Date.now() - st) + if (options.output) { + const output = path.resolve(options.cwd, options.output) + const dir = path.dirname(output) + if (lazyload) { + // lazyload 为 true时,wcc 返回值是个对象, 需要序列化一下 + result = JSON.stringify(result) + } + try { + await fs.stat(dir) + } catch (e) { + await fs.mkdir(dir, { + recursive: true, + }) + } + await fs.writeFile(output, result, 'utf8') + } + console.log('wcc get output', Date.now() - st) + resolve(result) + }) +} + +Object.defineProperty(exports, 'version', { + get() { + loadWccAddon() + return wcc.version + }, +}) + +module.exports = exports diff --git a/compiler/wcc_node/lib/wcsc.js b/compiler/wcc_node/lib/wcsc.js new file mode 100644 index 0000000..ceaea01 --- /dev/null +++ b/compiler/wcc_node/lib/wcsc.js @@ -0,0 +1,93 @@ +const util = require('./util') +const path = require('path') +const fs = util.fs + +let wcsc + +function loadWcscAddon() { + if (wcsc) return + // wcsc = require('../build/Release/wcsc.node') + wcsc = require('../src/wcsc') +} + +function tranWcscResultToObject(resultStr) { + const resultArr = resultStr.split('=') + const result = {} + for (let i = 0, len = resultArr.length; i < len && resultArr[i + 1]; i += 2) { + result[resultArr[i]] = resultArr[i + 1] + } + return result +} + +exports = async function (options) { + + loadWcscAddon() + + if (!options) throw Error('options is required') + + // avoid undefined or null + if (typeof options.subPackage !== 'string') { + delete options.subPackage + } + + if (typeof options.lazyload !== 'boolean') { + delete options.lazyload + } + + options = Object.assign( + { + files: [], + contents: [], + pageCount: 0, + cwd: process.cwd, + replaceContent: {}, + debug: false, + classPrefix: '', + lazyload: false, + }, + options, + ) + + if (!options.contents.length) { + const tasks = options.files.map((file) => { + if (typeof options.replaceContent[file] === 'string') { + return options.replaceContent[file] + } + return fs.readFile(path.resolve(options.cwd, file), 'utf8') + }) + options.contents = await Promise.all(tasks) || [] + } + + let wccResult + try { + wccResult = wcsc(options) + } catch (errmsg) { + throw new Error(errmsg) + } + + const result = options.lazyload ? wccResult : tranWcscResultToObject(wccResult) + + if (options.output) { + const output = path.resolve(options.cwd, options.output) + const dir = path.dirname(output) + try { + await fs.stat(dir) + } catch (e) { + await fs.mkdir(dir, { + recursive: true, + }) + } + await fs.writeFile(output, JSON.stringify(result, null, 2), 'utf8') + } + + return result +} + +Object.defineProperty(exports, 'version', { + get() { + loadWcscAddon() + return wcsc.version + }, +}) + +module.exports = exports diff --git a/compiler/wcc_node/package.json b/compiler/wcc_node/package.json index 35f4dfd..357a116 100644 --- a/compiler/wcc_node/package.json +++ b/compiler/wcc_node/package.json @@ -2,24 +2,15 @@ "name": "miniprogram-wcc", "version": "0.0.1", "description": "WCC node C++ addon", - "main": "index.js", + "main": "lib/index.js", "scripts": { - "install": "node-gyp-build", - "rebuild": "node-gyp rebuild", - "build:dist": "node scripts/build", - "build": "node-gyp build", - "test": "node ./test/index", + "test": "node ./test/wcc/index && node ./test/wcsc/index", "format": "prettier *.js test/*.js scripts/*.js --write" }, "author": "coverguo", "license": "MIT", - "dependencies": { - "node-gyp-build": "^4.2.1" - }, "devDependencies": { - "eustia-module": "^1.21.2", "licia": "^1.21.2", - "ncp": "^2.0.0", "node-gyp": "^7.0.0" } } diff --git a/compiler/wcsc_node/src/wcsc.js b/compiler/wcc_node/src/wcsc.js similarity index 100% rename from compiler/wcsc_node/src/wcsc.js rename to compiler/wcc_node/src/wcsc.js diff --git a/compiler/wcc_node/index.js b/compiler/wcc_node_old/index.js similarity index 100% rename from compiler/wcc_node/index.js rename to compiler/wcc_node_old/index.js diff --git a/compiler/wcc_node_old/package.json b/compiler/wcc_node_old/package.json new file mode 100644 index 0000000..35f4dfd --- /dev/null +++ b/compiler/wcc_node_old/package.json @@ -0,0 +1,25 @@ +{ + "name": "miniprogram-wcc", + "version": "0.0.1", + "description": "WCC node C++ addon", + "main": "index.js", + "scripts": { + "install": "node-gyp-build", + "rebuild": "node-gyp rebuild", + "build:dist": "node scripts/build", + "build": "node-gyp build", + "test": "node ./test/index", + "format": "prettier *.js test/*.js scripts/*.js --write" + }, + "author": "coverguo", + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.2.1" + }, + "devDependencies": { + "eustia-module": "^1.21.2", + "licia": "^1.21.2", + "ncp": "^2.0.0", + "node-gyp": "^7.0.0" + } +} diff --git a/compiler/wcc_node/src/index.js b/compiler/wcc_node_old/src/index.js similarity index 100% rename from compiler/wcc_node/src/index.js rename to compiler/wcc_node_old/src/index.js diff --git a/compiler/wcc_node_old/src/wcc.js b/compiler/wcc_node_old/src/wcc.js new file mode 100644 index 0000000..780213a --- /dev/null +++ b/compiler/wcc_node_old/src/wcc.js @@ -0,0 +1,438 @@ +const { spawnSync } = require("child_process"); +const fs = require("fs"); +const path = require("path"); +const nfs = require("fs"); +const os = require("os"); +const DEBUG_OUTPUT = process.env["WX_DEBUG_COMPILER_OUTPUT"]; + +function parseDeps(source, x, pageConfig, funcName) { + // 插入引用信息 + let dep_x = `var x=['`; + let dep_gz = ""; + let dep_d_ = ""; + let t_x = []; + if (funcName !== "$gwx") { + // TODO: 可能存在自定义目录无法识别的问题? + // 非标准函数名 + 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; + for (let dep of t_x) { + if (dep.startsWith("../")) continue; + + // d_ + const d_Exp = `d_\\[x\\[${x.indexOf( + dep + )}\\]\\]={}\n[\\s\\S]*?e_\\[x\\[${x.indexOf( + dep + )}\\]\\]={f:m\\d+,j:\\[.*?\\],i:\\[.*?\\],ti:\\[(.*?)\\],ic:\\[.*?\\]}`; + + let m0 = source.match(new RegExp(d_Exp)); + let m0_str = m0[0]; + const depIndex = m0[1].match(/\d+/g); + if (depIndex) { + for (let index of depIndex) { + m0_str = m0_str.replace( + new RegExp(`x\\[${index}\\]`, "g"), + `x[${t_x.indexOf(x[index])}]` + ); + } + } + // process.stderr.write(dep + '=====' + x.indexOf(dep) + "-" + t_x.indexOf(dep) + '\n') + dep_d_ += + m0_str + .replace( + new RegExp(`x\\[${x.indexOf(dep)}\\]`, "g"), + `x[${t_x.indexOf(dep)}]` + ) + .replace( + new RegExp(`\\${funcName}\\_\\d+`, "g"), + `${funcName}_${i}` + ) + .replace(/m\d+/g, `m${i - 1}`) + "\n"; + let gz_name = m0_str.match(/var z=gz(.*?)\(\)/)[1]; + // process.stderr.write("get funcName - " + t[0].match(/var z=gz(.*?)\(\)/)[1] + "\n") + // gz + const exp = `function gz\\${gz_name}\\(\\)\\{[\\s\\S]*?__WXML_GLOBAL__\\.ops_cached\\.\\${gz_name}\n}`; + DEBUG_OUTPUT && + process.stderr.write("COMMON=====" + dep + "----" + exp + "\n"); + const gz = source.match(new RegExp(exp)); + dep_gz += + gz[0].replace( + new RegExp(`\\${funcName}\\_\\d+`, "g"), + `${funcName}_${i}` + ) + "\n"; + i++; + } + dep_x += `${t_x.join("','")}'];`; + return { + dep_x, + dep_gz, + dep_d_, + }; +} +function genFunctionContent_LL(wxmlName, config = {}, source, funcName, x) { + // 起始 + let content = + `${config.funcName}` + + "=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 || {};\u000a"; + // + content += + "var 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"; + + // cs + const cs = source.match(/var cs([\s\S]*?)function gz/); + content += + "var cs" + + cs[1].replace(new RegExp(`\\${funcName}`, "g"), config.funcName); + + // gz函数 + const exp = `function gz\\${funcName}_${ + config.num + 1 + }\\(\\)\\{[\\s\\S]*_WXML_GLOBAL__\\.ops_cached\\.\\${funcName}_${ + config.num + 1 + }\n}`; + const gz = source.match(new RegExp(exp))[0]; + content += gz; + + // debug + let debug = source.match( + new RegExp( + `\\n__WXML_GLOBAL__\\.ops_set\\.\\${funcName}=[\\s\\S]*?\\nvar` + ) + ); + debug = debug[0] + .substring(0, debug[0].length - 3) + .replace(new RegExp(`\\${funcName}`, "g"), config.funcName); + content += debug; + + content += `var x=['./${wxmlName}.wxml'`; + // m0 --- m{num} + const m0Exp = `var m${config.num}=function\\(e,s,r,gg\\){[\\s\\S]*e_\\[x\\[(\\d+)\\]\\]={f:m${config.num},j:\\[.*?\\],i:\\[.*?\\],ti:\\[(.*?)\\],ic:\\[.*?\\]}`; + const m0 = source.match(new RegExp(m0Exp)); + let m0_str = m0[0].replace(new RegExp(`m${config.num}`, "g"), "m0"); + const cur_x = m0[1]; // cur_x与config.num不一定相同 + m0_str = m0_str.replace(new RegExp(`x\\[${cur_x}\\]`, "g"), "x[0]"); + const depIndex = m0[2].match(/\d+/g); + if (depIndex) { + let i = 1; + for (let index of depIndex) { + content += `,'${x[index]}'`; + m0_str = m0_str.replace( + new RegExp(`x\\[${index}\\]`, "g"), + `x[${i++}]` + ); + } + } + content += `];d_[x[0]]={}\u000a`; + m0_str = m0_str.replace(new RegExp(`x\\[${config.num}\\]`, "g"), "x[0]"); + content += m0_str.replace( + new RegExp(`\\${funcName}\\_\\d+`, "g"), + `${config.funcName}_1` + ); + + // path + content += `\u000aif(path&&e_[path]){\u000awindow.__wxml_comp_version__=0.02\u000areturn function(env,dd,global){$gwxc=0;var root={\u0022tag\u0022:\u0022wx-page\u0022};root.children=[]\u000a;g=\u0022${config.funcName}\u0022;var main=e_[path].f\u000acs=[]\u000aif (typeof global===\u0022undefined\u0022)global={};global.f=$gdc(f_[path],\u0022\u0022,1);\u000aif(typeof(window.__webview_engine_version__)!='undefined'&&window.__webview_engine_version__+1e-6>=0.02+1e-6&&window.__mergeData__)\u000a{\u000aenv=window.__mergeData__(env,dd);\u000a}\u000atry{\u000amain(env,{},root,global);\u000a_tsd(root)\u000aif(typeof(window.__webview_engine_version__)=='undefined'|| window.__webview_engine_version__+1e-6<0.01+1e-6){return _ev(root);}\u000a}catch(err){\u000aconsole.log(cs, env);\u000aconsole.log(err)\u000athrow err\u000a}\u000a;g=\u0022\u0022;\u000areturn root;\u000a}\u000a}\u000a}\u000a}`; + // end + content += `(__g.a,__g.b,__g.c,__g.d,__g.e,__g.f,__g.g,__g.h,__g.i,__g.j,__g.k,__g.l,__g.m,__g.n,__g.o,__g.p,__g.q,__g.r,__g.s,__g.t,__g.u,__g.v,__g.w,__g.x,__g.y,__g.z,__g.A,__g.B,__g.C,__g.D,__g.E,__g.F,__g.G,__g.H,__g.I,__g.J,__g.K,__g.L,__g.M,__g.N,__g.O,__g.P,__g.Q,__g.R,__g.S,__g.T,__g.U,__g.V,__g.W,__g.X,__g.Y,__g.Z,__g.aa);if(__vd_version_info__.delayedGwx||false)${config.funcName}();`; + content = content.replace( + new RegExp(`\\${funcName}_${config.num + 1}`, "g"), + `${config.funcName}_1` + ); + // console.log(content) + return content; +} +function genCommonContent_LL(source, funcName, pageConfig, x) { + let common = + "var __wxAppData=__wxAppData||{};var __wxAppCode__=__wxAppCode__||{};var global=global||{};var __WXML_GLOBAL__=__WXML_GLOBAL__||{entrys:{},defines:{},modules:{},ops:[],wxs_nf_init:undefined,total_ops:0};var Component=Component||function(){};var definePlugin=definePlugin||function(){};var requirePlugin=requirePlugin||function(){};var Behavior=Behavior||function(){};var __vd_version_info__=__vd_version_info__||{};var __GWX_GLOBAL__=__GWX_GLOBAL__||{};if(this&&this.__g===undefined)Object.defineProperty(this,\u0022__g\u0022,{configurable:false,enumerable:false,writable:false,value:function(){function D(e,t){if(typeof t!=\u0022undefined\u0022)e.children.push(t)}function S(e){if(typeof e!=\u0022undefined\u0022)return{tag:\u0022virtual\u0022,wxKey:e,children:[]};return{tag:\u0022virtual\u0022,children:[]}}function v(e){$gwxc++;if($gwxc>=16e3){throw\u0022Dom limit exceeded, please check if there's any mistake you've made.\u0022}return{tag:\u0022wx-\u0022+e,attr:{},children:[],n:[],raw:{},generics:{}}}function e(e,t){t&&e.properities.push(t)}function t(e,t,r){return typeof e[r]!=\u0022undefined\u0022?e[r]:t[r]}function u(e){console.warn(\u0022WXMLRT_\u0022+g+\u0022:\u0022+e)}function r(e,t){u(t+\u0022:-1:-1:-1: Template `\u0022+e+\u0022` is being called recursively, will be stop.\u0022)}var s=console.warn;var n=console.log;function o(){function e(){}e.prototype={hn:function(e,t){if(typeof e==\u0022object\u0022){var r=0;var n=false,o=false;for(var a in e){n=n|a===\u0022__value__\u0022;o=o|a===\u0022__wxspec__\u0022;r++;if(r>2)break}return r==2&&n&&o&&(t||e.__wxspec__!==\u0022m\u0022||this.hn(e.__value__)===\u0022h\u0022)?\u0022h\u0022:\u0022n\u0022}return\u0022n\u0022},nh:function(e,t){return{__value__:e,__wxspec__:t?t:true}},rv:function(e){return this.hn(e,true)===\u0022n\u0022?e:this.rv(e.__value__)},hm:function(e){if(typeof e==\u0022object\u0022){var t=0;var r=false,n=false;for(var o in e){r=r|o===\u0022__value__\u0022;n=n|o===\u0022__wxspec__\u0022;t++;if(t>2)break}return t==2&&r&&n&&(e.__wxspec__===\u0022m\u0022||this.hm(e.__value__))}return false}};return new e}var A=o();function T(e){var t=e.split(\u0022\u005cn \u0022+\u0022 \u0022+\u0022 \u0022+\u0022 \u0022);for(var r=0;r=\u0022:case\u0022<=\u0022:case\u0022>\u0022:case\u0022<\u0022:case\u0022<<\u0022:case\u0022>>\u0022:p=x(e[1],t,r,n,o,a);u=x(e[2],t,r,n,o,a);l=M&&(A.hn(p)===\u0022h\u0022||A.hn(u)===\u0022h\u0022);switch(i){case\u0022+\u0022:f=A.rv(p)+A.rv(u);break;case\u0022*\u0022:f=A.rv(p)*A.rv(u);break;case\u0022/\u0022:f=A.rv(p)/A.rv(u);break;case\u0022%\u0022:f=A.rv(p)%A.rv(u);break;case\u0022|\u0022:f=A.rv(p)|A.rv(u);break;case\u0022^\u0022:f=A.rv(p)^A.rv(u);break;case\u0022&\u0022:f=A.rv(p)&A.rv(u);break;case\u0022===\u0022:f=A.rv(p)===A.rv(u);break;case\u0022==\u0022:f=A.rv(p)==A.rv(u);break;case\u0022!=\u0022:f=A.rv(p)!=A.rv(u);break;case\u0022!==\u0022:f=A.rv(p)!==A.rv(u);break;case\u0022>=\u0022:f=A.rv(p)>=A.rv(u);break;case\u0022<=\u0022:f=A.rv(p)<=A.rv(u);break;case\u0022>\u0022:f=A.rv(p)>A.rv(u);break;case\u0022<\u0022:f=A.rv(p)>\u0022:f=A.rv(p)>>A.rv(u);break;default:break}return l?A.nh(f,\u0022c\u0022):f;break;case\u0022-\u0022:p=e.length===3?x(e[1],t,r,n,o,a):0;u=e.length===3?x(e[2],t,r,n,o,a):x(e[1],t,r,n,o,a);l=M&&(A.hn(p)===\u0022h\u0022||A.hn(u)===\u0022h\u0022);f=l?A.rv(p)-A.rv(u):p-u;return l?A.nh(f,\u0022c\u0022):f;break;case\u0022!\u0022:p=x(e[1],t,r,n,o,a);l=M&&A.hn(p)==\u0022h\u0022;f=!A.rv(p);return l?A.nh(f,\u0022c\u0022):f;case\u0022~\u0022:p=x(e[1],t,r,n,o,a);l=M&&A.hn(p)==\u0022h\u0022;f=~A.rv(p);return l?A.nh(f,\u0022c\u0022):f;default:s(\u0022unrecognized op\u0022+i)}}function x(e,t,r,n,o,a){var i=e[0];var p=false;if(typeof a!==\u0022undefined\u0022)o.ap=a;if(typeof i===\u0022object\u0022){var u=i[0];var l,f,v,c,s,y,b,d,h,_,g;switch(u){case 2:return m(e,t,r,n,o);break;case 4:return x(e[1],t,r,n,o,p);break;case 5:switch(e.length){case 2:l=x(e[1],t,r,n,o,p);return M?[l]:[A.rv(l)];return[l];break;case 1:return[];break;default:l=x(e[1],t,r,n,o,p);v=x(e[2],t,r,n,o,p);l.push(M?v:A.rv(v));return l;break}break;case 6:l=x(e[1],t,r,n,o);var w=o.ap;h=A.hn(l)===\u0022h\u0022;f=h?A.rv(l):l;o.is_affected|=h;if(M){if(f===null||typeof f===\u0022undefined\u0022){return h?A.nh(undefined,\u0022e\u0022):undefined}v=x(e[2],t,r,n,o,p);_=A.hn(v)===\u0022h\u0022;c=_?A.rv(v):v;o.ap=w;o.is_affected|=_;if(c===null||typeof c===\u0022undefined\u0022||c===\u0022__proto__\u0022||c===\u0022prototype\u0022||c===\u0022caller\u0022){return h||_?A.nh(undefined,\u0022e\u0022):undefined}y=f[c];if(typeof y===\u0022function\u0022&&!w)y=undefined;g=A.hn(y)===\u0022h\u0022;o.is_affected|=g;return h||_?g?y:A.nh(y,\u0022e\u0022):y}else{if(f===null||typeof f===\u0022undefined\u0022){return undefined}v=x(e[2],t,r,n,o,p);_=A.hn(v)===\u0022h\u0022;c=_?A.rv(v):v;o.ap=w;o.is_affected|=_;if(c===null||typeof c===\u0022undefined\u0022||c===\u0022__proto__\u0022||c===\u0022prototype\u0022||c===\u0022caller\u0022){return undefined}y=f[c];if(typeof y===\u0022function\u0022&&!w)y=undefined;g=A.hn(y)===\u0022h\u0022;o.is_affected|=g;return g?A.rv(y):y}case 7:switch(e[1][0]){case 11:o.is_affected|=A.hn(n)===\u0022h\u0022;return n;case 3:b=A.rv(r);d=A.rv(t);v=e[1][1];if(n&&n.f&&n.f.hasOwnProperty(v)){l=n.f;o.ap=true}else{l=b&&b.hasOwnProperty(v)?r:d&&d.hasOwnProperty(v)?t:undefined}if(M){if(l){h=A.hn(l)===\u0022h\u0022;f=h?A.rv(l):l;y=f[v];g=A.hn(y)===\u0022h\u0022;o.is_affected|=h||g;y=h&&!g?A.nh(y,\u0022e\u0022):y;return y}}else{if(l){h=A.hn(l)===\u0022h\u0022;f=h?A.rv(l):l;y=f[v];g=A.hn(y)===\u0022h\u0022;o.is_affected|=h||g;return A.rv(y)}}return undefined}break;case 8:l={};l[e[1]]=x(e[2],t,r,n,o,p);return l;break;case 9:l=x(e[1],t,r,n,o,p);v=x(e[2],t,r,n,o,p);function O(e,t,r){var n,o;h=A.hn(e)===\u0022h\u0022;_=A.hn(t)===\u0022h\u0022;f=A.rv(e);c=A.rv(t);for(var a in c){if(r||!f.hasOwnProperty(a)){f[a]=M?_?A.nh(c[a],\u0022e\u0022):c[a]:A.rv(c[a])}}return e}var s=l;var j=true;if(typeof e[1][0]===\u0022object\u0022&&e[1][0][0]===10){l=v;v=s;j=false}if(typeof e[1][0]===\u0022object\u0022&&e[1][0][0]===10){var P={};return O(O(P,l,j),v,j)}else return O(l,v,j);break;case 10:l=x(e[1],t,r,n,o,p);l=M?l:A.rv(l);return l;break;case 12:var P;l=x(e[1],t,r,n,o);if(!o.ap){return M&&A.hn(l)===\u0022h\u0022?A.nh(P,\u0022f\u0022):P}var w=o.ap;v=x(e[2],t,r,n,o,p);o.ap=w;h=A.hn(l)===\u0022h\u0022;_=N(v);f=A.rv(l);c=A.rv(v);snap_bb=K(c,\u0022nv_\u0022);try{P=typeof f===\u0022function\u0022?K(f.apply(null,snap_bb)):undefined}catch(t){t.message=t.message.replace(/nv_/g,\u0022\u0022);t.stack=t.stack.substring(0,t.stack.indexOf(\u0022\u005cn\u0022,t.stack.lastIndexOf(\u0022at nv_\u0022)));t.stack=t.stack.replace(/\u005csnv_/g,\u0022 \u0022);t.stack=T(t.stack);if(n.debugInfo){t.stack+=\u0022\u005cn \u0022+\u0022 \u0022+\u0022 \u0022+\u0022 at \u0022+n.debugInfo[0]+\u0022:\u0022+n.debugInfo[1]+\u0022:\u0022+n.debugInfo[2];console.error(t)}P=undefined}return M&&(_||h)?A.nh(P,\u0022f\u0022):P}}else{if(i===3||i===1)return e[1];else if(i===11){var l=\u0022\u0022;for(var D=1;D=0;o--){if(r[e].i[o]&&n[r[e].i[o]][t])return n[r[e].i[o]][t]}for(var o=r[e].ti.length-1;o>=0;o--){var a=ne(r[e].ti[o],r,e);if(a&&n[a][t])return n[a][t]}var i=ae(r,e);for(var o=0;o=0;p--)if(r[e].j[p]){for(var a=r[r[e].j[p]].ti.length-1;a>=0;a--){var u=ne(r[r[e].j[p]].ti[a],r,e);if(u&&n[u][t]){return n[u][t]}}}}function ae(e,t){if(!t)return[];if($gaic[t]){return $gaic[t]}var r=[],n=[],o=0,a=0,i={},p={};n.push(t);p[t]=true;a++;while(o=0.02+1e-6&&window.__mergeData__)\u000a{\u000aenv=window.__mergeData__(env,dd);\u000a}\u000atry{\u000amain(env,{},root,global);\u000a_tsd(root)\u000aif(typeof(window.__webview_engine_version__)=='undefined'|| window.__webview_engine_version__+1e-6<0.01+1e-6){return _ev(root);}\u000a}catch(err){\u000aconsole.log(cs, env);\u000aconsole.log(err)\u000athrow err\u000a}\u000a;g=\u0022\u0022;\u000areturn root;\u000a}\u000a}\u000a}\u000a}(__g.a,__g.b,__g.c,__g.d,__g.e,__g.f,__g.g,__g.h,__g.i,__g.j,__g.k,__g.l,__g.m,__g.n,__g.o,__g.p,__g.q,__g.r,__g.s,__g.t,__g.u,__g.v,__g.w,__g.x,__g.y,__g.z,__g.A,__g.B,__g.C,__g.D,__g.E,__g.F,__g.G,__g.H,__g.I,__g.J,__g.K,__g.L,__g.M,__g.N,__g.O,__g.P,__g.Q,__g.R,__g.S,__g.T,__g.U,__g.V,__g.W,__g.X,__g.Y,__g.Z,__g.aa);if(__vd_version_info__.delayedGwx||true)" + + funcName + + "();;var __WXML_DEP__=__WXML_DEP__||{};"; + // 追加引用 + let common_end = ""; + for (let key in pageConfig) { + if (pageConfig[key].deps.length > 0) { + common_end += `__WXML_DEP__["./${key}.wxml"]=["${pageConfig[ + key + ].deps.join('","')}",];`; + } + } + common += common_end; + return common; +} +/** + * 获取 wxml 编译器路径 + */ +let wxmlParserPath = ""; +function getWXMLParsePath() { + if (wxmlParserPath) return wxmlParserPath; + + const fileName = + process.platform === "darwin" + ? "../bin/mac/wcc" + : process.platform === "linux" + ? "../bin/linux/wcc" + : "../bin/windows/wcc.exe"; + wxmlParserPath = path.join(__dirname, fileName); + + // 尝试修改权限 + try { + fs.chmodSync(wxmlParserPath, 0o777); + } catch (err) { + // ignore + } + + return wxmlParserPath; +} + +/** + * 获取自定义组件编译参数 + */ +function getComponentArgs(files) { + let args = []; + let count = 0; + + files.forEach((file) => { + const fileJson = file.fileJson; + + if (fileJson.usingComponents) { + args.push(file.pagePath); + args.push(Object.keys(fileJson.usingComponents).length); + args = args.concat(Object.keys(fileJson.usingComponents)); + count++; + } + }); + args.unshift(count); + + return args; +} + +/** + * 获取完整文件列表,包括自定义组件 + */ +function getAllFiles(rootPath, files) { + const ret = []; + const hasCheckMap = {}; + + for (let i = 0, len = files.length; i < len; i++) { + const file = files[i]; + + let fileJson = {}; + const realPath = path.join(rootPath, file); + if (hasCheckMap[realPath]) continue; + hasCheckMap[realPath] = true; + try { + fileJson = require(`${realPath}.json`); + } catch (err) { + // ignore + } + + // 自定义组件 + if (fileJson.usingComponents) { + Object.keys(fileJson.usingComponents).forEach((subFileKey) => { + const subFile = fileJson.usingComponents[subFileKey]; + + len++; + + let relativePath = path.relative( + rootPath, + path.join(path.dirname(realPath), subFile) + ); + relativePath = relativePath.replace(/\\/g, "/"); + files.push(relativePath); + }); + } + + ret.push({ + pagePath: `${file}.wxml`, + jsonPath: `${file}.json`, + fileJson, + }); + } + + return ret; +} + +/** + * 入口 + * 编译 wxml 到 js + * files + * + * @param {*} options 配置选项 + * @returns String or Object with lazyload + */ +function wxmlToJS(options = {}) { + // 创建临时目录 + const tmp = nfs.mkdtempSync(path.join(os.tmpdir(), "wcc_")); + // 判断是否replace,是写入replace,否则拷贝文件到临时目录 + for (let file of options.files) { + if (typeof options.replaceContent[file] === "string") { + // 写入替换内容 + nfs.mkdirSync(path.dirname(path.resolve(tmp, file)), { + recursive: true, + }); + nfs.writeFileSync( + path.resolve(tmp, file), + options.replaceContent[file] + ); + } else { + // 复制原文件 + nfs.mkdirSync(path.dirname(path.resolve(tmp, file)), { + recursive: true, + }); + nfs.copyFileSync( + path.resolve(options.cwd, file), + path.resolve(tmp, file) + ); + } + } + // 使用临时目录执行wcc + options.cwd = tmp; + + let rootPath = options.cwd; + let files = options.files; + let cut = options.isCut; + const type = cut ? "-xc" : "-cc"; + // files = getAllFiles(rootPath, files) + + // @TODO,如果遇到参数过长被操作系统干掉的情况,可以使用 --config-path FILE 配置,参数空格换成空行 + // const componentArgs = getComponentArgs(files), componentArgs.join(' ') + let args = [ + "-d", + "--split", + options.wxmlCompileConfigSplit, + type, + options.wxmlCompileConfig, + ] + .concat(files) + .concat(["-gn", options.genfuncname || "$gwx"]); + + // wxs调试 + if (options.debugWXS) args.unshift("-ds"); + // 懒加载 + // if(options.lazyload)args=args.concat(['-ll', options.lazyloadConfig]) + + // wxmlParserPath 二进制可执行文件路径 + const wxmlParserPath = getWXMLParsePath(); + // console.warn('wcc args:', args) + const wcc = spawnSync(wxmlParserPath, args, { cwd: rootPath }); + + nfs.rmSync(tmp, { recursive: true, force: true }); + if (wcc.status === 0) { + let result = wcc.stdout.toString(); + DEBUG_OUTPUT && + fs.writeFileSync(`${DEBUG_OUTPUT}/linux_output.js`, result); + + if (options.lazyload) { + // 懒加载处理 + const str = result; + const resultObj = { + generateFunctionName: { + __COMMON__: options.genfuncname, + }, + generateFunctionContent: { + __COMMON__: null, + }, + }; + + const needArr = options.wxmlCompileConfig.split( + options.wxmlCompileConfigSplit + ); + const indexArr = eval(str.match(/var x=(\[.*\]);/)[1]); + const pageConfig = {}; + let i = 0; + indexArr.forEach((ele, index) => { + if (!ele.startsWith("../")) { + pageConfig[ele.substring(2, ele.length - 5)] = { + funcName: `${options.genfuncname}_XC_${i}`, + num: i, + deps: [], + }; + i++; + } + }); + // 引入解析 + const deps = str.matchAll( + /_ai\(.*?,x\[(\d+)\],.*?,x\[(\d+)\],\d+,\d+\)/g + ); + for (let dep of deps) { + // 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]]) + ); + } + for (let key in pageConfig) { + if (needArr.includes(`./${key}.wxml`)) { + resultObj.generateFunctionName[key] = + pageConfig[key].funcName; + resultObj.generateFunctionContent[key] = + genFunctionContent_LL( + key, + pageConfig[key], + str, + options.genfuncname, + indexArr + ); + } + } + resultObj.generateFunctionContent.__COMMON__ = genCommonContent_LL( + str, + options.genfuncname, + pageConfig, + indexArr + ); + // console.log(pageConfig) + result = resultObj; + } + return result; + } else { + throw new Error(`编译 .wxml 文件错误:${wcc.stderr.toString()}`); + } +} + +module.exports = wxmlToJS; diff --git a/compiler/wcsc_node/util.js b/compiler/wcc_node_old/util.js similarity index 100% rename from compiler/wcsc_node/util.js rename to compiler/wcc_node_old/util.js diff --git a/compiler/wcsc_node/index.js b/compiler/wcsc_node_old/index.js similarity index 100% rename from compiler/wcsc_node/index.js rename to compiler/wcsc_node_old/index.js diff --git a/compiler/wcsc_node/package.json b/compiler/wcsc_node_old/package.json similarity index 100% rename from compiler/wcsc_node/package.json rename to compiler/wcsc_node_old/package.json diff --git a/compiler/wcsc_node/src/index.js b/compiler/wcsc_node_old/src/index.js similarity index 100% rename from compiler/wcsc_node/src/index.js rename to compiler/wcsc_node_old/src/index.js diff --git a/compiler/wcsc_node_old/src/wcsc.js b/compiler/wcsc_node_old/src/wcsc.js new file mode 100644 index 0000000..c3a0d79 --- /dev/null +++ b/compiler/wcsc_node_old/src/wcsc.js @@ -0,0 +1,143 @@ +const { spawn, spawnSync } = require('child_process') +const fs = require('fs') +const path = require('path') +const os = require('os') +const { throws } = require('assert') + +/** + * 获取 wxss 编译器路径 + */ +let wxssParserPath = '' +function getWXSSParsePath() { + if (wxssParserPath) return wxssParserPath + + const fileName = process.platform === 'darwin' ? '../bin/mac/wcsc' : process.platform === 'linux' ? '../bin/linux/wcsc' : '../bin/windows/wcsc.exe' + wxssParserPath = path.join(__dirname, fileName) + + // 尝试修改权限 + try { + fs.chmodSync(wxssParserPath, 0o777) + } catch (err) { + // ignore + } + + return wxssParserPath +} + +/** + * 获取完整文件列表 + */ +function getAllFiles(rootPath, files) { + const ret = [] + let compWxssNum = 0 + + for (let i = 0, len = files.length; i < len; i++) { + const file = files[i] + + let fileJson = null + try { + fileJson = require(path.join(rootPath, `${file}.json`)) + } catch(err) { + // ignore + } + + if (fileJson) { + // 组件 wxss + compWxssNum++ + ret.unshift(`${file}.wxss`) + } else { + ret.push(`${file}.wxss`) + } + } + + return { + list: ret, + compWxssNum, + } +} + +/** + * 编译 wxss 到 js + */ +async function wxssToJS(options) { + // 创建临时目录 + const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'wcsc_')) + // 判断是否replace,是写入replace,否则拷贝文件到临时目录 + for(let file of options.files){ + if (typeof options.replaceContent[file] === 'string') { + // 写入替换内容 + fs.mkdirSync(path.dirname(path.resolve(tmp, file)), {recursive:true}) + fs.writeFileSync(path.resolve(tmp, file), options.replaceContent[file]) + }else{ + // 复制原文件 + fs.mkdirSync(path.dirname(path.resolve(tmp, file)), {recursive:true}) + fs.copyFileSync(path.resolve(options.cwd, file), path.resolve(tmp, file)) + } + } + // 使用临时目录执行wcc + options.cwd = tmp + + let rootPath = options.cwd, files=options.files + // files = getAllFiles(rootPath, files) + + const args = ['-db', '-pc', String(options.pageCount)].concat(files) + options.subPackage && (args.push("--subpackage"), args.push(options.subPackage.replace(/\/$/, ""))); + const wxssParserPath = getWXSSParsePath() + // console.warn('wcsc args: ', args) + // const wcsc = spawnSync(wxssParserPath, args, { cwd: rootPath }) + return new Promise((resolve, reject)=>{ + + const wcsc = spawn(wxssParserPath, args, { + cwd: rootPath, + }); + const spwanData = [], + errData = []; + wcsc.stdout.on("data", (e) => { + spwanData.push(e); + }); + wcsc.stderr.on("data", (e) => { + errData.push(e); + }); + wcsc.on("close", (code) => { + console.warn('close', new Date().getTime()/1000) + if (code === 0) { + let result = Buffer.concat(spwanData).toString(); + if(options.lazyload){ + result = result.split('=') + let funcList = {} + for (let i = 0, len = result.length; i < len && result[i + 1]; i += 2) { + funcList[result[i]] = result[i + 1] + .replace( + /[^\\]((\\x[\da-f]{2}|\\u[\da-f]{4})){1,}/gi, + function ($0, $1, $2) { + return eval('"' + $0 + '"'); + } + ) + .replace(/\\[\s\S]{1}/gi, function ($0, $1, $2) { + // console.log($0, $1) + const c = $0 === "\\n" ? "\n" : $0[1]; + return c + }) + } + const t = funcList + funcList = { + common: t.comm, + pageWxss: {} + } + for(let key in t){ + if(key.endsWith('.wxss')){ + funcList.pageWxss[key] = t[key] + } + } + result = funcList + } + resolve(result) + } else { + throw new Error(`编译 .wxss 文件错误(${wcsc.status}):${wcsc.stderr.toString()}`) + } + }) + }) + +} + +module.exports = wxssToJS diff --git a/compiler/wcsc_node_old/util.js b/compiler/wcsc_node_old/util.js new file mode 100644 index 0000000..aec070b --- /dev/null +++ b/compiler/wcsc_node_old/util.js @@ -0,0 +1,1134 @@ +// Built by eustia. +/* eslint-disable */ + +var _ = {}; + +/* ------------------------------ has ------------------------------ */ + +var has = _.has = (function (exports) { + /* Checks if key is a direct property. + * + * |Name |Desc | + * |------|--------------------------------| + * |obj |Object to query | + * |key |Path to check | + * |return|True if key is a direct property| + */ + + /* example + * has({ one: 1 }, 'one'); // -> true + */ + + /* typescript + * export declare function has(obj: {}, key: string): boolean; + */ + var hasOwnProp = Object.prototype.hasOwnProperty; + + exports = function(obj, key) { + return hasOwnProp.call(obj, key); + }; + + return exports; +})({}); + +/* ------------------------------ isUndef ------------------------------ */ + +var isUndef = _.isUndef = (function (exports) { + /* Check if value is undefined. + * + * |Name |Desc | + * |------|--------------------------| + * |val |Value to check | + * |return|True if value is undefined| + */ + + /* example + * isUndef(void 0); // -> true + * isUndef(null); // -> false + */ + + /* typescript + * export declare function isUndef(val: any): boolean; + */ + exports = function(val) { + return val === void 0; + }; + + return exports; +})({}); + +/* ------------------------------ types ------------------------------ */ + +var types = _.types = (function (exports) { + /* Used for typescript definitions only. + */ + + /* typescript + * export declare namespace types { + * interface Collection {} + * interface List extends Collection { + * [index: number]: T; + * length: number; + * } + * interface ListIterator { + * (value: T, index: number, list: List): TResult; + * } + * interface Dictionary extends Collection { + * [index: string]: T; + * } + * interface ObjectIterator { + * (element: T, key: string, list: Dictionary): TResult; + * } + * interface MemoIterator { + * (prev: TResult, curr: T, index: number, list: List): TResult; + * } + * interface MemoObjectIterator { + * (prev: TResult, curr: T, key: string, list: Dictionary): TResult; + * } + * type Fn = (...args: any[]) => T; + * type AnyFn = Fn; + * type PlainObj = { [name: string]: T }; + * } + * export declare const types: {}; + */ + exports = {}; + + return exports; +})({}); + +/* ------------------------------ keys ------------------------------ */ + +var keys = _.keys = (function (exports) { + /* Create an array of the own enumerable property names of object. + * + * |Name |Desc | + * |------|-----------------------| + * |obj |Object to query | + * |return|Array of property names| + */ + + /* example + * keys({ a: 1 }); // -> ['a'] + */ + + /* typescript + * export declare function keys(obj: any): string[]; + */ + + /* dependencies + * has + */ + + if (Object.keys && !false) { + exports = Object.keys; + } else { + exports = function(obj) { + var ret = []; + + for (var key in obj) { + if (has(obj, key)) ret.push(key); + } + + return ret; + }; + } + + return exports; +})({}); + +/* ------------------------------ optimizeCb ------------------------------ */ + +var optimizeCb = _.optimizeCb = (function (exports) { + /* Used for function context binding. + */ + + /* typescript + * export declare function optimizeCb( + * fn: types.AnyFn, + * ctx: any, + * argCount?: number + * ): types.AnyFn; + */ + + /* dependencies + * isUndef types + */ + + exports = function(fn, ctx, argCount) { + if (isUndef(ctx)) return fn; + + switch (argCount == null ? 3 : argCount) { + case 1: + return function(val) { + return fn.call(ctx, val); + }; + + case 3: + return function(val, idx, collection) { + return fn.call(ctx, val, idx, collection); + }; + + case 4: + return function(accumulator, val, idx, collection) { + return fn.call(ctx, accumulator, val, idx, collection); + }; + } + + return function() { + return fn.apply(ctx, arguments); + }; + }; + + return exports; +})({}); + +/* ------------------------------ identity ------------------------------ */ + +var identity = _.identity = (function (exports) { + /* Return the first argument given. + * + * |Name |Desc | + * |------|-----------| + * |val |Any value | + * |return|Given value| + */ + + /* example + * identity('a'); // -> 'a' + */ + + /* typescript + * export declare function identity(val: T): T; + */ + exports = function(val) { + return val; + }; + + return exports; +})({}); + +/* ------------------------------ objToStr ------------------------------ */ + +var objToStr = _.objToStr = (function (exports) { + /* Alias of Object.prototype.toString. + * + * |Name |Desc | + * |------|------------------------------------| + * |val |Source value | + * |return|String representation of given value| + */ + + /* example + * objToStr(5); // -> '[object Number]' + */ + + /* typescript + * export declare function objToStr(val: any): string; + */ + var ObjToStr = Object.prototype.toString; + + exports = function(val) { + return ObjToStr.call(val); + }; + + return exports; +})({}); + +/* ------------------------------ isArr ------------------------------ */ + +var isArr = _.isArr = (function (exports) { + /* Check if value is an `Array` object. + * + * |Name |Desc | + * |------|----------------------------------| + * |val |Value to check | + * |return|True if value is an `Array` object| + */ + + /* example + * isArr([]); // -> true + * isArr({}); // -> false + */ + + /* typescript + * export declare function isArr(val: any): boolean; + */ + + /* dependencies + * objToStr + */ + + if (Array.isArray && !false) { + exports = Array.isArray; + } else { + exports = function(val) { + return objToStr(val) === '[object Array]'; + }; + } + + return exports; +})({}); + +/* ------------------------------ castPath ------------------------------ */ + +var castPath = _.castPath = (function (exports) { + /* Cast value into a property path array. + * + * |Name |Desc | + * |------|-------------------| + * |path |Value to inspect | + * |obj |Object to query | + * |return|Property path array| + */ + + /* example + * castPath('a.b.c'); // -> ['a', 'b', 'c'] + * castPath(['a']); // -> ['a'] + * castPath('a[0].b'); // -> ['a', '0', 'b'] + * castPath('a.b.c', { 'a.b.c': true }); // -> ['a.b.c'] + */ + + /* typescript + * export declare function castPath(path: string | string[], obj?: any): string[]; + */ + + /* dependencies + * has isArr + */ + + exports = function(str, obj) { + if (isArr(str)) return str; + if (obj && has(obj, str)) return [str]; + var ret = []; + str.replace(regPropName, function(match, number, quote, str) { + ret.push(quote ? str.replace(regEscapeChar, '$1') : number || match); + }); + return ret; + }; // Lodash _stringToPath + + var regPropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + var regEscapeChar = /\\(\\)?/g; + + return exports; +})({}); + +/* ------------------------------ isNum ------------------------------ */ + +var isNum = _.isNum = (function (exports) { + /* Check if value is classified as a Number primitive or object. + * + * |Name |Desc | + * |------|-------------------------------------| + * |val |Value to check | + * |return|True if value is correctly classified| + */ + + /* example + * isNum(5); // -> true + * isNum(5.1); // -> true + * isNum({}); // -> false + */ + + /* typescript + * export declare function isNum(val: any): boolean; + */ + + /* dependencies + * objToStr + */ + + exports = function(val) { + return objToStr(val) === '[object Number]'; + }; + + return exports; +})({}); + +/* ------------------------------ isFn ------------------------------ */ + +var isFn = _.isFn = (function (exports) { + /* Check if value is a function. + * + * |Name |Desc | + * |------|---------------------------| + * |val |Value to check | + * |return|True if value is a function| + * + * Generator function is also classified as true. + */ + + /* example + * isFn(function() {}); // -> true + * isFn(function*() {}); // -> true + * isFn(async function() {}); // -> true + */ + + /* typescript + * export declare function isFn(val: any): boolean; + */ + + /* dependencies + * objToStr + */ + + exports = function(val) { + var objStr = objToStr(val); + return ( + objStr === '[object Function]' || + objStr === '[object GeneratorFunction]' || + objStr === '[object AsyncFunction]' + ); + }; + + return exports; +})({}); + +/* ------------------------------ isArrLike ------------------------------ */ + +var isArrLike = _.isArrLike = (function (exports) { + /* Check if value is array-like. + * + * |Name |Desc | + * |------|---------------------------| + * |val |Value to check | + * |return|True if value is array like| + * + * Function returns false. + */ + + /* example + * isArrLike('test'); // -> true + * isArrLike(document.body.children); // -> true; + * isArrLike([1, 2, 3]); // -> true + */ + + /* typescript + * export declare function isArrLike(val: any): boolean; + */ + + /* dependencies + * isNum isFn + */ + + var MAX_ARR_IDX = Math.pow(2, 53) - 1; + + exports = function(val) { + if (!val) return false; + var len = val.length; + return isNum(len) && len >= 0 && len <= MAX_ARR_IDX && !isFn(val); + }; + + return exports; +})({}); + +/* ------------------------------ each ------------------------------ */ + +var each = _.each = (function (exports) { + /* Iterate over elements of collection and invokes iterator for each element. + * + * |Name |Desc | + * |--------|------------------------------| + * |obj |Collection to iterate over | + * |iterator|Function invoked per iteration| + * |ctx |Function context | + */ + + /* example + * each({ a: 1, b: 2 }, function(val, key) {}); + */ + + /* typescript + * export declare function each( + * list: types.List, + * iterator: types.ListIterator, + * ctx?: any + * ): types.List; + * export declare function each( + * object: types.Dictionary, + * iterator: types.ObjectIterator, + * ctx?: any + * ): types.Collection; + */ + + /* dependencies + * isArrLike keys optimizeCb types + */ + + exports = function(obj, iterator, ctx) { + iterator = optimizeCb(iterator, ctx); + var i, len; + + if (isArrLike(obj)) { + for (i = 0, len = obj.length; i < len; i++) { + iterator(obj[i], i, obj); + } + } else { + var _keys = keys(obj); + + for (i = 0, len = _keys.length; i < len; i++) { + iterator(obj[_keys[i]], _keys[i], obj); + } + } + + return obj; + }; + + return exports; +})({}); + +/* ------------------------------ createAssigner ------------------------------ */ + +var createAssigner = _.createAssigner = (function (exports) { + /* Used to create extend, extendOwn and defaults. + * + * |Name |Desc | + * |--------|------------------------------| + * |keysFn |Function to get object keys | + * |defaults|No override when set to true | + * |return |Result function, extend... | + */ + + /* typescript + * export declare function createAssigner( + * keysFn: types.AnyFn, + * defaults: boolean + * ): types.AnyFn; + */ + + /* dependencies + * isUndef each types + */ + + exports = function(keysFn, defaults) { + return function(obj) { + each(arguments, function(src, idx) { + if (idx === 0) return; + var keys = keysFn(src); + each(keys, function(key) { + if (!defaults || isUndef(obj[key])) obj[key] = src[key]; + }); + }); + return obj; + }; + }; + + return exports; +})({}); + +/* ------------------------------ extendOwn ------------------------------ */ + +var extendOwn = _.extendOwn = (function (exports) { + /* Like extend, but only copies own properties over to the destination object. + * + * |Name |Desc | + * |-----------|------------------| + * |destination|Destination object| + * |...sources |Sources objects | + * |return |Destination object| + */ + + /* example + * extendOwn({ name: 'RedHood' }, { age: 24 }); // -> {name: 'RedHood', age: 24} + */ + + /* typescript + * export declare function extendOwn(destination: any, ...sources: any[]): any; + */ + + /* dependencies + * keys createAssigner + */ + + exports = createAssigner(keys); + + return exports; +})({}); + +/* ------------------------------ isBrowser ------------------------------ */ + +var isBrowser = _.isBrowser = (function (exports) { + /* Check if running in a browser. + */ + + /* example + * console.log(isBrowser); // -> true if running in a browser + */ + + /* typescript + * export declare const isBrowser: boolean; + */ + exports = + typeof window === 'object' && + typeof document === 'object' && + document.nodeType === 9; + + return exports; +})({}); + +/* ------------------------------ root ------------------------------ */ + +var root = _.root = (function (exports) { + /* Root object reference, `global` in nodeJs, `window` in browser. */ + + /* typescript + * export declare const root: any; + */ + + /* dependencies + * isBrowser + */ + + exports = isBrowser ? window : global; + + return exports; +})({}); + +/* ------------------------------ isMatch ------------------------------ */ + +var isMatch = _.isMatch = (function (exports) { + /* Check if keys and values in src are contained in obj. + * + * |Name |Desc | + * |------|----------------------------------| + * |obj |Object to inspect | + * |src |Object of property values to match| + * |return|True if object is match | + */ + + /* example + * isMatch({ a: 1, b: 2 }, { a: 1 }); // -> true + */ + + /* typescript + * export declare function isMatch(obj: any, src: any): boolean; + */ + + /* dependencies + * keys + */ + + exports = function(obj, src) { + var _keys = keys(src); + + var len = _keys.length; + if (obj == null) return !len; + obj = Object(obj); + + for (var i = 0; i < len; i++) { + var key = _keys[i]; + if (src[key] !== obj[key] || !(key in obj)) return false; + } + + return true; + }; + + return exports; +})({}); + +/* ------------------------------ isObj ------------------------------ */ + +var isObj = _.isObj = (function (exports) { + /* Check if value is the language type of Object. + * + * |Name |Desc | + * |------|--------------------------| + * |val |Value to check | + * |return|True if value is an object| + * + * [Language Spec](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types) + */ + + /* example + * isObj({}); // -> true + * isObj([]); // -> true + */ + + /* typescript + * export declare function isObj(val: any): boolean; + */ + exports = function(val) { + var type = typeof val; + return !!val && (type === 'function' || type === 'object'); + }; + + return exports; +})({}); + +/* ------------------------------ isStr ------------------------------ */ + +var isStr = _.isStr = (function (exports) { + /* Check if value is a string primitive. + * + * |Name |Desc | + * |------|-----------------------------------| + * |val |Value to check | + * |return|True if value is a string primitive| + */ + + /* example + * isStr('licia'); // -> true + */ + + /* typescript + * export declare function isStr(val: any): boolean; + */ + + /* dependencies + * objToStr + */ + + exports = function(val) { + return objToStr(val) === '[object String]'; + }; + + return exports; +})({}); + +/* ------------------------------ matcher ------------------------------ */ + +var matcher = _.matcher = (function (exports) { + /* Return a predicate function that checks if attrs are contained in an object. + * + * |Name |Desc | + * |------|----------------------------------| + * |attrs |Object of property values to match| + * |return|New predicate function | + */ + + /* example + * const filter = require('licia/filter'); + * + * const objects = [ + * { a: 1, b: 2, c: 3 }, + * { a: 4, b: 5, c: 6 } + * ]; + * filter(objects, matcher({ a: 4, c: 6 })); // -> [{a: 4, b: 5, c: 6}] + */ + + /* typescript + * export declare function matcher(attrs: any): types.AnyFn; + */ + + /* dependencies + * extendOwn isMatch types + */ + + exports = function(attrs) { + attrs = extendOwn({}, attrs); + return function(obj) { + return isMatch(obj, attrs); + }; + }; + + return exports; +})({}); + +/* ------------------------------ restArgs ------------------------------ */ + +var restArgs = _.restArgs = (function (exports) { + /* This accumulates the arguments passed into an array, after a given index. + * + * |Name |Desc | + * |----------|---------------------------------------| + * |function |Function that needs rest parameters | + * |startIndex|The start index to accumulates | + * |return |Generated function with rest parameters| + */ + + /* example + * const paramArr = restArgs(function(rest) { + * return rest; + * }); + * paramArr(1, 2, 3, 4); // -> [1, 2, 3, 4] + */ + + /* typescript + * export declare function restArgs( + * fn: types.AnyFn, + * startIndex?: number + * ): types.AnyFn; + */ + + /* dependencies + * types + */ + + exports = function(fn, startIdx) { + startIdx = startIdx == null ? fn.length - 1 : +startIdx; + return function() { + var len = Math.max(arguments.length - startIdx, 0); + var rest = new Array(len); + var i; + + for (i = 0; i < len; i++) { + rest[i] = arguments[i + startIdx]; + } // Call runs faster than apply. + + switch (startIdx) { + case 0: + return fn.call(this, rest); + + case 1: + return fn.call(this, arguments[0], rest); + + case 2: + return fn.call(this, arguments[0], arguments[1], rest); + } + + var args = new Array(startIdx + 1); + + for (i = 0; i < startIdx; i++) { + args[i] = arguments[i]; + } + + args[startIdx] = rest; + return fn.apply(this, args); + }; + }; + + return exports; +})({}); + +/* ------------------------------ promisify ------------------------------ */ + +var promisify = _.promisify = (function (exports) { + /* Convert callback based functions into Promises. + * + * |Name |Desc | + * |---------------|--------------------------------------| + * |fn |Callback based function | + * |multiArgs=false|If callback has multiple success value| + * |return |Result function | + * + * If multiArgs is set to true, the resulting promise will always fulfill with an array of the callback's success values. + */ + + /* example + * const fs = require('fs'); + * + * const readFile = promisify(fs.readFile); + * readFile('test.js', 'utf-8').then(function(data) { + * // Do something with file content. + * }); + */ + + /* typescript + * export declare function promisify( + * fn: types.AnyFn, + * multiArgs?: boolean + * ): types.AnyFn; + */ + + /* dependencies + * restArgs root types + */ + + exports = function(fn, multiArgs) { + return restArgs(function(args) { + return new root.Promise(function(resolve, reject) { + args.push( + restArgs(function callback(err, values) { + if (err) return reject(err); + if (!multiArgs) return resolve(values[0]); + resolve(values); + }) + ); + fn.apply(this, args); + }); + }); + }; + + return exports; +})({}); + +/* ------------------------------ safeGet ------------------------------ */ + +var safeGet = _.safeGet = (function (exports) { + /* Get object property, don't throw undefined error. + * + * |Name |Desc | + * |------|-------------------------| + * |obj |Object to query | + * |path |Path of property to get | + * |return|Target value or undefined| + */ + + /* example + * const obj = { a: { aa: { aaa: 1 } } }; + * safeGet(obj, 'a.aa.aaa'); // -> 1 + * safeGet(obj, ['a', 'aa']); // -> {aaa: 1} + * safeGet(obj, 'a.b'); // -> undefined + */ + + /* typescript + * export declare function safeGet(obj: any, path: string | string[]): any; + */ + + /* dependencies + * isUndef castPath + */ + + exports = function(obj, path) { + path = castPath(path, obj); + var prop; + prop = path.shift(); + + while (!isUndef(prop)) { + obj = obj[prop]; + if (obj == null) return; + prop = path.shift(); + } + + return obj; + }; + + return exports; +})({}); + +/* ------------------------------ property ------------------------------ */ + +var property = _.property = (function (exports) { + /* Return a function that will itself return the key property of any passed-in object. + * + * |Name |Desc | + * |------|---------------------------| + * |path |Path of the property to get| + * |return|New accessor function | + */ + + /* example + * const obj = { a: { b: 1 } }; + * property('a')(obj); // -> {b: 1} + * property(['a', 'b'])(obj); // -> 1 + */ + + /* typescript + * export declare function property(path: string | string[]): types.AnyFn; + */ + + /* dependencies + * isArr safeGet types + */ + + exports = function(path) { + if (!isArr(path)) return shallowProperty(path); + return function(obj) { + return safeGet(obj, path); + }; + }; + + function shallowProperty(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + } + + return exports; +})({}); + +/* ------------------------------ safeCb ------------------------------ */ + +var safeCb = _.safeCb = (function (exports) { + /* Create callback based on input value. + */ + + /* typescript + * export declare function safeCb( + * val?: any, + * ctx?: any, + * argCount?: number + * ): types.AnyFn; + */ + + /* dependencies + * isFn isObj isArr optimizeCb matcher identity types property + */ + + exports = function(val, ctx, argCount) { + if (val == null) return identity; + if (isFn(val)) return optimizeCb(val, ctx, argCount); + if (isObj(val) && !isArr(val)) return matcher(val); + return property(val); + }; + + return exports; +})({}); + +/* ------------------------------ map ------------------------------ */ + +var map = _.map = (function (exports) { + /* Create an array of values by running each element in collection through iteratee. + * + * |Name |Desc | + * |--------|------------------------------| + * |object |Collection to iterate over | + * |iterator|Function invoked per iteration| + * |context |Function context | + * |return |New mapped array | + */ + + /* example + * map([4, 8], function(n) { + * return n * n; + * }); // -> [16, 64] + */ + + /* typescript + * export declare function map( + * list: types.List, + * iterator: types.ListIterator, + * context?: any + * ): TResult[]; + * export declare function map( + * object: types.Dictionary, + * iterator: types.ObjectIterator, + * context?: any + * ): TResult[]; + */ + + /* dependencies + * safeCb keys isArrLike types + */ + + exports = function(obj, iterator, ctx) { + iterator = safeCb(iterator, ctx); + + var _keys = !isArrLike(obj) && keys(obj); + + var len = (_keys || obj).length; + var results = Array(len); + + for (var i = 0; i < len; i++) { + var curKey = _keys ? _keys[i] : i; + results[i] = iterator(obj[curKey], curKey, obj); + } + + return results; + }; + + return exports; +})({}); + +/* ------------------------------ toArr ------------------------------ */ + +var toArr = _.toArr = (function (exports) { + /* Convert value to an array. + * + * |Name |Desc | + * |------|----------------| + * |val |Value to convert| + * |return|Converted array | + */ + + /* example + * toArr({ a: 1, b: 2 }); // -> [{a: 1, b: 2}] + * toArr('abc'); // -> ['abc'] + * toArr(1); // -> [1] + * toArr(null); // -> [] + */ + + /* typescript + * export declare function toArr(val: any): any[]; + */ + + /* dependencies + * isArrLike map isArr isStr + */ + + exports = function(val) { + if (!val) return []; + if (isArr(val)) return val; + if (isArrLike(val) && !isStr(val)) return map(val); + return [val]; + }; + + return exports; +})({}); + +/* ------------------------------ fs ------------------------------ */ +_.fs = (function (exports) { + /* Promised version of node.js fs module. + */ + + /* example + * fs.readFile('test.js') + * .then(function(data) { + * // Do something + * }) + * .catch(function(err) { + * // Handle errors + * }); + */ + + /* typescript + * export declare const fs: { + * readFile(path: string, encoding: string): Promise; + * readFile(path: string): Promise; + * exists(path: string): Promise; + * unlink(path: string): Promise; + * writeFile(path: string, data: string, options?: string): Promise; + * writeFile(path: string, data: Buffer): Promise; + * readdir(path: string): Promise; + * rmdir(path: string): Promise; + * [key: string]: any; + * }; + */ + + /* dependencies + * promisify root each toArr + */ + + const fs = require('fs'); + + each( + [ + 'access', + 'appendFile', + 'chmod', + 'chown', + 'close', + 'fchmod', + 'fchown', + 'fdatasync', + 'fstat', + 'fsync', + 'ftruncate', + 'futimes', + 'link', + 'lstat', + 'mkdir', + 'mkdtemp', + 'open', + 'read', + 'readFile', + 'readdir', + 'readlink', + 'realpath', + 'rename', + 'rmdir', + 'stat', + 'symlink', + 'truncate', + 'unlink', + 'utimes', + 'write', + 'writeFile' + ], + function(method) { + exports[method] = promisify(fs[method]); + } + ); + + exports.exists = function() { + const args = toArr(arguments); + + return new root.Promise(function(resolve) { + args.push(resolve); + fs.exists.apply(null, args); + }); + }; + + return exports; +})({}); + +module.exports = _; \ No newline at end of file diff --git a/tools/fix-other.sh b/tools/fix-other.sh index 2f475b4..0d09396 100755 --- a/tools/fix-other.sh +++ b/tools/fix-other.sh @@ -22,12 +22,11 @@ cd $tmp_dir && npm install miniprogram-compiler # 可视化编译 (cd "${package_dir}/node_modules/" \ && rm -rf wcc wcsc \ -&& mkdir -p "wcc/bin/linux" "wcsc/bin/linux" \ +&& mkdir -p "wcc/bin/linux" \ && cp -r "${tmp_dir}/node_modules/miniprogram-compiler/bin/linux/wcc" "wcc/bin/linux/wcc" \ -&& cp -r "${tmp_dir}/node_modules/miniprogram-compiler/bin/linux/wcsc" "wcsc/bin/linux/wcsc" \ -&& chmod 0755 "wcc/bin/linux/wcc" "wcsc/bin/linux/wcsc" \ -&& cp -r "${srcdir}/compiler/wcc_node"/* "wcc" \ -&& cp -r "${srcdir}/compiler/wcsc_node"/* "wcsc" +&& cp -r "${tmp_dir}/node_modules/miniprogram-compiler/bin/linux/wcsc" "wcc/bin/linux/wcsc" \ +&& chmod 0755 "wcc/bin/linux/wcc" "wcc/bin/linux/wcsc" \ +&& cp -r "${srcdir}/compiler/wcc_node"/* "wcc" ) # 预览编译,设置NO_WINE=true环境变量生效