与脚手架大战:回合1

@youngwind 2016-03-20 15:09:31发表于 youngwind/blog 工程化

事出有因

随着团队的扩大,项目的增多,脚手架的缺失显得愈发地不可忍受。其问题主要有二:

  1. 每次新建项目都耗时耗力,特别是对于新员工来说,更是有更多的学习和操作成本。
  2. 项目规范难以推行。比方说,都知道需要用scss-lint,eslint等这些进行语法检查,但是大家新建项目的时候往往图快和方便而省略掉引入那些校验,如果能统一从脚手架中生成,只要保证脚手架是规范的,那么会很大程度提高项目的规范度。

yeoman的初尝试

一开始我是想自己写一个的,思路是这样的:

  1. 准备好项目架构文件
  2. 把文件copy到目的文件夹
  3. 执行npm install 和bower install 装包
  4. 执行gulp构建
  5. 执行npm run start 启动程序
    嗯,一切都规划地蛮好的。但是,有一个问题我一直没想通,也没google到,那就是,我如何让终端识别某个我自定义的命令generate-smart呢?也就是说,为啥我 npm install gulp -g之后,在终端输入gulp就能找到这个命令?一番挣扎无果之后我找到了yeoman,忽然发现这就是我要做的东西。一番欣喜若狂之后按照文档和api做了个demo出来。
var generators = require('yeoman-generator');

// 调用shell命令
var process = require('child_process');
var exec = process.exec;

module.exports = generators.Base.extend({
  constructor: function (args, options, config) {
    generators.Base.apply(this, arguments);
  },
  init: function () {
    // 这里还没想好怎么优化,只能先嵌套了!
    console.log('start copy');
    var copy = exec('cp -r ' + __dirname + "/demo/. " + this.options.env.cwd);
    copy.on('exit', function (code) {
      console.log('copy done!');
      console.log('start install bower dependiences');

      var bowerInstall = exec('bower install');
      bowerInstall.on('exit', function (code) {
        console.log('bower dependiences install done.');
        console.log('start install npm dependiences');

        var npmInstall = exec('npm install');
        npmInstall.on('exit', function (code) {
          console.log('npm dependiences install done.');
          console.log('start gulp');

          var gulp = exec('gulp');
          gulp.on('exit', function (code) {
            console.log('gulp done.');
            console.log('start the app....');
            var start = exec("npm run start");
            console.log("please visit http://localhost:3000");
          })
        })
      });
    });
  }
});

现在回头看这段代码,真的是惨不忍睹。。。

  1. 几乎没怎么使用yeoman提供的api,就用了继承和init,其他都是直接通过child_process调用子进程来执行命令的,好粗暴。。。
  2. 子进程嵌套子进程,没办法,那玩意儿是异步的,又没有promise模式,只能这么将就写着了。

反思

  1. 其实我想做脚手架的目的是为了方便公司团队内部用的,而公司团队内部所采用的项目架构与技术栈无非那么两三套,我有必要搞那么灵活度(意味着内部实现难度高)的yeoman吗?
  2. 自己尝试造一下轮子也可以长进很多知识啊。
    于是,贼心不死的我在学习了 inquirer #41 之后,又开始准备自己再写一次脚手架了。

参考资料:

  1. https://segmentfault.com/a/1190000004431257
  2. https://github.com/JST-CN/yeoman-cn/blob/master/wiki-cn/docs/Generators.md