Webpack实战教程
目录
1.webpack简介
1.1版本要求
Node.js >= 10
webpack >= 4.26
1.2webpack简介
- 一种前端资源构建工具
- 一个静态模块打包器
- 通过webpack可以将前端所有的资源文件(js/json/css/img/less)等资源根据相互依赖关系进行静态分析,打包生成对应的静态资源bundle
1.2webpack五个核心概念
- entry:入口
- output:输出
- loader:处理非js文件,因为webpack只能识别js,所以需要将其他的非js文件转换为js
- plugins:插件,用于进行打包优化,压缩,定义环境中的变量等
- mode:模式,用于区分开发环境和生产环境,分为development和production
2.webpack初体验
2.1初始化项目
// 初始化项目目录
npm init -y
// 安装webpack、webpack-cli
npm i webpack webpack-cli -D
- 项目目录
- index.js文件
function add(x, y) {
return x + y
}
console.log(add(1, 2));
- 开发和生产模式下对项目进行打包
//development
npx webpack ./src/index.js -o ./dist --mode=development
//production
npx webpack ./src/index.js -o ./dist --mode=production
- 打包完成生成dist文件夹及该文件夹下的main.js文件
2.2.引入json文件
- person.json
{
"name": "Tom",
"age": 18
}
- 引入index.js文件中
import person from './person.json'
function add(x, y) {
return x + y
}
console.log(add(1, 2));
console.log(person);
- 对项目进行打包,并运行打包后的文件,发现能够正常输出,说明webpack可以识别js和json格式的文件
node .\dist\main.js
//输出
3
{"name": "Tom", "age": 18}
2.3.webpack配置文件
// 引入node的路径path模块
const path = require("path")
module.exports = {
// entry入口文件地址
entry: "./src/index.js",
// output输出文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist')
},
// loader相关配置
module: {
rules: []
},
// plugins插件相关配置
plugins: [],
// mode模式
mode: 'development'
// mode: 'production'
}
- 打包生成bundle.js文件
npx webpack
2.4.打包样式资源文件
- 安装相关的loader依赖
npm i css-loader style-loader -D
- 创建css文件,并引入index.js文件中
html
body{
padding: 0px;
margin: 0px;
background-color: aqua;
}
import './style.css'
- 配置webpack
// 引入node的路径path模块
const path = require("path")
module.exports = {
// entry入口文件地址
entry: "./src/index.js",
// output输出文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist')
},
// loader相关配置
module: {
rules: [
{
// 正则匹配文件名
test: /\.css$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
'style-loader',
// 加载css相关文件,转换成能识别的js文件
'css-loader'
]
}
]
},
// plugins插件相关配置
plugins: [],
// mode模式
mode: 'development'
// mode: 'production'
}
- 执行打包命令,发现css文件被成功的打包了
2.5.打包样式资源less文件
- 安装less及less-loader依赖
npm i less less-loader -D
- webpack相关配置
// 引入node的路径path模块
const path = require("path")
module.exports = {
// entry入口文件地址
entry: "./src/index.js",
// output输出文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist')
},
// loader相关配置
module: {
rules: [
{
// 正则匹配文件名
test: /\.css$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
'style-loader',
// 加载css相关文件,转换成能识别的js文件
'css-loader'
]
},
{
// 正则匹配文件名
test: /\.less$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
'style-loader',
// 加载css相关文件,转换成能识别的js文件
'css-loader',
// 使用less-loader将less文件转换成css文件
'less-loader'
]
}
]
},
// plugins插件相关配置
plugins: [],
// mode模式
mode: 'development'
// mode: 'production'
}
- 执行打包命令,发现less文件被成功的打包了
2.6.打包HTML资源
- 安装插件html-webpack-plugin
npm i html-webpack-plugin -D
- 此插件的目的是默认创建一个index.html文件,并引入打包后的bundle.js文件,如下是webpack相关配置
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// entry入口文件地址
entry: "./src/index.js",
// output输出文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist')
},
// loader相关配置
module: {
rules: [
{
// 正则匹配文件名
test: /\.css$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
'style-loader',
// 加载css相关文件,转换成能识别的js文件
'css-loader'
]
},
{
// 正则匹配文件名
test: /\.less$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
'style-loader',
// 加载css相关文件,转换成能识别的js文件
'css-loader',
// 使用less-loader将less文件转换成css文件
'less-loader'
]
}
]
},
// plugins插件相关配置
plugins: [
new HtmlWebpackPlugin({
// html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
template: './src/index.html'
})
],
// mode模式
mode: 'development'
// mode: 'production'
}
2.7.打包图片资源
- 安装依赖
npm i html-loader -D
-
需要注意的是,这里的图片可以在js、css和html的img标签中引入,使用url-loader可以处理js和css中的图片,html中的图片需要使用html-loader进行单独的处理
-
webpack4中图片的loader配置较为繁琐
{
// 正则匹配文件名
test: /\.(png|svg|jpg|jpeg|gif)$/i,
loader: 'url-loader',
options: {
// 图片大小小于8kb,就会被base64编码
// 优点:减少请求次数,减轻服务器压力
// 缺点:js体积变大,速度变慢
limit: 8 * 1024,
// 问题:url-loader默认使用es6模块解析,而html-loader引入图片是common.js,解析时会出现【object module】
// 解决:关闭url-loader的es6模块化,使用common.js解析
esModule: false,
// 自定义命名,取hash值的前十位
name: '[hash:10].[ext]'
}
},
// 处理html中的图片,让后续的loader进行解析
{
test: /\.html$/i,
loader: 'html-loader'
}
- webpack5中对于图片的处理相对简单
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// entry入口文件地址
entry: "./src/index.js",
// output输出文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist'),
// 自定义静态资源文件名
assetModuleFilename: "images/[hash:10][ext][query]"
},
// loader相关配置
module: {
rules: [
{
// 正则匹配文件名
test: /\.css$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
'style-loader',
// 加载css相关文件,转换成能识别的js文件
'css-loader'
]
},
{
// 正则匹配文件名
test: /\.less$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
'style-loader',
// 加载css相关文件,转换成能识别的js文件
'css-loader',
// 使用less-loader将less文件转换成css文件
'less-loader'
]
},
{
// 正则匹配文件名
test: /\.(png|svg|jpg|jpeg|gif)$/i,
// webpack5
type: 'asset'
},
// 处理html中的图片,让后续的loader进行解析
{
test: /\.html$/i,
loader: 'html-loader'
}
]
},
// plugins插件相关配置
plugins: [
new HtmlWebpackPlugin({
// html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
template: './src/index.html'
})
],
// mode模式
mode: 'development'
// mode: 'production'
}
2.8.打包字体资源
- webpack4中的相关配置
{
exclude:/\.(js|less|html|css)$/i,
type:'file-loader',
options:{
name:'[hash:10].[ext]'
}
}
- webpack5中的相关配置
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// entry入口文件地址
entry: "./src/index.js",
// output输出文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist'),
// 自定义静态资源文件名
assetModuleFilename: "images/[hash:10][ext][query]"
},
// loader相关配置
module: {
rules: [
{
// 正则匹配文件名
test: /\.css$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
'style-loader',
// 加载css相关文件,转换成能识别的js文件
'css-loader'
]
},
{
// 正则匹配文件名
test: /\.less$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
'style-loader',
// 加载css相关文件,转换成能识别的js文件
'css-loader',
// 使用less-loader将less文件转换成css文件
'less-loader'
]
},
{
// 正则匹配文件名
test: /\.(png|svg|jpg|jpeg|gif)$/i,
// webpack5
type: 'asset'
},
// 处理html中的图片,让后续的loader进行解析
{
test: /\.html$/i,
loader: 'html-loader'
},
// 处理字体文件
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource'
}
]
},
// plugins插件相关配置
plugins: [
new HtmlWebpackPlugin({
// html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
template: './src/index.html'
})
],
// mode模式
mode: 'development'
// mode: 'production'
}
3.Webpack开发环境基本配置
3.1.devServer开发服务器(自动编译,自动打开浏览器,自动刷新浏览器),特点就是开发服务器不会再dist文件夹下有任何的输出,他是在内存中完成的编译
- 安装依赖
npm i webpack-dev-server --D
- 为了方便启动,可以在package.json文件中配置启动命令
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack serve",
"build": "webpack"
},
- 然后执行npm run dev即可,不会在dist文件夹中有任何的输出
4.Webpack生产环境基本配置
4.1.如果按照开发环境进行配置的话会有以下几个问题
- css通过js动态生成,会出现闪屏的问题
- 代码没有压缩
- 浏览器兼容性问题
4.2.提取css成单独的文件
- 安装依赖
npm i mini-css-extract-plugin -D
- 相关配置
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
// devServer
// webpack5
devServer: {
// 启动后自动打开浏览器
open: true,
// 监听端口号
port: 8080
},
// entry入口文件地址
entry: "./src/index.js",
// output输出文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist'),
// 自定义静态资源文件名
assetModuleFilename: "images/[hash:10][ext][query]"
},
// loader相关配置
module: {
rules: [
{
// 正则匹配文件名
test: /\.css$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
// 'style-loader',
// 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
MiniCssExtractPlugin.loader,
// 加载css相关文件,转换成能识别的js文件
'css-loader'
]
},
{
// 正则匹配文件名
test: /\.less$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
// 'style-loader',
// 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
MiniCssExtractPlugin.loader,
// 加载css相关文件,转换成能识别的js文件
'css-loader',
// 使用less-loader将less文件转换成css文件
'less-loader'
]
},
{
// 正则匹配文件名
test: /\.(png|svg|jpg|jpeg|gif)$/i,
// webpack5
type: 'asset'
},
// 处理html中的图片,让后续的loader进行解析
{
test: /\.html$/i,
loader: 'html-loader'
},
// 处理字体文件
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource'
}
]
},
// plugins插件相关配置
plugins: [
new HtmlWebpackPlugin({
// html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
template: './src/index.html'
}),
// 提取css为单独的文件
new MiniCssExtractPlugin({
filename: "[name].css"
})
],
// mode模式
mode: 'development'
// mode: 'production'
}
4.3.css兼容性处理
- 在处理css样式兼容性问题时,需要考虑两个方面,一是样式的确会有兼容性问题,二是当前的css需要兼容到哪个版本的浏览器也就是browserslist
//在package.json中,添加browserslist
"browserslist": {
"development": [
"last 1 version"
],
"production": [
"last 1 version",
">1%",
"ie 10"
]
}
- webpack相关配置(webpack5)
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
// devServer
// webpack5
devServer: {
// 启动后自动打开浏览器
open: true,
// 监听端口号
port: 8080
},
// entry入口文件地址
entry: "./src/index.js",
// output输出文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist'),
// 自定义静态资源文件名
assetModuleFilename: "images/[hash:10][ext][query]",
// 在生成文件之前清空output目录
clean: true
},
// loader相关配置
module: {
rules: [
{
// 正则匹配文件名
test: /\.css$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
// 'style-loader',
// 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
MiniCssExtractPlugin.loader,
// 加载css相关文件,转换成能识别的js文件
'css-loader',
// 配置预加载样式postcss
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env"
]
]
}
}
},
]
},
{
// 正则匹配文件名
test: /\.less$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
// 'style-loader',
// 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
MiniCssExtractPlugin.loader,
// 加载css相关文件,转换成能识别的js文件
'css-loader',
// 配置预加载样式postcss
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env"
]
]
}
}
},
// 使用less-loader将less文件转换成css文件
'less-loader'
]
},
{
// 正则匹配文件名
test: /\.(png|svg|jpg|jpeg|gif)$/i,
// webpack5
type: 'asset'
},
// 处理html中的图片,让后续的loader进行解析
{
test: /\.html$/i,
loader: 'html-loader'
},
// 处理字体文件
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource'
}
]
},
// plugins插件相关配置
plugins: [
new HtmlWebpackPlugin({
// html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
template: './src/index.html'
}),
// 提取css为单独的文件
new MiniCssExtractPlugin({
filename: "[name].css"
})
],
// mode模式
mode: 'development'
// mode: 'production'
}
4.4.css压缩
- webpack4中使用optimize-css-assets-webpack-plugin
- webpack5中使用css-minimizer-webpack-plugin
- 安装依赖(此处以webpack5为例)
npm i css-minimizer-webpack-plugin -D
- webpack配置
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
module.exports = {
// devServer
// webpack5
devServer: {
// 启动后自动打开浏览器
open: true,
// 监听端口号
port: 8080
},
// entry入口文件地址
entry: "./src/index.js",
// output输出文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist'),
// 自定义静态资源文件名
assetModuleFilename: "images/[hash:10][ext][query]",
// 在生成文件之前清空output目录
clean: true
},
// loader相关配置
module: {
rules: [
{
// 正则匹配文件名
test: /\.css$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
// 'style-loader',
// 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
MiniCssExtractPlugin.loader,
// 加载css相关文件,转换成能识别的js文件
'css-loader',
// 配置预加载样式postcss
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env"
]
]
}
}
},
]
},
{
// 正则匹配文件名
test: /\.less$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
// 'style-loader',
// 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
MiniCssExtractPlugin.loader,
// 加载css相关文件,转换成能识别的js文件
'css-loader',
// 配置预加载样式postcss
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env"
]
]
}
}
},
// 使用less-loader将less文件转换成css文件
'less-loader'
]
},
{
// 正则匹配文件名
test: /\.(png|svg|jpg|jpeg|gif)$/i,
// webpack5
type: 'asset'
},
// 处理html中的图片,让后续的loader进行解析
{
test: /\.html$/i,
loader: 'html-loader'
},
// 处理字体文件
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource'
}
]
},
// plugins插件相关配置
plugins: [
new HtmlWebpackPlugin({
// html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
template: './src/index.html'
}),
// 提取css为单独的文件
new MiniCssExtractPlugin({
filename: "[name].css"
})
],
optimization: {
// 开发环境下启用css优化
minimize: true,
minimizer: [
// 使用cssnano优化和压缩css
new CssMinimizerPlugin()
]
},
// mode模式
mode: 'development'
// mode: 'production'
}
4.5.js语法检查Eslint
- 可以通过配置文件中的rules规则,去检查代码,现阶段eslint配置文件的写法有多种,可以时.eslintrc、.eslintrc.js、.eslintrc.json、也可以在package.json中写eslintConfig配置实现
- 这里以.eslintrc.js为例
module.exports = {
// 继承Eslint官方的配置
extends: ["eslint:recommended"],
env: {
node: true, //启用node全局变量
browser: true,//启用浏览器中全局变量
},
parserOptions: {
ecmaVersion: 6, //es6
sourceType: "module" //es module
},
rules: {
"no-var": 2, //不能使用var声明变量
}
}
- webpack相关配置(这里以webpack5为例)
// 引入node的路径path模块
const path = require("path")
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const ESlintPlugin = require('eslint-webpack-plugin')
module.exports = {
// devServer
// webpack5
devServer: {
// 启动后自动打开浏览器
open: true,
// 监听端口号
port: 8080
},
// entry入口文件地址
entry: "./src/index.js",
// output输出文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist'),
// 自定义静态资源文件名
assetModuleFilename: "images/[hash:10][ext][query]",
// 在生成文件之前清空output目录
clean: true
},
// loader相关配置
module: {
rules: [
{
// 正则匹配文件名
test: /\.css$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
// 'style-loader',
// 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
MiniCssExtractPlugin.loader,
// 加载css相关文件,转换成能识别的js文件
'css-loader',
// 配置预加载样式postcss
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env"
]
]
}
}
},
]
},
{
// 正则匹配文件名
test: /\.less$/,
// 使用的loader处理文件,执行顺序是从下到上
use: [
// 创建style标签,插入到head中
// 'style-loader',
// 如果使用了mini-css-extract-plugin插件,就不需要创建style标签插入head中了
MiniCssExtractPlugin.loader,
// 加载css相关文件,转换成能识别的js文件
'css-loader',
// 配置预加载样式postcss
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env"
]
]
}
}
},
// 使用less-loader将less文件转换成css文件
'less-loader'
]
},
{
// 正则匹配文件名
test: /\.(png|svg|jpg|jpeg|gif)$/i,
// webpack5
type: 'asset'
},
// 处理html中的图片,让后续的loader进行解析
{
test: /\.html$/i,
loader: 'html-loader'
},
// 处理字体文件
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource'
},
]
},
// plugins插件相关配置
plugins: [
new HtmlWebpackPlugin({
// html模板文件的位置,打包完成后会在dist文件夹下生成index.html文件,并且会默认的引入bundle.js
template: './src/index.html'
}),
// 提取css为单独的文件
new MiniCssExtractPlugin({
filename: "[name].css"
}),
// 在webpack5中配置eslint不需要配置loader了,只需要配置plugin即可
new ESlintPlugin({
// 使用eslint对代码进行检查,只需要检查src下面的文件
context:path.resolve(__dirname,'src')
})
],
optimization: {
// 开发环境下启用css优化
minimize: true,
minimizer: [
// 使用cssnano优化和压缩css
new CssMinimizerPlugin()
]
},
// mode模式
mode: 'development'
// mode: 'production'
}
4.6.js的兼容性处理
- 处理方案有三种
- 1、@babel/preset-env基于js兼容性处理,问题是只能转换基本的js代码,不能转换高级的Promise语法
- 2、@babel/polyfil兼容全部的js,问题是将所有兼容的代码全部引入,体积太大
- 3、core-js按需加载,只加载需要处理的兼容性语法
- 方案一
安装依赖
npm i babel-loader @babel/core @babel/preset-env -D
webpack相关配置
// js兼容性处理
{
test:/\.m?js$/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
// 基本的兼容性处理
preset:['@babel/preset-env']
}
}
- 方案二
安装依赖
npm i @babel/polyfill -S
这里不需要再webpack配置,只需要在main.js中引入即可
import '@babel/polyfill'
- 方案三
安装依赖
npm i core-js -D
webpack配置
// js兼容性处理
{
test: /\.m?js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 基本的兼容性处理
presets: [['@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core版本
corejs: {
version: 3
},
// 指定兼容性到哪个浏览器版本
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]]
}
}
4.7.压缩html和js
- 当mode模式设置为production后,默认会开启html和js的压缩,我们这里可以使用terser优化html和js的压缩
安装依赖
npm i terser-webpack-plugin --save-dev
webpack依赖
const TerserPlugin=require('terser-webpack-plugin')
optimization: {
// 开发环境下启用css优化
minimize: true,
minimizer: [
// 使用cssnano优化和压缩css
new CssMinimizerPlugin(),
// 使用terser优化压缩
new TerserPlu**加粗样式**gin()
]
},
5.Webpack性能优化配置
- 开发环境性能优化
- 优化代码构建速度
- 优化代码调试
- 生产环境性能优化
- 优化打包构建速度
- 优化代码运行的性能
5.1.HMR模块热更新:当一个模块发生变化时,只会重新打包这一个模块的代码,不是打包所有的代码,会提高构建速度
- 样式文件:可以使用HMR功能,style-loader内部实现
- js文件,默认没有HMR热更新
- html文件,默认没有HMR热更新
webpack配置
devServer: {
// 启动后自动打开浏览器
open: true,
// 监听端口号
port: 8080,
// 开启HMR功能,修改配置之后需要重启webpack
hot:true
},
5.2.sorce map源码映射:一种提供源代码到构建后代码映射技术,一旦构建代码出错,可以通过映射关系找到源代码出错的位置
webpack相关配置
module.exports = {
// devServer
// webpack5
devServer: {
// 启动后自动打开浏览器
open: true,
// 监听端口号
port: 8080,
// 开启HMR功能,修改配置之后需要重启webpack
hot: true
},
// 可选值[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
devtool: 'source-map',
}
值 | 说明 | 错误提示 |
---|---|---|
source-map | 外部 | 错误代码的准确信息,源代码的错误位置 |
inline-source-map | 内联,只生成一个内联source-map | 错误代码的准确信息,源代码的错误位置 |
hidden-source-map | 外部 | 错误代码的原因,没有源代码错误位置,只有构建后的代码位置 |
eval-source-map | 内联每个文件都生成对应的source-map,都在eval里 | 错误代码的准确信息,源代码的错误位置 |
nosource-source-map | 外部 | 有错误代码准确信息,没有源代码位置 |
cheap-source-map | 外部 | 有错误代码准确信息,有源代码信息,只能精确到行 |
cheap-module-source-map | 外部 | 有错误代码准确信息,源代码的错误位置 |
- 内联和外部
- 内联:构建速度快
- 外部:生成单独的文件,内联没有
范德萨发
开发环境:速度快,调试更友好
速度快:
eval>inline>cheap>eval-cheap-source-map>eval-source-map
调试更友好:
source-map
生产环境:内联会让代码体积变大,所以生产环境不适用内联
nosource-source-map 全部隐藏
hidden-source-map 只会隐藏源代码,会提示构建后代码错误
5.3.babel-loader缓存:第二次打包构建速度更快
webpack配置
// js兼容性处理
{
test: /\.m?js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 基本的兼容性处理
presets: [['@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core版本
corejs: {
version: 3
},
// 指定兼容性到哪个浏览器版本
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]],
// 开启编译缓存
cacheDirectory: true
}
}
5.4.文件资源缓存
- hash:每次webpack构建打包,都会生成唯一的hash,如果只有一个文件发生变化,也会重新打包生成新的hash,这样会导致资源的浪费
- chunkhash:根据chunk生成hash值,入股哦打包来源于同一个chunk,那么hash值就是一样的
- contenthash:根据文件的内容生成hash,如果内容发生变化会重新生成新的hash值
5.5.tree shaking树摇
- 去除无用代码,减少代码体积,webpack5中已默认支持tree shaking,但是需要使用es6模块化,必须开启production,
- 简单来说有三种:
- usedExports:会删除没有使用过的一些导入
- sideEffects:删除模块中导出了,但是未被使用的变量
- dead code elimination:删除死代码
5.6.code split代码分割
- 使用多入口文件
// entry多入口文件
entry:{
main:'./main.js',
index:'./index.js'
},
- 公共代码防止重复打包
//自动分析多入口chunk中,如果有公共的代码,会打包成单独的一个chunk
optimization: {
splitChunks:{
chunks:'all', //对所有模块都进行分割
}
},
- 动态导入,按需加载
document.getElementById('app').onclick=function(){
import ('./index.js').then(res=>{
// 加载成功
}).catch(err=>{
// 加载失败
})
}
5.7.多进程打包
// 安装依赖
npm i thread-loader -D
webpack配置
{
test: /\.m?js$/,
exclude: /node_modules/,
use:[
{
loader:'thread-loader', //开启多线程打包
},
{
loader: 'babel-loader',
options: {
// 基本的兼容性处理
presets: [['@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core版本
corejs: {
version: 3
},
// 指定兼容性到哪个浏览器版本
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]],
// 开启编译缓存
cacheDirectory: true
}
}
]
}
6.Webpack性能优化总结
- 开发环境性能优化:1、优化打包速度,可以通过HMR热更新实现。2、优化代码调试,使用source-map
- 生产环境性能优化:1、优化打包速度:使用babel缓存和多进程打包。2、优化代码运行的性能:使用缓存、tree shaking、code split代码分割、多入口打包,chunk拆分和动态引入,按需加载