webpack5 入门学习笔记(五)详细配置
写在前面
最后一章。
详细配置
entry
分类
-
单入口
string --> './src/js/index.js'
- 打包形成一个
chunk
,输出一个bundle
文件 - 此时
chunk
的名称默认是main '[name].js'
-
多入口
array --> ['./src/js/index.js','./src/js/add.js']
-
所有入口文件最终只会形成一个
chunk
,输出出去只有一个bundle
文件 -
只有在
HMR
功能中使用,让html
热更新生效['./src/js/index.js','./src/index.html']
object
多入口
-
有几个入口文件就形成几个
chunk
,输出几个bundle
文件(key/value
) -
此时
chunk
的名称是key
{ index:'./src/js/index.js', add:'./src/js/add.js' }
特殊用法
-
所有入口文件最终只会形成一个
chunk
,输出出去只有一个bundle
文件 -
可以把同一类型的文件打包进一个
chunk
{ index:['./src/js/index.js','./src/js/count.js'], react:['react','react-dom','react-router-dom'], add:'./src/js/add.js' }
代码实现
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { resolve } = require('path');
module.exports = {
entry: {
index:'./src/js/index.js',
add:'./src/js/add.js'
},
output: {
filename: '[name].js',
path: resolve(__dirname, 'dist'),
clean:true
},
plugins: [
new HtmlWebpackPlugin()
],
mode:'development'
}
output
参数详情
filename: 'js/[name].js'
文件名称(指定名称+目录)path: resolve(__dirname, 'dist')
输出文件目录(将来所有资源输出的公共目录)publicPath: '/'
资源引入的时候路径前面加/
- (生产环境适用)所有资源引入的路径前缀
'imgs/a.jpg'
是在当前路径下直接找imgs
'/imgs/a.jpg' “/”
会以当前服务器地址补充 在服务器根目录下去找imgs
目录再找a.jpg
- 代码上线是更倾向于使用这种路径
publicPath:'/'
clean: true
清理旧文件chunkFilename:'js/[name]_chunk.js'
非入口文件chunk
的名称,不是entry
指定的入口文件
- import方式引入的
- optimization 将
node_modules
里的分割成单独的chunk
webpack5
自动命名 加上了源文件目录信息js/src_js_add_js.js
- 使用
chunkFilename
之后为js/src_js_add_js_chunk.js
- 都是输出到
filename
指定的目录下(chunkFilename
指定目录优先)
代码实现
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { resolve } = require('path');
module.exports = {
entry: './src/js/index.js',
output: {
//文件名称(指定名称+目录)
filename: 'js/[name].js',
//输出文件目录(将来所有资源输出的公共目录)
path: resolve(__dirname, 'dist'),
/**
* (生产环境适用)所有资源引入的路径前缀
* --> 'imgs/a.jpg' 是在当前路径下直接找imgs
* '/imgs/a.jpg' “/”会以当前服务器地址补充 在服务器根目录下去找imgs目录再找a.jpg 代码上线是更倾向于使用这种路径
* 用publicPath:'/'
*/
publicPath: '/', //资源引入的时候路径前面加/
clean: true, //清理旧文件
/**
* chunkFilename,非入口文件chunk的名称,不是entry指定的入口文件
* 1. import方式引入的
* 2. optimization 将node_modules里的分割成单独的chunk
* webpack5 自动命名 加上了源文件目录信息 js/src_js_add_js.js
* 使用chunkFilename之后为 js/src_js_add_js_chunk.js
* 都是输出到filename指定的目录下(chunkFilename指定目录优先)
*/
// chunkFilename:'js/[name]_chunk.js'
},
plugins: [
new HtmlWebpackPlugin()
],
mode:'development'
}
module
代码实现
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { resolve } = require('path');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].js',
path: resolve(__dirname, 'dist'),
clean: true, //清理旧文件
},
module: {
rules: [
//loader的配置
{
test: /\.css$/,
//多个loader用use
use:['style-loader','css-loader']
},
{
test: /\.js$/,
//排除node_modules下的js文件
exclude: /node_modules/,
//只检查src下的js文件
include: resolve(__dirname, 'src'),
//优先执行
enforce: 'pre',
//延后执行
// enforce: 'post',
//多个loader用use
loader: 'eslint-loader',
options:{}
},
{
//以下配置只会生效一个
oneOf:[]
}
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode:'development'
}
resolve
resolve
解析模块的规则alias
配置解析模块的路径别名alias: { //优点:简写路径,缺点:路径没有提示 $css: resolve(__dirname, 'src/css') //$css 这个变量的值是'src/css'的绝对路径 },
extensions
配置省略文件路径的后缀名//优点:提高开发效率 //缺点:默认有js和json,如果文件同名,优先找第一个js文件 extensions: ['js', 'json', 'css', 'jsx'],
modules
告诉webpack
解析模块是去哪儿找哪个目录//不用一层一层去找 modules:[resolve(__dirname,'../../node_modules'),'node_modules']
代码实现
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { resolve } = require('path');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].js',
path: resolve(__dirname, 'dist'),
clean: true, //清理旧文件
},
module: {
rules: [
//loader的配置
{
test: /\.css$/,
//多个loader用use
use:['style-loader','css-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'development',
//解析模块的规则
resolve: {
//配置解析模块的路径别名:优点:简写路径,缺点:路径没有提示
alias: {
$css: resolve(__dirname, 'src/css') //$css 这个变量的值是'src/css'的绝对路径
},
/**
* 配置省略文件路径的后缀名
* 优点:提高开发效率
* 缺点:默认有js和json,如果文件同名,优先找第一个js文件
*/
extensions: ['js', 'json', 'css', 'jsx'],
/**
* 告诉webpack 解析模块是去哪儿找哪个目录
* 不用一层一层去找
*/
modules:[resolve(__dirname,'../../node_modules'),'node_modules']
}
}
devServer
代码实现
devServer: {
//运行代码的目录
contentBase: resolve(__dirname, 'dist'),
//监视contentBase目录下的所有文件,一旦文件变化就会reload
watchContentBase: true,
watchOptions: {
//忽略一些文件
ignored: /node_modules/
},
//启动gzip压缩
compress: true,
//端口号
port: 5000,
//域名
host: 'loacalhost',
//自动打开浏览器
open: true,
//开启HMR功能
hot: true,
//不要显示启动服务器日志信息
clientLogLevel: 'none',
//除了一些基本的启动信息意外,其他内容都不要显示
quiet: true,
//如果出错了不要全屏提示
overlay: false,
/**
* 服务器代理 --> 解决开发环境跨域问题
* 正常浏览器和服务器通信的时候是存在跨域问题的,
* 同源策略:域名、端口号、协议名不一样就会产生跨域
* 服务器和服务器之间是没有跨域的,我们的代码通过代理服务器运行,浏览器和代理服务器之间是没有跨域的,浏览器将请求发送到代理服务器上
* 代理服务器转发到另一个服务器上,所以请求成功,代理服务器再把响应到的信息转发给浏览器,解决开发环境下的跨域问题
*/
proxy: {
//一旦devServer(5000)服务器接收到/api/xxx的请求,就会把请求转发到另一个服务器(3000)
'/api': {
target: 'http://localhost:3000',
//发送请求时,请求路径重写:将/api/xxx --> /xxx (去掉api)
pathRewrite: {
'^/api':''
}
}
}
}
optimization
- 参考 官方文档splitChunks
splitChunks
参数
- 默认值可以不写
minSize
: 30 * 1024, //分割的chunk最小最30kbmaxSize
: 0, //最大没有限制minChunks
: 1, //要提取的chunk最少被引用一次maxAsyncRequests
: 30, //按需加载时并行加载的文件的最大数量为30minInitialRequests
: 30, //入口js文件最大并行请求数量automaticNameDelimiter
:’~’, //webpack使用块的来源和名称生成名称(例如vendors~main.js),此项指定生成名称的连接符name
:true, // 可以使用命名规则cacheGroups
: {
//分割chunk的组
//node_modules文件会被打包到 defaultVendors组的chunk中 --> defaultVendors~xxx.js
//满足上面的公共规则:如:大小超过30kb,至少被引用一次…
defaultVendors
: {
test
: /[\/]node_modules[\/]/,
priority
: -10,/ /优先级
reuseExistingChunk
: true,- },
default
: {
minChunks
: 2,//要引用的chunk最少被引用两次
priority
: -20,//优先级比-10低
reuseExistingChunk
: true,//如果当前要打包的模块和之前已经被提取的模块是同一个,就会代码复用,而不是重新打包模块- },
- },
runtimeChunk
将当前模块的记录其他模块的hash
单独打包为一个文件runtime
- 解决:修改
a
文件导致b
文件的contenthash
变化,提取公共代码导致缓存失效 - 参考 官方文档runtimeChunk
minimizer
配置生产环境的压缩方案:js
和css
代码实现
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { resolve } = require('path');
const TerserWebpackPlugin = require('terser-webpack-plugin')
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'dist'),
clean: true, //清理旧文件
chunkFilename:'js/[name].[contenthash:10]_chunk.js'
},
module: {
rules: [
//loader的配置
{
test: /\.css$/,
//多个loader用use
use:['style-loader','css-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'production',
//解析模块的规则
resolve: {
//配置解析模块的路径别名:优点:简写路径,缺点:路径没有提示
alias: {
$css: resolve(__dirname, 'src/css') //$css 这个变量的值是'src/css'的绝对路径
},
/**
* 配置省略文件路径的后缀名
* 优点:提高开发效率
* 缺点:默认有js和json,如果文件同名,优先找第一个js文件
*/
extensions: ['js', 'json', 'css', 'jsx'],
/**
* 告诉webpack 解析模块是去哪儿找哪个目录
* 不用一层一层去找
*/
modules:[resolve(__dirname,'../../node_modules'),'node_modules']
},
optimization: {
//参考 [官方文档splitChunks](https://webpack.js.org/plugins/split-chunks-plugin/)
splitChunks: {
chunks: 'all', // all(所有类型的chunks)、async、initial
/* 默认值可以不写
minSize: 30 * 1024, //分割的chunk最小最30kb
maxSize: 0, //最大没有限制
minChunks: 1, //要提取的chunk最少被引用一次
maxAsyncRequests: 30, //按需加载时并行加载的文件的最大数量为30
minInitialRequests: 30, //入口js文件最大并行请求数量
automaticNameDelimiter:'~', //webpack使用块的来源和名称生成名称(例如vendors~main.js),此项指定生成名称的连接符
name:true, // 可以使用命名规则
cacheGroups: { //分割chunk的组
//node_modules文件会被打包到 defaultVendors组的chunk中 --> defaultVendors~xxx.js
//满足上面的公共规则:如:大小超过30kb,至少被引用一次...
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
//优先级
priority: -10,
reuseExistingChunk: true,
},
default: {
//要引用的chunk最少被引用两次
minChunks: 2,
//优先级比-10低
priority: -20,
//如果当前要打包的模块和之前已经被提取的模块是同一个,就会代码复用,而不是重新打包模块
reuseExistingChunk: true,
},
},
*/
},
//参考 [官方文档runtimeChunk](https://webpack.js.org/configuration/optimization/#optimizationruntimechunk)
//将当前模块的记录其他模块的hash单独打包为一个文件 runtime
//解决:修改a文件导致b文件的contenthash变化,提取公共代码导致缓存失效
runtimeChunk: {
name: (entrypoint) => `runtime~${entrypoint.name}`
},
minimize: true,
minimizer: [
//配置生产环境的压缩方案:js和css
new TerserWebpackPlugin({
//参考[官方文档optimization](39节,配置完minimizer之后打包出错,因为webpack5TerserWebpackPlugin中不支持cache和sourceMap参数,注释这两项就不报错了,具体的使用:详见https://webpack.js.org/configuration/optimization/#optimizationruntimechunk)
//开启缓存
// cache: true,
//开启多进程打包
parallel: true,
//启动source-map
// sourceMap: true,
// terserOptions: {
// // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
// },
})
]
}
}
写在后面
webpack5 从入门到精通的学习,完结了,自己最多只算得上入门,还谈不上精通,不过回顾这一段时间的学习,刚好差不多一个月的时间,这种从无到有的感觉,可以拯救自己,去享受这种时刻的时候,仿佛可以暂时忘记生活带来的焦虑,好像自己的生命并不是静止或者倒退,仅仅是这样已经能给人带来莫大的慰藉了,但是这一切都只是开始,不知道终点在何处。