webpack之resolve

webpack从entry开始递归解析所有依赖的模块,而怎么找到这些模块对应的文件,怎么更准确更快地找到这些模块所在文件,这就是resolve擅长的了。我们来了解下。

resolve.modules

默认值是["node_modules"], 意思是,webpack默认先去 当前目录node_modules里找模块,要是没找着,就往上一级目录的node_modules找,还没找着,就继续往上,直到找到为止。
要是到头了还是没找着,那说明根本没这模块。

举例

webpack找模块的机制和Node找模块一样,毕竟webpack是基于nodejs写的嘛。
所以,我们来看Node是怎样解析模块的。
比如,我们可能会这样启动webpack调试,node --inspect-brk node_modules\webpack\bin\webpack.js
webpack.js里需要require.resolve('webpack-cli'),即解析webpack-cli这个模块的绝对路径。
解析过程是这样的:

  • 项目根目录\node_modules\webpack\bin\node_modules里找,没找到,往上
  • 项目根目录\node_modules\webpack\node_modules"里找,没找到,继续往上
  • 项目根目录\node_modules里找,找到了和webpack-cli有关的目录:项目根目录\node_modules\webpack-cli

接下来就是要从项目根目录\node_modules\webpack-cli这个目录找到webpack-cli模块的入口文件。
怎么找?
Node解析模块时会根据文件扩展名[".js", ".json",".node", ".mjs"]去一 一查找。

  • 项目根目录\node_modules有没有webpack-cli.js,没有

  • 项目根目录\node_modules有没有webpack-cli.json,没有

  • 项目根目录\node_modules有没有webpack-cli.node,没有

  • 项目根目录\node_modules有没有webpack-cli.mjs,没有

怎么办?

  • 项目根目录\node_modules\webpack-cli里有没有package.json,有!
  • 读取package.json内容,获取main属性值:./bin/cli.js

所以模块webpack-cli的入口文件所在绝对路径,即require.resolve('webpack-cli')的结果 就是项目根目录\node_modules\webpack-cli\bin\cli.js

实践

实际使用的第三方模块,比如reactvue都是默认放在项目根目录的node_modules里,所以可以指明路径,减少查找。

const path = require('path');
module.exports = {
    resolve:{
        modules:[path.resolve(__dirname,'node_modules')]
    }
}

另外,如果我们自己开发的模块有经常被引用,也可以放到resolve.modules里。

resolve.extensions

默认值是[".wasm",".mjs",".js",".json"]
如果导入的模块没有扩展名,webpack会根据resolve.extensions指定的扩展名一 一查找,谁在前就先查找谁,就像刚刚Node解析webpack-cli模块那样。
显然,如果我们导入模块时就带上文件扩展名,webpack就不用费劲巴拉地找了,
如果我们提供的扩展名们准确,即使要找,webpack也能更快地找到 。
所以,

  • import utils from './utils';import data from './data;' 不如 import utils from './utils.js';import data from './data.json'
  • [".wasm",".mjs",".js",".json"] 比不上 [".js",".json"]

resolve.alias

给文件路径取个别名,这样每次导入模块时就不用写一长串了。

const path = require('path');
module.exports = {
    resolve:{
        alias:{
            'button':path.resolve(__dirname,'src/components/button.js')
            //'button$':path.resolve(__dirname,'src/components/button.js')
        }
    }
}

所以不论哪个文件需要用到Button,直接 import Button from 'button'就好。
'button$':path.resolve(__dirname,'src/components/button.js')用于精准匹配,button$命中以button结尾的文件。
再比如,vue$命中vue.runtime.ems.js或者vue.esm.js 等以vue为结尾的文件。

resolve.mainFiles

默认值是["index"],意思是解析目录时,入口文件名是index

参考文档

解析(Resolve)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值