读完 Vue 发布源码,小姐姐回答了 leader 的提问,并优化了项目发布流程~

大家好,我是若川。这是 源码共读 第三期活动,纪年小姐姐的第三次投稿。纪年小姐姐学习完优化了自己的项目发布流程,而且回答了leader对她的提问,来看看她的思考和实践。

第三期是 Vue 3.2 发布了,那尤雨溪是怎么发布 Vue.js 的?。不知不觉,源码共读已经进行了快一个月,有些小伙伴表示对面试和工作很有帮助,学完立马能用。如果你也感兴趣可以加我微信 ruochuan12参加。

1. 学习目标和资源准备

这一期阅读的是 Vue3 源码中的 script/release.js 代码,也就是 Vue.js 的发布流程。在上一期源码阅读中从 .github/contributing.md[1] 了解到 Vue.js 采用的是 monorepo 的方式进行代码的管理。

monorepo 是管理项目代码的一个方式,指在一个项目仓库 (repo) 中管理多个模块/包 (package),不同于常见的每个 package 都建一个 repo。

刚好我最近搭建组件库也是使用 monorepo 的方式去管理包。monorepo 有个缺点,因为每个包都维护着自己的 dependencies,那么在 install 的时候会导致 node_modules 的体积非常大。目前最常见的 monorepo 解决方案是使用 lerna 和 yarn 的 workspaces 特性去处理仓库的依赖,我搭建的组件库也是使用了 lerna 和 yarn。但 Vue3 的包管理没有使用 lerna,它是怎么管理依赖包的版本号呢?让我们跟着源码一探究竟。

Lerna[2] 是一个管理工具,用于管理包含多个软件包(package)的 JavaScript 项目,针对使用 git 和 npm 管理多软件包代码仓库的工作流程进行优化。

学习目标:

1)学习 release.js 源码,输出记录文档。

资源准备:

Vue3 源码地址:https://github.com/vuejs/vue-next

2. Yarn Workspace

// vue-next/package.json (多余的代码已省略)
{"private": true,"version": "3.2.2","workspaces": ["packages/*"],"scripts": {"release": "node scripts/release.js"}
}

Yarn 从 1.0 版开始支持 Workspace (工作区),Workspace 可以更好的统一管理有多个项目的仓库。

  • 管理依赖关系便捷:每个项目使用独立的 package.json 管理依赖,可以使用 yarn 命令一次性安装或者升级所有依赖,无需在每个目录下分别安装依赖

  • 降低磁盘空间占用:可以使多个项目共享同一个 node_modules 目录

3. release.js 文件解读

先手动跑一遍 yarn run release --dry,控制台会输出以下信息(多余信息已省略),从控制台日志看出来,发布 Vue.js 会经历以下几个步骤:

// 确认发布版本号
? Select release type ...
> patch (3.2.3)minor (3.3.0)major (4.0.0)custom
// 执行测试用例
Running tests...
// 更新依赖版本
Updating cross dependencies...
// 打包编译所有包
Building all packages...
// 生成 changelog
conventional-changelog -p angular -i CHANGELOG.md -s
// 提交代码
Committing changes...
// 发布包
Publishing packages...
// 推送代码到 GitHub
Pushing to GitHub...

初步了解发布流程后,来看看 release.js 源码做了什么,先看入口函数 main()

main 函数

代码太多就不贴代码了,记录一下思路和思考

  1. 确认要发布的版本:

    • 如果从命令行获取到了版本号,先验证版本号规范,再次确认版本号

    • 如果命令行没有输入版本号,会让用户选择一个版本发布

确认版本号使用了一个库叫 semver,它的作用是用于版本校验比较。

// 目的是获取命令行参数(也就是允许用户自定义输入版本号,比如 yarn release v3.5.0)
const args = require('minimist')(process.argv.slice(2))
let targetVersion = args._[0]
  1. 执行测试用例

const execa = require('execa')
const run = (bin, args, opts = {}) => execa(bin, args, { stdio: 'inherit', ...opts })
const bin = name => path.resolve(__dirname, '../node_modules/.bin/' + name)if (!skipTests && !isDryRun) {// bin("jest") 先获取 node_modules/.bin/jest 的目录,run 的本质就是执行命令行// 这行代码的意思就相当于在命令终端,项目根目录运行 ./node_modules/.bin/jest 命令。await run(bin('jest'), ['--clearCache'])await run('yarn', ['test', '--bail'])
} else {console.log(`(skipped)`)
}
  1. 更新依赖版本

// 1)获取 packages 目录下的所有包
const packages = fs.readdirSync(path.resolve(__dirname, '../packages')).filter(p => !p.endsWith('.ts') && !p.startsWith('.'))
// 1)获取包的根目录路径
const getPkgRoot = pkg => path.resolve(__dirname, '../packages/' + pkg)
// 2)更新根目录和 packages 目录下每个包的 package.json 的版本号
function updateVersions(version) {}
// 3)实现更新 package.json 版本号的,以及更新依赖包的版本号
function updatePackage(pkgRoot, version) {}
// 4)实现更新与 vue 相关依赖包的版本号
function updateDeps(pkg, depType, version) {}
  1. 打包编译所有包

这部分涉及另外一个文件 script/build.js,这个文件主要是将各个包打包在对应的目录下,比如打包一个依赖就运行一次yarn build,如果有多个包,就异步循环调用打包命令。核心代码如下:

/*** 迭代打包* @param {*} maxConcurrency 最大并发* @param {*} source 目录* @param {*} iteratorFn 构建函数(核心就是运行 build 命令)* @returns*/
async function runParallel(maxConcurrency, source, iteratorFn) {const ret = [];const executing = [];for (const item of source) {const p = Promise.resolve().then(() => iteratorFn(item, source));ret.push(p);if (maxConcurrency <= source.length) {const e = p.then(() => executing.splice(executing.indexOf(e), 1));executing.push(e);if (executing.length >= maxConcurrency) {await Promise.race(executing);}}}return Promise.all(ret);
}
  1. 生成 CHANGELOG 文件

主要运行的是这行命令:conventional-changelog -p angular -i CHANGELOG.md -s

  1. 提交代码

先执行 git diff 命令,检查文件是否有修改,如果有,执行 git add 和 git commit 命令

  1. 发布包

最后执行的命令是,yarn publish,发布新版本和打 Tag

  1. 推送到 GitHub

主要运行的命令:

    • 打 tag:git tag ${version}

    • 推送 tag:git push origin refs/tags/${version}

    • 提交代码到远程仓库:git push

至此,release 发布流程已经分析完了。

release 发布流程

4. 感想

回答一下开篇的问题,Vue 是如何管理版本号呢?阅读完源码我们会分现,在发版的时候会统一更新所有包的 package.json 的版本号。对比我在搭建组件库过程中使用的 lerna,其实 lerna 是把 release 这一套流程封装成了一个包,它里面处理发包的流程跟 Vue Release 流程基本是一致的。

这次的源码解读解答了我的一些疑惑。在我搭建组件库的过程中,我一开始了解到的是一个组件一个目录,单包推送到 npm 私库。这样做的缺点很明显,需要在每个目录安装一遍依赖,单独处理版本号。后来了解到了 yarn workspace,知道它可以处理依赖安装的问题,但版本号的处理还是没有解决方案。于是我去寻找业内比较流行的解决办法,发现大部分是使用了 lerna。

于是我向我的 TL 沟通询问,可否采用 yarn + lerna 的方式来搭建组件库。我记得特别清楚他反问我,问我 lerna 解决了什么问题,我支支吾吾回答了官网上的介绍,因为我当时对 lerna 的了解仅停留在官网以及它的常用命令,实际上我不知道它解决了什么问题。TL 见我答不上来,回复了我一句【如无必要,勿增实体】。

通过这次的源码阅读,我可以回答 TL 反问我的那个问题了,lerna 解决的是发包流程中版本号处理,自动生成 CHANGELOG 文件,提交代码,发布包,推送到仓库这几个问题,它把这几个流程封装成命令供用户使用。它不是搭建组件库非必要引入的工具,虽然引用了 lerna 会增加了新的复杂度,但在不了解发包流程的前期使用 lerna 可以使组件库开发者更专注于组件开发的工作上,而不需要过度关注如何发包。

5. 实践

经过一番思考,我认为引入 lerna 确实给系统增加了一些复杂度,因为它要求开发人员额外学习 lerna 的一些知识和命令,增加了学习成本以及系统复杂度。我觉得可以参考 Vue 的 release.js,写一个适用于项目的构建发版脚本用来发包,降低系统复杂度。

逻辑代码基本与 Vue3 的 release.js 和 build.js 一致,去掉了一些没必要的代码,比如单元测试和一些环境判断。还修改了一下 rollup.config.js 的配置,感觉用起来确实比 lerna 好用一些。最终效果如下:

img

参考资料

[1]

.github/contributing.md: https://github.com/vuejs/vue-next/blob/master/.github/contributing.md

[2]

Lerna: https://www.lernajs.cn/

最近组建了一个江西人的前端交流群,如果你是江西人可以加我微信 ruochuan12 私信 江西 拉你进群。


推荐阅读

我在阿里招前端,该怎么帮你(可进面试群)
我读源码的经历

初学者也能看懂的 Vue3 源码中那些实用的基础工具函数
老姚浅谈:怎么学JavaScript?

················· 若川简介 ·················

你好,我是若川,毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》多篇,在知乎、掘金收获超百万阅读。
从2014年起,每年都会写一篇年度总结,已经写了7篇,点击查看年度总结。
同时,活跃在知乎@若川,掘金@若川。致力于分享前端开发经验,愿景:帮助5年内前端人走向前列。

识别方二维码加我微信、拉你进源码共读

今日话题

略。欢迎分享、收藏、点赞、在看我的公众号文章~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/275518.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小程序 富文本自适应屏幕_自适应文本:跨屏幕尺寸构建可读文本

小程序 富文本自适应屏幕Many of you may already know about responsive web design. Cited from Wikipedia, responsive web design (RWD) is an approach to web design that makes web pages render well on a variety of devices and windows or screen sizes. The respon…

Vue、React 之间如何实现代码移植?

大家好&#xff0c;我是若川。面对前端最火的两个框架&#xff0c;学 React 还是 Vue &#xff1f;这可能是每个前端人都曾纠结过的问题。不过&#xff0c;现在你不用纠结了——因为很多公司都是两个框架都有大量的应用&#xff0c;取决于不同团队的技术选型&#xff0c;特别是…

linux mariadb 乱码,配置mariadb远程访问权限,解决数据库乱码问题

配置mariadb远程访问权限&#xff1a;1)登录数据库:# mysql -uroot -p2)配置授权数据库用户远程访问权限&#xff0c;%表示所有远程IP&#xff0c;也可以指定IP。WITH GRANT OPTION表示mysql数据库的grant表中重新加载权限数据&#xff1a;GRANT ALL PRIVILEGES ON *.* TO 用户…

平面设计师和ui设计师_游戏设计师的平面设计

平面设计师和ui设计师Design is a very ancient practice, but graphic design really found its core principles post World War One. Games are also very ancient but video games are still finding their feet. I think graphic design has a few things to teach people…

java合成海报的工具类

2019独角兽企业重金招聘Python工程师标准>>> package io.renren.common.utils;import cn.hutool.core.lang.Console; import io.renren.modules.oss.cloud.OSSFactory;import javax.imageio.ImageIO; import javax.imageio.stream.ImageOutputStream; import java.a…

a说b说谎b说c说谎说d说_说谎的眼睛及其同伙

a说b说谎b说c说谎说d说The eye is a complex and temperamental organ. By the end of this article, designers will have a better understanding of how the eye works with the brain, how it deconstructs images that the brain stitches back up again, and how the two…

一名运营,自学一年前端,成功入职杭州某独角兽企业,他的面试经验和学习方法等分享...

大家好&#xff0c;我是若川。这是我的微信群里小伙伴年年 的投稿。他是19年毕业&#xff0c;之前做的是运营相关的工作&#xff0c;在我的交流群里非常活跃&#xff0c;自学一年前端&#xff0c;目前成功转行入职杭州一家独角兽企业。相信他的文章能带给大家一些启发和激励。0…

百度指数可视化_可视化指数

百度指数可视化Abstract:– Analysis of the visual representations of exponentials.– Proposals to solve current visualization issues.– Call to discussion to come up with a better visual representation convention.抽象&#xff1a; –分析指数的视觉表示形式。…

阿里云谦大佬:时间精力有限的情况下如何高效学习前端?

大家好&#xff0c;我是若川。最近组织了源码共读活动1个月&#xff0c;200人&#xff0c;一起读了4周源码&#xff0c;欢迎加我微信 ruochuan12 进群参与。今天分享一篇阿里云谦大佬的文章。昨天在群里也有小伙伴说到&#xff1a;大佬们是需要什么学什么&#xff0c;新手一般是…

sketch钢笔工具_Sketch和Figma,不同的工具等于不同的结果

sketch钢笔工具We like to compare the difference between various design programs and debate about which one is the most powerful. But we often forget to reflect on how using one of these tools is impacting our product. A powerful artist would say that he ca…

程序下载

Zaxis终端前置机 版 本下 载特 性1.20.1104.102ZaxisSetup.rar 分类: 程序下载转载于:https://www.cnblogs.com/baijinlong/archive/2011/05/13/2045263.html

提升效率的Vue组件开发和实战技巧

大家好我是若川。现在的大前端时代&#xff0c;是一个动荡纷争的时代&#xff0c;江湖中已经分成了很多门派&#xff0c;主要以Vue&#xff0c;React还有Angular为首&#xff0c;形成前端框架三足鼎立的局势。Vue在前端框架中的地位就像曾经的 jQuery&#xff0c;由于其简单易懂…

linux下telnet失败怎么处理,CentOS下telnet退出失败的解决办法

最近有CentOS用户反映在调试网络程序时出现了问题&#xff0c;服务虽然启动了&#xff0c;但客户端却无法连接上&#xff0c;用telnet连接后发现是Windows防火墙的问题&#xff0c;可是用telnet命令连接成功后发现退不出去了&#xff0c;这该怎么办&#xff1f;下面小编就给大家…

figma下载_Figma中的动态内容和颜色

figma下载First off, why use dynamic data?首先&#xff0c;为什么要使用动态数据&#xff1f; It’s easy to create and manage long lists of content 创建和管理一长串内容很容易 You get a better idea of what your product will look like with actual data 通过实际…

你可能不知道的package.json

大家好&#xff0c;我是若川。最近组织了源码共度活动&#xff1a;1个月&#xff0c;200人&#xff0c;一起读了4周源码&#xff0c;参与的小伙伴都表示收获很大。如果感兴趣可以点击链接扫码加我微信 ruochuan12。今天推荐一篇相对简单的文章。前言在上一篇npm init vitejs/ap…

基于上下文的rpn_构建事物-产品评论视频中基于上下文的情感分析

基于上下文的rpnThe word “Social” has taken a whole new meaning in today’s digital era. Simply going out to enjoy is no longer the only “social” criteria. Social now is — giving a peek in your personal and professional life to your connections. Facebo…

可爱的 Python: 使用 mechanize 和 Beautiful Soup 轻松收集 Web 数据

可爱的 Python: 使用 mechanize 和 Beautiful Soup 轻松收集 Web 数据 使用 Python 工具简化 Web 站点数据的提取和组织 David Mertz, Ph.D., 开发人员, Gnosis Software, Inc.从 2000 年开始&#xff0c;David Mertz 就一直在为 developerWorks 专栏 Charming Python 和 XML M…

JavaScript 断点调试技巧

大家好&#xff0c;我是若川。最近组织了源码共度活动&#xff1a;1个月&#xff0c;200人&#xff0c;一起读了4周源码&#xff0c;参与的小伙伴都表示收获很大。如果感兴趣可以点击链接扫码加我微信 ruochuan12。之前推荐过很多次调试文章&#xff0c;说明调试的重要性&#…

大学生电子设计大赛案例分析_为大学生设计问答平台—案例研究

大学生电子设计大赛案例分析Dealing with academic-related questions like picking a course, fulfilling a major requirement can be tedious and ineffective when you have to simultaneously balance school work, social activities, and focus on personal growth and …

最新最详细最简洁Eclipse调试PHP配置详解(Xdebug,Zend Debugger)

搬家注&#xff1a;该日志写于2011 年 04 月 07 日&#xff0c;Eclipse&#xff0c;PHP等版本号很多&#xff0c;更新也比较快&#xff0c;请注意文章中的版本。本文不一定帮您解决问题&#xff0c;但能给您一些解决问题的思路及一些概念。 最近开始做SRTP项目WebOS&#xff0c…