之前写了一些写electron, 浏览器插件, vscode插件这样的项目. 这些项目其实是有一些固定模板的, 但又没有主流脚手架, 于是观察了一些其他脚手架, 写个自己的脚手架来快速启动项目.

脚手架的来历和构成

脚手架是前端工程化的一个部分.

前端工程化的起点是nodejs.

脚手架就是用nodejs写一些脚本, 来提高日常开发的效率.

提高效率的方式是: 把日常要”复制-粘贴-修改”的动作做成”命令+配置”的形式.

接下来看看脚手架的具体工作.

脚手架的进化

与任何软件一样, 一个复杂的东西都是由一个简单的核心功能开始的.

封装一下cv操作

如果每次新项目都要找老项目复制, 那么我们就写一个固定的初始模板, 然后封装一个node命令来一键复制指定模板粘贴到新项目里.

我认为复制/粘贴的脚本是脚手架最核心的功能, 之后花来呼哨的进化都是为了功能更多, 更灵活.

模板的灵活性

比如vue的项目是否用vuex, 是否用router, 是否用ts等, 一个固定的模板就不行了. 除了设置多个模板外, 有(可能是)yoeman发明的generator写模板的方法, 也可以是js模板字符串, ejs, 或是任何js来灵活生成模板的方法.

模板来源的灵活性

模板接受更多的来源, 就可以有更大的社区拓展性, 除了在npm包内部写好模板, 还可以从git, http, 文件, 其他npm包等方式读取. 只要遵守一些规定, 很多地方的模板都可以被加载.

scripts与template分离与配置读取

模板除了一些html文件, 还会有dev, build, test等scripts.

这些scripts需要和很多配置文件(比如webpack配置/babel配置等)配合使用. 而这些配置文件在一些脚手架会被封装起来.

封装起来以后, 用户看不到, 也不能操作配置文件. 那有一些简单的自定义配置就需要封装后的scripts去读取用户目录下的配置文件. cra还提供了eject方法不可逆的把配置吐出来.

​ 不知道scripts与template的分离的主要作用是不是看起来更高端, 配置文件露在外面真的有多少影响用户使用吗?

更多的业务集成, 插件系统

而脚手架有更高阶的形式(指umi). 把更多业务场景集成落地, 除了配置还能灵活使用插件来使更多的项目都可以使用他.

复杂的东西都是由简单的核心功能开始一样, 前端组件系统, 也会从组件, 到高级组件, 到模板市场.

写一个普通脚手架的步骤

看了一些别人脚手架, 其实核心部分不多, 很多是读取参数, 判断参数等提升用户体验的代码.

所以完成一个可用脚手架poc还是很简单的.

下面说说我这个简单的脚手架的完全开发流程. 效果是执行npx create-haha-app <项目名称>就可以产生一个可以dev, build的electron应用了.

我主要参考的是cra来写了这个脚手架. 主要流程是:

  1. 在create-app包中: 读取参数, 确定template和script. template和script都是npm包. (template也可以是别的)
  2. 在create-app包中: 使用npm安装template和script. 并调用script中的init方法.
  3. 在script包中: init方法复制template(此时已经被安装)到项目文件夹中.
  4. 在script包中: 移除template.

然后具体实施的流程如下:

  1. 创建monorepo. create-app包和script包, template包是不用的npm包, 并且script和template还是可以多份的. lerna init来创建, lerna create <package>来新增一个包.
  2. create-app包以create-开头, 除了npx可以执行, 便于npm inityarn create执行. 并在指定bin文件第一行声明执行语言.
  3. 在create-app包的入口里: 读取参数, 安装script和template. 安装后使用script的init方法初始化项目文件.

(完)

是的, 一个create-app的脚手架就完成, 算上换行和日志不到100行. 之后要编写更多别的模板, 在monorepo里新增包就可以了!

而template和script的具体内容, 其实就属于工程化的另一个范畴了. (通常是dev, build和test)

调试模板时的思考

因为我的目的是做electron, chrome插件这样的脚手架, 意识到市面上的很多脚手架还是相当行业定制化的.

template与script应当是1对1关系. electron的脚本一定运行不了chrome, 反之亦然.

而cra是同一个script可以运行2个template: 普通的和使用ts的. script也就是判断了是否是ts然后加一些配置. 在我看来这个灵活性还是有问题的. 看了一下别的cra-based脚手架, 也都没有明确指出template和script对应关系.

另外, 在调试模板时, 我选择了用monorepo特性在template文件夹里直接调试, 也不知道cra和其他脚手架是如何调试的.

最后, 看了下cra的测试用例, 非常明显是不能保证自己功能的, 只是写了几个js方法的测试. 看来脚手架的测试和模板的调试目前也算是个没明确解决方案的问题.

总结

  1. 脚手架是一段nodejs的脚本, 封装日常开发的重复事项, 发布到npm来方便使用.
  2. 脚手架的开发模式其实并没有固定的, 根据作用粒度和针对的业务来创造代码结构.
  3. 脚手架本身的开发流程和测试用例还处于继续探索阶段.