Yarn 3.0 Plug'n'Play (PnP) 安装和迁移
前言
以前用 npm, 后来 yarn 火了就用 yarn. 后来 yarn 2.0 大改版, Angular 不支持就一直没用.
一直到去年的 Angular 13 才开始支持. 最近又开始写 Angular 了, 所以来补上它吧.
这篇会讲到 Node.js v16 + Yarn 3 运行 TypeScript esbuild 和 Webpack 的例子. (刚好我之前有写过 Webpack 和 TypeScript esbuild)
还有如何从 Yarn 1 升级到 Yarn 3 (我之前写的 Webpack 和 TypeScript esbuild 是用 Yarn 1 的)
最后是 Angular 的例子.
一点点历史 npm, yarn, cnpm, pnpm
参考:
主流包管理工具npm、yarn、cnpm、pnpm之间的区别与联系——原理篇
JavaScript package managers compared: npm, Yarn, or pnpm?
npm 是最早的, 很多问题, 后来
yarn 出现了, 解决了很多问题, 后来
pnpm 出现了, 比 npm 和 yarn 都好
yarn 出现后, npm 也一直在进步.
pnpm 出现后, yarn 也一直在进步
cnpm 是 for china 的 npm, 只是这样而已
目前 yarn 1.x 是经典版 (classic) 已经没有在开发了, 但还是有维护
yarn 2.0 (berry 版) 时代是比较苦难的年代, 因为改版太大了, node_modules 直接没了. 所以很多 library 更不上.
yarn 3.0 才比较好一些. 这篇主要就是介绍这个.
Uninstall Yarn 1 and Node.js (npm)
Yarn 3 是搭配 Node.js 一套的, 为了测试我直接把 Yarn 1 和所有 Node.js, npm 统统删除. 一个干净的开始
删除 Node.js 的方式: stackoverflow – How to completely remove node.js from Windows
Yarn 1 的删除方式: Windows start > add or remove > search yarn > remove (如果没有找到就算了)
Remove Yarn files. 上面的所以 folder 检查 nodejs 和 npm 的同时也检查 yarn 这个关键字.
比如 C:\Users\{User}\.yarn 之类的. 全部删除. environment variable 也是删除和 yarn 有关的.
安装 Node.js & Yarn 3
参考: Getting Started with Yarn 3 with TypeScript
安装 Node.js
去 Node.js 官网下载 v16 或以上, 然后安装.
安装 Yarn 3
参考: 官网 installation
安装好 Node.js 后, 打开 cmd (run as administrator).
corepack enable
Yarn 安装和管理是靠它的, 这个是 v16 才有的功能. 默认是关闭的, 以后可能默认会开哦
这个时候 Yarn 就安装好了.
Yarn 3 with VS Code
参考: Editor SDKs
为了让 VS Code 知道 TypeScript, ESLint, Prettier 等等
需要安装 yarn sdk
yarn dlx @yarnpkg/sdks vscode
没有安装的话, TypeScript 会找不到 node_modules/@types, 就报错了.
还需要安装 VS Code ZipFS extension
这是因为 Yarn 3 会用到 zip file
p.s. 每个项目都需要安装一次哦
Multiple wordspace issue
如果你通过项目的 parent folder 打开 VS Code, 你会发现 ESLint 会报错
error log
如果是在 test-material-web folder 打开, 则一切正常, 所以我觉得应该是 multiple workspace 的问题.
然后我找到了一个 VS Code 关于 Yarn PnP 的 issue: Choose different Typescript version for projects in multi root workspaces (needed for Yarn PnP)
他的问题是使用 Yarn PnP 无法在 multiple workspace 情况下选择不同版本的 TypeScript. 虽然和我遇到的不同但是应该是类似的问题.
Yarn 3 with TypeScript esbuild
更新: 20-02-2023 从 v0.15.0 以后 native 就直接支持 PnP 了. 不需要在安装 plugin (安装反而会有 bug, 比如 TS + PnP + esbuild + RxJS 会 error)
之前有写过一篇 TypeScript – Work with JavaScript Library (using esbuild).
可以 follow 搭环境的部分去做.
和 Yarn 1 主要的区别有几点
1. 需要安装 plugin for esbuild
yarn add @yarnpkg/esbuild-plugin-pnp --dev
2. 需要使用 esbuild.js (类似一个 config file, 为了引入 plugin)
const esbuild = require("esbuild"); const { pnpPlugin } = require("@yarnpkg/esbuild-plugin-pnp"); esbuild .build({ entryPoints: ["./index.ts"], minify: process.env.NODE_ENV === "production", bundle: true, outfile: "./bundle.js", plugins: [pnpPlugin()], }) .catch(() => process.exit(1));
3. 运行 command 需要加上 yarn
yarn node esbuild.js
Yarn 3 with Webpack
之前有写过一篇 Webpack 学习笔记
Webpack 5.0 直接支持 Yarn 3, 什么都不需要安装.
用 yarn init -2 做初始化, 然后照着把所有需要的加进去就可以了.
关键: 只有一个点不一样. 不可以用 npm start, 要改成 yarn start, 这样就 ok 了.
Yarn 升级
检查 version
yarn -v
升级
yarn set version stable yarn set version from sources // pre-release yarn set version from sources --branch 1211 // target specify branch yarn install // 升级后最好跑一下
local 也是相同做法
Yarn 降级 downgrade to classic
有时候需要切换 classic 和 canary (比如遇到 bug, 你怀疑是它的问题, 或者项目太久不敢升级)
yarn set version classic // 切换回 1.x 版本, 这时 yarn init 就是 node_modules 的 pattern yarn set version canary // 切换到 3.x 版本. 这时就没有 node_modules 了. 2.x 版本叫 berry yarn set version stable // 建议用这个, 上面那个有时候跑不到的... yarn set version berry // canary 不行, 但是 berry 可以哦 (它也会更新版本 3)
Migration Yarn 1 to 3
为了测试, 我是像上面那样 uninstall Node.js, 然后重新安装 Node.js 和 Yarn 1 (下载 msi)
接着就 follow 官网的 step 做: Yarn Migration
Without PnP
它分 2 个环节
第一个是升级 Yarn, 但没有使用 Plug'n'Play (PnP), node_modules 依然还在那里.
因为不是所有 library 都支持 PnP, 比如 esbuild 需要一个 PnP plugin 才支持, Webpack 要 v5 才支持 (v4 需要 plugin).
所以要确保你依赖的 library 支持 Yarn 3 才可以转去 PnP 哦.
叉的部分是不重要或我的项目不需要的, 所以我不重视.
注意第 10, yarn outdated 没有了, 取而代之的是 yarn upgrade-interactive (有时候需要加 --latest), 要运行这个需要安装 yarn plugin import interactive-tools
它用起来是这样的.
keyboard 上下左右 enter 操作
With PnP
without PnP 会把 nodeLinker set 成 node_modules, 在这里换成 pnp 或者删除它 (因为默认就是 pnp 了)
建议大家可以 yarn init -2 创建一个新项目来对比一下 migration 的版本.
比如 .gitignore
我的发现是 .yarn 里面有些 folder 是必须的, cache (最大的) 则可以不要
.yarn/* !.yarn/patches !.yarn/plugins !.yarn/releases !.yarn/sdks !.yarn/versions # Swap the comments on the following lines if you don't wish to use zero-installs # Documentation here: https://yarnpkg.com/features/zero-installs !.yarn/cache #.pnp.*
如果想把 releases, plugins 全部都 ignore 也不是不行. 只是 git clone 后不能马上 yarn install.
会报错 The "yarn-path" option has been set, 原因是 .yarnrc.yml 记入了路径
这时可以把 .yarnrc.yml 洗掉, 重新跑一次
yarn set version berry
yarn plugin import interactive-tools
让它安装过 plugin 就可以了.
但我还是推荐不要 ignore releases 和 plugins, 这样 git clone 就可以马上 yarn install 使用了. 方便很多.
# Yarn PnP */.yarn/* */!.yarn/patches !*/.yarn/plugins !*/.yarn/releases */!.yarn/sdks */!.yarn/versions # Swap the comments on the following lines if you don't wish to use zero-installs # Documentation here: https://yarnpkg.com/features/zero-installs */!.yarn/cache #.pnp.*
.gitignore starts with ! 意思是反义词, 要保留.
.editor.config
root = true [*] end_of_line = lf insert_final_newline = true [*.{js,json,yml}] charset = utf-8 indent_style = space indent_size = 2
migration 可能会撞, 要小心哦.
yarn list 换成了 yarn info
以前想 list out all package and version 用 yarn list
现在改成了 yarn info
yarn info // all package information yarn info typescript // only typescript info yarn info --name-only // show only name and version
遇到 Bug
我以为等了一个 version, 从 Yarn 2 到 Yarn 3 应该不会遇到什么 Bug 了吧. 不可能还算早鸟吧.
还是太天真...
今天遇到一个 error: The TypeScript language service died 5 times right after it got started. The service will not be restarted
我猜是 Yarn 3 造成的, 于是拿一个 Yarn 1 来跑. 果然是
然后就开始排查. 最后确定是 sdk 的问题, 就去 Github 开 Issue
Yarn 开 Issue 很苛刻, 指明要用 Sherlock 做 reproduction. 不然不处理. 但我不会啊, 而且这个又牵涉到 VS Code 和 TypeScript, Sherlock 未必就搞的出来吧.
不管就直接提交了.
结果他们不到 5 分钟就回复我了, 给了我一个 RC 版本.
安装以后问题就解决了, 也不知道是我倒霉还是怎么着...纳闷...
yarn dlx @yarnpkg/sdks@3.0.0-rc.43 vscode
遇到 Bug 2.0
我就知道, 不成熟的东西总是有 Bug 的. 升级 TypeScript 到 4.7 所有 depend 的 library 直接红灯.
Github Issue – [Bug?]: TS 4.7 beta breaks with yarn pnp
升级 Yarn 到最新的 3.2.1 就可以了
02-09-2022 又来了, 升级 TypeScript 到 4.8 所有 depend 的 library 直接红灯.
Github Issue – Module resolution breaking for Yarn PNP in TS 4.8
Github Issue – TS 4.8.4 not working
Github Issus – [Bug?]: TS 4.9.4 PnP Cannot find module error (update 12-12-2022: 真的是每一版都有 issue 呢)
等吧... 总是慢一拍就是了.
遇到 Bug 3.0
升到 TypeScript 5.0 又出 error.
这里给一点 tips.
1. update yarn version (workspace & global)
2. update @yarnpkg/sdks
3. 却换 TypeScript version
换来换去一下, 有时候它就是要一个 reset 的动作
遇到 Bug 4.0
Issue – ENOTDIR when using yarn 3
Issue – [Bug]: Error with prettier 3.0.0
这次不是 TypeScript 而是 VS Code Prettier Extension。
Prettier 2.8.8 没有问题,升级到 3.0.0 直接坏掉!
目前的 workaround 是 unplug Prettier。
yarn unplug prettier
还有 .vscode > setting.json 一定要指名 prettier sdk 路径
通常在安装 yarn dlx @yarnpkg/sdks vscode 的时候它 detect 到你有 prettier 就会自动添加的。
注意: 上面的方法也解决不了 stylelint extension 的问题。
总之问题多多,如果不要用 Yarn PnP 那全部都可以用新的。如果要 PnP 那么可以考虑用旧 package
保持这几个在旧版本就可以了。不然就是用上面不完善的 wordaround.