关于前端:手摸手教你搭个脚手架

34次阅读

共计 3444 个字符,预计需要花费 9 分钟才能阅读完成。

目录

  1. 脚手架
  2. 全局命令
  3. 交互式输出
  4. 拉取近程仓库代码
  5. 优化
  6. 总结

1、脚手架

明天工地的砖有点烫,我低头望了望天,思考了半分钟,决定为了当前搬砖不便,先搭个脚手架:

不好意思,拿错了,是这个:

置信很多小伙伴都用过 vue-cli、create-react-app 或 angular-cli 之类的脚手架,一个命令行就能疾速搭起我的项目框架,辞别刀耕火种的复制粘贴,分分钟解放生产力。

作为一个有谋求的切图仔,这种摸鱼神器,必须立马安顿。

好了,那么问题来了:什么是脚手架?

从表现形式上来看,脚手架次要有以下几个特点:

  1. 一个能全局执行的命令;
  2. 能实现交互式输出,比方输出项目名称,抉择配置项等;
  3. 能主动拉取 github 或 gitlab 近程仓库的代码。

当然高级的脚手架必定不止这么点性能,不过咱们先从最简略的实现起。

2、全局命令

2.1 基本原理

先拆包察看一下,相似 vue-cli 这类的全局命令是如何实现的。
首先找到 vue-cli 的装置门路,全局装置能够通过 npm config get prefix 找到门路,比方我的 windows 零碎就是
C:\Users\ 用户名 \AppData\Roaming\npm:

能够看到这个目录下有很多与全局命令同名的文件,以及一个 node_modules 文件夹。咱们全局装置的依赖包就在 node_modules 里。找到 @vue\cli,这个就是vue-cli 的源码包。

vue-cli源码包中的 package.json 有这样一个要害配置:

  "bin": {"vue": "bin/vue.js"},

这个 bin/vue.js 脚本必须以 #!/usr/bin/env node 结尾,

当 npm 全局装置时,就会依据这个配置,生成对应的同名可执行文件。

而当咱们运行 vue 时,零碎就会以 node 程序来运行 vue.js。

npm 官网文档中提供了 npm link 命令,用以让用户将自定义的脚手架生成一个全局命令。

npm link次要做了两步操作:

  • 一是在 npm 全局装置门路下的 node_modules 文件夹里生成一个链接文件,这个链接文件指向执行该命令的文件夹,也就是咱们的脚手架源码文件夹;
  • 二是在 npm 全局装置门路下生成与配置 bin 里同名的可执行文件。

所以,通过npm link,咱们就能够生成一个 node 全局命令

npm link官网文档:https://docs.npmjs.com/cli/v6…。

2.2 全局命令的实现

话不多说,先来撸一个全局命令。

1)执行 npm init 初始化一个package.json

2)在 package.json 里加上 bin 配置:

  "bin": {"test-cli": "./test.js"},

3)增加对应的执行脚本文件test.js

#! /usr/bin/env node
console.log("Hello! My CLI!");

4)在 package.json 同级目录下执行npm link

5)在控制台运行一下咱们定义的全局命令test-cli,看到输入后果:

实现!

3、交互式输出

通过上述操作,用户曾经能够通过全局命令执行到咱们的 test.js 文件,剩下的性能咱们就能够在 js 里去自由发挥了。

Node 社区有着数量宏大的第三方模块,藉由这些模块咱们能够疾速开发实现想要的性能。

inquirier就是其中之一,目前在 github 上有 14.5k 的 star,它的指标就是“致力于成为一个易于嵌入且好看的命令行工具”。顾名思义,通过 inquirier 模块,咱们能够在命令行中实现与用户的输出交互。

咱们须要晓得用户要创立的项目名称是什么,以及用户想要下载哪个近程仓库的代码:

const inquirer = require("inquirer");

inquirer
    .prompt([
        {
            type: "input",
            name: "project",
            message: "项目名称",
        },
        {
            type: "list",
            name: "tpl",
            message: "请抉择模板",
            choices: ["vue", "react"],
        }
    ])
    .then((res) => {console.log(res);
        const {project, tpl} = res;
        // project 就是用户输出的项目名称
        // tpl 就是用户抉择的模板
    });

这段代码就是为用户提供了一个 input 输出选项,来输出项目名称,以及一个 list 列表选项,来抉择要下载的模板(之后咱们再依据这个模板名称去对应的仓库地址进行下载)。

inquirer还有更多的选项性能,感兴趣的小伙伴能够去官网文档上自在摸索:https://github.com/SBoudrias/…。

4、拉取近程仓库代码

当初咱们曾经晓得用户要下载的是哪个模板代码,也晓得这些模板代码对应的下载地址:

const stores = [
    {
        name: "vue",
        url: "https://github.com/vuejs/vue.git"
    },
    {
        name: "react",
        url: "https://github.com/facebook/react.git"
    }
]

拉取 github 或者 gitlab 近程仓库代码的第三方模块也有好几个,我选用的是nodegit,这个我的项目在 github 上目前有 4.9k 的 star,用起来也很简略:

const Git = require("nodegit");

/** 克隆近程仓库代码 */
// url: 源码仓库地址; path: 要下载的指标门路; cb: 下载完结后的回调函数
const gitClone = (url, path, cb)=>{console.log("正在下载近程仓库代码...")
    console.log(url)
    Git.Clone(url, path)
       .then(function(res) {console.log("下载实现")
            cb(true)
        })
        .catch(function(err) {console.log("下载失败"+err);cb(false) });
}

nodegit 官网地址:
https://github.com/nodegit/no…

至此三个基本功能都已实现!

5、优化

深谙摸鱼之道的我想了想,感觉还能更进一步,比方下载完源码,再帮我主动装置下依赖包啦:

const process = require('child_process');

/** 装置依赖包 */
const install = (path)=>{ // path 是源码模板中 package.json 所在的门路
    console.log("正在装置依赖包...")
    const cmd = 'cd'+path+'&& yarn';
    process.exec(cmd, function(error, stdout, stderr) {console.log(error);
        console.log(stdout);
        console.log(stderr);
        console.log("装置实现")
    });
}

之前看到很多脚手架出场都自带拉风的艺术字,作为一个有谋求的切图仔,这个必须安顿!
这个也是用到了一个第三方模块figlet(https://github.com/patorjk/fi…):

const figlet = require('figlet');   
figlet('My CLI!', {horizontalLayout:"full"}, function(err, data) {if (err) {console.log('Something went wrong...');
        console.dir(err);
        return;
    }
    console.log(data)
    // do something...
});

很多脚手架还提供了参数配置、帮忙信息等性能,这个大多是通过 commander 模块实现的(https://github.com/tj/command…,20.7k star),这里就不具体开展了,我在 demo 我的项目里也简略实现了下,的确很弱小很好用。

Demo 已开源:https://github.com/youzouzou/…

这个 demo 只是简略地实现了脚手架的基本功能,摸索了一下几个 node 模块的用法,还有很多须要优化的点。进一步学习的最好方法就是去看那些成熟的脚手架源码,而后去模拟去实际,再结合实际状况,摸索出最适宜本人团队的计划。

6、总结

工欲善其事,必先利其器。

实际上脚手架并不拘泥于下面的实现模式,但凡能提高效率的工具,在某种意义上都能够称之为脚手架。

模拟只是最高级的阶段,翻新才是真正的开始。

正文完
 0