通常,我们用配置文件指明「构建插件包」,也可以直接在命令里指明,比如 dcli build --builder=build-h5;后者往往适用于一套代码打包出多种结果,如京东的 Taro cli
平时大家用惯了 npm run build yarn build,只需在我们的模板中的 package.json 添加一行:
{ "script": { ++ "build": "dcli build" } }
5.6 dev命令:启动 devServer 进行调试
类似 build 只不过 webpack 配置不同,此处略
6 模板插件包
核心功能:提供模板文件夹 + 文件夹的拷贝。这里同样提供了一个样例工程 gen-tpl (仅 50 行代码)
处理流程如下:
询问用户,并获取反馈的答案
比如工程名是什么,描述一下你的工程,是否使用 TypeScript,是否使用 Sass/Less/Stylus 等
根据用户的答案,拷贝对应的模板,细分两种拷贝
直接拷贝,直接把模板插件包里的文件夹/文件,拷贝到用户工程目录
填充模板拷贝,将用户答案,填充到文档的对应位置,类似 WebpackHTMLPlugin、ejs,如将 name: <%= packageName %> 填充成 name: 我的工程
在工程中执行 npm 依赖的安装
【重点来了】看似流程蛮多,其实只用一个现成的轮子即可搞定,即yeoman-generator,它帮我们把这些过程都封装好了,我们只需继承基类,并写几个预设的生命周期函数即可,无脑到令人发指 (细节处理,可参考模板仓库)
module.exports = class extends Generator { // 【问询环节】 prompting() { return this.prompt([ { type: 'input', name: 'appName', message: '请输入项目名称:', }, { type: 'list', choices: ['Javascript', 'TypeScript'], name: 'language', message: '请选择项目语言', default: 'TypeScript', }, ]).then(answers => { this.answers = answers }) } // 【模板拷贝】 writing() { // 从模板路径拷贝到工程路径 this.fs.copy(this.templatePath(), this.destinationPath()) } // 【安装依赖】 install() { this.installDependencies() } end() { this.log('happy coding!') } }
很明显,「模板插件包」导出的是一个 class,我们需要通过上文提到的「全局命令包」里的 yeoman-environment 来启动:
// 【节选自 全局命令包 init 命令,略修改以增加可读性】 yoemanEnv.register(resolveFrom('./maoda', 'gen-tpl'), 'gen-tpl') yoemanEnv.run('gen-tpl', (e, d) => { d && this.console('happy coding', 'green') })
这里同样用到前文提到的 resolve-from 包,进行跨目录的引用解析
yeoman 是一个比较完善的生态,模板插件包可用 yeoman 提供的全局命令 yo 来创建,但并非必要,此处就不展开说了
7 构建插件包
同样我们提供了一个构建插件包的模板build-tpl (20行代码,启动 webpack),webpack 配置都是空的,大家在开发过程中可自行定制
构建插件包其实核心就是 webpack 能力,webpack 能力这里就不展开说了,这里只描述一下调用关系
以 dcli build 为例,「全局命令包」在收到 build 命令后,启动「构建插件包」
importFrom(process.cwd(), 'build-tpl')
没错,就是这么简单,import-from 库能跨文件目录,指定使用特定目录的文件;使得全局包可以直接去执行工程目录的包 效果与同工程下 require('build-tpl') 一样
此处也可以使用 import-cwd 库
而 build-tpl 这个构建插件包,负责将内置的 webpack.config.js 与用户工程下自定义的 webpackCustom 进行 merge,然后执行 webpack 流程
当然,构建工具不一定非要使用 webpack,比如可以选择 rollup 或者像 Taro 在构建小程序代码时候,自己创建一套工具
8 写在最后的话
笔者认为,只有够精简,才能降低入门门槛,才能强化记忆;因此,本文的案例,在成熟的脚手架上进行不断删减,剔除掉哪些徒增记忆负担的部分,只保留精髓和核心,旨在快速在脑海里建模出一个企业级脚手架
同时提供了脚手架 3 个组成部分的 仓库/npm 包,以增加可操作性
如需引用与实际开发中,我们需要继续丰满其血肉,包括但不限于:
异常处理 (如一些边界情况)
webpack 配置部分需完善 (本 demo 中 webpack.config 是空的)
UI 和提升语可更友好
根据业务需求,扩展额外的命令,比如卸载包,发布cdn等
文章博客地址:https://github.com/imaoda/js-front-end-practice 欢迎批评指正