Skip to content

Latest commit

 

History

History
117 lines (106 loc) · 4.96 KB

16.webpack中resolve配置项解析.md

File metadata and controls

117 lines (106 loc) · 4.96 KB

resolve配置的作用

在实际的项目开发中,可能会引入不同来源的模块依赖,一般情况下webpack在打包时的模块依赖分为两大类:

  1. 模块来源自自己编写的代码
  2. 模块来源于npm安装的第三方库

那么webpack在打包的时候遇到import语句或者require语句的时候,该如何正确的引入合适的模块代码呢? 这就要用到resolve配置,resolve下的配置都是用来告诉webpack从每个require/import语句中,找到需要引入到bundle中的模块代码。所以resolve的作用就是帮助webpack寻找模块绝对路径的。当打包模块时,webpack 使用 enhanced-resolve 来解析文件路径。

webpack解析不同模块路径的规则

webpack可以对三种文件路径进行解析:

1. 绝对路径

如果模块的路径是一个绝对路径,那么无需再做进一步的解析,比如:

import '/home/me/file';
import 'C:\\Users\\me\\file';

2. 相对路径

如果模块的路径是一个相对路径,那么就会分两步来确定最终导入模块的绝对路径:

  • 首先确定当前使用import或者require的文件的目录,这个目录也就是上下文目录;
  • 然后读取import语句导入时的相对路径,拼接上前面的上下文路径,得到模块的绝对路径

比如在main.js中导入模块:

import APP from "./pages/app.vue"

首先确定当前使用import或者require的文件的目录也就是上下文目录,可以使用path.resolve(__dirname)来进行获取,获取到的路径如下:

C:\Users\克林辣舞\Desktop\webpack\webpack-demo\src 

然后将相对路径"./pages/app.vue"拼接即可,得到最终的模块绝对路径:

C:\Users\克林辣舞\Desktop\webpack\webpack-demo\src\pages\app.vue

3. 模块路径

如果import/require语句导入了一个第三方模块,那么此时webpack就会基于resolve.modules的配置去指定的目录检索模块,默认情况下resolve.modules的值为"node_modules",这也就意味着webpack默认就会去"node_modules"文件夹中读取模块。当然

webpack解析文件/文件夹的规则

在解析完路径之后,如果路径的末尾是一个没有后缀名的文件或者是一个文件夹,那么还需要借助于resolve.extensions和resolve.mainFiles属性来正确的找到最终的模块。

1. 如果是一个文件

  • 文件有拓展名,比如后面是.js、.jsx等,那么就直接加载这个模块即可,比如:
import home from "./pages/home.jsx"
  • 文件没有拓展名,此时webpack并不知道你要加载的是何种类型的模块,此时webpack就会去读取resolve.extensions属性的值,并且读取该属性的值来为此模块加上一个后缀名,然后再加载模块
import utils from "./utils/math"

读取resolve.extensions属性的值:

module.exports = {
	resolve:{
		extensions:['.js', '.json', '.wasm','.jsx','.vue']
	},
}

为math模块拼接上.js后缀,最终得到完整路径:

import utils from "./utils/math.js"

2. 如果是一个文件夹

  • webpack首先会读取resolve.mainFiles属性的值,并按照resolve.extensions配置指定的文件顺序查找。resolve.extensions的默认值是["index"]
  • 再根据resolve.extensions属性配置的值为该文件添加上一个拓展名
import app from "./pages"

首先查找resolve.mainFiles配置的值:

module.exports = {
	resolve:{
		extensions:['.js', '.json', '.wasm','.jsx','.vue'],
		mainFiles: ['index','main'],
	},
}

等于读取到的文件为:

import app from "./pages/index"

然后再读取resolve.extensions属性的值为.js,所以最终解析出的文件路径为:

import app from "./pages/index.js"

配置项目目录别名alias

当我们项目的目录结构比较深的时候,此时如果我们引用一个模块的时候可能需要使用"../../../../"这种相对路径来引入,为了避免这种多个../的书写问题,我们可以在resolve中对常见的路径配置一个项目目录别名:

module.exports = {
	resolve:{
		extensions:['.js', '.json', '.wasm','.jsx','.vue','.mjs','.ts'],
		mainFiles: ['index','main'],
		alias:{
			"@":path.resolve(__dirname,'./src');
			"pages":path.resolve(__dirname,'./src/pages');
		}
	},
}

alias的值是一个对象,可以接受多个项目目录别名配置,在配置之后就可以在项目中基于别名来引入资源:

import Home from "@/Home.vue";

配置导入第三方包时字段mainFields

当我们在代码中导入一个来自node_modules包的时候,默认情况下其实是以下字段的顺序去包的package.json文件下导入模块:

module.exports = {
	resolve:{
		mainFields:['browser','module','main']
	}
}

上面代码的意思是默认情况下,webpack在打包时候遇到第三方模块的时候,是按照'browser'-'module'-'main'字段的顺序去导入模块的,一般情况下都是main字段对应的文件路径,也就是导入模块的路径。