UNPKG

@uiw-admin/plugins

Version:
204 lines (198 loc) 6.76 kB
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 }; };