第二节:Webpack资源模块(替代file/url-loader)、插件使用(Clean/Html/Define/Copy)、mode的配置说明
一. 资源模块(asset model)
1. 说明
资源模块(asset module)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader。
(1). 在 webpack 5 之前,通常使用: (需要npm来安装)
raw-loader 将文件导入为字符串
url-loader 将文件作为 data URI 内联到 bundle 中
file-loader 将文件发送到输出目录
(2). 在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
,并且配置资源体积限制实现。 【等价于:file-loader + url-loader 】
2. 常用PlaceHolders
3. 实战-文件解析打包
(1). 代码准备
// 通过背景的模式设置图片 import "../font/iconfont.css"; const bgDivEl = document.createElement('div'); bgDivEl.className = "image-bg"; document.body.appendChild(bgDivEl); // 通过src的模式设置img import myImg from '../img/02.jpg'; const imgEl = document.createElement('img'); //注意,这里必须用上面import的模式来写,看做一个模块,否则打包的时候,路径就错误了 imgEl.src = myImg; imgEl.height=140; imgEl.width=140; document.body.appendChild(imgEl);
css代码
.image-bg { background-image: url("../img/01.jpg"); background-size: contain; width: 140px; height: 140px; }
(2). 相关配置
// 文件解析功能,"asset/resource"(等价于file-loader ) { test: /\.(jpe?g|png|gif|svg)$/, type: "asset/resource", generator: { filename: "img/[name]_[hash:6][ext]" } },
补充:输出路径也可以全局配置
output: { path: path.resolve(__dirname, "./build"), //打包后存放路径, 必须写绝对路径 filename: "bundle.js", //打包后的文件名称 assetModuleFilename: "img/[name]_[hash:6][ext]" //全局配置资源模块 }
(3). 打包测试即可
【npm run build】
4. 实战-文件转换base64
可以将较小的文件,转成base64的URI,存放到打包后的js文件里
核心配置:
// 含转换base64的功能 "asset", (等价于 file + url 两个loader) { test: /\.(jpe?g|png|gif|svg)$/, type: "asset", generator: { filename: "img/[name]_[hash:6][ext]" }, parser: { dataUrlCondition: { maxSize: 100 * 1024 //(表示100kb以下的文件转换成base64编码) } } },
5. 实战-解析字体
核心配置 :
// 解析字体(也可以用file-loader处理) { test: /\.(eot|ttf|woff2?)$/, type: "asset/resource", generator: { filename: "font/[name]_[hash:6][ext]" } },
其它代码:
// 字体相关的使用 import "../font/iconfont.css"; const iEl = document.createElement('i'); iEl.className = "iconfont icon-ashbin"; document.body.appendChild(iEl);
补充:
(1). file-loader
【npm install file-loader -D】
{ test: /\.(jpe?g|png|gif|svg)$/, use: { loader: "file-loader", options: { // outputPath: "img", name: "/img/[name]_[hash:6].[ext]", } } },
(2). url-loader
【npm install url-loader -D】
{ test: /\.(jpe?g|png|gif|svg)$/, use: { loader: "url-loader", options: { // outputPath: "img", name: "/img/[name]_[hash:6].[ext]", limit: 100 * 1024 //100kb (表示100kb以下的图片转换成base64编码) } } },
二. 常用插件
1. 什么是插件
常用插件见:https://webpack.docschina.org/plugins/
2. CleanWebpackPlugin
(1). 作用:每次修改了一些配置,重新打包时,都需要手动删除打包后build的文件夹。
(2). 核心配置
A. 指令安装:【npm install clean-webpack-plugin -D】
B. 配置
// 导入插件 const { CleanWebpackPlugin } = require("clean-webpack-plugin"); module.exports = { plugins: [ new CleanWebpackPlugin() ] }
3. HtmlWebpackPlugin
(1). 作用:在打包文件夹里自动生成一个入口页面index.html
(2). 核心配置
A. 指令安装:【npm install html-webpack-plugin -D】
B. 配置
// 导入插件 const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { module: { plugins: [new HtmlWebpackPlugin({ title: "hello webpack" }) ] }
总结:
上面的配置会默认生成一个index.html,默认情况下是根据ejs的一个模板来生成的;在html-webpack-plugin的源码中,有一个default_index.ejs模块。
补充-自定义html模板
比如新建public文件夹,在里面放上vue-cli创建的index.html作用模板页面,那么就需要修改配置。。。
模板页面
<!DOCTYPE html> <html lang=""> <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"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
配置文件
// 导入插件 const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { module: { plugins: [ new HtmlWebpackPlugin({ template: "./public/index.html", title: "hello webpack" }) ] }
4. DefinePlugin
(1). 作用:DefinePlugin允许在编译时创建配置的全局常量,是一个webpack内置的插件(不需要单独安装)
(2). 核心配置:
// 导入插件 const { DefinePlugin } = require("webpack"); module.exports = { plugins: [new DefinePlugin({ BASE_URL: "'./'" }) ] }
5. CopyWebpackPlugin
(1). 作用:通过这个插件,可以实现将自定义的public文件夹中的文件复制到build下,但是我又不想全复制,那么就要配置一下忽略。
(2). 核心配置
A. 指令安装:【npm install copy-webpack-plugin -D】
B. 配置
// 导入插件 const CopyWebpackPlugin = require('copy-webpack-plugin'); module.exports = { plugins: [new CopyWebpackPlugin({ patterns: [{ from: "public", //设置从哪一个源中开始复制; // to: "./", //复制到的位置,可以省略,会默认复制到打包的目录下; globOptions: { //下面配置忽略清单 ignore: [ "**/index.html" ] } }] }) ] }
三. mode配置
1. 简单说明
(详见:https://webpack.docschina.org/configuration/mode/)
提供 mode
配置选项,告知 webpack 使用相应模式的内置优化。
2. 使用
默认情况下,假设有一句js代码出错了,打包后的文件无法快速定位到哪里出错了,但是如果按照下面的方式配置一下,就可以定位了。
// 这里必须通过 commonjs的写法配置,不能写 ES6的写法 const path = require('path'); module.exports = { // 设置模式, development 开发阶段, 会设置development, production 准备打包上线的时候, 设置production(默认) mode: "development", // 设置source-map, 建立js映射文件, 方便调试代码和错误 devtool: "source-map", entry: "./src/main.js", //入口文件 output: { path: path.resolve(__dirname, "./build"), //打包后存放路径, 必须写绝对路径 filename: "bundle.js" //打包后的文件名称 }, }
如图:
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。