yalc(比 yarn/npm link 更加友好的前端依赖库 link 方案)
不是生活的苟且
编辑于 2022年07月17日 22:18

参考链接

【yalc 官方文档】:https://github.com/wclr/yalc

【yalc-watch 官方文档】:https://github.com/johot/yalc-watch

链接依赖库背景

以 D-SASS 前端框架为例,当我们在修改 D-SASS 前端框架时,当想着马上就要预览到修改的内容是否生效,于是在前端框架目录下进行 npm link 生成一个依赖包的软连接,然后在业务工程中进行 npm install,但是这一过程却有一个致命的缺点就是,webpack 在进行编译的时候无法编译软链接的依赖库。

npm link 或 yarn link

npm link 或者 yarn link 实际上在全局包路径(Global Path)下创建一个软连接(Symlinked)指向 你的 npm 包

然后在业务工程里通过软链接,将全局的软链接指向到 node_modules/[package]

这个往往也是需要两个步骤

npm link # 在需要生成软链接库下执行 npm link [package] # 在业务工程下执行 yarn link #​ 在需要生成软链接库下执行 yarn link [package] # 在业务工程下执行

此方案缺点:

  1. 影响node_modules中原本的依赖包;

  2. 软链接和文件系统引发的其他各种奇怪的问题;

相对路径或者绝对路径使用

比起 npm link,我们还尝试过使用相对路径或者绝对路径进行引用。

将业务代码中的 import 和require所用到的地址,从在 node_modules 里检索改为真实的物理地址。例如:

// import { Button } from 'good-ui' // 为了调试,强行改成了绝对或者相对路径 import { Button } from 'C:/codes/good-ui/dist'

此方案缺点:需要频繁改业务代码,这既麻烦又危险(路径有可能进行修改,在 git 提交代码的时候,引用路径忘记修正回来则其他开发者无法正常使用)。

路径替换

于是 D-SASS 框架支持了使用路径替换问题来解决上面的问题,我们进行提供配置来替换依赖包的真实物理地址,但是该解决方案其实与上面的出现的问题大同小异(配置路径也是挺麻烦的一件事)。

yalc 使用背景

在组件和插件依赖开发中,项目作为依赖库没办法单独直接运行,需要依赖进别的项目执行,这时候最常用的方式就是 npm link。但用 npm link 引入的依赖由于资源文件不在项目下,webpack不会对其做预编译,导致实际构建或者运行时会报错,此时如果直接将文件复制进依赖目录则能正常运行,yalc 能解决此类问题。

优缺点对比

工具

优点

缺点

npm/yarn

无需要更新本地缓存,软链接

会存在相关依赖库丢失问题,正式发布的话会污染 npm 官方源的版本,软链接形式对于预编译库不太友好

yalc

可以模拟 npm 发布,发布至本地缓存库,下载时也是完全模拟 npm install 的过程,不会存在相关依赖库丢失问题,只是模拟发布和下载不会进行真正的推包动作

yalc 本身暂时不能实现自动监听文件变化来自动更新本地仓库代码

为什么要用 yalc

yalc 可以在本地将 npm 包模拟发布,将发布后的资源存放在一个全局存储中。然后可以通过 yalc 将包添加进需要引用的项目中。

这时候 package.json 的依赖表中会多出一个 file:.yalc/... 的依赖包,这就是 yalc 创建的特殊引用。同时也会在项目根目录创建一个 yalc.lock 确保引用资源的一致性。因此,测试完项目还需要执行删除 yalc 包的操作,才能正常使用。

整个过程相对于 npm link 会更加繁琐一些,要经过发包、添加依赖,结束后也需要做清除操作,但也正因此才避免了 npm link 的一些问题。

传统 npm link 依赖表如果出现 N 个依赖,则在使用 npm link 包的时候,需要一个个的去安装,而对于 yalc 来说无需一个个去安装依赖,在项目目录下直接进行 npm install 即可。

yalc 的工作原理

实际上 yalc 和 npm link 的工作原理是大同小异的,可以参照一下下面这张图

npm 包进行 yalc publish 之后(yalc publish 过程只是模拟 npm publish 过程,但是不会真正进行发布,不会污染到官方源的版本线),会把当前的 NPM 包进行发布至本地仓库之中,当项目需要使用到该 NPM 包的时候,我们可以像往常一样安装 yalc 包,这时候 yalc 会把在本地仓库的依赖包拷贝至你的项目 .yalc 这个目录中, 就像 node_modules 一样,当依赖包需要进行修改的话你只需要进行 yalc push 则可以自动更新全局的依赖库以及项目中的依赖库。

yalc 全局存储仓库位置

使用以下命令即可查看存储仓库位置

代码块
Shell
自动换行
复制代码
yalc dir
复制成功

这个位置其实就是相当于 npm publish 发布至 npm 官方仓库的位置,之后我们只要使用 yalc 自带的一些命令即可完成发布和更新的动作

yalc 发布依赖和安装依赖

在所开发的依赖项目下执行发布操作

代码块
Shell
自动换行
复制代码
yalc publish
复制成功

此时如果存在 npm  生命周期脚本:prepublish、prepare、prepublishOnly、prepack、preyalcpublish,会按此顺序逐一执行。

如果存在:postyalcpublish、postpack、publish、postpublish,也会按此顺序逐一执行。

想要完全禁用脚本执行需要使用

代码块
Shell
自动换行
复制代码
yalc publish --no-scripts
复制成功

此时就已经将依赖发布到本地仓库了。在项目中如果想使用该依赖库的时候,可以像 yarn 安装依赖一样安装该依赖

代码块
Shell
自动换行
复制代码
yalc add [packageName]
复制成功

当有新修改的包需要发布时,使用推送命令可以快速的更新所有依赖(此时无需在项目中再次进行 yalc add 了,这一过程 yalc 会进行自动更新)

代码块
Shell
自动换行
复制代码
yalc publish --push
复制成功

以上命令可以简写成

代码块
Shell
自动换行
复制代码
yalc push
复制成功

当你完成依赖包的调试工作,想要回归于原始版本,则只需要一条命令即可解决

代码块
Shell
自动换行
复制代码
yalc remove [packageName]
复制成功

实现自动监听、自动发布更新

yalc 本身是没有做 yalc watch 这个功能的,详见 https://github.com/wclr/yalc/issues/22

之前也说过,在更新依赖库代码的时候需要手动的进行发布和更新,如果有非常频繁的修改,则这一过程也是繁琐的,于是引入了 yalc-watch

yalc-watch 用于监听本地文件修改然后实现自动发布、自动更新的这样一个过程,此工具流程如下。

在依赖库工程下安装 yalc-watch

代码块
Shell
自动换行
复制代码
npm i -D yalc-watch
复制成功

在 package.json 中新增以下代码

代码块
JavaScript
自动换行
复制代码
{  
  "scripts": {    
    "yalc-watch": "yalc-watch"  
  },  
  "yalcWatch": {    
    "watchFolder": "dist",    
    "buildWatchCommand": "tsc --watch", // 依据实际情况配置    
    "extensions": "js,png,svg,gif,jpeg,css" // 依据实际情况配置 
  }
}
复制成功

之后只需要执行 npm run yalc-watch 即可实现自动进行文件监听、自动发布依赖包