一、深入理解Webpack配置文件
1.1 webpack配置文件 - webpack.config.js
1. 特点:
- 简化命令的选项
- 默认配置文件名称为
webpack.config.js - 操作webpack大部分都在配置
webpack.config.js文件 - webpack 的配置文件是JavaScript文件,文件内导出了一个 webpack 配置的对象
- webpack遵循 CommonJS 模块规范
- 支持导出为多个配置
- 支持由多种编程和数据语言编写的配置文件
2. 配置详情:
-
配置文件:在项目根目录下创建文件
webpack.config.js -
文件详情:webpack配置文件的详情我们可以大致按照以下几类进行分类
- Mode - 模式
- entry - 入口
- output - 出口
- module - 模块
- 服务器 - devServer
- 插件 - plugins
-
打包命令配置:
在文件
package.json中的调试字段scripts新增值"build": "webpack",
3. 文件详情 - Mode(模式)
-
作用:告知webpack使用响应模式的内置优化
-
使用:
// 打包模式配置 mode: String, // 默认值:production。值的范围:development || production || none- development:开发环境。会将
DefinePlugin中process.env.NODE_ENV的值设置为development。为模块和chunk启用有效的名 - production:生产环境。会将
DefinePlugin中process.env.NODE_ENV的值设置为production。为模块和chunk启用确定性的混淆名称 - none:不适用任何默认优化选项
通过修改mode的值,再打包,对比打包后的文件内容,我们可以清晰看到这三个值打包后的区别:
- development:开发环境。会将
4. 文件详情 - entry(入口)
- 作用:入口对象是用于 webpack 查找构建 bundle 的地方。
- 使用:
-
单个入口:
用法:string || [string]
module.exports = { entry: './src/index.js', }; // 是以下形式的简写: module.exports = { entry: { main: './path/to/my/entry/file.js', }, };一次注入多个依赖文件,并且将它们的依赖关系绘制在一个“chunk”中时,可以采用数组的方式:
module.exports = { entry: ['./src/file_1.js', './src/file_2.js'], output: { filename: 'bundle.js', }, };
-
- 优点:适用于通过一个入口为应用程序或工具快熟设置 webpack 配置
- 缺点:扩展或调整配置的灵活性不大
5. 文件详情 - output(出口)
-
作用:告知 webpack 如何向硬盘写入编译文件。指定输出文件的目标路径和文件名
-
特点:
- 只能制定一个
output配置
- 只能制定一个
-
使用:
const { resolve } = require("path") module.exports = { output: { // 所有输出文件的目标路径,必须是绝对路径 path: resolve(__dirname, 'dist'), // 出口文件名配置 filename: 'main.js' } }效果如下:
6. 文件详情 - modules(模块)
- 作用:决定了如何处理项目中的 不同类型的模块
- 天生支持的模块类型:
- ECMAScript 模块
- CommonJS 模块
- AMD 模块
- ASSets
- WebAddembly 模块
- 天生支持的模块类型:
- 使用:
- 用法:
Object
// 模块配置 module: { generator: { // webpack5.12.0+;在一个地方配置所有生成器的选项 }, parser: { // webpack5.12.0+;在一个地方配置所有解析器的选项 }, noParser: RegExp [RegExp] function(resource) string [string], // 防止 webpack 解析那些任何与给定正则表达式相匹配的文件。 unsafeCache: Boolean, // 缓存模块请求的解析。true=>cache 被启用;false=>cache未被启用 rules: [ // 配置多个模块规则(配置loader,解析器(parser)等选项) ], }, - 用法:
7. 文件详情 - devServer(服务器开发)
- 作用:提供了代码修改后 自动编译、自动打包、自动刷新浏览器 等的功能,会将打包后的产物放入内存中,如此一来就大大的提升了 构建速度 与 访问速度,同时也不会有磁盘的 IO 开销,延长硬盘使用寿命。
- 使用:Object
8. 文件详情 - plugins(插件)
- 作用:解决 loader 无法实现的其他事
- 使用:
const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); // 访问内置的插件 module.exports = { plugins: [ // ProgressPlugin: 用于自定义编译过程中的进度报告 new webpack.ProgressPlugin(), // HtmlWebpackPlugin:将生成一个HTML文件,并在其中使用 script 引入一个名为 my-first-webpack.bundle.js 的 JS 文件。 new HtmlWebpackPlugin({ template: './src/index.html' }), ], };
二、HTML资源打包
2.1 自动生成HTML文件和指定模板
1 自动生成HTML文件(html-webpack-plugin)
-
定义:该插件可以生成一个HTML文件,并在HTML中加载所有打包资源,便于服务器访问
-
安装:
npm i html-webpack-plugin -D -
引入:
const HtmlWebpackPlugin = require('html-webpack-plugin'); -
配置:
plugins: [ new HtmlWebpackPlugin(), ],
打包后的文件多了一个index.html文件,并且内容如下:
通过浏览器我们打开该html文件,可以看到控制台内容如下:
2 指定生成HTML模板
-
新建HTML文件:在src下新建文件
index.html -
配置
plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', // 指定 HTML 模板 filename: 'index.html', // 指定 HTML 名称 title: 'hello webpack', // 指定 HTML title }), ] -
title使用// 使用ESJ语法,是JS的模板引擎 <title><%=htmlWebpackPlugin.options.title%></title>
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%=htmlWebpackPlugin.options.title%></title>
</head>
<body>
</body>
</html>
webpack.config.js:
/**
* webpack.config.js
*/
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 打包环境设置
mode: "none",
// 入口
entry: "./src/index.js",
// 出口文件配置
output: {
// // 所有输出文件的目标路径,必须是绝对路径
// path: resolve(__dirname, 'dist'),
// // 出口文件名配置
// filename: 'main.js'
// 所有输出文件的目标路径,必须是绝对路径
path: resolve(__dirname, 'outputpath'),
// 出口文件名配置
filename: 'filename.js'
},
// 插件
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // 指定 HTML 模板
filename: 'index.html', // 指定 HTML 名称
title: 'hello webpack', // 指定 HTML title
}),
],
}
2.2 打包多个HTML页面和压缩
-
配置:
// webpack.config.js // 插件 plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', // 指定 HTML 模板 filename: 'index.html', // 指定 HTML 名称 title: '首页', // 指定 HTML title }), new HtmlWebpackPlugin({ template: './src/index.html', // 指定 HTML 模板 filename: 'mine.html', // 指定 HTML 名称 title: '我的', // 指定 HTML title }), ], -
跳转配置:
// src/index.html <body> <h3>webpack学习</h3> <a href="index.html">首页</a> <a href="mine.html">我的</a> </body>
效果如下:
- 打包后文件效果:
- 打包后文件执行效果:
- 压缩:
- 配置:
// 插件 plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', // 指定 HTML 模板 filename: 'index.html', // 指定 HTML 名称 title: '首页', // 指定 HTML title minify: { collapseWhitespace: true, // 清除空格换行 removeComments: true, // 清除注释 } }), new HtmlWebpackPlugin({ template: './src/index.html', // 指定 HTML 模板 filename: 'mine.html', // 指定 HTML 名称 title: '我的', // 指定 HTML title }), ], - 打包后的文件对比:
-
经过压缩有的打包文件没有换行空格等,全部一行展示:
-
压缩后的文件大小明显小:
-
- 打包后的文件执行对比:与没有压缩的效果一模一样,不受影响
- 配置:
三、CSS资源打包
3.1 剖析CSS打包的原理
-
打包CSS的loader
- css-loader:将css代码转化为JS代码,合并到打包后的JS文件中
- style-loader:将包含CSS内容的JS代码,插入到html中的style标签中
-
安装
npm i css-loader style-loader -D -
CSS 文件引入
// index.js import './css/main.css' -
webpack配置
// 模块配置 module: { rules: [ // 配置多个模块规则(loader、解析器等选项) { // 匹配CSS文件 test: /\.css$/i, // 指定加载器,加载顺序是从左到右或者从上到下 use: ['style-loader', 'css-loader'], } ], }, -
打包后的效果如下:CSS内容插入在html中的style标签中
-
不使用 style-loader 的效果:页面背景色不见了,打包的JS文件中还是有样式的设置
use: ['css-loader']
3.2 将CSS代码抽象成单独文件
将CSS代码抽象成单独文件 - mini-css-extract-plugin
-
作用:
- 从JS文件中抽离出CSS代码,减少JS文件体积
- 当JS文件比较庞大时,可以避免阻碍页面的渲染
- 提高渲染速度
-
安装:
npm i mini-css-extract-plugin -D -
引入:
// webpack.config.js const miniCssExtractPlugin = require("mini-css-extract-plugin") -
loader配置(替换 styl-loader)
// webpack.config.js module: { rules: [ // 配置多个模块规则(配置loader,解析器等选项) { // 匹配CSS文件 test: /\.css$/i, // 指定加载器,加载顺序是从左到右或者从上到下 use: [miniCssExtractPlugin.loader, 'css-loader'], } ], }, -
实例化插件
// webpack.config.js plugins: [ new miniCssExtractPlugin({ filename: "./css/index.css", // 指定文件位置和文件名 }) ],
打包后的效果:此时我们已经在打包后的JS文件中找不到相关CSS样式了,同时输出文件夹下多了一个CSS文件夹,以及一个index.css文件,
3.3 剖析CSS预编译语言
-
CSS预编译语言的安装
- less
npm i less less-loader -D- sass
npm i node-sass sass-loader -D- stylus
npm i stylus stylus-loader -D -
使用:
// src/index.js import './main.less' -
webpack配置:
['style-loader', 'css-loader', 'less-loader']
打包后和页面效果:
3.4 对特殊的CSS样式添加兼容前缀
-
作用:
- 兼容各个浏览器
-
安装
npm i postcss-loader autoprefixer -D -
配置
- webpack.config.js
module: { rules: [ { test: /.css$/i, // postcss-loader => 处理CSS兼容 use: [miniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'], }, ], }, - postcss.config.js
module.exports = { plugins: [require('autoprefixer')] // 添加浏览器前缀 } - package.json
"browserslist": [ "last 2 version", // 兼容浏览器的最近两个版本 "> 1%", // 全球占有率超过1%的浏览器 ]
- webpack.config.js
打包效果如下:
3.5 CSS压缩
optimize-css-assets-webpack-plugin
-
作用:
- 压缩后的代码去除空格和换行
- 文件体积更小,提高请求的速度
-
安装
npm i optimize-css-assets-webpack-plugin -D -
引入
// webpack.config.js const optimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin"); -
配置
// webpack.config.js plugins: [ new optimizeCssAssetsWebpackPlugin() ]
效果如下:
遇到的报错
安装时报错:Conflicting peer dependency: webpack@4.47.0XXXXXXXX
-
现象:
-
原因:webpack版本过高,与需要安装的插件版本不兼容有冲突
-
解决方案:
- 安装命令后面加上
--force或--legacy-peer-deps。不一定能解决 - 降低 webpack 版本:
- 直接覆盖原版本:
npm i webpack@4.0.4 -D - 卸载当前版本,再重新下载需要的版本:
// 卸载命令 npm uninstall webpack -g // 安装命令 npm i webpack@4.0.4 -D
- 直接覆盖原版本:
- 安装命令后面加上