likes
comments
collection
share

一个webpack的配置错误引发的思考,让我的调错能力提升了一个台阶

作者站长头像
站长
· 阅读数 3

这个问题已经是去年 3 三月份遇到的了,因为解决了,所以也就没有怎么理会这个问题了,那么今天我们就对这个问题来进行一下复盘。

项目背景

我开发了一个脚手架,其中有一个包是使用 webpack 配置的 npm 包,在我们项目中安装这个依赖包,并在终端使用特定命令则可以启动该 webpack 配置:

一个webpack的配置错误引发的思考,让我的调错能力提升了一个台阶

当我们安装相关依赖的时候,并执行 start 这个命令,我们的项目就可以打开了。

现在的问题就是,当我们在配置中,对 loader 的配置直接使用 loader 名称字符串(如 "postcss-loader"),Webpack 会在启动构建的项目的 node_modules 目录中寻找这个 loader。但是,由于实际的 loader 位于你的 npm 包内,而非项目本身的 node_modules 目录,Webpack 就无法找到这个 loader,从而报出“模块找不到”的错误。

一个webpack的配置错误引发的思考,让我的调错能力提升了一个台阶

首先,我们先忽略上面的 require.resolve,这个是没有问题的,就是用这个来解决的,那么接下来我们就来复盘一下我是怎么解决了这个问题的。

问题思考

因为这是 webpack 相关的配置,首先我去查找到了相关的官方文档:

一个webpack的配置错误引发的思考,让我的调错能力提升了一个台阶

我看到了这些配置好像和我的并没有什么特别的点,然后我的目光来到了该文档页面的最底部:

一个webpack的配置错误引发的思考,让我的调错能力提升了一个台阶

既然模块是从 node_modules 中查找,我翻遍了第一层目录,好像并没有 postcss-loader 找到这个模块,毛都没有。

那么我的问题就来了,我在另外一个普通的项目中,在项目中直接配置了 webpack 的相关配置,并启动项目:

一个webpack的配置错误引发的思考,让我的调错能力提升了一个台阶

你会发现项目是能启动成功的,那么我们再看看 node_modules 目录下的文件:

一个webpack的配置错误引发的思考,让我的调错能力提升了一个台阶

找到了,这也验证了官方文档中说到的那样,正是通过 node_modules 中查找到的。

那大概问题就找到了,在我的脚手架中的 Webpack 配置里,由于 postcss-loader 是作为依赖包的一个依赖安装的,所以在运行时,Webpack 在尝试解析这个 loader 时未能在项目的直接依赖中找到它,导致了路径查找失败。这表明,问题发生在运行时对模块路径的解析上,即 Webpack 未能定位到 postcss-loader 的实际路径。

解决问题的过程

首先我是查阅了 webpack 的官方文档的,上面已经提到了。

然后我又带着这个问题去查看 Stackoverflow,依然没有找到(我感觉我太菜了),因为国内的社区上并没有写这种项目的相关教程,况且也没有多少人写这种项目,所以我无聊怎么问这个问题我都问不出来。在问问题的过程中,我又去看了一下 webpack 相关的 issue,还是没有发现怎么解决的。

这个问题困扰了我很久还是没有解决,突然我想到 create-react-app 就是我要的,于是我便翻开了它的源码,发现它就是用 require.resolve 来解决这个问题的。

经过这次的思考,我开始学会了查阅官方文档,相关依赖包的 issue,stackoverflow,还有源码来解决问题。

require.resolve 来解决这个问题

require.resolve 是 Node.js 中的一个函数,用于解析某个模块的路径。当你使用 require 函数来导入模块时,Node.js 会根据一定的规则去查找和定位这个模块。require.resolve 函数则可以用来找出 require 函数将会加载的确切文件路径,但它并不会实际加载这个模块。

简单来说,如果你想知道使用 require 加载一个模块时,Node.js 会从哪个文件路径加载,而又不想实际加载这个模块,那么 require.resolve 就非常有用。

通过下面这样的代码,我们就能具体查阅到 postcss-loader 模块的具体入口位置:

const modulePath = require.resolve("postcss-loader");
console.log(modulePath);

这段代码会打印出 postcss-loader 模块的完整路径。如果 postcss-loader 无法被解析,require.resolve 会抛出一个错误。

一个webpack的配置错误引发的思考,让我的调错能力提升了一个台阶

这样,我们就在配置时查找到了该 loader 的具体位置,它会基于 npm 包的位置(而非项目的位置)解析模块的路径,确保无论 npm 包被安装在何处,Webpack 都能正确地找到并加载这些 loader。

总结

一个小小的 webpack 配置,那时候真的是花了我一天时间才解决到的,那时候还不知道为什么能够这样解决的。

于是便有了今天的分享,希望这个查找问题的过程能对你有帮助,如果你有比较好的解决问题过程,也可以分享出来。

最后分享两个我的两个开源项目,它们分别是:

这两个项目都会一直维护的,如果你也喜欢,欢迎 star 🥰🥰🥰