:mortar_board: my university code & article collection: create & share, thought & works
Creative Commons Attribution Share Alike 4.0 International
45
stars
10
forks
source link
[B1B]造轮子之 npm i -g creatshare-app-init 源码浅析 #59
Open
hylerrix opened 6 years ago
以我的小经验来看,软件萌新写出来的代码大多“无法直视”。具体现象包括空格和换行符乱用、文件夹和变量的命名多使用拼音等。坐不住的我,便想到了通过 ESLint 配置文件来规范实验室的 JavaScript 代码规范的 Idea。
于是巧遇前实验室毕业学长曾经发布的 npm 包——creatshare-project-quick-init。安装好这个包,我们便可以在空文件夹下生成一个项目的基础骨架。
What a good idea~!
在学长的这个包中,主要构建了 gulp 配置,less 和测试文件的骨架。虽然再无更多内容,但这份构建基础骨架的灵感还是被我愉快的收走了——学前端的人很多,但大多都太缺工程化意识了。于是,这个灵感成为了不错突破口。
creatshare-app-init 脚手架孕育而生。
0
通过这篇文章,你能了解到:
在本文中,或多或少出现过以下关键字,我的解释是:
creatshare-app-init
就是一个模块,是开发前端项目中的一个子集。正如汽车的各个部件一样,多个模块合理组装起来才是一辆汽车。1
尝试解析源码,第一步,从模块根目录下的
package.json
来看。如上,
dependencies
声明了模块上线时的依赖,devDependencies
声明了模块开发时的依赖。该模块在上线时,即 npm 包被用户用到时,只需要commander
库。commander
库是 NodeJS 命令行接口开发的优选解决方案,受启发于 Ruby 的 commander。在解析bin/index.js
源码时将详细拓展。上面一段是
package.json
最开头的内容,字段详情如下:name
字段:声明模块名称。特殊注意该字段不允许大写字母及空格的出现,且其与version
字段形成了 npm 模块的唯一标识符。version
字段:声明模块当前版本号。这里每当使用npm publish
将模块发布到 npm 仓库中时,版本号都需要手动自增。description
字段:对模块进行描述,同时有助于被检索。bin
字段:npm 本身是通过 bin 属性配置一个或多个可解析到 PATH 路径下的可执行模块。模块若被全局安装,则 npm 会为 bin 中配置的文件在 bin 目录下创建一个软连接;模块若被局部安装,软连接会配置在项目内的./node_modules/.bin/
目录下。script
字段:定义模块的脚本配置。如,当我们在模块目录下使用npm run compile
时,将自动执行babel src/ -d lib/
命令,进行 ECMAScript6 代码的转译。2
刚刚提到
package.json
配置文件下的bin
字段声明了 npm 在生成软连接时的配置。这就便是用户在安装好这个目录后,可以随时使用cs
命令的出处。我们又提到了该模块在非开发环境下只需用到
commander
模块,这个模块是 NodeJS 命令行接口开发的优选解决方案。基于这俩点,我们就从
bin
字段所指向的bin/index.js
聊起。就这么二十来行。因为我们要写的模块是要运行在命令行下的,就需要
#!/usr/bin/env node
语句来告诉系统使用 node 环境来运行我们的文件,必不可少。在引入
commander
并将其赋值给program
变量后,我们对其使用了如下方法:.allowUnknownOption()
方法:.version()
方法:用于设置命令程序的版本号。.description()
方法:用于设置命令的描述。可以绑定在跟命令下,这里是cs
命令;或绑定在子命令下,如cs create <dir>
命令。.option()
方法:定义命令的具体选项。.command()
方法:定义命令的子命令,这里是cs create <dir>
命令。.action()
方法:用于设置命令执行的相关回调。这里绑定在cs create <dir>
命令上,在使用该命令时触发执行回调函数。代码最后的
process
为进程对象,是 NodeJS 运行时存在的众多全局变量之一。process 对象中的 argv 属性用来捕获命令行参数。3
刚刚在
bin/index.js
里说明的.action
回调函数绑定在cs create <dir>
命令下。当我们使用该命令时,会触发cs.create()
语句的执行,这就要提及我们引入的lib/cs.js
文件了。打住,第一节里展示的
package.json
中,script
字段里有这么一条语句:"compile": "babel src/ -d lib/"
。这是说明lib/
文件夹下的代码是通过src/
文件夹下的代码转译过来的,真正我们需要去关注的是src/cs.js
文件。src/cs.js
主要代码片段为:不难理解,
create
变量指向cs create <dir>
所要执行的源代码;path
是 NodeJS 自带模块,提供文件目录解析功能。最终
src/index.js
使用exports.create
语句向外部暴露出create
方法。bin/index.js
便可以将该方法通过.action()
绑定到cs create <dir>
命令上了。4
精彩的来了。都说 ECMAScript6 的指定振奋人心,JavaScript 的魅力越来越大,这里便是一次体验 JavaScript 在 NodeJS 上的新玩法有趣之旅。
在
src/create.js
文件中,主要用到了 NodeJS 自带的fs
文件模块,来生成新项目的基础架构。文件最后暴露出的init
方法源码如下。init
方法获取了path
参数、dist
参数和rootDir
参数。在该方法中,我们先将rootDir
参数传入createRootDir()
函数中创建项目根目录。在哪里创建项目根目录呢?就在执行
cs
命令时的当前目录下:有了项目根目录,就要将模块下
dist/
文件夹里的所有文件递归拷贝到根目录下。一个参数用来指向dist/
文件夹,另一个参数用来指向根目录,便可以开始递归复制。fs
文件模块的具体内容推荐阅读阮一峰的开源电子书——《JavaScript 标准参考教程》中的“NodeJS”章节,来深入浅出fs
模块的用法。完美,这时我们就可以发布我们的脚手架包了。
5
如何发布一个 npm 包到 npm 仓库中,供其他人使用?当我们照着第一步,将
package.json
配置好后,其实模块的准备工作已经做好了。还没有做的就是在域名为 npmjs.com 的官网上注册一个账号。这样,当我们直接在模块根目录使用
npm publish
命令的时候,输入正确的 npmjs.com 账号、密码,就能成功发布你的开源包了!纵然读博文是一个有趣的体验,但也可以亲自动手试一试哦。
6
也就是说,酷炫的生成新项目骨架的来源,只是简单的递归复制该模块下的
dist/
文件夹到新项目中。但我们需要关注的重点在于,dist/
文件夹下,到底装了什么?“初级 Web App 项目初始化工具”一说,也就名归有主了。
dist/
模板,也就是新项目的骨架如下。新项目骨架中默认推荐了:
src/
目录下;src/
目录要对不同的代码进行合理的分层。End
现在的不足,是未来的畅想。
这个模块并不完美,一个健壮的命令还应该能支持足够多的参数,运行足够有意义的子命令。比如我们常用
man
命令来看另一个命令的使用手册,那要让用户能用到man cs
命令,还需要我们在代码中加入man
字段等等。。我又为什么,这么热衷于分享这个轮子?
记得有一个前端群里曾有人问过:
时,我说过:
这样的能力并不是人人都能具备,也不必要让人人都具备。我曾在大一傲气的说过“做最好的自己,影响该影响的人”,现在想起来除了有立刻找地洞钻进去的冲动外,反而还是觉得有一定的道理(笑。这时候允许我自称为一次“教主”,我们的理念是:
读文档,读文档,读文档。 写博客,写博客,写博客。