webpack5资源模块

852 阅读2分钟

| webpack 资源模块

资源模块(asset module)是一种模块类型
它允许我们应用Webpack来打包其他资源文件(字体,图标等)
无需配置额外 loader

webpack 5 之前
资源模块通常使用:

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

webpack 5 之后
资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:

  1. asset/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。
  2. asset/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现。
  3. asset/source 导出资源的源代码。之前通过使用 raw-loader 实现。
  4. asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现。

| 配置文件结构

module.exports = {
   ...,
   module:{
       rules:[
           {
               test:/\.png$/, // 匹配以.png为后缀的资源
               type:'asset/resource'           
           }       
       ]   
   }
};

| asset/resource

可以发送一个单独文件,并导出URL,一般用于加载图片

module.exports = {
   ...,
   module:{
       rules:[
           {
               test:/\.png$/, // 匹配以.png为后缀的资源
               type:'asset/resource'                 
           }       
       ]   
   }
};

比如需要引入一张图片

import imgSrc from './assets/img-1.png';
console.log(imgSrc) // http://192.168.3.137:8080/992c7a5a7908732f7526.png

| asset/inline

将文件导出一个Data url,比如base64
比如要加载svg格式的文件

module.exports = {
   module:{
       rules:[
             {
                test: /\.svg$/, // 匹配以.svg为后缀的资源
                type: 'asset/inline',
            },       
       ]   
   }
};

导出是一个base64

image.png

| asset/source

导出文件的源代码,比如txt

module.exports = {
   module:{
       rules:[
             {
                test:/\.txt$/,
                type:'asset/source'
            }       
       ]   
   }
};

会输出txt中的内容

import textContent from './assets/text.txt';
console.log(textContent) // 我是内容

| asset

通用资源类型,自动决定文件导出时是data url还是单独文件
也就是在resourceinline之间选择

默认选择规则:

  • 小于8kb的文件用inline
  • 大于等于8kb用resource

可以自定义判断规则
在module>rule层级中设置parser.dataUrlCondition.maxSize来自定义规则

module.exports = {
   module:{
       rules:[
             {
                test:/\.jpg$/,
                type:'asset',
                parser:{
                    dataUrlCondition: {
                        maxSize: 4 *1024 // 4kb                    
                    }                
                }
            }       
       ]   
   }
};

配置后可以看到是resource形式

image.png

自定义maxSize小于60kb使用inline形式,

module.exports = {
   module:{
       rules:[
             {
                test:/\.jpg$/,
                type:'asset',
                parser:{
                    dataUrlCondition: {
                        maxSize: 6 * 1024 * 1024 // 60kb               
                    }                
                }
            }       
       ]   
   }
}

可以看到图片变为base64

image.png

| Q&A

1.如何自己定义文件名与文件目录

  • 可以在output中配置assetModuleFilename字段
  • 也可以在module的rules里配置generatorfilename属性
  • 后者的优先级比较高

在output中配置assetModuleFilename字段

module.exports = {
   ...,
   output:{
      assetModuleFilename:'images/test.png' // 指定目录与文件名    
   },
   module:{
       rules:[
           {
               test:/\.png$/, // 匹配以.png为后缀的资源
               type:'asset/resource'                 
           }       
       ]   
   }
};

当然不能全部文件名都一样,我们可以使用webpack自带的默认命名

module.exports = {
   ...,
   output:{
       // 指定目录与文件名 
       // 其中的[contenthash]生成hash名,[ext]是指使用原文件扩展名
      assetModuleFilename:'images/[contenthash][ext]'    
   },
};

在module的rules里配置generator的filename属性

module.exports = {
   module:{
       rules:[
           {
               test:/\.png$/, // 匹配以.png为后缀的资源
               type:'asset/resource',
               // 指定目录与文件名 
               // 其中的[contenthash]生成hash名,[ext]是指使用原文件扩展名
               generator:{
                   filename: 'images/[contenthash][ext]'               
               }     
           }       
       ]   
   }
};

| 参考

# webpack基础篇(二):资源模块asset module(asset/resource、asset/inline、asset/source、asset
# webpack官方文档