yarn 4.x版本创建项目坑

956 阅读6分钟

yarn 4.x版本创建项目坑

yarn 的新版本速度确实非常哇塞,完全不输于 pnpm,并且其天然提供的 workspace 功能更是非常的省事儿,所以我也注意到了这个包管理工具。用了一点空闲时间去了解了一下新版本的yarn。

注意,如果需要直接获取解决方案,找到对应章节下的解决方案直接跳转查看就好。

使用包管理工具那么肯定需要有项目去“play”一下子。但是我在创建项目和使用yarn的过程中遇到了很多有意思的现象,这里也做一个记录,也希望能帮助到大家。

[TOC]

1 初始化一个项目

使用 vite 创建项目。并使用官方提供的示例进行初始化。

yarn create vite 
# 选择vue项目其他配置自选。后续所有vite有关项目都是使用这个命令来创建

yarn 官方的做法是这样的。

corepack enable

yarn init -2

而后静等一下。

这个时候当我想要启动项目的时候发现——:heavy_exclamation_mark:dev 不能被识别为一个命令。

why?我带着好奇心打开了package.json,发现package.json只有两个字段了,一个是name,一个是packageManager。

好奇刚发生了什么,于是我重新创建了一个项目,最后发现是 yarn init -2会直接重写 package.json,导致内容被改写了。丢失了原来的 script。那要怎么把项目中的yarn升级到新版本?

解决方案

yarn set version stable
# stable 也可以换成具体想要的版本号。

# 如果电脑是第一次执行会慢一点,后面就会很快了,

然后就可以正常使用了吗?可能有的小伙伴会继续遇到启动的问题。如果遇到了请继续往后看。

经过我的测试,如果是直接使用下面的方式安装的yarn可能不需要担心后续的问题而直接可以使用了,如果是使用的 npm i -g yarn 会有更大的概率出现下面的问题。至于这个原因我没有深究,就只谈我尝试成功的解决方案。当然我欢迎探讨

# 首先设置corepack
corepack enable

# 注意 如果node版本低于 16 的话可能需要安装一下corepack,16版本之后corepack是会被node默认携带的。
# 安装方法如下:
npm install -g corepack

# 然后直接输入 yarn
yarn 

# 这个时候会提示电脑没有,是否安装,回答 y
# 稍等一些时间yarn就安装好了。
# 不用担心,这个包是全局安装的,

2 缓存配置

所有的包管理器都需要解决一个问题,就是包放哪?也就是包缓存到哪里去。

比如 npm 和 cnpm 会直接缓存到 node_modules, pnpm 会把包放到 node_modules/.pnpm然后通过软连接的形式链接到node_modules下面。其他工具像bun也大差不差。

而自 yarn 2 之后,包也不会直接放在node_modules中了。到了yarn 的 3.x 版本,node_modules几乎就是一个空壳,依赖都默认放在了 .yarn/cache 中。

这一块内容会大量涉及yarn的配置内容,我也大量参考了官方文档:Manifest (package.json) | YarnSettings (.yarnrc.yml) | Yarn 。这里附上链接,相信大佬们肯定会有更不一样的见解。

到了 yarn 4.x ,包的存放方案也有提升,有了全局缓存了。对应的开关就是 enableGlobalCache。以及cacheFolder 对缓存目录的配置。

**为什么提这个?**肯定是和缓存有关了。

当我们按上文配置好yarn的版本后进行启动项目,就会意外发现,启动成功了,但成功了一半。

因为当我们使用启动命令后就会发现,虽然端口出来了,但是随之而来的也有一些文件的报错。目前我收集了两种。

<1> 控制台报错找不到某个文件

启动命令能正常提示出访问网址,但是同时会出现报错。

对于react项目还会出现两个。

image-20241125215424292-1732547887968-5.png 通过这里报错的原因可以知道是因为去找了全局的缓存目录,但是优美找到,而且还寻找了本项目下的.yarn/__virtual__目录,而本地并没有。

image-20241125215750275-1732547858138-2.png

这里我尝试过降低yarn的版本,能够解决这个问题。因为我使用的是 stable 所以是最新版 4.5.2,我就尝试降低一个大版本看看。这个问题会消失的。

yarn set version 3

降低版本的做法让我发现.yarn目录和node_modules的变化。所以这里更是验证了就是下载依赖后的位置和依赖寻址的问题。所以我很容易就去找缓存配置的问题以及包寻址的方式。也不出意外,我找到了能解决这个问题的方案。

解决方法

在项目根路径下创建一个.yarnrc.yml文件,在其中配置:

cacheFolder: .yarn/cache

enableGlobalCache: false

然后就能顺利解决这个问题了。

<2> ts-plugin 提示无法找到模块

对于这个问题,有好几种状态。我参考了这篇文章:关于yarn4与typescript项目编译器报错找不到模块的问题_yarn 4-CSDN博客,大概意思是yarn团队准备出一款vscode插件帮助开发者解决这个问题,而在这个过程中,我们可以通过在.yarnrc.yml中配置nodeLinker: node_modules作为临时方案。虽然知晓了这个问题是客观存在且没有解决的,但是我还有我的考量,因为我发现不同IDE有不同的表现(这里主要指 vscode 和 webStrom)。我做了两个表格简单总结了一下。

首先,我需要解释一下我尝试的三种方案。

  1. nodeLinker 方案。也就是配置 nodeLinker: node_modules 。这样会把依赖全部解析到 node_modules 中,和原来使用 npm 有差别但差别不大,所以 ts-plugin 就能正常解析了。
  2. cacheFolder 方案。可以配置为 cacheFolder: .yarn/cache 。这个做法基本和yarn 3 一致。
  3. Zero-install 方案。也叫零安装。也就是yarn 4.x的默认方案。如果没有配置前两种方案的额内容且使用的是yarn 4.x版本则会默认使用这种方案。

vscode

指标nodeLinker 方案cacheFolder 方案Zero-install 方案
ts-plugin 不报错××
准确类型提示××
打开源码××

webStrom

指标nodeLinker 方案cacheFolder 方案Zero-install 方案
ts-plugin 不报错
准确类型提示×
打开源码×

结论,目前各 IDE 对 零安装的支持还是不高的,但是出乎意料的是webStrom居然能解析cacheFolder方案产生的压缩包,并准确识别到源码。从某种程度上还能让我们去选择跳转到cjs还是mjs文件。webStrom这点挺让我意外的。

希望能帮助各位大佬解决问题,或者进一步分析。

image-20241125223948941-1732547959683-8.png