- 作者:老汪软件技巧
- 发表时间:2024-12-28 15:05
- 浏览量:
文章原文位于github
本书中所说的yarn统一指yarn1,如果是yarn2或者yarn3 yarn4 会特别的著名版本号。
yarn的简介
yarn是一个老版的包管理工具,并一直处于迭代阶段。在2020年之后很多新型的包管理工具,比如pnpm yarn2(也就是之后的berry) 都发展起来,但yarn现在(2024)也是一个很强大的包管理工具,很多新型的包管理工具比如pnpm都沿用了yarn里面的设计和概念。比较知名的是resolution 以及patch。这些概念知道现在还被各个包管理工具沿用。由此可见yarn是一个很强大的工具。
理解yarn的原理有助于理解各个包管理工具的基本概念以及熟练使用各种包管理工具。对于yarn原理的理解,本书用解析源码的方式来展示yarn是如何工作并运行的。另外本书会提及较少新的包管理工具如pnpm以及yarn4的知识。
为什么选择yarn
包管理工具有很多本书为什么偏偏选yarn来讲。
对于新型的包管理工具来讲,比如pnpm以及yarn4,整个源代码体积太大内容太多,组织源代码的形式都是monorepo,很多关键的信息不明显。
对比npm来讲,npm很多关系的代码都是依赖的外部的包,源码并没有在同一个仓库里面,调试起来也很麻烦。
yarn相比之下内容都在一个仓库里面github/yarn/yarn,而且yarn最近4年基本无新的commit,很早就不再继续迭代而且在berry上进行迭代,十分有利于调试。
yarn的发展历史
从yarn官网blog来看yarn最开始于2016年发布,最开始的主打的就是一个快。一直保持很频繁的迭代知道2020年。2020年开始yarn团队主要投入到当时yarn2的开发,也就是berry版本,也就是现在的最新版yarn4的前身。从github/yarn仓库来看,yarn从2020年开始就不再迭代,只是提交了几个细小的配置问题,剩余的pr全部没有合入。现在所有的feature以及bug都在berry的仓库进行修改
截至2024.12.26,yarn的最新版本是1.22.22
源码调试
接下来是调试源码的操作指南
环境准备
需要准备的环境有node,yarn,以及git
运行以下命令
git clone https://github.com/yarnpkg/yarn.git
cd yarn
git checkout -b mybuild-v1.22.22
git reset --hard v1.22.22
yarn
由于yarn源码的包管理工具还是yarn,所以准备的环境中需要有yarn。很多的包管理工具源码的包管理工具也是自己,比如pnpm的源码是用pnpm来管理,npm的源码也是使用npm自己来管理
代码分析
通过package.json看到yarn的源码使用flow来编写,使用babel以及flow 的babel插件来完成编译。为了统一流程yarn使用了gulp。常用的编译是build script,这是把编译到lib目录下,这种编译并不打包。还有一种是build-bundle,这是使用webpack把所有yarn的代码以及依赖的代码全部打到一个文件里面,corepack使用的yarn就是使用的这种形式的打包。
yarn有一些依赖比如package.json里面声明的debug以及commander,这些依赖在全部安装yarn时会一起安装到全局的node_modules文件夹里面。在build-bundle模式下则和yarn的源码被一起打包到了一个单独的文件。
yarn的依赖
yarn打包使用的babel在现在已经时一个很古老的版本了,yarn使用的babel6,现在主流时babel7而且两个版本的插件不兼容,包名也不一样。
为了调试需要编译出带有正确sourcemap的产物文件。这里直接使用新的babel版本以及@babel/preset-flow来编译。由于yarn的源码中大部分的语法都是es6的语法,所以不需要@babel/preset-env,直接生成es6语法的代码。同时为了编译出的module是commonjs需要使用@babel/plugin-transform-modules-commonjs。
打包调试版本
通过上面的分析安装babel有关的包
yarn add -D @babel/core @babel/cli @babel/preset-flow @babel/plugin-transform-modules-commonjs
新建babel.config.js配置文件
module.exports = {
presets: ["@babel/flow"],
plugins: [
[
"@babel/plugin-transform-modules-commonjs",
{
lazy: () => true
}
]
]
};
写入打包的script
{
"mybuild": "babel --no-babelrc src -s -d mybuild"
}
运行yarn mybuild或者直接运行yarn babel --no-babelrc src -s -d mybuil。可以看到mybuild目录生成了带有sourcemap的产物文件。
运行node mybuild/cli/index.js --version输出1.22.22
断点进src/cli/index.js的main函数,进行调试,发现断点能命中,证明编译的文件以及sourcemap没有问题
后续
本章已经打包出sourcemap的产物并验证了可以调试源码,后续将使用此产物调试。可以结合vscode的launch.json来进行调试。
author: xiaochuan
date: 2024.12.23