Webpack 5 中 inline 资源使用

335 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情

在 Webpack 出现之前,我们前端开发人员会使用类似于 grunt 和 gulp 等工具来处理资源等工具来处理资源。将 src 文件夹里的文件移动到 dist 或者是 build 目录中。

其实,Webpack 最出色的功能之一就是除了引入 JS,还可以使用内置的资源模块还(Asset Modules )引入任何的其他类型资源。

资源模块(asset module)是一种模块类型,它允许我们使用 Webpack 打包其他的资源文件(字体,图标等),而无需配置额外 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 5 中使用旧的 assets loader(如 file-loader/url-loader/raw-loader 等)和 asset 模块时,你可能想停止当前 asset 模块的处理,并再次启动处理,这可能会导致 asset 重复,你可以通过将 asset 模块的类型设置为 'javascript/auto' 来解决。

inline 资源类型,用于导出一个资源的 data URL。

// webpack.config.js
//...
module.exports = {
  //...
    module:{
        rules:[
            {
                test:/.svg$/,
                type: 'asset/inline'
            }
        ]
    }
}
//src/index.js
import imgsvg from './assets/webpack5-logo.svg'

const img2 =document.createElement('img')
img2.src=imgsvg
document.body.appendChild(img2)

 

执行 webpack-dev-server 命令,启动 Webpack 服务。打开浏览器访问:http://localhost:8080/index_app.html

image.png

可以看到,它不是一个图片的 URL,.svg 文件都将作为 data URI 注入到 bundle 中。

Webpack 输出的 data URI,默认是呈现为使用 Base64 算法编码的文件内容。那么,我们能否自定输入 data URI 呢?当然可以。如果要使用自定义编码算法,则可以指定一个自定义函数来编码文件内容,先安装自定义 data URI 生成器:

npm install mini-svg-data-uri -D

在 webpack.config.js 文件中配置 data URI。

// webpack.config.js
//...
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);
                    }
                }
            },
            
        ]
    }


}

现在,所有 .svg 文件都将通过 mini-svg-data-uri 包进行编码。