Webpack基础应用篇 - [7] 资源模块

1.5 资源模块

目前为止,我们的项目可以在控制台上显示 “Hello world~~~”。现在我们尝试混合一些其他资源,比如 images,看看 webpack 如何处理。

在 webpack 出现之前,前端开发人员会使用 gruntgulp 等工具来处理资源,并将它们从 /src 文件夹移动到 /dist/build 目录中。webpack 最出色的功能之一就是,除了引入 JavaScript,还可以内置的资源模块 Asset Modules 引入任何其他类型的文件

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

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

  • asset/resource 发送一个单独的文件并导出 URL。
  • asset/inline 导出一个资源的 data URI。
  • asset/source 导出资源的源代码。
  • asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。

1.5.1 Resource 资源

修改 webpack.config.js配置:

// 配置资源文件
  module: {
    rules: [{
      test: /\.png/,
      type: 'asset/resource'
    }]
  },

06-asset-modules/webpack.config.js

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
//...

// 配置资源文件
 module: {
   rules: [{
     test: /\.png/,
     type: 'asset/resource'
   }]
 },
	 //...
}

准备资源文件,在入口文件中引入,并显示在页面上:

请添加图片描述

06-asset-modules/src/index.js

// 导入函数模块
import helloWorld from './hello-world.js'
import imgsrc from './assets/img-1.png'

helloWorld()

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

执行打包命令:

[felix] 06-asset-modules $ npx webpack
asset 8ec2798f81f4745a7c9b.png 101 KiB [emitted] [immutable] [from: src/assets/img-1.png] (auxiliary name: main)
asset bundle.js 10.5 KiB [emitted] (name: main)
asset app.html 326 bytes [emitted]
runtime modules 1.72 KiB 5 modules
cacheable modules 388 bytes (javascript) 101 KiB (asset)
  ./src/index.js 208 bytes [built] [code generated]
  ./src/hello-world.js 138 bytes [built] [code generated]
  ./src/assets/img-1.png 42 bytes (javascript) 101 KiB (asset) [built] [code generated]
webpack 5.54.0 compiled successfully in 114 ms

发现图片(.png)文件已经打包到了dis目录下:

请添加图片描述

执行启动服务命令:

请添加图片描述

打开浏览器:

请添加图片描述

  • 自定义输出文件名

    默认情况下,asset/resource 模块以 [contenthash][ext][query] 文件名发送到输出目录。

    可以通过在 webpack 配置中设置 output.assetModuleFilename 来修改此模板字符串:

    output: {
       assetModuleFilename: 'images/[contenthash][ext][query]'
    },
    

06-asset-modules/webpack.config.js

//...
module.exports = {
//...

output: {
  //...

assetModuleFilename: 'images/[contenthash][ext][query]'
 },

//...
}

执行编译:

[felix] 06-asset-modules $ npx webpack
assets by status 101 KiB [cached] 1 asset
asset bundle.js 10.5 KiB [compared for emit] (name: main)
asset app.html 326 bytes [compared for emit]
runtime modules 1.72 KiB 5 modules
cacheable modules 356 bytes (javascript) 101 KiB (asset)
  ./src/index.js 208 bytes [built] [code generated]
  ./src/hello-world.js 106 bytes [built] [code generated]
  ./src/assets/img-1.png 42 bytes (javascript) 101 KiB (asset) [built] [code generated]
webpack 5.54.0 compiled successfully in 125 ms

请添加图片描述

另一种自定义输出文件名的方式是,将某些资源发送到指定目录,修改配置:

rules: [{
  test: /\.png/,
  type: 'asset/resource',

  // 优先级高于 assetModuleFilename
  generator: {
    filename: 'images/[contenthash][ext][query]'
  }
}]

06-asset-modules/webpack.config.js

//...
module.exports = {
//...

output: {
//...

// 配置资源文件
   module: {
      rules: [
   {
          test: /\.png/,
          type: 'asset/resource',

          // 优先级高于 assetModuleFilename
        generator: {
       filename: 'images/[contenthash][ext][query]'
         }
       }
 ],
  },

//...
}

执行编译:

[felix] 06-asset-modules $ npx webpack
assets by status 102 KiB [cached] 2 assets
assets by path . 10.5 KiB
  asset bundle.js 10.5 KiB [compared for emit] (name: main)
  asset app.html 71 bytes [compared for emit]
runtime modules 1.72 KiB 5 modules
cacheable modules 356 bytes (javascript) 101 KiB (asset)
  ./src/index.js 208 bytes [built] [code generated]
  ./src/hello-world.js 106 bytes [built] [code generated]
  ./src/assets/img-1.png 42 bytes (javascript) 101 KiB (asset) [built] [code generated]
webpack 5.54.0 compiled successfully in 113 ms

请添加图片描述

输出结果与 assetModuleFilename 设置一样。

1.5.2 inline 资源

修改 webpack.config.js配置:

// 配置资源文件
  module: {
    [
      {
        test: /\.svg/,
        type: 'asset/inline'
      }
    ],
  }

06-asset-modules/webpack.config.js

//...
module.exports = {
//...

// 配置资源文件
module: {
  rules: [
     //...
     {
        test: /\.svg/,
        type: 'asset/inline'
     }
		],
 },

	//...
}

执行启动服务命令:

请添加图片描述

打开浏览器:

请添加图片描述

可见, .svg 文件都将作为 data URI 注入到 bundle 中。

  • 自定义 data URI 生成器

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

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

安装自定义函数模块:

[felix] webpack5 $ npm install mini-svg-data-uri -D

修改配置文件:

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

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

06-asset-modules/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 包进行编码。重新启动服务,在浏览器查看效果:

请添加图片描述

1.5.3 source 资源

source资源,导出资源的源代码。修改配置文件,添加:

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

06-asset-modules/webpack.config.js

//...

module.exports = {
//...

// 配置资源文件
module: {
  rules: [
      //...

      {
        test: /\.txt/,
         type: 'asset/source'
      }
    ],
},

//...
}

在assets里创建一个 example.txt文件:

06-asset-modules/src/assets/example.txt

hello webpack

在入口文件里引入一个 .txt文件,添加内容:

import exampleText from './assets/example.txt'

const block = document.createElement('div')
block.style.cssText = `width: 200px; height: 200px; background: aliceblue`
block.textContent = exampleText
document.body.appendChild(block)

06-asset-modules/src/index.js

// 导入函数模块
//...
import exampleText from './assets/example.txt'

//...

const block = document.createElement('div')
block.style.cssText = `width: 200px; height: 200px; background: aliceblue`
block.textContent = exampleText
document.body.appendChild(block)

//...

启动服务,打开浏览器:
请添加图片描述

所有 .txt 文件将原样注入到 bundle 中。

1.5.4 通用资源类型

通用资源类型 asset , 在导出一个 data URI 和发送一个单独的文件之间自动选择。

修改配置文件:

module: {
  rules: [
    test: /\.jpg/,
		type: 'asset'
  ]
}

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

可以通过在 webpack 配置的 module rule 层级中,设置 Rule.parser.dataUrlCondition.maxSize 选项来修改此条件:

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

06-asset-modules/webpack.config.js

//...

module.exports = {
//...

// 配置资源文件
module: {
rules: [
    //...

    {
      test: /\.jpg/,
  			type: 'asset',
      	parser: {
        dataUrlCondition: {
      		maxSize: 4 * 1024 // 4kb
       }
    }
	 }
],
},

//...
}

assets目录下创建 .jpg 文件,然后在入口文件中引入:

import jpgMap from './assets/qianfeng-sem.jpg'

const img3 = document.createElement('img')
img3.style.cssText = 'width: 600px; height: 240px; display: block'
img3.src = jpgMap
document.body.appendChild(img3)

06-asset-modules/src/index.js

// 导入函数模块
//...
import jpgMap from './assets/qianfeng-sem.jpg'

//...
const img3 = document.createElement('img')
img3.style.cssText = 'width: 600px; height: 240px; display: block'
img3.src = jpgMap
document.body.appendChild(img3)

启动服务,打开浏览器:

请添加图片描述

执行编译命令:

[felix] 06-asset-modules $ npx webpack
assets by status 101 KiB [cached] 1 asset
assets by status 653 KiB [emitted]
  asset images/33120e6c4bd92df7bec8.jpg 637 KiB [emitted] [immutable] [from: src/assets/qianfeng-sem.jpg] (auxiliary name: main)
  asset bundle.js 15.7 KiB [emitted] (name: main)
asset app.html 326 bytes [compared for emit]
runtime modules 1.72 KiB 5 modules
cacheable modules 4.03 KiB (javascript) 738 KiB (asset)
  asset modules 3.1 KiB (javascript) 738 KiB (asset)
    ./src/assets/img-1.png 42 bytes (javascript) 101 KiB (asset) [built] [code generated]
    ./src/assets/webpack-logo.svg 2.99 KiB [built] [code generated]
    ./src/assets/example.txt 25 bytes [built] [code generated]
    ./src/assets/qianfeng-sem.jpg 42 bytes (javascript) 637 KiB (asset) [built] [code generated]
  javascript modules 949 bytes
    ./src/index.js 843 bytes [built] [code generated]
    ./src/hello-world.js 106 bytes [built] [code generated]
webpack 5.54.0 compiled successfully in 139 ms

请添加图片描述

发现当前的 .jpg文件被打包成了单独的文件,因为此文件大小超过了 4kb

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值