摘要:以下阅读将花费分钟前言日常开发中,我们都只专注在业务上的开发,拿起一套开箱即用的模板项目就直接开搞了,不知道大家有没有思考过,平时我们使用的脚手架里面到底做了什么,并且如果是自己来搭一套脚手架,应该怎么去搭呢在本博客中,将记录作者搭建脚手架
(以下阅读将花费10分钟)
前言日常开发中,我们都只专注在业务上的开发,拿起一套开箱即用的模板项目就直接开搞了,不知道大家有没有思考过,平时我们使用的脚手架里面到底做了什么,并且如果是自己来搭一套脚手架,应该怎么去搭呢?
在本博客中,将记录作者搭建脚手架的过程,整体将分为两个部分,第一部分是cli的搭建,第二部分是模板项目的搭建;
cli的搭建在搭建脚手架cli之前,我们首先思考一下,一个cli,需要什么能力呢?答案是初始化能力,那么初始化的功能需要怎样去实现呢,这里,我们先梳理一下思路。
思路我们在使用其他cli时,会发现,它们有问询的功能,比如询问项目名称,项目描述等;然后还可以选择模板项目将要使用什么css预处理器等的问题;所以,cli首先就要具备问询功能,用以获取定制化信息;
问询结束后,我们的cli会获得即将创建的项目的基本信息,接下来我们就需要以一个模板项目作为模板去创建,模板项目将会在第二部分讲解,这里一笔带过~;OK,既然有了模板项目,cli就需要下载这个项目,然后复制这个项目,同时将前面问询所得的定制化信息写入项目配置中,所以cli还需要有下载和复制,写入模板功能;
到此,一个模板项目基本已经创建成功了,那后面我们还希望脚手架可以帮忙进行git初始化以及安装依赖的功能,所以最终,还需要添加git初始化和安装依赖的功能;
总结一下,实现一个cli的初始化功能我们需要有如下能力:
问询 ==> 下载模板 ==> 复制,写入模板 ==> git初始化 ==> 安装依赖
好了,为了实现上述思路,cli将会引入如下依赖去实现对应的功能:
const program = require("commander"); // commander负责读取命令 const inquirer = require("inquirer"); // inquirer负责问询 const download = require("download-git-repo"); // download-git-repo负责下载对应模板项目的git仓库 const fse = require("fs-extra"); // fs-extra负责文件的复制 const memFs = require("mem-fs"); const editor = require("mem-fs-editor"); // mem-fs-editor负责模板的复制以及嵌入模板字符串,它需要依赖mem-fs const { exec } = require("child_process"); // child_process负责执行命令行
当然除了上述必须的依赖外,为了更好的交互体验,还引入了如下依赖:
const chalk = require("chalk"); // 改变命令行输出样式 const ora = require("ora"); // 一个优雅地命令行交互spinner
至此,准备的工作已经完毕,下面,就开始一步步来编写cli了
cli的编写万事开头难,有了思路后,实现思路才是真正的开始,下面将介绍如何组织cli项目
项目组织首先看一下,工程的组织
├── bin | ├── begin | ├── begin-init ├── src | ├── constants.js | ├── project.js | └── utils.js ├── .gitignore ├── .npmrc ├── README.md └── package.json第一步,解析命令
在bin/begin中引入commander,并且声明init命令,commander会在同级目录中寻找begin-init文件
const program = require("commander"); program .usage("第二步,问询[options]") .command("init [name]", "init a project") .parse(process.argv);
有了第一步的解析后,我们可以在begin-init文件中编写创建逻辑,这里,我们再抽象project文件到src目录底下,以便更好地分离职责,bin文件只负责解析命令就好啦~
下面就看看project文件中,如何实现问询
inquirer.prompt([{ type: "input", name: "projectName", message: "请输入项目名:", validate(input) { if (!input) { return "项目名不能为空"; } if (fse.existsSync(input)) { return "当前目录已存在同名项目,请更换项目名"; } return true; } }]);
inquirer提供prompt函数来实现问询,其参数为数组,问询顺序将按照数组的顺序来进行;
第三步,下载仓库在问询结束后,我们基本知道需要创建的项目的名称、描述等信息了,下一步,就是下载仓库了,下面我们来看看核心代码:
const downloadPath = path.join(projectPath, "__download__"); download(TEMPLATE_GIT_REPO, downloadPath, { clone: true }, (err) => { // 拷贝 // 此处省略若干代码 // 拷贝完成后删除临时文件 fse.remove(downloadPath); }
这里需要注意的是,模板工程所在的仓库,即TEMPLATE_GIT_REPO,最好是public的
第四步,复制文件,将信息写入模板下载仓库只是把模板工程存放在一个临时文件夹内,真正的工程文件需要等信息写入模板后再生成;
这里需要注意的是,模板写入时遵循ejs规范
const memFs = require("mem-fs"); const editor = require("mem-fs-editor"); // 这里需要mem-fs进行内存优化 const store = memFs.create(); this.memFsEditor = editor.create(store); // 这里source表示源文件,dest表示目标文件,data表示需要写入的数据 this.memFsEditor.copyTpl( source, dest, data );
在调用copyTpl时,data字段中的key-value将被写入到模板中,举个栗子:
// 模板文件中,字段是这样的 { name: "<%= projectName %>" } // data就要这样去写 { projectName: "this is your project name" }第五步,进行git init和npm install
这两步的核心都是使用nodejs提供的child_process中exec方法去执行命令来实现,exec能帮助我们在命令行中执行shell命令,exec函数有对应的回调方法来让我们判断命令执行是否成功,核心代码如下:
exec("npm install", (error, stdout, stderr) => { if (error) { // 出错了 } else { // 成功了 } })
是不是很简单呢,想了解更多的操作可以搜索官方文档查看哈,这里就不详解了。
调试和发布到这里,我们的cli已经实现的差不多了,这里我们总结一下如何测试和发布吧
npm link // 本地调试 npm publish // 发布
通过npm link命令,即可以在命令行工具测试你的cli了,注意在package.json的bin字段中定义好入口命令和文件
// package.json { "bin": { "begin": "bin/begin" } }小结
OK,文章主要总结了编写一个脚手架中init功能的思路以及一些实现的方法,具体一些细节仍有优化的空间,欢迎大家讨论!
文章的具体代码可以参考我的仓库begin-cli
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/105170.html
摘要:各个大厂也相继宣布开源。但是也会存在一些问题,比如每个公司可能需要的业务组件不尽相同,或者我们想自己开发一套属于自己的组件库,来增强对组件的可控性。 前言: 前端组件化是当今热议的话题之一,也是我们在开发单页应用经常会碰到的一个问题,现在我们有了功能非常完善的Element-UI。各个大厂也相继宣布开源XXX-UI。但是也会存在一些问题,比如每个公司可能需要的业务组件不尽相同,或者我们...
摘要:各个大厂也相继宣布开源。但是也会存在一些问题,比如每个公司可能需要的业务组件不尽相同,或者我们想自己开发一套属于自己的组件库,来增强对组件的可控性。 前言: 前端组件化是当今热议的话题之一,也是我们在开发单页应用经常会碰到的一个问题,现在我们有了功能非常完善的Element-UI。各个大厂也相继宣布开源XXX-UI。但是也会存在一些问题,比如每个公司可能需要的业务组件不尽相同,或者我们...
摘要:后来经过排查你会发现是由于目前还没有版本。可以使用该方式解决。这就是我为什么不推荐你使用创建脚手架的原因此文的受众是想要进阶中级的初级前端人员。 最近在知乎看到一个问题,原问题如下: 很奇怪,为什么现在能找到自己手动创建vue脚手架的文章非常少,而且大家似乎对webpack4的热情并不高,对于想基于vue2.0+webpack4搭建一个脚手架的我来说资料真是少得可怜。难道现在一般的做...
摘要:可以使用或来安装我用来重新尝试一次对速度表示不理想的可以尝试淘宝的不要过度依赖中可以写成放哪都行,可以写成可以写成看到这个画面,安装完成了。 初步搭建脚手架 Tips 任何不错的开源项目都有 project-cli 脚手架、我们用它生成往往能快速配制出最佳的、理想的脚手架 我通常使用 cli 生成项目骨架再在之基础上进行个人修改。 什么是 CLI 命令行界面(英语:command-li...
阅读 1788·2021-10-09 09:44
阅读 2665·2021-09-22 15:38
阅读 2410·2021-09-09 09:33
阅读 653·2021-09-07 09:58
阅读 1763·2021-09-02 15:41
阅读 2439·2019-08-30 15:55
阅读 1775·2019-08-30 15:55
阅读 505·2019-08-30 15:44