# 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 ![RUNOOB 图标](./src/assets/webpack-1.png) > 可以将 **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)