本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
- 前言
大家好,我是若川。欢迎关注我的公众号若川视野,最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12 参与,已进行两个多月,大家一起交流学习,共同进步。
想学源码,极力推荐之前我写的《学习源码整体架构系列》 包含jQuery
、underscore
、lodash
、vuex
、sentry
、axios
、redux
、koa
、vue-devtools
、vuex4
、koa-compose
、vue-next-release
、vue-this
等十余篇源码文章。
美国时间 2021 年 10 月 7 日早晨,Vue 团队等主要贡献者举办了一个
Vue Contributor Days
在线会议,蒋豪群(知乎胖茶,Vue.js 官方团队成员,Vue-CLI 核心开发),在会上公开了create-vue
,一个全新的脚手架工具。
create-vue
使用npm init vue@next
一行命令,就能快如闪电般
初始化好基于vite
的Vue3
项目。
本文就是通过调试和大家一起学习这个300余行的源码。
阅读本文,你将学到:
1 | sh复制代码1. 学会全新的官方脚手架工具 create-vue 的使用和原理 |
- 使用 npm init vue@next 初始化 vue3 项目
create-vue github README上写着,An easy way to start a Vue project
。一种简单的初始化vue项目的方式。
1 | sh复制代码npm init vue@next |
估计大多数读者,第一反应是这样竟然也可以,这么简单快捷?
忍不住想动手在控制台输出命令,我在终端试过,见下图。
最终cd vue3-project
、npm install
、npm run dev
打开页面http://localhost:3000。
2.1 npm init && npx
为啥 npm init
也可以直接初始化一个项目,带着疑问,我们翻看 npm
文档。
npm init 用法:
1 | sh复制代码npm init [--force|-f|--yes|-y|--scope] |
npm init <initializer>
时转换成npx
命令:
- npm init foo -> npx create-foo
- npm init @usr/foo -> npx @usr/create-foo
- npm init @usr -> npx @usr/create
看完文档,我们也就理解了:
1 | sh复制代码# 运行 |
我们可以在这里create-vue,找到一些信息。或者在npm create-vue找到版本等信息。
其中@next
是指定版本,通过npm dist-tag ls create-vue
命令可以看出,next
版本目前对应的是3.0.0-beta.6
。
1 | sh复制代码npm dist-tag ls create-vue |
发布时 npm publish --tag next
这种写法指定 tag
。默认标签是latest
。
可能有读者对 npx
不熟悉,这时找到阮一峰老师博客 npx 介绍、nodejs.cn npx
npx 是一个非常强大的命令,从 npm 的 5.2 版本(发布于 2017 年 7 月)开始可用。
简单说下容易忽略且常用的场景,npx
有点类似小程序提出的随用随走。
轻松地运行本地命令
1 | sh复制代码node_modules/.bin/vite -v |
使用不同的 Node.js 版本运行代码
某些场景下可以临时切换 node
版本,有时比 nvm
包管理方便些。
1 | sh复制代码npx node@14 -v |
无需安装的命令执行
1 | sh复制代码# 启动本地静态服务 |
1 | sh复制代码# 无需全局安装 |
npm init vue@next
(npx create-vue@next
) 快的原因,主要在于依赖少(能不依赖包就不依赖),源码行数少,目前index.js
只有300余行。
- 配置环境调试源码
3.1 克隆 create-vue 项目
本文仓库地址 create-vue-analysis,求个star
~
1 | sh复制代码# 可以直接克隆我的仓库,我的仓库保留的 create-vue 仓库的 git 记录 |
顺带说下:我是怎么保留 create-vue
仓库的 git
记录的。
1 | sh复制代码# 在 github 上新建一个仓库 `create-vue-analysis` 克隆下来 |
关于更多 git subtree
,可以看Git Subtree 简明使用手册
3.2 package.json 分析
1 | js复制代码// create-vue/package.json |
bin
指定可执行脚本。也就是我们可以使用 npx create-vue
的原因。
outfile.cjs
是打包输出的JS
文件
1 | js复制代码{ |
执行 npm run test
时,会先执行钩子函数 pretest
。run-s
是 npm-run-all 提供的命令。run-s build snapshot
命令相当于 npm run build && npm run snapshot
。
根据脚本提示,我们来看 snapshot.js
文件。
3.3 生成快照 snapshot.js
这个文件主要作用是根据const featureFlags = ['typescript', 'jsx', 'router', 'vuex', 'with-tests']
组合生成31种
加上 default
共计 32种
组合,生成快照在 playground
目录。
因为打包生成的 outfile.cjs
代码有做一些处理,不方便调试,我们可以修改为index.js
便于调试。
1 | js复制代码// 路径 create-vue/snapshot.js |
我们可以在for
和 createProjectWithFeatureFlags
打上断点。
createProjectWithFeatureFlags
其实类似在终端输入如下执行这样的命令
1 | sh复制代码node ./index.js --xxx --xxx --force |
1 | js复制代码function createProjectWithFeatureFlags(flags) { |
调试:
VSCode
打开项目,VSCode
高版本(1.50+)可以在create-vue/package.json
=>scripts
=>"test": "node test.js"
。鼠标悬停在test
上会有调试脚本提示,选择调试脚本。如果对调试不熟悉,可以看我之前的文章koa-compose,写的很详细。
调试时,大概率你会遇到:create-vue/index.js
文件中,__dirname
报错问题。可以按照如下方法解决。在 import
的语句后,添加如下语句,就能愉快的调试了。
1 | js复制代码// 路径 create-vue/index.js |
接着我们调试 index.js 文件,来学习。
- 调试 index.js 主流程
回顾下上文 npm init vue@next
初始化项目的。
单从初始化项目输出图来看。主要是三个步骤。
1 | sh复制代码1. 输入项目名称,默认值是 vue-project |
1 | js复制代码async function init() { |
4.1 解析命令行参数
1 | js复制代码// 返回运行当前脚本的工作目录的路径。 |
简单说,这个库,就是解析命令行参数的。看例子,我们比较容易看懂传参和解析结果。
1 | bash复制代码$ node example/parse.js -a beep -b boop |
比如
1 | sh复制代码npm init vue@next --vuex --force |
4.2 如果设置了 feature flags 跳过 prompts 询问
这种写法方便代码测试等。直接跳过交互式询问,同时也可以省时间。
1 | js复制代码// if any of the feature flags is set, we would skip the feature prompts |
4.3 交互式询问一些配置
如上文npm init vue@next
初始化的图示
- 输入项目名称
- 还有是否删除已经存在的同名目录
- 询问使用需要 JSX Router vuex cypress 等。
1 | js复制代码let result = {} |
4.4 初始化询问用户给到的参数,同时也会给到默认值
1 | js复制代码// `initial` won't take effect if the prompt type is null |
4.5 根据模板文件生成初始化项目所需文件
1 | js复制代码 // todo: |
4.6 渲染生成代码模板
1 | js复制代码// Render code template. |
4.7 如果配置了需要 ts
重命名所有的 .js
文件改成 .ts
。
重命名 jsconfig.json
文件为 tsconfig.json
文件。
jsconfig.json 是VSCode的配置文件,可用于配置跳转等。
把index.html
文件里的 main.js
重命名为 main.ts
。
1 | js复制代码// Cleanup. |
4.8 配置了不需要测试
因为所有的模板都有测试文件,所以不需要测试时,执行删除 cypress
、/__tests__/
文件夹
1 | js复制代码 if (!needsTests) { |
4.9 根据使用的 npm / yarn / pnpm 生成README.md 文件,给出运行项目的提示
1 | js复制代码// Instructions: |
- npm run test => node test.js 测试
1 | js复制代码// create-vue/test.js |
主要对生成快照时生成的在 playground
32个文件夹,进行如下测试。
1 | sh复制代码pnpm test:unit:ci |
- 总结
我们使用了快如闪电般的npm init vue@next
,学习npx
命令了。学会了其原理。
1 | sh复制代码npm init vue@next => npx create-vue@next |
快如闪电的原因在于依赖的很少。很多都是自己来实现。如:Vue-CLI
中 vue create vue-project
命令是用官方的npm
包validate-npm-package-name,删除文件夹一般都是使用 rimraf。而 create-vue
是自己实现emptyDir
和isValidPackageName
。
非常建议读者朋友按照文中方法使用VSCode
调试 create-vue
源码。源码中还有很多细节文中由于篇幅有限,未全面展开讲述。
学完本文,可以为自己或者公司创建类似初始化脚手架。
目前版本是3.0.0-beta.6
。我们持续关注学习它。
最后欢迎加我微信 ruochuan12 交流,参与 源码共读 活动,大家一起学习源码,共同进步。
- 参考资料
发现 create-vue 时打算写文章加入到源码共读计划中,大家一起学习。而源码共读群里小伙伴upupming
比我先写完文章。
@upupming vue-cli 将被 create-vue 替代?初始化基于 vite 的 vue3 项目为何如此简单?
关于 && 交流群
最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12 参与,长期交流学习。
作者:常以若川为名混迹于江湖。欢迎加我微信ruochuan12
。前端路上 | 所知甚少,唯善学。
关注公众号若川视野,每周一起学源码,学会看源码,进阶高级前端。
segmentfault
若川视野专栏,开通了若川视野专栏,欢迎关注~
掘金专栏,欢迎关注~
知乎若川视野专栏,开通了若川视野专栏,欢迎关注~
github blog,求个star
^_^~
本文转载自: 掘金