repalceRouter.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. const parser = require('@babel/parser');
  2. const traverse = require('@babel/traverse');
  3. const generate = require('@babel/generator');
  4. const t = require('@babel/types');
  5. const fs = require('fs');
  6. const prettier = require('prettier');
  7. const getNewRouteCode = (configPath, newRoute) => {
  8. const ast = parser.parse(fs.readFileSync(configPath, 'utf-8'), {
  9. sourceType: 'module',
  10. plugins: ['typescript'],
  11. });
  12. let routesNode = null;
  13. const importModules = [];
  14. // 查询当前配置文件是否导出 routes 属性
  15. traverse.default(ast, {
  16. Program({ node }) {
  17. // find import
  18. const { body } = node;
  19. body.forEach(item => {
  20. if (t.isImportDeclaration(item)) {
  21. const { specifiers } = item;
  22. const defaultEpecifier = specifiers.find(s => {
  23. return t.isImportDefaultSpecifier(s) && t.isIdentifier(s.local);
  24. });
  25. if (defaultEpecifier && t.isStringLiteral(item.source)) {
  26. importModules.push({
  27. identifierName: defaultEpecifier.local.name,
  28. modulePath: item.source.value,
  29. });
  30. }
  31. }
  32. });
  33. },
  34. ObjectExpression({ node, parent }) {
  35. // find routes on object, like { routes: [] }
  36. if (t.isArrayExpression(parent)) {
  37. // children routes
  38. return;
  39. }
  40. const { properties } = node;
  41. properties.forEach(p => {
  42. const { key, value } = p;
  43. if (t.isObjectProperty(p) && t.isIdentifier(key) && key.name === 'routes') {
  44. if (value) {
  45. // find json file program expression
  46. (p.value = parser.parse(JSON.stringify(newRoute)).program.body[0].expression),
  47. (routesNode = value);
  48. }
  49. }
  50. });
  51. },
  52. });
  53. if (routesNode) {
  54. const code = generateCode(ast);
  55. return { code, routesPath: configPath };
  56. } else {
  57. throw new Error('route array config not found.');
  58. }
  59. };
  60. /**
  61. * 生成代码
  62. * @param {*} ast
  63. */
  64. function generateCode(ast) {
  65. const newCode = generate.default(ast, {}).code;
  66. return prettier.format(newCode, {
  67. // format same as ant-design-pro
  68. singleQuote: true,
  69. trailingComma: 'es5',
  70. printWidth: 100,
  71. parser: 'typescript',
  72. });
  73. }
  74. module.exports = getNewRouteCode;