核心概念
entry、output、loader、plugins、mode
entry
entry含义:用来指定打包的入口
entry用法:
- 单入口 => 应用:单页应用
- 多入口 => 应用:单页应用
output
output用来告诉webpack如何将编译后的文件输入到磁盘。
应用:单/多入口配置
单入口配置
'use strict';
const path = require('path');
module.exports = {
entry: {
index: './src/index.js',
search: './src/search.js'
},
output: {
path: path.join(__dirname, 'dist'), // 文件夹
filename: '[name].js' // 文件
},
mode: 'production'
}
多入口配置
'use strict';
const path = require('path');
module.exports = {
entry: { // entry采用键值对形式
index: './src/index.js',
search: './src/search.js'
},
output: { // output采用占位符
path: path.join(__dirname, 'dist'),
filename: '[name].js' // [] 占位符
},
mode: 'production'
}
loader
webpack开箱即用,只支持Js和json两种文件类型,通过loader去支持其他文件类型并把它们转成有效的模块,并且可以添加到依赖图中。
loader可以理解为转换文件类型。
本身是一个函数,接受源文件作为参数,返回转换的结果。
常见的loader有哪些?
名称 | 作用 |
---|---|
babel-loader | 转换ES6、ES7等新特性语法 |
css-loader | 支持.css文件的加载和解析 |
less-loader | 将less转换成css |
ts-loader | 将ts转换成js |
file-loader | 进行图片、字体等的打包 |
raw-loader | 将文件以字符串的形式导入 |
thread-loader | 多进程打包js和css,加快打包速度 |
写法:
plugins
插件用于bundle文件的优化,资源管理和环境变量注入。可以理解为loader无法做到的事情都是给plugins去完成。
作用于整个构建过程。包括构建前,构建中,构建后。
常用的plugins有哪些?
名称 | 作用 |
---|---|
CommonsChunkPlugin | 将chunks相同的模块代码提取成公共js |
CleanWebpackPlugin | 清理构建目录 |
ExtractTextWebpackPlugin | 将css从bundle文件里提取成一个独立的Css文件 |
CopyWebpackPlugin | 将文件或者文件夹拷贝到构建的输出目录 |
HtmlWebpackPlugin | 创建html文件去承载输出的bundle |
UglifyjsWebpackPlugin | 压缩js |
ZipWebpackPlugin | 将打包的资源压缩成zip包 |
mode
mode用来指定当前的构建环境是:production、development、none
设置mode可以使用webpack的内置函数,默认值为production。
注意:mode是webpack4才有的概念。
mode的内置函数:
选项 | 描述 |
---|---|
development | 设置procee.env.NODE_ENV值为development.开启NameChunkPlugin和NameModulesPlugin |
production | 设置procee.env.NODE_ENV值为production.开启FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurenceOrderPlugin, SideEffectsFlagPlugins和TerserPlugin. |
none | 不开启任何优化选项 |
资源解析
解析ES6、 解析CSS、解析图片和字体
解析ES6
babel-loader + babel配置
// npm安装 babel-core、 babel-preset-env 、babel-loader
npm i @babel/core @babel/preset-env babel-loader -D --save
// 设置.babelrc配置
{\
"presets": [
"@babel/preset-env"
]
}
// webpack.config.js 增加babel-loader配置
module: {
rules: [
{
test: /.js$/,
use: 'babel-loader'
}
]
}
解析CSS
css-loader 用于加载.css文件,并且转换成commonjs对象。
style-loader 将样式通过<style>标签插入到head中。
// 安装npm
npm i style-loader css-loader --save-dev
// webpack.config.js的配置
module: {
rules: [
{
test: /\.css$/,
use: [ // 注意顺序
'style-loader',
'css-loader'
]
}
]
}
注意:loader的调用顺序是从右往左调用,先调用css-loader,再调用style-loader
less
less-loader用于将less转换成css
// npm
npm i less less-loader --save-dev
// webpack.config.js配置
module: {
rules: [
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
解析图片和字体
file-loader 解析文件
// webpack.config.js配置
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
'file-loader'
]
}
url-loader 也可以处理图片和字体,除此之外,还可以对小图片和小字体进行base64的转换。
// webpack.config.js配置
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10240 // 限制10K以下的图片转为base64
}
}
]
}
webpack的文件监听
文件监听是在源码发生变化时,自动重新构建出新的输出文件。
webpack开启文件监听有两种方式:
- 启动webpack命令,带上--watch参数
// package.json添加命令
"scripts": {
"build": "webpack",
"watch": "webpack --watch",
"test": "echo \"Error: no test specified\" && exit 1"
}
- 在配置webpack.config.js的时候,设置watch: true
文件监听的原理分析
轮询判断文件最后编辑时间是否变化
某个文件发生了变化,并不会立刻告诉监听者,而是先缓存起来,等待aggregateTimeout
// webpack.config.js
module.export = {
// 默认false, 也就是不开启
watch: true,
// 只有开启监听模式时,watchOptions才有意义
watchOptions:{
// 默认为空,不监听的文件或者文件夹,支持正则匹配.
// 忽略node_modules,可提高监听性能。
ignored: /node_modules/,
// 监听到变化后会等待300ms执行,默认300ms
aggregateTimeout: 300,
// 判断文件是否发生变化是通过不停询问系统指定文件有没有变化实现的,默认每秒问1000次
poll: 1000
}
}
以上两种方式的文件监听,唯一缺陷: 每次需要手动刷新浏览器。
热更新
- 使用HotModuleReplacementPlugin插件
WDS不刷新浏览器、WDS不输出文件而是放在内存中。
// webpack.config.js
mode: 'development', // 只有开发环境才可以用热更新
plugins: [
new webpack.HotModuleReplacementPlugin()
],
devServer: {
contentBase: './dist',
hot: true
}
// pack.json
"scripts": {
"build": "webpack",
"watch": "webpack --watch",
"dev": "webpack-dev-server --open" // 添加WDS命令
}
- 使用webpack-dev-middleware
WDM将webpack的文件传输给服务器
适用于灵活的定制场景
原理解析: 请参考视频中的概念和流程图。
最主要是HMR server和HMR的runTime
文件指纹
文件指纹是指打包后输出的文件的后缀。好处是用于文件的版本管理以及缓存文件。
chunkHash: 用于js文件
// webpack.config.js
output: {
path: path.join(__dirname, 'dist'), // 文件夹
// js的文件指纹设置
filename: '[name]_[chunkhash:8].js' // 文件
}
contentHash: 用于css文件
// webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [
new MiniCssExtractPlugin({
filename: '[name]_[contenthash:8].css'
})
]
注意:style-loader是将css放入到header里面,而MiniCssExtractPlugin是将css提取出来,两者会有冲突,只能选择一个。
file-loader的name: 图片的文件指纹设置
// webpack.config.js 的 loader设置
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'file-loader',
options: {
// 设置图片的文件指纹
name: '[name]_[hash:8].[ext]'
}
}
]
}
代码压缩
- html压缩
修改html-webpack-plugin的,设置压缩参数。
- css压缩
使用optimize-css-assets-webpack-plugin进行压缩,同时用cssnano进行匹配。
- js压缩
webpack4.0内置了uglifyjs-webpack-plugin的压缩,不需要手动设置。不过可以自行配置参数启动并行压缩。