# webpack-read
**Repository Path**: pipepandafeng/webpack-read
## Basic Information
- **Project Name**: webpack-read
- **Description**: webpack理解
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 0
- **Created**: 2022-02-14
- **Last Updated**: 2022-03-05
## Categories & Tags
**Categories**: Uncategorized
**Tags**: webpack
## README
# webpack

> 可以将 **webpack** 理解为 **pipe** (管道)。
## 目录
- [webpack](#webpack)
- [核心概念](#核心概念)
- [安装](#安装)
- [开箱即用](#开箱即用)
- [示例](#示例)
- [灵活的配置](#灵活的配置)
- [插件和 loader](#插件和-loader)
- [搭建开发服务器](#搭建开发服务器)
- [处理ES6以及更高级的语法](#处理es6以及更高级的语法)
- [处理 css](#处理-css)
- [css-loader](#css-loader)
- [style-loader](#style-loader)
- [mini-css-extract-plugin](#mini-css-extract-plugin)
- [其他 css 相关 loader 和插件](#其他-css-相关-loader-和插件)
- [处理图片](#处理图片)
- [file-loader](#file-loader)
- [url-loader](#url-loader)
- [资源模块](#资源模块)
- [ImageMinimizerWebpackPlugin](#imageminimizerwebpackplugin)
## 核心概念
本质上,webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。 —— 摘自官网
- 入口(entry)
- 输出(output)
- loader
- 插件(plugin)
- 模式(mode)
- 浏览器兼容性(browser compatibility) - ES5 标准
- 环境(environment) - Node.js v10.13.0+
https://webpack.docschina.org/concepts
## 安装
> 本文使用`webpack v5.0`进行配置
- `yarn add webpack webpack-cli -D`
## 开箱即用
> webpack 开箱即用,可以无需使用任何配置文件。然而,webpack 会假定项目的入口起点为 src/index.js,然后会在 dist/main.js 输出结果,并且在生产环境开启压缩和优化。 —— 摘自官网
```bash
npx webpack
```
## 示例
> 用于理解核心概念
1. 创建两个文件,`src/index.js`, `src/test.js`。
2. 执行命令打包构建 `npx webpack`
3. 查看打包结果
结论:本质上,webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。 —— 摘自官网
## 灵活的配置
> webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。
1. 新建文件`webpack.config.js`,使用 node 语法。
```js
const path = require("path");
module.exports = {
mode: "production",
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"), // 此处需要一个绝对路径
filename: "js/index.[hash].js",
},
};
```
2. 配置`npm script`
```js
+ "build":"webpack --config webpack.config.js"
```
## 插件和 loader
- HtmlWebpackPlugin
```bash
yarn add html-webpack-plugin -D
```
```js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "production",
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"), // 此处需要一个绝对路劲
filename: "js/index.[hash].js",
},
plugins: [
new HtmlWebpackPlugin({
template: "./index.html", //模板位置
filename: "index.html", //打包出来后的文件名
}),
],
};
```
此时即可看到控制台输出了打印
但此时修改文件后只能再次执行打包命令,才能看到最新结果,非常繁琐。如何才能更改代码后,webpack 自动打包构建,实时编译及更新页面呢。接下来介绍**webpack 的 HMR(热更新)**
## 搭建开发服务器
1. 安装依赖
```bash
yarn add webpack-dev-server -D
```
2. 配置`npm script`
```js
+ "dev": "webpack serve --progress --color --config webpack.config.dev.js"
```
3. 运行命令
此时即可看到控制台的 HMR 启动成功,修改文件后页面实时更新了结果。
> 从 webpack-dev-server v4.0.0 开始,热模块替换是默认开启的。
## 处理ES6以及更高级的语法
未转换前的构建包代码:`\nconst sum = (a, b) => {\r\n console.log(a+b);\r\n};`
转换后的构建包代码:`\nvar sum = function sum(a, b) {\n console.log(a + b);\n};`
1. 安装依赖
```bash
yarn add babel-loader @babel/core @babel/preset-env -D
```
2. 配置 loader
```js
+ module: {
+ rules: [
+ {
+ test: /\.m?js$/,
+ exclude: /node_modules/,
+ use: {
+ loader: 'babel-loader',
+ options: {
+ presets: [
+ ['@babel/preset-env', { targets: "defaults" }]
+ ]
+ }
+ }
+ }
+ ]
+ }
```
## 处理 css
### css-loader
> css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
1. 安装依赖
```bash
yarn add css-loader -D
```
2. 配置 loader
```js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
plugins:[
...,
+ new MiniCssExtractPlugin()
...
]
module{
...,
+ {
+ test: /\.css$/i,
+ use: use: [MiniCssExtractPlugin.loader,"css-loader"],
+ }
...
}
```
此时在 js 中既可以访问到 css 变量,但此时 css 还不能直接作用与页面,还需要结合**style-loader**一起使用
### style-loader
> 将 CSS 注入 DOM。
```js
+ {
+ test: /\.css$/i,
+ use: ["style-loader","css-loader"], // 应用规则为从下至上,从右到左
+ }
```
此时,可以看到 css 效果已作用于页面,但存在以下缺点
1. css 被打包进入和 js 文件,随着 css 编写越来越多,js 文件将会越来越大。
2. 打开浏览器控制台可发现,style-loader 是采用 js 通过插入多个 ``标签的形式 自动把 样式 插入到 DOM 中,也就是全部采用的内部样式,不利于样式和结构的分离与维护。
为了解决以上问题**mini-css-extract-plugin**孕育而生。
### mini-css-extract-plugin
> 本插件会将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。
> 注意:本插件基于 webpack v5 的新特性构建,并且需要 webpack 5 才能正常工作。
1. 安装依赖
```bash
yarn add mini-css-extract-plugin -D
```
2. 配置 loader
```js
+ {
+ test: /\.css$/i,
+ use: ["style-loader","css-loader"]
+ }
```
### 其他 css 相关 loader 和插件
- **less** **less-loader** 处理 less 文件
- **sass** **sass-loader** 处理 sass 文件
- **postcss** **autoprefixer** 自动添加浏览器前缀
- **css-minimizer-webpack-plugin** 压缩 css
## 处理图片
在此之前,先介绍 3 个 loader。
- **raw-loader** 将文件导入为字符串
- **file-loader** 解析图片类型的静态资源,将文件发送到输出目录。
- **url-loader** 将文件作为 data URI 内联到 bundle 中,,低于阈值采用内联,高于阈值采用外联。
> **url-loader** 是增强型的**file-loader**。如果图片较多,会发很多 http 请求,会降低页面性能。**url-loader** 会将引入的图片编码,生成 dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此 **url-loader** 提供了一个 limit 参数,小于 limit 字节的文件会被转为 DataURl,大于 limit 的还会使用 **file-loader** 进行 copy。
### file-loader
1. 安装依赖
```bash
yarn add file-loader -D
```
2. 配置 loader
```js
module: {
...,
+ {
+ test: /\.(png|jpe?g|gif)$/i,
+ use: [
+ {
+ loader: "file-loader",
+ options: {
+ outputPath: "imgs",// 输出目录位置
+ },
+ },
+ ],
+ },
...
}
```
此时即可发现可在 js 文件中直接引入图片资源,但是所有图片都采用了外联模式,如果图片资源文件过多,会增加 http 请求。那当图片较小时,我们是不是可以将图片资源转换为**DATAURL-base64**形式,降低 http 请求。**url-loader**便孕育而生。
### url-loader
> 一个用于将文件转换为 base64 URI 的 webpack 加载器。
1. 下载依赖
```bash
yarn add url-loader -D
```
2. 配置 loader
```js
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
},
},
],
},
],
},
```
此时可看到,其中一个尺寸超过`limit`的图片被外联,一个小于`limit`的图片资源被转换为了**base64 url**并被打进了代码中,没有产生多余的资源文件。思考?
### 资源模块
> 资源模块(asset module)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader。
在 webpack5 之前通常使用**row-loader**,**url-loader**,**file-loader**来处理文件。webpack5 之后提供了资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader
- **asset/resource** 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。
- **asset/inline** 导出一个资源的 data URI。之前通过使用 url-loader 实现。
- **asset/source** 导出资源的源代码。之前通过使用 raw-loader 实现。
- **asset** 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 - url-loader,并且配置资源体积限制实现。
改造 webpack 配置文件如下:
```js
module: {
...,
+ {
+ test: /\.(png|jpg|gif)$/i,
+ type: "asset",
+ parser: {
+ dataUrlCondition: {
+ maxSize: 8 * 1024 // 4kb
+ }
+ }
+ }
...
}
```
此方法会跟使用**url-loader**产生同样的效果。
### ImageMinimizerWebpackPlugin
> 自动压缩图片
[官网介绍:ImageMinimizerWebpackPlugin](https://webpack.docschina.org/plugins/image-minimizer-webpack-plugin)