fetch-block.js 3.99 KB
Newer Older
้™ˆๅธ…'s avatar
้™ˆๅธ… committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
const parser = require('@babel/parser');
const traverse = require('@babel/traverse');
const generate = require('@babel/generator');
const t = require('@babel/types');
const path = require('path');
const fs = require('fs');
const exec = require('child_process').exec;

const prettier = require('prettier');

const router = require('./router.config');

const getNewRouteCode = (configPath, newRoute, absSrcPath) => {
  const ast = parser.parse(fs.readFileSync(configPath, 'utf-8'), {
    sourceType: 'module',
    plugins: ['typescript'],
  });
  let routesNode = null;
  const importModules = [];
  // ๆŸฅ่ฏขๅฝ“ๅ‰้…็ฝฎๆ–‡ไปถๆ˜ฏๅฆๅฏผๅ‡บ routes ๅฑžๆ€ง
  traverse.default(ast, {
    Program({ node }) {
      // find import
      const { body } = node;
      body.forEach(item => {
        if (t.isImportDeclaration(item)) {
          const { specifiers } = item;
          const defaultEpecifier = specifiers.find(s => {
            return t.isImportDefaultSpecifier(s) && t.isIdentifier(s.local);
          });
          if (defaultEpecifier && t.isStringLiteral(item.source)) {
            importModules.push({
              identifierName: defaultEpecifier.local.name,
              modulePath: item.source.value,
            });
          }
        }
      });
    },
    ObjectExpression({ node, parent }) {
      // find routes on object, like { routes: [] }
      if (t.isArrayExpression(parent)) {
        // children routes
        return;
      }
      const { properties } = node;
      properties.forEach(p => {
        const { key, value } = p;
        if (t.isObjectProperty(p) && t.isIdentifier(key) && key.name === 'routes') {
          if (value) {
            // find json file program expression
            (p.value = parser.parse(JSON.stringify(newRoute)).program.body[0].expression),
              (routesNode = value);
          }
        }
      });
    },
  });
  if (routesNode) {
    const code = generateCode(ast);
    return { code, routesPath: configPath };
  } else {
    throw new Error('route array config not found.');
  }
};

/**
 * ็”Ÿๆˆไปฃ็ 
 * @param {*} ast
 */
function generateCode(ast) {
  const newCode = generate.default(ast, {}).code;
  return prettier.format(newCode, {
    // format same as ant-design-pro
    singleQuote: true,
    trailingComma: 'es5',
    printWidth: 100,
    parser: 'typescript',
  });
}

const relativePath = path.join(__dirname, '../config/config.ts');

const filterParentRouter = router => {
  return [...router]
    .map(item => {
      if (item.routes) {
        return { ...item, routes: filterParentRouter(item.routes) };
      }
      return null;
    })
    .filter(item => item);
};
const parentRouter = filterParentRouter(router);
const { routesPath, code } = getNewRouteCode(relativePath, parentRouter);
// write ParentRouter
fs.writeFileSync(routesPath, code);

const findAllInstallRouter = router => {
  let routers = [];
  router.forEach(item => {
    if (item.routes) {
      routers = routers.concat(findAllInstallRouter(item.routes));
    }
    if (item.component && item.path) {
      if (item.path === '/user' || item.path === '/') {
        return;
      }
      routers.push({
        ...item,
        routes: '',
      });
    }
    return null;
  });
  return routers;
};

const installRouters = findAllInstallRouter(router);
let i = 0;
const firstUpperCase = pathString => {
  return pathString
้™ˆๅธ…'s avatar
้™ˆๅธ… committed
123
    .replace('.', '')
้™ˆๅธ…'s avatar
้™ˆๅธ… committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137
    .split(/\/|\-/)
    .map(s => s.toLowerCase().replace(/( |^)[a-z]/g, L => L.toUpperCase()))
    .filter(s => s)
    .join('');
};
const installBlock = () => {
  const item = installRouters[i];

  if (!item || !item.path) {
    return;
  }
  console.log('install  ' + item.name + '   to:  ' + item.component);
  const cmd = `umi block add https://github.com/ant-design/pro-blocks/tree/master/${firstUpperCase(
    item.path,
้™ˆๅธ…'s avatar
้™ˆๅธ… committed
138 139
  )} --npm-client=cnpm  --path=${item.path}`;
  console.log(cmd);
้™ˆๅธ…'s avatar
้™ˆๅธ… committed
140 141
  exec(cmd, { encoding: 'utf8' }, (error, statusbar) => {
    if (error) console.log(error);
้™ˆๅธ…'s avatar
้™ˆๅธ… committed
142
    console.log(statusbar);
้™ˆๅธ…'s avatar
้™ˆๅธ… committed
143 144 145 146 147
    i += 1;
    installBlock();
  });
};
installBlock();