日常吐槽
本来想搭建一个webpack脚手架的,于是在搭建的过程中不断地搜集相关资料。可最终的结果是,webpack脚手架没有搭建成,却写出个 CLI 小工具。其实,这也并不是没有原因的。现在流行的框架都推出了自己的脚手架工具,比如,Vue CLI,Create React App 等。脚手架和CLI往往如影随形,这也导致了两者在概念上的混淆。标题为什么这么拗口,其实是为了区分这两个概念。
我有一个想法
既然被带跑偏了,就只能在跑偏的路上越跑越远吧。
命令行界面(英语:Command-Line Interface,缩写:CLI)是在图形用户界面得到普及之前使用最为广泛的用户界面,它通常不支持鼠标,用户通过键盘输入指令,计算机接收到指令后,予以执行。也有人称之为字符用户界面(character user interface, CUI) ———— 维基百科
使用过 Vue CLI 的同学应该都知道,我们只需要在终端敲几个的命令就可以搭建一个 Vue 的脚手架。如果不使用 CLI 的话,每次创建项目时,都需要配置文件(比如webpack配置文件)、设计结构、技术栈选型等。如果每次从零开始去搭建项目就会很麻烦,所以我们可以把相同的东西抽离成脚手架。以后创建项目时,就可以直接把脚手架复制过来,并以此为基础搭建项目。
回过头来再看看我们手动搭建项目的过程,从每次从零开始搭建项目到脚手架的复用,这中间有了很大的进步。可即使是复制黏贴,我们依然觉得很麻烦,如果用命令行的方式来取代图形操作,我们就可以更懒一些了。
回到主题,我本来打算写的webpack脚手架是基于这样的一个想法。➡️ 现在大部分的前端工程,webpack作为打包工具已经成了标配了。而 webpack 的配置是大同小异的,完全可以剥离出一个通用的webpack配置,然后针对个别配置进行修改。本次希望最终实现一个基于webpack适用于不同前端模板(React、Vue、ES+)的脚手架。
现在脚手架有了,如何自动化去搭建一个项目呢?
复制或下载脚手架模板。(为了更灵活,上传到GitHub,或发布npm中)。
根据不同需求,在脚手架模板基础上重新配置webpack、package文件。
安装依赖。
以下代码可见GitHub。
CLI 中的预备工作
首先了解一下 #!
。文件开头要加上#! /usr/bin/env node
。
在计算领域中,Shebang(也称为 Hashbang )是一个由井号和叹号构成的字符序列 #! ,其出现在文本文件的第一行的前两个字符。 在文件中存在 Shebang 的情况下,类 Unix 操作系统的程序加载器会分析 Shebang 后的内容,将这些内容作为解释器指令,并调用该指令,并将载有 Shebang 的文件路径作为该解释器的参数。 ———— 维基百科
使用 #!/usr/bin/env 脚本解释器名称 是一种常见的在不同平台上都能正确找到解释器的办法。 ———— 维基百科
然后看看都用到了哪些东西(部分)。
1 | npm install commander chalk fs-extra shelljs inquirer ora ejs --save |
1 |
|
命令的解析
类似与 Vue 的 vue init
,我们也希望自己的 CLI 也能拥有类似的功能。
1 | // package.json |
这样,我们就有了multi-spa-webpack
的命令。如果我们想要全局使用,还需要执行下面命令。
1 | npm link |
接下来就要初始化multi-spa-webpack
相关的命令了。
1 | // multi-spa.js |
复制或下载模板
在执行multi-spa-webpack init spa-project
后,就需要拷贝一份脚手架到本地了。至于脚手架从哪里来,可以放在 github 上(类似 Vue CLI)或 放在 CLI 对应的目录下(类似create-react-app)。
本文是采用的是从 github 获取脚手架模板的。但是常规的方式,只能下载整个项目,而对于不需要的文件夹或文件,也会同时下载,下载后,只能在本地中删除无关文件了。我这里是从源头上剔除无关文件的下载,这个方法可能会有一些局限性吧(sparse-checkout)。不过两者最终的目的是一样的。
1 | // multi-spa.js |
重新生成配置文件
像 webpack、package 等配置文件,也都是包含在脚手架里的,不过这些配置还不能直接拿来用。我们还需要通过交互式问答,来针对性得在现有的基础上重新生成配置文件。
1 | // multi-spa.js |
在获得特定的需求后,还要把这些数据注入到配置文件中。就是通过模板引擎把数据塞到模板里。这里使用的是 ejs 模版引擎。
1 | <!-- webpack.common.ejs --> |
1 | // multi-spa.js |
安装依赖
其实配置文件生成后,CLI 就快接近尾声了。剩下就是安装依赖。
1 | // multi-spa.js |
小结
一个粗糙的CLI,就这么完成了。把以上几个方法包装一下,就是本次 CLI 的全部内容了。
- 拷贝脚手架。2. 重新生成配置文件。3安装依赖。
1 | async function GenarateProject(targetDir) { |
如果想要发布,需要登陆npm ,npm publish
。