|
|
|
@ -3,7 +3,8 @@ const path = require("path");
|
|
|
|
|
const prettier = require("prettier"); |
|
|
|
|
const { exec } = require("child_process"); |
|
|
|
|
const { search, initDepts, depts } = require("./es6.xtype"); |
|
|
|
|
const _ = require("lodash"); |
|
|
|
|
const lodash = require("lodash"); |
|
|
|
|
const DEPTS = depts; |
|
|
|
|
|
|
|
|
|
// const XTYPE_ONLY = false;
|
|
|
|
|
// const THIS_REPLACE = false;
|
|
|
|
@ -12,6 +13,10 @@ const ConflictImport = [];
|
|
|
|
|
const CircularDependency = []; |
|
|
|
|
|
|
|
|
|
function objHaveFunction(obj) { |
|
|
|
|
if (obj === null) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return Object.keys(obj).some(key => { |
|
|
|
|
const value = obj[key]; |
|
|
|
|
if (typeof value === "object") { |
|
|
|
@ -32,10 +37,11 @@ function parserImport(code) {
|
|
|
|
|
while (regResult) { |
|
|
|
|
importMap[regResult[2]] = regResult[1] |
|
|
|
|
.split(",") |
|
|
|
|
.map(el => el.trim()).filter(el => el); |
|
|
|
|
.map(el => el.trim()) |
|
|
|
|
.filter(el => el); |
|
|
|
|
regResult = reg.exec(code); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return importMap; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -46,7 +52,7 @@ async function saveAndFixCode(path, code) {
|
|
|
|
|
} |
|
|
|
|
const prettierCode = prettier.format(_code, { |
|
|
|
|
tabWidth: 4, |
|
|
|
|
parser: 'babel', |
|
|
|
|
parser: "babel", |
|
|
|
|
printWidth: 120, |
|
|
|
|
}); |
|
|
|
|
fs.writeFileSync(path, prettierCode); |
|
|
|
@ -58,56 +64,18 @@ async function saveAndFixCode(path, code) {
|
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const target = [ |
|
|
|
|
"isNull", |
|
|
|
|
"toPix", |
|
|
|
|
"isKey", |
|
|
|
|
"isObject", |
|
|
|
|
"map", |
|
|
|
|
"extend", |
|
|
|
|
"isFunction", |
|
|
|
|
"isEmptyArray", |
|
|
|
|
"isArray", |
|
|
|
|
"Controller", |
|
|
|
|
"createWidget", |
|
|
|
|
"Events", |
|
|
|
|
"emptyFn", |
|
|
|
|
"nextTick", |
|
|
|
|
"bind", |
|
|
|
|
"i18nText", |
|
|
|
|
"isNotNull", |
|
|
|
|
"isString", |
|
|
|
|
"isNumber", |
|
|
|
|
"isEmpty", |
|
|
|
|
"isEmptyString", |
|
|
|
|
"any", |
|
|
|
|
"deepContains", |
|
|
|
|
"isNotEmptyString", |
|
|
|
|
"each", |
|
|
|
|
"contains", |
|
|
|
|
"remove", |
|
|
|
|
"createItems", |
|
|
|
|
"makeArrayByArray", |
|
|
|
|
"VerticalAlign", |
|
|
|
|
"pushDistinct", |
|
|
|
|
"endWith", |
|
|
|
|
"transformItems", |
|
|
|
|
"print", |
|
|
|
|
"Tree", |
|
|
|
|
"Func", |
|
|
|
|
"Selection", |
|
|
|
|
]; |
|
|
|
|
// const target = [];
|
|
|
|
|
|
|
|
|
|
// 加载模块
|
|
|
|
|
const loader = { |
|
|
|
|
// G: { "@/core": { shortcut: true } },
|
|
|
|
|
load(srcName, module) { |
|
|
|
|
const G = loader.G; |
|
|
|
|
if (target.indexOf(module) >= 0) { |
|
|
|
|
G["@/core"][module] = true; |
|
|
|
|
// if (target.indexOf(module) >= 0) {
|
|
|
|
|
// G["@/core"][module] = true;
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
// return true;
|
|
|
|
|
// }
|
|
|
|
|
if (module.startsWith('"bi.')) { |
|
|
|
|
const key = search(srcName, module); |
|
|
|
|
if (key) { |
|
|
|
@ -136,15 +104,16 @@ const loader = {
|
|
|
|
|
async function handleFile(srcName) { |
|
|
|
|
await saveAndFixCode(srcName); |
|
|
|
|
// 全局状态回归
|
|
|
|
|
let G = loader.G = { }; |
|
|
|
|
|
|
|
|
|
let G = (loader.G = {}); |
|
|
|
|
|
|
|
|
|
const sourceCode = fs.readFileSync(srcName).toString(); |
|
|
|
|
|
|
|
|
|
const result = /BI\.(.*?)\s=\sBI\.inherit\(/.exec(sourceCode); |
|
|
|
|
|
|
|
|
|
if (!result) { |
|
|
|
|
// console.log(`已经es6过,替换 xtype => ${srcName}`);
|
|
|
|
|
if (!/export class/.test(sourceCode)) { |
|
|
|
|
console.log("忽略文件", srcName); |
|
|
|
|
// console.log("忽略文件", srcName);
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -165,9 +134,9 @@ async function handleFile(srcName) {
|
|
|
|
|
}); |
|
|
|
|
// 识别 import
|
|
|
|
|
const importMap = parserImport(noXtypeCode); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 合并原来的 import 到 G
|
|
|
|
|
_.forEach(importMap, (depts, module) => { |
|
|
|
|
lodash.forEach(importMap, (depts, module) => { |
|
|
|
|
depts.forEach(dept => { |
|
|
|
|
if (!G[module]) { |
|
|
|
|
G[module] = {}; |
|
|
|
@ -176,56 +145,113 @@ async function handleFile(srcName) {
|
|
|
|
|
G[module][dept] = true; |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 合并 core
|
|
|
|
|
const crossPackages = fs.readdirSync("src"); |
|
|
|
|
_.forEach(G, (depts, module) => { |
|
|
|
|
// 合并包
|
|
|
|
|
const crossPackages = fs.readdirSync("src").map(el => `@/${el}`); |
|
|
|
|
lodash.forEach(G, (depts, module) => { |
|
|
|
|
crossPackages.forEach(crosspackage => { |
|
|
|
|
if (module.indexOf(crosspackage) >= 0) { |
|
|
|
|
if (!G[`@/${crosspackage}`]) { |
|
|
|
|
G[`@/${crosspackage}`] = {}; |
|
|
|
|
if (module.indexOf(crosspackage.replace(/^@\//, "")) >= 0) { |
|
|
|
|
if (!G[crosspackage]) { |
|
|
|
|
G[crosspackage] = {}; |
|
|
|
|
} |
|
|
|
|
Object.assign(G[`@/${crosspackage}`], depts); |
|
|
|
|
Object.assign(G[crosspackage], depts); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const tmpG = {}; |
|
|
|
|
_.forEach(G, (depts, module) => { |
|
|
|
|
const flag = _.some(crossPackages, crosspackage => module.indexOf(crosspackage) >= 0 && !module.startsWith("@")); |
|
|
|
|
lodash.forEach(G, (depts, module) => { |
|
|
|
|
const flag = lodash.some( |
|
|
|
|
crossPackages, |
|
|
|
|
crosspackage => |
|
|
|
|
module.indexOf(crosspackage) >= 0 && !module.startsWith("@"), |
|
|
|
|
); |
|
|
|
|
if (!flag) { |
|
|
|
|
tmpG[module] = depts; |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
let circle = false; |
|
|
|
|
// 处理循环依赖,base: ["@/case", "@/base", "@/widget"] 等于 base 不能直接引数组内的包
|
|
|
|
|
const forbiddenCrossRules = { |
|
|
|
|
base: ["@/case", "@/base", "@/widget"], |
|
|
|
|
"case": ["@/case", "@/widget"], |
|
|
|
|
widget: ["@/widget"], |
|
|
|
|
component: ["@/component"], |
|
|
|
|
core: ["@/core", "@base", "@/widget", "@/case"], |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const forbiddenKeys = []; |
|
|
|
|
const circleG = {}; |
|
|
|
|
|
|
|
|
|
lodash.forEach(G, (depts, module) => { |
|
|
|
|
// 找出 rule
|
|
|
|
|
const packages = Object.keys(forbiddenCrossRules); |
|
|
|
|
|
|
|
|
|
let key = packages.filter( |
|
|
|
|
_package => srcName.indexOf(_package) >= 0, |
|
|
|
|
); |
|
|
|
|
if (key.length !== 1) { |
|
|
|
|
throw new Error( |
|
|
|
|
"理论不可能出现这个问题,需要 treecat 优化下找包逻辑1", |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
key = key[0]; |
|
|
|
|
const rule = forbiddenCrossRules[key]; |
|
|
|
|
|
|
|
|
|
if (lodash.includes(rule, module)) { |
|
|
|
|
circle = true; |
|
|
|
|
|
|
|
|
|
const deptsArr = Object.keys(depts); |
|
|
|
|
if (deptsArr.filter(dept => !DEPTS[dept]).length > 0) { |
|
|
|
|
throw new Error( |
|
|
|
|
"理论不可能出现这个问题,需要 treecat 优化下找包逻辑2", |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
deptsArr |
|
|
|
|
.filter(dept => DEPTS[dept]) |
|
|
|
|
.forEach(dept => { |
|
|
|
|
const value = `@${DEPTS[dept].replace(path.resolve("src"), "").replace(/\\/g, "/").replace(/\.js$/, "")}`; |
|
|
|
|
if (!tmpG[value]) { |
|
|
|
|
tmpG[value] = {}; |
|
|
|
|
} |
|
|
|
|
tmpG[value][dept] = true; |
|
|
|
|
}); |
|
|
|
|
forbiddenKeys.push(module); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
Object.assign(tmpG, circleG); |
|
|
|
|
forbiddenKeys.forEach(key => { |
|
|
|
|
delete tmpG[key]; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 较验手工 import 错误
|
|
|
|
|
const map = {}; |
|
|
|
|
let conflict = false; |
|
|
|
|
let circle = false; |
|
|
|
|
_.forEach(tmpG, (imports, fromStr) => { |
|
|
|
|
if (srcName.indexOf("base") >= 0) { |
|
|
|
|
if (fromStr === "@/case" || fromStr === "@/base") { |
|
|
|
|
circle = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_.forEach(imports, (bools, _import) => { |
|
|
|
|
if (map[_import] && map[_import] !== fromStr) { |
|
|
|
|
lodash.forEach(tmpG, (depts, module) => { |
|
|
|
|
lodash.forEach(depts, (_, _import) => { |
|
|
|
|
if (map[_import] && map[_import] !== module) { |
|
|
|
|
conflict = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
map[_import] = fromStr; |
|
|
|
|
|
|
|
|
|
map[_import] = module; |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
conflict && ConflictImport.push(srcName); |
|
|
|
|
circle && CircularDependency.push(srcName); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
G = tmpG; |
|
|
|
|
|
|
|
|
|
const noImportCode = noXtypeCode.replace(/import {([\s\S]*?)} from "(.*?)";/g, ""); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const noImportCode = noXtypeCode.replace( |
|
|
|
|
/import {([\s\S]*?)} from "(.*?)";/g, |
|
|
|
|
"", |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
let I = ""; |
|
|
|
|
Object.keys(G).forEach(key => { |
|
|
|
|
let moduleKey = key; |
|
|
|
@ -236,14 +262,13 @@ async function handleFile(srcName) {
|
|
|
|
|
Object.keys(G[moduleKey]).forEach(key => { |
|
|
|
|
i += `${key}, `; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 必须以 . 开头
|
|
|
|
|
const moduleInValid = /^[^@.]/.test(moduleKey); |
|
|
|
|
if (moduleInValid) { |
|
|
|
|
moduleKey = `./${moduleKey}`; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
I += `import {${i}} from '${moduleKey}'\n`; |
|
|
|
|
}); |
|
|
|
|
const code = `${I}\n${noImportCode}`; |
|
|
|
@ -255,17 +280,16 @@ async function handleFile(srcName) {
|
|
|
|
|
|
|
|
|
|
G["@/core"] = { shortcut: true }; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const clzName = result[1]; |
|
|
|
|
|
|
|
|
|
if (!clzName) { |
|
|
|
|
console.log(`${srcName} 不需要 es6 化`); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const superName = /inherit\(BI\.(.*?),/.exec(sourceCode)[1]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const xtype = /BI.shortcut\(\"(.*?)\"/.exec(sourceCode)[1];
|
|
|
|
|
|
|
|
|
|
const collection = { |
|
|
|
@ -391,6 +415,10 @@ async function handleFile(srcName) {
|
|
|
|
|
M += `${f}\n`; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
if (!collection.xtype) { |
|
|
|
|
delete G["@/core"].shortcut; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Object.keys(G).forEach(key => { |
|
|
|
|
let moduleKey = key; |
|
|
|
|
if (moduleKey === path.basename(srcName).replace(/.js$/g, "")) { |
|
|
|
@ -413,9 +441,9 @@ async function handleFile(srcName) {
|
|
|
|
|
const outputCode = ` |
|
|
|
|
${I} |
|
|
|
|
|
|
|
|
|
@shortcut() |
|
|
|
|
${collection.xtype ? "@shortcut()" : ""} |
|
|
|
|
export class ${clzName} extends ${superName} { |
|
|
|
|
\tstatic xtype = "${collection.xtype}" |
|
|
|
|
${collection.xtype ? `static xtype = "${collection.xtype}"` : ""} |
|
|
|
|
|
|
|
|
|
${A} |
|
|
|
|
|
|
|
|
@ -463,19 +491,6 @@ async function traverse(srcName) {
|
|
|
|
|
const srcName = process.argv[2]; |
|
|
|
|
|
|
|
|
|
initDepts().then(async () => { |
|
|
|
|
const content = fs.readFileSync("src/core/2.base.js").toString(); |
|
|
|
|
|
|
|
|
|
let result = content.match(/export function (.*?)\(/g); |
|
|
|
|
target.push( |
|
|
|
|
...result.map(el => |
|
|
|
|
el.replace("export function ", "").replace("(", ""), |
|
|
|
|
), |
|
|
|
|
); |
|
|
|
|
result = content.match(/export const (.*?) =/g); |
|
|
|
|
target.push( |
|
|
|
|
...result.map(el => el.replace("export const ", "").replace(" =", "")), |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
await traverse(srcName); |
|
|
|
|
|
|
|
|
|
// 对数据处理
|
|
|
|
@ -483,6 +498,6 @@ initDepts().then(async () => {
|
|
|
|
|
console.log(`导入冲突 ${el}`); |
|
|
|
|
}); |
|
|
|
|
CircularDependency.forEach(el => { |
|
|
|
|
console.log(`出现循环依赖 ${el}`); |
|
|
|
|
console.log(`出现循环依赖(已经fixed) ${el}`); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|