接上文,继续对webpack的一些配置进行总结
resolve
resolve 可以翻译为解析,webpack是从entry入口文件开始,遍历寻找各个模块的依赖,而通过resolve的配置,可以更快速查看到依赖.
常用的配置项有:
resolve.extensions
resolve.extensions
是帮助webpack解析拓展名的配置,默认为
['.wasm', '.mjs', '.js', '.json']
,所以我们引入js和json文件可以不用写拓展名,我们也可以在extensions中添加css,ts等.
module.exports={
resolve:{
extension:['js','json']
}
}
引入方式
import testJson from './index'
resolve.alias
alias可能是我们平时最常用的配置,我们经常喜欢通过alias配置用@
指向文件夹的src
目录.alias
意为别名
,配置alias可以在引入依赖时,使用我们指定的别名来代替文件夹.
module.exports={
resolve:{
alias:{
'@':path.resolve(__dirname,'src')
}
}
}
引用时
const data=require('@/lib/data')
tips
可以通过配置jsconfig.json文件来解决vscode中无法检测文件内容的问题
alias还可以在名称末尾添加$
符号缩小范围只命中以关键词结尾的导入语句,这样可以做到精准匹配
alias:{
react:'/path/react.min.js'
}
import react from 'react' // 会命中精准匹配,指向react.min.js文件
resolve.mainFields
有一些模块会针对不同的环境提供几份代码,比如针对最常见的node和browers环境,在package中可能会这样配置:
{
'main':"",
"module":"",
"browers":""
}
在webpack中会根绝mainFields的设置去决定使用哪个模块代码,不同的target下的mainFields的默认值不同,比如target=web下的默认值为
resolve:{
mainField:['brower','module','main'] // 表示优先级为brower>module>main
}
关于package.json中的brower,main,module可以看这篇文章
package.json 中 你还不清楚的 browser,module,main 字段优先级
module
webpack解析模块时,不同类型的模块需要不同的模块处理器来处理,这部分的配置就是在module中进行配置,module中有两个配置:noParse
和rules
module.noParse
该配置可以忽略对部分没有采用模块化的文件的解析处理,这样可以提高构建速度,使用的方法为一个正则表达式,正则数组或者一个接受模块路径参数的函数
module.exports = {
module: {
// 使用正则表达式
noParse: /jquery|lodash/
// 使用函数,从 Webpack 3.0.0 开始支持
noParse: (content) => {
// content 代表一个模块的文件路径
// 返回 true or false
return /jquery|lodash/.test(content);
}
}
}
module.rules
rules
可以定义webpack在处理指定符合规则的文件时,提交给对应的loader去进行解析处理,rules类型是个数组,每个部分都可以定义处理部分类型文件的方式;
每一项的rules大致由下面三个部分组成:
- 条件匹配:
test
,include
,exclude
可以匹配到对应的文件; - 应用规则:对符合
条件匹配
规则的文件,通过use来指定对应的loader
来解析处理文件; - 重置规则:可以指定一组loader的执行顺序,默认是从右到左;
条件匹配
和条件匹配相关的配置有test
、include
、exclude
、resource
、resourceQuery
和issuer
,条件匹配的对象有三类,resource
,resourceQuery
和issuer
比如说在app.js中导入./style.less?inline
- resource 是path/to/style.less,是对应模块的绝对路径
- resourceQuery 是?之后的inline
- issuer 是path/to/app.js,是引入依赖的文件的绝对路径
rules各配置和匹配对象的对应关系如下:
rule 配置项 | 匹配的对象 |
---|---|
test | resource类型 |
include | resource类型 |
exclude | resource类型 |
resource | resource类型 |
resourceQuery | resourceQuery类型 |
issuer | issuer类型 |
{
test: [/\.jsx?$/, /\.tsx?$/],
include: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'test')
],
exclude: [
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, 'bower_modules')
]
}
如上表示匹配的条件为:来自src
和test
文件夹,不包含node_modules
和bower_modules
子目录,模块的文件路径为.tsx
和.jsx
结尾的文件。
loader
loader用来解析对应的模块
使用loader之前我们需要先安装对应的loader
modules:{
rules:[
{
test:/\.less$/,
use:'less-loader'
}
]
}
如上,对模块名符合/\.less$/
正则匹配的模块,我们使用less-loader去解析,这里的less-loader
会被作为require('less-loader')
进行使用
loader还可以在文件中直接使用
const htmlStr=require('html-loader!./loader.html');
//或者
import htmlStr from 'html-loader!./loader.html'
(这里的!
隔开的命令是从右到左,先加载loader.html在将文件传递给html-loader)
等同于
const html = require('./loader.html');
// webpack.config.js
module.exports = {
module: {
rules: [{test: /\.html$/, use: ['html-loader']}]
}
};
loader的传参
loader本质上是一个函数,可以传递参数,传递参数的方法有两种
- 通过webpack中配置
options
- 通过在loader后直接加
query
// 通过 query 传入
const html = require("html-loader?minimize=true&removeComments=false&collapseWhitespace=false!./file.html");
// 通过 options 传入
module: {
rules: [{
test: /\.html$/,
use: [{
loader: 'html-loader',
options: {
minimize: true,
removeComments: false,
collapseWhitespace: false
}
}]
}]
}
// config内写法,通过 query 传入
module: {
rules: [{
test: /\.html$/,
use: [ {
loader: 'html-loader?minimize=true&removeComments=false&collapseWhitespace=false',
}]
}]
}
loader的执行顺序
一个模块我们在使用时可能需要通过多个loader进行解析,比如less文件我们可以通过less-loader
,css-loader
,style-loader
三个loader进行解析
// query 写法从右到左,使用!隔开
const styles = require('style-loader!css-loader!less-loader!./src/index.less');
// 数组写法,从后到前
module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: [
{
loader: 'style-loader',
enforce:'pre'
},
{
loader: 'css-loader'
},
{
loader: 'less-loader',
enforce:'post'
}
]
}
]
}
};
默认的制定的顺序是从后到前,也就是从less-loader => css-loader => style-loader
,通过enforce配置可以制定loader的执行顺序
oneOf方法
oneOf表示对该资源只应用某一个匹配的规则,一般结合resourceQuery
module.exports = {
//...
module: {
rules: [
{
test: /\.css$/,
oneOf: [
{
resourceQuery: /inline/, // foo.css?inline
use: 'url-loader'
},
{
resourceQuery: /external/, // foo.css?external
use: 'file-loader'
}
]
}
]
}
};
plugin
loader
面对的是一个或者一类模块的,例如less,html的解析,img文件的base64转化,而plugin
面对的是项目的整体,比如整体项目的打包,压缩等,
解决的是loader解决不了的问题.
{
plugins:[
new webpack.optimize.UglifyJsPlugin();
]
}
plugins是一个数组,内容为插件对象的实例,可以使用webpack内置的也可以使用npm引入