Webpack5 系列(二):静态资源的处理1

简介: Webpack5 系列(二):静态资源的处理

一、前言

上一篇讲解了 webpack5 的基础配置。这一篇文章将会介绍如何利用 webpack 中的 Loaders 对静态资源做处理,Loaders 是 webpack 的核心概念之一。

静态资源主要包括以下几方面的内容:

  • 样式文件(CSS)
  • 图片(Images)
  • 字体(Fonts)
  • 数据文件(Data)
  • ...

文件结构:

webpack
|- /dist
  |- index.html
|- /src
  |- /assets
    |- /fonts
      |- font-a.otf
      |- font-b.ttf
      |- font-c.woff
      |- font-d.woff2
      |- font-e.svg
    |- /icons
      |- icon-a.png
      |- incon-b.svg
    |- /images
      |- img-a.png
      |- img-b.jpg
      |- img-gif.jpg
    |- /js
      |- js-a.js
    |- /others
      |- o-a.txt
      |- o-b.xml
    |- /styles
      |- global.scss
      |- reset.css
  |- /components
    |- content.js
    |- header.js
    |- sidebar.js
|- index.js
|- package.json
|- webpack.config.js

assets 文件夹中存放了若干静态文件(例如:字体、图标、图片、文本、样式以及 JS 文件),中间根据文件的不同,又分了几个文件夹。这里为了方便起见,文件名均已作简化处理。

index.js


// js 模块
const Header = require("./components/header");
const Sidebar = require("./components/sidebar");
const Content = require("./components/content");
// 图片模块 (这 5 个都是小图)
const icon1 = require("./assets/icons/mac-os.png");
const icon2 = require("./assets/icons/apple-tv.png");
const icon3 = require("./assets/icons/apple-contacts.png");
const iconSvg1 = require("./assets/icons/arrow-up.svg");
const iconSvg2 = require("./assets/icons/arrow-down.svg");
// 图片模块 (这 3 个都是大图)
const dog1 = require("./assets/images/animal-dog-1.png");
const avatar1 = require("./assets/images/avatar-1.jpg");
const cat1 = require("./assets/images/express-cat-1.gif");
// 数据模块
const fileTxt = require("./assets/data/notes.txt");
const fileXml = require("./assets/data/hello.xml");
// 字体模块
const font = require("./assets/fonts/Calibre-Regular.otf");
const iconFont1 = require("./assets/fonts/iconfont.ttf");
const iconFont2 = require("./assets/fonts/iconfont.woff");
const iconFont3 = require("./assets/fonts/iconfont.woff2");
// 样式模块
// const reset = require('./assets/styles/reset.css');
// const global = require('./assets/styles/global.scss');
const dom = document.getElementById("root");
// header
new Header(dom);
// side-bar
new Sidebar(dom);
// content
new Content(dom);

引入了各种文件模块并放入变量中,每一个模块在打包以后都有值,可以正常使用。

二、Loaders — 加载器

webpack enables use of loaders to preprocess files. This allows you to bundle any static resource way beyond JavaScript. You can easily write your own loaders using Node.js.

简单来说,loaders 可以帮我们预处理任何静态文件并打包

例如:图片文件,样式文件、html 文件,甚至是一些数据文件:txt 文件、xml 文件……

那么,如何配置呢?

三、Asset Modules — 静态资源模块

根据 Webpack5 的文档,它简化了之前版本对于文件方面的配置,提供了 Asset Modules (静态资源模块),替代了之前常用的 raw-loader、url-loader、file-loader

也就是说不用再安装这几个 loader 了,直接通过一行type: 'asset' 搞定,书写更加方便!(注意 module 中 type 的设置!)

// webpack 配置文件
const path = require("path");
module.exports = {
  mode: "production",
  entry: {
    main: "./src/index.js",
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  // *** 模块选项中匹配的文件会通过 loaders 来转换!
  module: {
    rules: [
      // 图片文件
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        type: "asset", // 一般会转换为 "asset/resource"
      },
      // 字体文件
      {
        test: /\.(otf|eot|woff2?|ttf|svg)$/i,
        type: "asset", // 一般会转换为 "asset/inline"
      },
      // 数据文件
      {
        test: /\.(txt|xml)$/i,
        type: "asset", // 一般会转换成 "asset/source"
      },
    ],
  },
};

每次打包后,文件都会根据 output 的配置放进输出文件夹,但是对于压缩处理的文件则不会被打包到文件夹,只会以base64 编码格式或者 URI 编码等格式存在于 bundle.js 的源码中。

  • 源码中的 base64

1688267570858.png

源码中的 URI


1688267587150.png


默认情况下,当文件小于 8 kb 则会采用 base64 编码,那么上面出现的 URI 编码怎么设置的呢?

1. 特殊处理

某些文件需要特殊处理。例如,SVG 文件转换为 URI 编码后,与 base64 相比,体积会更小;

处理 txt、xml 文件 type: 'asset/source' 更好,它会导出资源的源码,这样就能看到全貌,而非 base64 格式的编码字符串。

最小化 SVG 文件需要安装一个第三方库:mini-svg-data-uri.

npm i -D mini-svg-data-uri

安装之后,重新配置如下:

// webpack 配置文件
const path = require("path");
const miniSVGDataURI = require("mini-svg-data-uri");
module.exports = {
  // ...
  module: {
    rules: [
      // 图片文件
      {
        test: /\.(jpe?g|png|gif)$/i,
        type: "asset",
      },
      // svg文件
      {
        test: /\.svg$/i,
        type: "asset/inline",
        generator: {
          dataUrl(content) {
            content = content.toString();
            return miniSVGDataURI(content);
          },
        },
      },
      // 字体文件
      {
        test: /\.(otf|eot|woff2?|ttf|svg)$/i,
        type: "asset",
      },
      // 数据文件
      {
        test: /\.(txt|xml)$/i,
        type: "asset/source",
      },
    ],
  },
};

至此,打包完成。现在,看看这些文件模块究竟被打包成什么数据了,在 index.js 文件中添加如下代码:

// js 模块
const Header = require("./components/header");
const Sidebar = require("./components/sidebar");
const Content = require("./components/content");
// 图片模块 (这 5 个都是小图)
const icon1 = require("./assets/icons/mac-os.png");
const icon2 = require("./assets/icons/apple-tv.png");
const icon3 = require("./assets/icons/apple-contacts.png");
const iconSvg1 = require("./assets/icons/arrow-up.svg");
const iconSvg2 = require("./assets/icons/arrow-down.svg");
// 图片模块 (这 3 个都是大图)
const dog1 = require("./assets/images/animal-dog-1.png");
const avatar1 = require("./assets/images/avatar-1.jpg");
const cat1 = require("./assets/images/express-cat-1.gif");
// 其他文件模块
const fileTxt = require("./assets/data/notes.txt");
const fileXml = require("./assets/data/hello.xml");
// 字体模块
const font = require("./assets/fonts/Calibre-Regular.otf");
const iconFont1 = require("./assets/fonts/iconfont.ttf");
const iconFont2 = require("./assets/fonts/iconfont.woff");
const iconFont3 = require("./assets/fonts/iconfont.woff2");
// 样式模块
// const reset = require('./assets/styles/reset.css');
// const global = require('./assets/styles/global.scss');
// 在控制台中打印这些模块:
console.log("icon-png: ", icon1);
console.log("icon-svg: ", iconSvg1);
console.log("png: ", dog1);
console.log("jpg: ", avatar1);
console.log("gif: ", cat1);
console.log("txt: ", fileTxt);
console.log("xml: ", fileXml);
console.log("font: ", font);
console.log("iconFont: ", iconFont1);
const dom = document.getElementById("root");
// 插入一张图片
const img = new Image();
img.src = dog1; // 图片模块 dog1 作为 img 变量的 src 属性值
img.width = 200;
root.append(img);
// header
new Header(dom);
// side-bar
new Sidebar(dom);
// content
new Content(dom);

浏览器页面展示如下:

1688267632113.png


可以看到 SVG 文件 (icon-svg) 是被处理成 URI 编码的!

目录
相关文章
|
前端开发 JavaScript
Webpack5 系列(二):静态资源的处理4
Webpack5 系列(二):静态资源的处理4
127 0
|
前端开发 JavaScript Shell
Webpack5 系列(二):静态资源的处理3
Webpack5 系列(二):静态资源的处理3
100 0
|
XML 前端开发 JavaScript
Webpack5 系列(二):静态资源的处理2
Webpack5 系列(二):静态资源的处理2
349 0
|
3月前
|
JavaScript
webpack打包TS
webpack打包TS
135 60
|
2月前
|
缓存 前端开发 JavaScript
Webpack 打包的基本原理
【10月更文挑战第5天】
|
2月前
|
前端开发 JavaScript
ES6模块化和webpack打包
【10月更文挑战第5天】
|
2月前
|
缓存 前端开发 JavaScript
深入了解Webpack:模块打包的革命
【10月更文挑战第11天】深入了解Webpack:模块打包的革命
|
3月前
|
JavaScript 测试技术 Windows
vue配置webpack生产环境.env.production、测试环境.env.development(配置不同环境的打包访问地址)
本文介绍了如何使用vue-cli和webpack为Vue项目配置不同的生产和测试环境,包括修改`package.json`脚本、使用`cross-env`处理环境变量、创建不同环境的`.env`文件,并在`webpack.prod.conf.js`中使用`DefinePlugin`来应用这些环境变量。
123 2
vue配置webpack生产环境.env.production、测试环境.env.development(配置不同环境的打包访问地址)
|
2月前
|
缓存 前端开发 JavaScript
Webpack技术深度解析:模块打包与性能优化
【10月更文挑战第13天】Webpack技术深度解析:模块打包与性能优化
|
2月前
|
前端开发 JavaScript 开发者
深入了解Webpack:现代JavaScript应用的打包利器
【10月更文挑战第11天】 深入了解Webpack:现代JavaScript应用的打包利器