<>webpack5使用

<>1.安装依赖包

* 创建一个文件夹
* npm init 生成package.json文件夹 然后安装依赖 cnpm webpack webpack-cli
html-webpack-plugin webpack-dev-server cross-env -D
* 新建一个webpack.config.js文件写配置
* 新建src/inde.js 文件
* 新建模板文件 src/index.html
* packjson命令 "scripts": { "build": "webpack", // 直接打包用 "start": "webpack
serve", // 启动服务器 可以开发用 },
* 配置好entry 和 output等基本信息就可以使用基础版本的了 module.exports = { mode: 'development',
// 配置的模式 devtool: 'source-map', // 调试工具 context: process.cwd(), //
node命令运行的进程的当前目录 就是这个项目根目录 entry: { main: './src/index.js' }, output: { path:
path.resolve(__dirname, 'dist'), filename: '[name].js' }, module: { }, plugins:
[ new HtmlWebpackPlugin({ template: './src/index.html', minify: { // 压缩html
collapseWhitespace: true, // 压缩空白 removeComments: true // 去除注释 } }), ] };
<>2.安装插件

<>2.1 日志美化安装

* friendly-errors-webpack-plugin 可以识别某类别的 webpack 错误,并清理,聚合和优先级,以提供更好的开发人员体验
cnpm i friendly-errors-webpack-plugin node-notifier -D
* 使用错误提示插件 const FriendlyErrorsWebpackPlugin = require(
'friendly-errors-webpack-plugin'); const notifier = require('node-notifier');
const icon = path.join(__dirname, 'icon.jpg'); plugins: [ ... + new
FriendlyErrorsWebpackPlugin({ + onErrors: (severity, errors) => { + let error =
errors[0]; + notifier.notify({ + title: 'webpack编译失败了', + message: severity +
':' + error.name, + subtitle: error.file || '', + icon + }); + } + }), ]
<>2.2 速度分析

* speed-measure-webpack5-plugin 进行分析打包速度 cnpm i speed-measure-webpack5-plugin
-D const SpeedMeasureWebpack5Plugin = require('speed-measure-webpack5-plugin');
const smw = new SpeedMeasureWebpack5Plugin(); module.exports = smw.wrap({ //
配置文件 mode: 'development', // 配置的模式 devtool: 'source-map', // 调试工具 context:
process.cwd(), // node命令运行的进程的当前目录 就是这个项目根目录 entry: { main: './src/index.js' },
output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, module
: { }, plugins: [ ] })
时间分析

<>2.3 文件体积监控

* webpack-bundle-analyzer 是一个 webpack 插件,需要配合 webpack 和 webpack-cli 一起使用,
生产代码分析报告,
* 可以分析打包出文件的大小,依赖关系,压缩大小如何等。
<>2.3.1 安装
cnpm i webpack-bundle-analyzer -D const { BundleAnalyzerPlugin } = require(
'webpack-bundle-analyzer'); plugins: [ ... + new BundleAnalyzerPlugin({ +
analyzerMode: 'disabled', // 不启动展示打包报告的HTTP服务器 也可以启动 直接可以看效果 + generateStatsFile
: true // 要生成stats.json文件 + }), ]
命令:
"build": "webpack", // 会生成stats.json文件 // 下次想看分析效果就执行analyzer 启动服务看 "analyzer":
"webpack-bundle-analyzer --port 8888 ./dist/stats.json"
<>3.编译时间优化

* 减少要处理的文件
* 缩小查找的范围
<>3.1 缩小查找范围

<>3.1.1 extensions

* 指定 extensions 之后可以不用再 require 或是 import 的时候加文件拓展名
* 查找的时候会依次尝试添加拓展名进行匹配 resolve:{ extensions: ['.js', '.jsx','.json'] }
<>3.1.2 alias

* 配置别名加快 webpack 查找模块的速度
* 每当引入 bootstrap 模块的时候,它会直接引入 bootstrap 而不需要从 node_modules 文件夹中按模块的查找规则查找 安装
cnpm i bootstrap css-loader style-loader -S const bootstrap = path.resolve(
__dirname, 'node_modules/bootstrap/dist/css/bootstrap.css' ); alias: {
bootstrap // 查找别名 },
<>3.2缓存

* 利用缓存
* 重新构件时会尝试读取缓存, 从而提高打包速度
* 缓存存放位置 node_modules/.cache/babel-loader module: { rules: [ { test:
/\.js$/, include: path.resolve(__dirname, 'src'), exclude: /node_modules/, //
不解析 use: [ // 开启多线程池 弊端开线程和线程通信需要时间的 { loader: 'thread-loader', options: {
workers: 3 } }, { loader: 'babel-loader', options: { cacheDirectory: true //
自动babel缓存 } } ] }, ] }
<>3.3 cache-loader

* 在一些性能开销大的 loader 之前添加此 loader, 可以将结果缓存在磁盘中
* 默认保存在 node_modules/.cache/cache-loader 目录下 cnpm i cache-loader -D { test:
/\.css$/, use: [ 'cache-loader', 'css-loader' ] }
<>3.4 hard-source-webpack-plugin

* hardSourceWebpackPlugin 为模块提供了中间缓存, 缓存默认存放的路径是
node_modules/.cache/hard-source
* 首次构建无太大变化, 第二次构建时间大约可以减少 80%
* webpack5 已经内置了模块缓存,不需要再使用此插件
<>4.编译体积优化

<>4.1 压缩 js、css、HTML 和图片

* optimize-css-assets-webpack-plugin 是一个优化和压缩 css 资源的插件
* terser-webpack-plugin 是一个优化和压缩 js 资源的插件
* image-webpack-loader 可以帮助我们对图片进行压缩和优化
<>4.1.2 安装
cnpm i terser-webpack-plugin optimize-css-assets-webpack-plugin
image-webpack-loader -D const OptimizeCssAssetsWebpackPlugin = require(
'optimize-css-assets-webpack-plugin'); const TerserWebpackPlugin = require(
'terser-webpack-plugin'); { // js压缩 optimization: { minimize: true, // 开始最小化
minimizer: [new TerserWebpackPlugin()] }, module: { rules: [ { test:
/\.(jpg|png|gif|bmp)$/, use: [ {// 图片压缩 + loader: 'image-webpack-loader',
options: { mozjpeg: { progressive: true }, // optipng.enabled: false will
disable optipng optipng: { enabled: false }, pngquant: { quality: [0.65, 0.9],
speed: 4 }, gifsicle: { interlaced: false }, // the webp option will enable WEBP
webp: { quality: 75 } } } ] }, ] }, plugins: [ ... + new
OptimizeCssAssetsWebpackPlugin() // 压缩css ] }
<>4.2 清除无用的 css

* purgecss-webpack-plugin mini-css-extract-plugin 单独提取 css 并清除用不到的 css
<>4.2.1 安装
cnpm i purgecss-webpack-plugin mini-css-extract-plugin -D const
PurgecssWebpackPlugin= require('purgecss-webpack-plugin'); const
MiniCssExtractPlugin= require('mini-css-extract-plugin'); const glob = require(
'glob'); const PATHS = { src: path.resolve(__dirname, 'src') }; module: { rules:
[ { test: /\.css$/, use: [ 'cache-loader', 'log-loader', + MiniCssExtractPlugin.
loader, // 在css loader 前引入 'css-loader' ] } ], }, plugins: [ // 提取的css文件名 + new
MiniCssExtractPlugin({ + filename: '[name].css' + }), + // /**/* **匹配任意字段
包括路径分隔符 *匹配任意字符 不包含路径分隔符 、、 // 去除无用css new PurgecssWebpackPlugin({ paths: glob.
sync(`${PATHS.src}/**/*`, { nodir: true }) }), + ]
<>5. 环境

<>4.1 mode 的默认值

* webpack 的 mode 默认 production
* webpack serve 的 mode 默认为 development
* 可以在模块内通过 process.env.NODE_ENV 获取当前环境变量, 无法在 webpack 配置文件中获取此变量
<>4.2 修改

* 命令行加–mode=production 可以赋值 可以覆盖掉配置文件 优先级 默认 mode <config < --mode 配置
<>4.3 DefinePlugin修改

* 设置全局变量 所有模块都能读取该变量的值
* 可以在任意模块内通过 process.env.NODE_ENV 获取当前的环境变量
* 但无法在 node 环境(webpack 配置文件中)下获取当前的环境变量 // 定义全局变量 修改process.env.NODE_ENV
plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(
'production'), ENV: JSON.stringify('ENV') }) ]
* 模块代码可以读取上面定义的变量

<>4.4 cross-env 设置
npm i cross-env -D
命令行
"build1": "cross-env NODE_ENV=development webpack",
可以在配置文件读到该值cross-env设置的值添加按到 process.env对象里面

<>4.5 .env文件修改

根目录新建.env文件
// .env文件内容 NODE_ENV=development ENV=TEST cnpm i dotenv -D // 可以读取.env文件,
获取里面的值 设置到process.env里面 require('dotenv').config();

<>小结

webpack5和webpack4配置基本差不多,使用上不会有太大区别, dll 已经去除了,使用
hard-source-webpack-plugin代替等。

* 通过持久化缓存提高性能
* 采用更好的持久化缓存算法和默认行为
* 通过优化 Tree Shaking 和代码生成来减小Bundle体积
* 提高 Web 平台的兼容性
* 清除之前为了实现 Webpack4 没有不兼容性变更导致的不合理 state
* 尝试现在引入重大更改来为将来的功能做准备,以使我们能够尽可能长时间地使用 Webpack 5
* 自动 Polyfills 一些 Node 模块(例如 crypto)无疑会增加打包体积,在 Webpack5 之后去掉了这个自动行为
附:
试验过程的完整配置
/* * @description: * @author: steve.deng * @Date: 2020-12-19 06:51:55 *
@LastEditors: steve.deng * @LastEditTime: 2020-12-22 14:38:50 */ const path =
require('path'); const FriendlyErrorsWebpackPlugin = require(
'friendly-errors-webpack-plugin'); const notifier = require('node-notifier');
const icon = path.join(__dirname, 'icon.jpg'); const SpeedMeasureWebpack5Plugin
= require('speed-measure-webpack5-plugin'); const { BundleAnalyzerPlugin } =
require('webpack-bundle-analyzer'); const HtmlWebpackPlugin = require(
'html-webpack-plugin'); const smw = new SpeedMeasureWebpack5Plugin(); const
selfLoadersPath= path.resolve(__dirname, 'loader'); const webpack = require(
'webpack'); const TerserWebpackPlugin = require('terser-webpack-plugin'); const
OptimizeCssAssetsWebpackPlugin= require('optimize-css-assets-webpack-plugin');
const ImageWebpackLoader = require('image-webpack-loader'); const
PurgecssWebpackPlugin= require('purgecss-webpack-plugin'); // 因为css和js加载可以并行
所以我们可以通过此插件提取css为单独的文件 然后去掉无用css 进行压缩 const MiniCssExtractPlugin = require(
'mini-css-extract-plugin'); const glob = require('glob'); const { DefinePlugin }
= require('webpack'); const PATHS = { src: path.resolve(__dirname, 'src') };
const bootstrap = path.resolve( __dirname,
'node_modules/bootstrap/dist/css/bootstrap.css' ); // 可以读取.env文件, 获取里面的值
设置到process.env.NODE_ENV里面 require('dotenv').config(); console.log('.env
process.env.NODE_ENV', process.env.NODE_ENV); console.log('.env ENV', process.
env.ENV); // 默认值undefined 无法在配置文件中获取 在模块代码内可以获取 console.log(
'process.env.NODE_ENV', process.env.NODE_ENV); module.exports = smw.wrap({ //
mode: 'development', // 配置的模式 devtool: 'source-map', // 调试工具 context: process.
cwd(), // node命令运行的进程的当前目录 就是这个项目根目录 entry: { main: './src/index.js' }, output:
{ path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, // js压缩
optimization: { minimize: true, // 开始最小化 minimizer: [new TerserWebpackPlugin()]
}, resolve: { extensions: ['.js', '.jsx', '.json'], // 指定扩展名 alias: { bootstrap
// 查找别名 }, modules: ['node_modules'], // 指定查找目录 mainFields: ['browser', 'module'
, 'main'], // 从package.json中的哪个字段查找入口文件 mainFiles: ['index'] //
如果找不到mainFields的话 会找索引文件 index.js }, resolveLoader: { modules: [selfLoadersPath,
'node_modules'] // selfLoadersPath 自定义loader解析 }, externals: { jquery: 'jQuery'
}, module: { rules: [ { test: /\.js$/, include: path.resolve(__dirname, 'src'),
exclude: /node_modules/, // 不解析 use: [ // 开启多线程池 弊端开线程和线程通信需要时间的 { loader:
'thread-loader', options: { workers: 3 } }, { loader: 'babel-loader', options: {
cacheDirectory: true // 自动babel缓存 } } ] }, { test: /\.(jpg|png|gif|bmp)$/, use:
[ { loader: 'image-webpack-loader', options: { mozjpeg: { progressive: true },
// optipng.enabled: false will disable optipng optipng: { enabled: false },
pngquant: { quality: [0.65, 0.9], speed: 4 }, gifsicle: { interlaced: false },
// the webp option will enable WEBP webp: { quality: 75 } } } ] }, { test:
/\.css$/, use: [ 'cache-loader', 'log-loader', MiniCssExtractPlugin.loader,
'css-loader' ] } ] }, plugins: [ new HtmlWebpackPlugin({ template:
'./src/index.html', minify: { // 压缩html collapseWhitespace: true, // 压缩空白
removeComments: true // 去除注释 } }), new MiniCssExtractPlugin({ filename:
'[name].css' }), // /**/* **匹配任意字段 包括路径分隔符 *匹配任意字符 不包含路径分隔符 、、 // 去除无用css new
PurgecssWebpackPlugin({ paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }) }
), new FriendlyErrorsWebpackPlugin({ onErrors: (severity, errors) => { let error
= errors[0]; notifier.notify({ title: 'webpack编译失败了', message: severity + ':' +
error.name, subtitle: error.file || '', icon }); } }), new BundleAnalyzerPlugin(
{ analyzerMode: 'disabled', // 不启动展示打包报告的HTTP服务器 generateStatsFile: true //
要生成stats.json文件 }), // 忽略模块打包 比如语言包 new webpack.IgnorePlugin({ resourceRegExp:
/^\.\/locale$/, // 资源正则 contextRegExp: /moment$/ // 上下文, 目录正则 }), // 定义全局变量 new
webpack.DefinePlugin({ // 定义在编译使用的全局变量 在浏览器运行阶段时就是值了 // 'process.env.NODE_ENV':
JSON.stringify('production'), 'process.env.NODE_ENV': JSON.stringify(process.env
.NODE_ENV), ENV: JSON.stringify('ENV') }), new OptimizeCssAssetsWebpackPlugin()
// 压缩css ] });

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信