@uiw-admin/plugins
Version:
204 lines (198 loc) • 6.76 kB
JavaScript
import { parse } from '@babel/parser';
import traverse from '@babel/traverse';
import * as t from '@babel/types';
import generate from '@babel/generator';
import template from '@babel/template';
import { getToUpperCase } from './index';
var pluginsConfig = ['jsx', 'typescript', 'classProperties', 'dynamicImport', 'exportDefaultFrom', 'exportNamespaceFrom', 'functionBind', 'nullishCoalescingOperator', 'objectRestSpread', 'optionalChaining', 'decorators-legacy'];
var getAst = content => {
var option = {
// 在严格模式下解析并允许模块声明
sourceType: 'module',
plugins: pluginsConfig
};
return parse(content, option);
};
function getVarInit(node, path) {
// 判断 默认导出变量的方式
if (t.isIdentifier(node) && path.scope.hasBinding(node.name)) {
// 导出变量的方式 从 path scope 取值 bindings 里面对应 node.name 的变量内容
var bindingNode = path.scope.getBinding(node.name).path.node;
// 判断对象类型 是否是 VariableDeclarator
if (t.isVariableDeclarator(bindingNode)) {
// 取 这个里面的 init 对象
bindingNode = bindingNode.init;
}
return bindingNode;
}
return node;
}
// 使用 ts 判断
function getTSNode(node) {
if (t.isTSTypeAssertion(node) || t.isTSAsExpression(node)) {
return node.expression;
} else {
return node;
}
}
export var getReactLazy = path => {
// ------------------ 创建 React.lazy ------------------
// 第一步 创建 字符串外层 @/pages/TableList
var callOne = t.callExpression(t.import(), [t.stringLiteral(path)]);
// 第二步 创建 ArrowFunctionExpression
var callTwo = t.arrowFunctionExpression([], callOne);
var callThree1 = t.memberExpression(t.identifier('React'), t.identifier('lazy'));
// 第三步,value 值
var callThree = t.callExpression(callThree1, [callTwo]);
// const call4 = t.callExpression(callThree1, [callThree])
// const callObj = t.objectProperty(t.identifier("a"), call4)
// console.log("callObj", callObj)
// ------------------ 创建 React.lazy 结束 ------------------
return callThree;
};
export var getJSX = name => {
var one = t.jsxOpeningElement(t.jsxIdentifier(name), [], true);
var two = t.jsxElement(one, null, []);
return two;
};
export var IsModel = content => {
var isModels = false;
var modelNames;
var isCreateModel = false;
var ast = parse(content, {
// 在严格模式下解析并允许模块声明
sourceType: 'module',
plugins: pluginsConfig
});
traverse(ast, {
ExportDefaultDeclaration(path) {
var node = path.node.declaration;
node = getTSNode(node);
node = getVarInit(node, path);
node = getTSNode(node);
if (t.isCallExpression(node) && node.arguments) {
node = node.arguments[0];
isCreateModel = true;
}
// 如果 node 是一个对象
// 并且 子集存在 state reducers, subscriptions, effects, name 则是一个 model 返回true
if (t.isObjectExpression(node) && node.properties.some(property => {
return ['state', 'reducers', 'subscriptions', 'effects', 'name'].includes(property.key.name);
})) {
isModels = true;
var modeObj = node.properties.find(property => property.key.name === 'name');
if (t.isObjectProperty(modeObj) && t.isStringLiteral(modeObj.value)) {
modelNames = modeObj.value.value;
}
}
}
});
return {
isModels,
modelNames,
isCreateModel
};
};
// 转换成对象
export var stringToJson = str => {
var json = new Function('return ' + str)();
return json;
};
// ts/js 文件获取里面的 默认导出内容
export var getJSONData = content => {
var isJSON = false;
var jsonArr = [];
var jsonCode = '';
var ast = getAst(content);
var isReact = false;
traverse(ast, {
ExportDefaultDeclaration(path) {
var node = path.node.declaration;
node = getTSNode(node);
node = getVarInit(node, path);
node = getTSNode(node);
// 如果 node 是一个数组
if (t.isArrayExpression(node)) {
isJSON = true;
}
},
ImportDefaultSpecifier(path) {
var node = path.node;
if (t.isImportDefaultSpecifier(node)) {
if (node.local.name === 'React') {
isReact = true;
}
}
}
});
jsonCode = generate(ast).code;
return {
isJSON,
jsonArr,
jsonCode: isReact ? jsonCode : "import React from \"react\"\n" + jsonCode
};
};
/** 对字符串进行解析处理图标和 404、403、500 页面加载 */
export var babelPluginComponents = content => {
var ast = getAst(content);
var iconsList = [];
var importList = [];
traverse(ast, {
ImportSpecifier(path) {
var node = path.node;
if (t.isIdentifier(node.local)) {
var values = node.local.name;
importList.push(values);
}
},
ObjectProperty(path) {
// 判断父级的父级是否是数组 如果是数组则进行转换
if (t.isArrayExpression(path.parentPath.parent)) {
var {
node
} = path;
// 对组件进行处理
if (t.isStringLiteral(node.key) && node.key.value === 'component' || t.isIdentifier(node.key) && node.key.name === 'component') {
if (t.isStringLiteral(node.value)) {
var valus = node.value.value;
if (['404', '403', '500'].includes(node.value.value)) {
node.value = getJSX("Exceptions" + valus);
} else {
node.value = getReactLazy(valus);
}
}
}
// 对icon图标进行处理
if (t.isStringLiteral(node.key) && node.key.value === 'icon' || t.isIdentifier(node.key) && node.key.name === 'icon') {
if (t.isStringLiteral(node.value)) {
var _valus = node.value.value;
var newValue = getToUpperCase(_valus) + "_Icon";
node.value = getJSX("" + newValue);
iconsList.push(newValue);
}
}
// 对 navigate 进行转换
if (t.isStringLiteral(node.key) && node.key.value === 'navigate' || t.isIdentifier(node.key) && node.key.name === 'navigate') {
if (t.isStringLiteral(node.value)) {
var _valus2 = node.value.value;
var fn = template(_valus2);
var _newValue = fn();
if (t.isExpressionStatement(_newValue)) {
node.value = _newValue.expression;
}
}
}
}
}
});
var jsonCode = generate(ast).code;
// icon 去重
var newIcon = Array.from(new Set(iconsList));
importList.forEach(k => {
newIcon = newIcon.filter(ik => ik !== k);
});
return {
iconsList: newIcon,
code: jsonCode
};
};