Skip to content

npm link 的使用踩坑记录 #136

Description

@lmk123

此博文已迁移至 https://www.micais.me/posts/2025/05/issue-136


我有两个项目 A 和 B。其中:

  • A 是一个 npm 包
  • B 是一个 Webpack 项目,它通过 npm install A 的方式安装 A

现在,我想要在开发阶段直接让 B 安装本地的 A,这样当我频繁修改 A 时,无需 publish 到 npm 里。

踩坑开始。

Webpack 报错“找不到 core-js“

经过排查,问题原因如下。

前提:

  • A 是使用最新的 js 语法写的,且在打包时没有注入任何 polyfill
  • 为此,B 的 Webpack 启用了 @babel/preset-env,这个插件会根据代码里的使用情况自动注入来自 core-js 的 polyfill

报错的原因是,当将 A link 进 B 之后,Webpack 自动给 A 的代码注入了 import 'core-js/xxx 的代码,然后由于 A 在 B 中是一个软链接,B 中的 Webpack 会从 A/node_modules/core-js 读取 corejs,而 A 并没有安装 core-js,所以报错了。

一开始,我是通过给 webpack 设置 resolve.symlinks: false 的方式来解决这个问题的。设置后,webpack 对于软链接的项目,会改为从自身项目里寻找 deps。但是,这样会带来两个问题。

resolve.symlinks: false 的第一个问题:webpack --watch 对项目 A 失效了

在没设置前,webapck --watch 对软链接项目内的代码修改也会触发,而设置后,虽然控制台有动静,但实际上并没有用最新代码。

resolve.symlinks: false 的第二个问题:需要临时安装项目 A 的依赖

在将 A link 进 B 后,npm 会从 B/node_modules 中删掉 A 的所有 deps(类似于 npm uninstall A),而如果 B 没有这些 deps,那么 webpack 还是会报错“找不到模块 xxx“,此时就需要临时把 A 的 deps 安装进 B 中,等开发完了再卸载,很麻烦。

改为在项目 A 中安装 core-js 也有问题

为此,我决定在项目 A 中 npm i -D core-js,并且不设置 resolve.symlinks: false。这样一来,webpack 能从项目 A 中找到 core-js,也不会有上面的两个问题。

一开始挺好的,但是直到有一天,我给 A 和 B 同时安装了 react 和 react-dom。在 B 运行时,浏览器的控制台会报错:使用 hooks 失败,可能原因列了很多,其中一条是“使用了不同版本的 react”。有了前面的经验,我立马明白问题的原因了:A 使用了 A/node_modules/react 而 B 使用了 B/node_modules/react,导致出现了这个问题。

所以,对于 react 这类特殊的 npm 包,必须得让 webpack 只从 B/node_modules 里读取。

最终解决方案:resolve.alias

resolve: {
      alias: {
        react: path.dirname(require.resolve('react/package.json')),
        'react-dom': path.dirname(require.resolve('react-dom/package.json')),
        'core-js': path.dirname(require.resolve('core-js/package.json')),
      }
}

有了上面的配置,就能确保 webpack 在读取 core-js、react 和 react-dom 时,都从 B/node_modules 里读取,这样也不用给 A 安装 core-js 了,算是完美解决了问题。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions