1 Star 1 Fork 0

思量短_. / caique

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
index.mjs 11.78 KB
一键复制 编辑 原始数据 按行查看 历史
王会峰 提交于 2022-01-12 17:32 . 优化类型
#!/usr/bin/env zx
const esprima = require('esprima');
const estraverse = require('estraverse');
const escodegen = require('escodegen');
let utilsBuffer
if(!await isTestTypeYes()){
console.log(chalk.yellow('🔑 请确保您的项目是 uniapp 或 小程序 ,并在根目录执行的目录'))
}else{
const q1 = await question('请选择您的操作?add 添加 del 删除? ',{
choices: Object.keys(process.env)
});
let msgok = '', type = 'start',qName = [],watData={};
if(q1.includes('add')){
watData = await setUp();
msgok = '完成导入'
type = 'start'
}else{
watData = await delUp();
msgok = '删除完成'
type = 'delFunc'
}
if (watData) {
qName = await logList(watData.pkgName);
utilsBuffer = await readFile()
circulation(qName,watData.pkgData,type).then(async(nameList)=>{
await fs.writeFile(process.cwd()+'/common/utils.js',utilsBuffer)
nameList.length && console.log(chalk.blue("✔ 包[ "+nameList+" ]"+msgok))
})
}
}
/**
* 删除函数
* @returns
*/
async function delUp(){
let pkgName = [],pkgData={}
try {
pkgData = require(process.cwd()+'/common/utils.js')
pkgName = Object.keys(pkgData);
if(!pkgName.length){
console.log( chalk.yellow("⚠ 暂无可删除的包"));
return
}
} catch (error) {
console.log( chalk.yellow("⚠ 不符合预期"));
return
}
console.log("支持删除的包内容如下:");
return {
pkgData,
pkgName
}
// console.log("您选择的是",q1.split(' '));
}
// 添加函数
async function setUp(){
const pkgData = require('./pkg');
let pkgName = Object.keys(pkgData);
try {
let packaget = Object.keys(require(process.cwd()+'/common/utils.js'));
pkgName = pkgName.filter(item=>!packaget.includes(item))
if(!pkgName.length){
console.log( chalk.yellow("⚠ 暂无可导入的包或包均已导入"));
return
}
} catch (error) {
}
console.log("支持可导入的包内容如下:");
return {
pkgData,
pkgName
}
}
/**
* log 打印
* @param {array} pkgName
* @returns
*/
async function logList(pkgName=[]){
console.log(chalk.blue("ID : FunctionName"));
pkgName.forEach((item,index)=>{
console.log( chalk.blue(index+':',item))
})
let q1 = await question('(支持空格隔开导入多个函数)\n请选择您要删除的函数名或id? ',{
choices: Object.keys(process.env)
});
if(q1.includes('--all')){
return pkgName
}
let qName = q1.split(' ').filter(item=>item).map(item=>{
if(!isNaN(parseInt(item))){
return pkgName[item]||item
}
return item
})
console.log("您选择的是",qName);
return qName
}
/**
* 轮训执行
* @param {array} qName
* @param {object} pkgData
* @param {string} type
* @returns
*/
async function circulation(qName,pkgData,type='start'){
utilsBuffer = await readFile()
let func = {
start:start,
delFunc:delFunc
}
let nameList = []
return qName.reduce((resolve,item,index)=>{
return resolve.then(async ()=>{
if(!pkgData[item]){
console.log( chalk.red("❌ error:您选择的包["+item+"]不存在!!"));
return
}else{
utilsBuffer = await func[type](utilsBuffer,item,pkgData)
nameList.push(item)
}
})
},Promise.resolve()).then(res=>nameList)
}
/**
* 创建目录
* */
async function mkdir(name){
try{
return await $`mkdir ${name}`;
}catch(err){
return ''
}
}
/**
* 判断文件是否存在
* */
async function isCommonFile(){
return (await fs.readdir(process.cwd())).includes('common');
}
/**
* 判断项目类型
* */
async function isTestTypeYes(){
const testProjectType = ['./manifest.json','./project.config.json']
return await Promise.any(testProjectType.map(item=>fs.readFile(item))).then(res=>true,err=>false)
}
/**
* 读取文件
* @param {*} name
* @returns
*/
async function readFile(name='utils.js'){
return await fs.readFile(process.cwd()+'/common/'+name,"utf8").catch(()=>'');
}
async function createFile(name='utils.js'){
return await fs.writeFile(process.cwd()+'/common/'+name,'')
}
async function start(utilsBuffer='',q1='',pkgData={}){
if(!await isCommonFile()){
await mkdir('common');
await createFile();
}
if(!utilsBuffer){
// 基础文件
console.log("➕ 创建文件")
const basicsJS = [
`;var ${q1} = ${pkgData[q1].toString()};`,
`module.exports = {`,
` ${q1}:${q1}`,
` };`
].join('\n')
utilsBuffer = basicsJS
}else{
try{
let utilsJS = require(process.cwd()+'/common/utils.js');
if(Object.keys(utilsJS).includes(q1)){
console.log( chalk.yellow(q1+'函数已存在'))
return
}else{
// 导出方式
utilsBuffer = await parseModule(utilsBuffer,q1,pkgData)
}
}catch(err){
utilsBuffer = await parseModule(utilsBuffer,q1,pkgData)
}
}
return utilsBuffer
}
/**
* 删除
* @param {*} utilsBuffer
* @param {*} q1
* @param {*} pkgData
* @returns
*/
async function delFunc(utilsBuffer='',q1='',pkgData={}){
let AST = esprima.parseScript(utilsBuffer)
let utilsName
console.log("🖍 开始删除"+q1+"文件...")
estraverse.traverse(AST,{
enter:(node,parent)=>{
if(node.type === 'ExpressionStatement' && node.expression.type === 'AssignmentExpression'&&node.expression.operator==='='){
let leftAST = node.expression.left
let rightAST = node.expression.right
estraverse.traverse(leftAST,{
enter:(left)=>{
if(left.type==='Identifier' && left.name === 'module'){
// 解析右侧的等于至 rightAST
if(rightAST.type === 'Identifier'){
utilsName = rightAST.name
}
if(rightAST.type === 'ObjectExpression'){
utilsName = '!ObjectExpression'
// 删除函数
rightAST.properties.splice(rightAST.properties.findIndex(item=>item?.key?.name === q1),1)
}
}
}
})
}
}
})
if(utilsName&&utilsName !== '!ObjectExpression'){
let index = AST.body.findIndex(node=>node.type === 'ExpressionStatement' && node.expression.type === 'AssignmentExpression' &&node.expression.operator==='=' && node.expression.left.object.name === utilsName && node.expression.left.property.name === q1)
AST.body.splice(index,1)
return escodegen.generate(AST)
}
let kind =['var','let','const']
let index = AST.body.findIndex(item=>(item.type === 'FunctionDeclaration' && item.id.name === q1));
let bodyIndex = AST.body.findIndex(item=>item.type ==='VariableDeclaration' && kind.includes(item.kind)
&& item?.declarations?.findIndex(it=>it.type==='VariableDeclarator'&&it?.id?.name===q1)>=0);
let body = AST.body[bodyIndex];
// console.log(AST.body);
if(index>-1){
AST.body.splice(index,1)
}else if(bodyIndex>-1){
if(body.length>1){
body.declarations.splice(body.declarations.findIndex(item=>item.id.name===q1),1);
AST.body[bodyIndex] = body
}else{
AST.body.splice(bodyIndex,1)
}
}
return escodegen.generate(AST)
}
/**
* 解析AST
* @param {*} utilsBuffer
* @param {*} q1
* @param {*} pkgData
* @returns
*/
async function parseModule(utilsBuffer='',q1='',pkgData={}){
console.log("🖍 开始解析"+q1+"文件...")
// console.log(esprima.parseScript(pkgData[q1].toString()+';'))
let AST = esprima.parseScript(utilsBuffer)
// pkgParseModule(q1)
let utilsName
estraverse.traverse(AST,{
enter:(node)=>{
if(node.type === 'ExpressionStatement' && node.expression.type === 'AssignmentExpression'&&node.expression.operator==='='){
let leftAST = node.expression.left
let rightAST = node.expression.right
estraverse.traverse(leftAST,{
enter:(left)=>{
if(left.type==='Identifier' && left.name === 'module'){
// 解析右侧的等于至 rightAST
if(rightAST.type === 'Identifier'){
utilsName = rightAST.name
}
if(rightAST.type === 'ObjectExpression'){
utilsName = '!ObjectExpression'
let ASTS = {
type: 'Property',
key:{ type: 'Identifier', name: q1 },
computed: false,
value:{ type: 'Identifier', name: q1 },
kind: 'init',
method: false,
shorthand: false
}
// 追加函数
rightAST.properties.push(ASTS);
}
}
}
})
}
}
})
let JScode = escodegen.generate(AST)
if(!utilsName){
// 这是一个未知情况
return utilsBuffer
}else if(utilsName && utilsName !== '!ObjectExpression'){
let JScope = `${utilsName}.${q1} = ${pkgData[q1].toString()};\n`
let index = AST.body.findIndex(item=>item.type==='VariableDeclaration' && item?.declarations?.findIndex(it=>it.type==='VariableDeclarator'&&it?.id?.name==utilsName)>=0)
AST.body.splice(index+1,0,esprima.parseScript(JScope).body[0])
JScode = escodegen.generate(AST);
return JScode;
// 共有对象 utilsName
}else if(utilsName === '!ObjectExpression'){
// ObjectExpression
let JScope = `var ${q1} = ${pkgData[q1].toString()};\n`
return JScope+JScode;
}else{
// console.log(AST)
if(utilsBuffer.includes('export')){
console.log( chalk.yellow("? 文件为ESM"));
}
return Error("错误"),utilsBuffer
}
}
/**
* 解析原 模块语法树
*/
async function pkgParseModule(q1){
let pkg = await fs.readFile('./pkg.js',"utf8").catch(console.error);
let pkgAST = esprima.parseScript(pkg);
let mut
estraverse.traverse(pkgAST,{
enter:(node)=>{
if(node.type === 'ExpressionStatement' && node.expression.type === 'AssignmentExpression'&&node.expression.operator==='='){
let leftAST = node.expression.left
let rightAST = node.expression.right
estraverse.traverse(leftAST,{
enter:(left)=>{
if(left.type==='Identifier' && left.name === 'module'){
if(rightAST.type === 'ObjectExpression'){
mut = rightAST.properties.filter(item=>item.key.name === q1 && item.key.type==='Identifier')
// console.log("mut",mut)
}
}
}
})
}
}
})
return mut
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/hf4514/caique.git
git@gitee.com:hf4514/caique.git
hf4514
caique
caique
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891