《webpack5 实战五》之资源模块

2022-03-09 11:38:37 浏览数 (1)

本文目录
  • 系列文章目录
  • 前言
  • Resource 资源模式
    • 1、 引入图片
    • 2、webpack.config 配置
    • 3、引入照片,执行webpack打包
    • 4、另外一种输出文件名的方式
      • webpack.config 文件loader 配置
      • 执行webpack 打包结果
  • inline 资源模式
    • 1、引入 jpeg 文件
    • 2、webpack.config 配置
    • 3、引入、打包验证结果
    • 4、自定义 data URI 生成器
  • source 资源模式
    • 1、新建txt 文件,并引入
    • 2、webpack.config 配置
    • 3、打包验证
  • 通用模式
    • 1、 引入文件
    • 2、 webpack config 配置
    • 3、 打包验证
  • 总结

前言

资源模块(asset module)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader。

在 webpack 5 之前,通常使用:

  • raw-loader 将文件导入为字符串
  • url-loader 将文件作为 data URI 内联到 bundle 中
  • file-loader 将文件发送到输出目录

资源模块类型(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 基础配置:

代码语言:javascript复制
'use strict';

const path = require('path');
const svgToMiniDataURI = require('mini-svg-data-uri');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  module: {
  },
  resolve: {
  },
  devtool: 'source-map',
  plugins: [
  ]
};

index.html 引入打包之后的js文件:

代码语言:javascript复制
<!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>Document</title>
</head>
<body>
  <script src="./dist/bundle.js"></script>
</body>
</html>

Resource 资源模式

Resource 模式的作用是将 资源输送到指定目录,修改名称,并且其路径将被注入到 bundle 中。

例子过程描述:

  • 项目里加入img1.png 文件
  • webpack 配置loader ,将png 打包到指定目录
  • bundle.js 自动引入打包之后的图片路径

1、 引入图片

这里添加img1 图片

2、webpack.config 配置

webpack.config 文件里 ,配置png 文件为Resource 模式

代码语言:javascript复制
  module: {
    rules: [
      {
        test: /.png/,
        type: 'asset/resource'
      }
   }

指定图片打包之后的文件夹,如果不指定默认打包到根目录。

代码语言:javascript复制
 output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    assetModuleFilename: 'images/[hash][ext][query]'
  },

3、引入照片,执行webpack打包

webpack 打包入口文件为 index.js , 这里以后会陆续引入图片资源。

index.js :

代码语言:javascript复制
/*
 * @Author: ZY
 * @Date: 2022-02-16 10:44:46
 * @LastEditors: ZY
 * @LastEditTime: 2022-02-16 14:55:09
 * @FilePath: /webpack-demo/packages/asset-demo/src/index.js
 * @Description: 打包资源
 */


import png from "../images/img1.png";

const container = document.createElement("div");
Object.assign(container.style, {
	display: "flex",
  flexDirection:'column',
	justifyContent: "center",  
});
document.body.appendChild(container);


function createImageElement(title, src) {
	const div = document.createElement("div");
	div.style.textAlign = "center";

	const h2 = document.createElement("h2");
	h2.textContent = title;
	div.appendChild(h2);

	const img = document.createElement("img");
	img.setAttribute("src", src);
	img.setAttribute("width", "150");
	div.appendChild(img);

	container.appendChild(div);
}

[png].forEach((src,index) => {
  const typeArray = ['resource']
	createImageElement(typeArray[index], src);
});

执行webpack 打包后的结果:

自定注入bundle.js 里:

4、另外一种输出文件名的方式

以html 文件为例,所有的html 文件都会被输出到static 目录下:

webpack.config 文件loader 配置
代码语言:javascript复制
 {
        test: /.html/,
        type: 'asset/resource',
        generator: {
          filename: 'static/[hash][ext][query]'
        }
      },
执行webpack 打包结果

在项目目录里放一个test,html 文件并在入口index.js 文件里引入,执行webpack 打包。

验证结果如下:

inline 资源模式

inline 资源模式,默认将图片编程base64 的格式,注入到bundle.js 内部。

内联模式以jpeg 类型文件为例。

1、引入 jpeg 文件

引入img2,jpeg 文件

2、webpack.config 配置

代码语言:javascript复制
 {
        test: /.jpeg/,
        type: 'asset/inline'
      },

3、引入、打包验证结果

图片变成了base64 出现在bundlle.js 里

4、自定义 data URI 生成器

webpack 输出的 data URI,默认是呈现为使用 Base64 算法编码的文件内容。

如果要使用自定义编码算法,则可以指定一个自定义函数来编码文件内容,

以 svg 图片为例,利用mini-svg-data-uri压缩编码格式

  1. 引入 svg 图片
  2. npm 引入 mini-svg-data-uri 包
  3. 配置 webpack.config
代码语言:javascript复制
/*
 * @Author: ZY
 * @Date: 2022-02-15 15:51:35
 * @LastEditors: ZY
 * @LastEditTime: 2022-02-16 14:56:22
 * @FilePath: /webpack-demo/packages/asset-demo/webpack.config.js
 * @Description: 文件描述
 */

'use strict';

const svgToMiniDataURI = require('mini-svg-data-uri');

module.exports = {
  module: {
    rules: [
      {
        test:/.svg/,
        type: 'asset/inline',
        generator: {
          dataUrl: content => {
            content = content.toString();
            return svgToMiniDataURI(content);
          }
        }
      },
    ]
  },
};

source 资源模式

将文件原样注入到打包后的文件,类似raw-loader实现

例子以 txt 文件为例

1、新建txt 文件,并引入

新建txt 文文件

index.js 引入:

代码语言:javascript复制
import helloText from "./hello.txt";
const text = document.createElement("h2");
text.textContent = helloText;
container.appendChild(text);

2、webpack.config 配置

代码语言:javascript复制
{
        test:/.txt/,
        type:'asset/source'
      },

3、打包验证

打包完之后,直接内容到bundle.js :

通用模式

现在,webpack 将按照默认条件,自动地在 resource 和 inline 之间进行选择:小于 8kb 的文件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。

1、 引入文件

为了更好的验证,引入小于8kb 文件和大于8kb 文件

例子以jpg 文件为例

2、 webpack config 配置

代码语言:javascript复制
 {
        test:/.jpg/,
        type:'asset'
      }

3、 打包验证

dist 只有 大于290kb 文件资源,小于8kb 的会被内联。具体看demo案例。

总结

webpack5 引入资源干掉了一堆loader,改为type 模式loader,更清晰。本文示例详细,文章没有提及到的请查看demo。

  • webpack5实战源码

0 人点赞