查阅文档后,最终发现,在 webpack 中其实是可以定义模块解析规则的,除了省略扩展名,定义 alias 外,还可以指定路径,这一项在默认情况下其实是正确的,但是如果你定义了绝对路径,那么他只会根据你定义的路径进行解析,这一部分的 webpack 源码晚些我会发布在下面。
webpack 的具体配置如下
// 文档中的描述
// Tell webpack what directories should be searched when resolving modules.
// Absolute and relative paths can both be used, but be aware that they will behave a bit differently.
// A relative path will be scanned similarly to how Node scans for node_modules, by looking through the current directory as well as its ancestors (i.e. ./node_modules, ../node_modules, and on).
// With an absolute path, it will only search in the given directory.
resolve: {
modules: ['node_modules'], // 这部分非常重要,之前错误的定义为决定路径,实则如果不定义,那么它就会和 nodejs 的行为相近
},
在一个月前遇到了一个棘手的问题,起因大概是这样的,由于我自己希望了解全部的生态,所以我一直都是使用自己的脚手架,而不是Vue或者React官方的提供的脚手架,虽然诸如umi,vue-cli,create-react-app他们做的都很优秀,但是我还是想从中知道每一个plugin,每一个loader都做了什么事情。
在最近的一次升级中,我使用了最新的babel7,并且使用了core-js@3版本,但在过程中遇到了一些问题。
问题
先来看一下我遇到的问题,我使用了
ant-design-vue
这个UI库,他依赖了babel-runtime@6.x
,从编译后的代码可以看到存在着诸如许多import _extends from 'babel-runtime/helpers/extends';
这样的代码。然后我们再来看一下
babel-runtime@6.x
这个库,他依赖了core-js@2
的版本,主要是提供运行时的新 API 转换,例如 babel 不能转换的一些新的 API,他会提供一些 polyfill 级别的解决方案,当然与babel-polyfill
是有本质差异的,babel-polyfill
更多是偏向业务层面的东西,他所支持的语法更多,毕竟babel-runtime
只支持到 static 语法,并不能对[1, 2, 3].includes(1)
进行处理,这里不展开,后面会有篇幅重点介绍。那么现在依赖关系就是我依赖了
ant-design-vue
和core-js@3
,但是ant-design-vue
依赖了core-js@2
,看了 core-js 2和3版本,发现差异还是非常大的,连目录结构都不同了,我仔细查看了依赖结构,实际上其实是不应该有问题的,我把依赖结构写在下面,为了清晰表达省略一些内容。但当我执行编译时,webpack 却提示找不到
core-js@2
中的模块。定位问题
当发现这个问题后,首先想到的肯定是查看 node_modules 中是否存在这个模块,但是查询后发现由于依赖关系的原因,
core-js@2
被放到了babel-runtime
中的 node_modules,然后我就去查阅了 nodejs 的 require 规则,发现他是从module.paths
的目录中依次顺序查找的,那么根据规则,实际上在babel-runtime
中的调用并不会去找我项目中的 node_modules 而是去寻找babel-runtime
中的 node_modules。那么从nodejs的行为上来说,这是正确的,并不会造成两个库依赖的版本不同。找不到模块的情况。
然后我尝试写了一个简单的 demo 来验证这个结论,直接执行 node src/main.js,注释掉对vue文件的引用,因为没有经过 vue-loader 处理的 vue 文件是无法被 nodejs 直接解析的,发现可以顺利通过。
随后使用 webpack 执行,发现报告了找不到模块的错误,这时候第一反应就是 webpack 的配置是有问题的。
解决问题
查阅文档后,最终发现,在 webpack 中其实是可以定义模块解析规则的,除了省略扩展名,定义 alias 外,还可以指定路径,这一项在默认情况下其实是正确的,但是如果你定义了绝对路径,那么他只会根据你定义的路径进行解析,这一部分的 webpack 源码晚些我会发布在下面。
webpack 的具体配置如下
实际上这个问题如果说的复杂,还需要牵扯到许多,我会分几期来说这些问题。