我的脚手架项目历程

207 阅读4分钟

为什么我要搞个脚手架

因为喜欢用sass,喜欢用命令行生成模板文件(angular 有提供)。当然这不是全部的原因,最根本的原因,应该是,如果要开始一个项目,我希望能快速地进入开发状态,而不是将时间用在各种库的脚手架生成基本项目后又配sass,搬运模板文件,搬运一些基本配置上面。而且,这种工具类的项目能通过自己改造,跟随自身技术进步而进化的。最适合自己的,还是得自己去调校啊。

怎么搞脚手架

1. 自定义输入脚手架名字

首先,我们看到脚手架是这样输入的:

vue init hello-world

所以我们开发的脚手架,假如我们叫它 my-cli ,那么我们应该也是这样输入:

my-cli init hello-cli

而不是这样输入:

node main.js init hello-cli

当然不是说这样输入就不行,该优雅的时候还是得优雅,而且如果发布出去了,难道也要这样输入吗?太掉价了啊,我等之辈,当生而雅。

node 天生支持命令,我们分几步完成这个步骤:

  1. package.json 添加 bin 字段

    {
        ...
        "bin" : {
            "my-cli": "bin/main.js"
        },
        ...
    }
    

    bin/main.js 是执行文件的路径,你大可以自定义。

  2. 编辑 main.js

    #!/usr/bin/env node
    require("../src/main.js");
    

    ../src/main.js 这个是脚手架的主要逻辑文件的路径,也可大方自定义。

  3. npm link

    这样就链接到全局环境了,然后就可以

    my-cli init xxx
    

2. 接受输入的参数

仔细一看,其实人家是这样的:

vue init hello-world

接收到一个动作 init ,一个参数值 hello-world 。那做一个脚手架,肯定是要根据输入的参数来做一些处理,然后生成一个项目的。要不然,还不如直接 copy 来的痛快呢。

想到接收参数,是不是会想起 process.args ,当然这个是一个可行的办法,但是跟 commander 相比,就像刀耕火种的原始跟飞机大炮的现代一样。当然可能差距不会那么大,但是明显地, commander 是一个比较好的选择。

var commander = require('commander');
commander
    .version('0.0.1', '-v, --version')
    .usage('搭建自定义的脚手架')
    .description('To make myself cli');

commander
    .command('init [name]')
    .action((name, value) => {
        init(name)
    });

commander.parse(process.argv);

function init(name) {
    console.log(name);
}

此处附上一个网站是关于 commanderAPI 的学习的:Commander.js中文文档

这个时候,可以输入:

my-cli init hello
// hello

这里输入参数的问题,应该解决了,具体的脚手架的代码,我完成后,会放到git上面去,这里只做一些基础的记录。

3. 友好提示输入

如果你输入了 my-cli init hello-world ,下面应该是要生成一些模板,比如记录 author ,比如提示要用到哪一个框架(假如是可输入的),用到哪些组件(sass, antd)等,是不是需要一些有好的提示,方便完成项目的搭建呢。这里也可以提供一个想法,当然是很原始的,但是,是最容易想到的,就是 console.log 后监听输入。刚才只是说了一下笑,我们当然不能这样干啊,我们要将目光尽可能地聚焦在主要逻辑上。所以我们可以选用 inquirer ,当然,不是唯一的选择,只是刚好我知道这个,所以就用了。

var inquirer = require('inquirer');
inquirer.prompt([{
    name: 'projectName',
    message: 'Please enter the project name'
}, {
    name: 'projectType',
    message: 'Please enter the project type'
}]).then(answers => {
    console.log(answers);
});

输入命令 my-cli 就会出现 Please enter the project name 回车后进入下一个问题,当所有问题答完,将会得到 answers

my-cli
// ? Please enter the project name hello
// ? Please enter the project type vue
// answers: { projectName: 'hello', projectType: 'vue' }

这里的代码,并不承接上文的(与 commander 部分代码无关),只是为了说明,刚好有一个组件能完成我们想要的功能而已。

4. 可选组件上下选择

当你有一些可选的组件,比如:scss,less或直接就css的时候,你的脚手架,是不是需要一个上下选择的功能呢?未研究,待解决。

5. 下载模板的进度显示

当填写完成信息,挑选完组件后,是不是应该下载对应的模板文件来组成一个项目了,这时候,下载的模板应该是远程的,所以应该有一个进度显示,表明程序正在下载模板文件,而不是卡死了,或者躺着不动了。所以,推荐用 ora 来完成这个功能。

var ora = require('ora');
let loading = ora('downloading template ...');
    loading.start();
    setTimeout(() => {
        loading.succeed();
    }, 2000);

6. 下载依赖

当模板文件下载好了之后,对应的依赖,应当是自动下载,当然也可以提示他:

cd xxx and npm install and npm start

友好点的话,应该是自己下载依赖(你的脚手架长大了,应该要学会自动下载依赖了,不要学我的花呗,现在还不会自己还)。这方面还没研究,待解决。

7. 配置好对应的项目

未解决。

需要用到的插件

npm i --save inquirer ora commander