从零开始搭建 Vue 脚手架工具(一)

前言

在实际的开发过程当中,从零开始创建项目的结构是一件让人头疼的事情,因此各类各样的脚手架工具应运而生。它们功能丰富,但最核心的功能都是可以快速搭建一个完整的项目的结构,开发者只须要在生成的项目结构的基础上进行开发便可,很是简单高效。vue

接下来就让咱们一来看看一个脚手架是如何从0开始搭建的吧。node

总体架构

总体架构以下图: webpack

一个模板就是一个项目的样板,包含项目的完整结构和信息。 咱们把模板信息都存放在一个文件中scaffold-config-dev.json。 用户经过选择不一样模板,经过 axios 下载远程仓库模板到本地,完成项目的搭建ios

最终整个脚手架的文件结构以下:git

=================
├── bin
│   └── ivue-material-cli.js
├── node_modules
├── package.json
└── packages
    └── src
        ├── commander
        │   └── index.js
        ├── lib
        │   └── utils
        │       └── log.js
        └── locals
            ├── index.js
            └── zh_CN
                └── index.js
复制代码

相关插件

包名称 功能
commander 可以更好地组织和处理命令行的输入
chalk 输出有颜色的命令行
mz 在node中使用 es6

命令行构建

咱们先从最简单的步骤开始,-v 输出版本号。es6

内容文件

首先咱们须要知道,-v后命令须要输出什么内容,因此咱们在locals目录对输出的内容进行国际化内容的管理,在这里咱们一切从简,使用中文内容。github

zh_CN->index.jsweb

module.exports = {
    LANG: 'zh_CN',
    SHOW_VERSION: '查看当前版本',
    NO_COMMAND: '命令不存在'
};
复制代码

而后在locals文件下对内容文件进行管理。vue-cli

locals->index.jsjson

module.exports = function () {
    let lang = process.env.LANG || 'zh_CN';

    if (/zh/g.test(lang)) {
        return require('./zh_CN');
    }
};
复制代码

有颜色的命令行

咱们知道一个好看的命令好必需要有颜色,接下来咱们须要使用chalk来对命令行进行上色。咱们在 lib->utils 文件夹下对其进行管理。

/**
 * @file logger
 */

'use strict';

/* eslint-disable */
const chalk = require('chalk');
const util = require('util');

let log = {};

// 管理命令 log 颜色
let logTypes = [
    {
        name: 'info',
        color: chalk.green,
        level: 2
    },
    {
        name: 'error',
        color: chalk.red,
        level: 4
    }
];


logTypes.forEach(function (item) {

    /**
     * 定义打印日志格式
     *
     * @param {string} format 要输出的内容.
     * @param {...*} varArgs 变长参数.
     */
    log[item.name] = function (format, varArgs) {
        // 格式化输出字符串
        let msg = util.format.apply(null, arguments);

        if (msg) {
            console.log((log.prefix || 'IVUE') + ' ' + item.color(item.name.toUpperCase()) + ' ' + msg);
        }
        else {
            console.log();
        }
    };
});


module.exports = log;

复制代码

编写 -v 命令

接下来咱们来编写 -v 命令,咱们在 commander 文件夹下对命令行进行管理,咱们使用 ```commander`` 插件输出命令行由于其可以更好地组织和处理命令行的输入

index.js

// 可以更好地组织和处理命令行的输入
const program = require('commander');
// 内容文件
const locals = require('../locals')();
// 命令行颜色
const log = require('../lib/utils/log');

// 版本号
let version = process.env.VERSION || require('../../../package.json').version;

// 获取输入的命令行
let argv = process.argv[2];

if (argv === '-v' || argv === '--version') {
    log.info('ivue version: ', version);
}

// 定义命令
program
    // 设置/获取命令用法str
    .usage('[commands] [options]')
    // 定义顶级命令的参数语法。
    .arguments('<cmd> [env]')
    // 当使用 --help 时,all 将以这种方式输出。
    // 查看当前版本
    .option('-v, --version', locals.SHOW_VERSION)
    // 注册命令的回调
    .action((cmd, env) => {
        // 输出错误
        if (env) {
            log.error(`\`ivue ${cmd} ${env}\` ${locals.NO_COMMAND}`);
        }
        else {
            log.error('`ivue ' + cmd + '` ' + locals.NO_COMMAND);
        }
    });

// 处理参数
program.parse(process.argv);

复制代码

执行 -v 后输出以下:

帮助命令 -h

接下来咱们来继续构建 -h 帮助命令,修改 commander->index.js 文件

····
// 在node 中使用 es6 语法
const exec = require('mz/child_process').exec;


// 若是后序没有输入命令,执行帮助指令
if (!process.argv[2]) {
    let output = exec('ivue -h');
    console.log(output[0]);
}
// 获取版本号
else {
    let argv = process.argv[2];

    if (argv === '-v' || argv === '--version') {
        log.info('ivue version: ', version);
    }
}

····

复制代码

最终输出以下:

以上也正是 ivue-cli 脚手架的一部分的源码。

下一篇咱们将继续讲解最复杂的功能 init 命令

本文章将一直持续更新到脚手架所有源码的讲解~~~~

若有不对欢迎提出您宝贵的意见

欢迎各位提出 issues 或者 star

github仓库地址:

ivue-cli

webpack模板配置

相关文章
相关标签/搜索