前言

资源模块可以帮助我们打包不同类型的资源文件,例如:图片,字体
资源模块(asset module)是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 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,并且配置资源体积限制实现。

前期准备

我们现在src文件夹里放入asset文件夹,内部装有我们需要的资源文件.jpg .png .webp图片以及.ttf和.txt文件
image.pngimage.png

1. Resource 资源

resource 会发送一个单独的文件并导出 URL

  1. const path = require("path")
  2. const HtmlWebpackPulgin = require("html-webpack-plugin")
  3. module.exports = {
  4. mode: 'development',
  5. entry: './src/index.js',
  6. output: {
  7. filename: 'bundle.js',
  8. path: path.resolve(__dirname, './dist'),
  9. clean: true,
  10. // assetModuleFilename控制输出文件的文件名,还能指定目录(优先级低于generator)
  11. // [contenthash]:webpack自带的 自动生成名字
  12. // [ext]:webpack自带的 保留源文件扩展名
  13. assetModuleFilename: 'images/[contenthash][ext]'
  14. },
  15. devtool: 'inline-source-map',
  16. plugins: [
  17. new HtmlWebpackPulgin({
  18. // html的模板
  19. template: './index.html',
  20. // 导出html文件的名字
  21. filename: 'app.html',
  22. // 让 js 文件在 body标签 内被引入
  23. inject: 'body'
  24. }),
  25. new MiniCssExtractPlugin({
  26. filename: 'style/[contenthash].css'
  27. }),
  28. new CssMinimizerPlugin()
  29. ],
  30. devServer: {
  31. static: './dist',
  32. hot: true,
  33. },
  34. // asset.moudle 资源模块(允许我们打包除 JS 以外的文件,比如字体,图片等)
  35. // 其内部有四种新的资源模块,替换所有的 loader
  36. // (1) asset / resource 发送一个单独文件并导出URL
  37. // (2) asset / inline 导出一个资源的dataURL
  38. // (3) asset / source 导出一个资源的源代码
  39. // (4) asset 会在 resource 和 inline 之间自动选择
  40. // loader:通过loader我们也可以加载资源文件
  41. // style-loader 和 css-loader,通过这两个我们可以实现CSS文件的加载
  42. module: {
  43. rules: [
  44. {
  45. // 会单独生成一个文件,并且在浏览器上能看到导出的路径
  46. // http://localhost:8080/images/92f14689885b0e09af6d.jpg
  47. test: /\.jpg$/i,
  48. type: 'asset/resource',
  49. generator: {
  50. filename: 'images/[contenthash][ext]'
  51. }
  52. },
  53. }
  54. }
  1. // index.js
  2. import { helloworld } from "./helloworld";
  3. import imgsrc_1 from './asset/云谨.jpg'
  4. helloworld()
  5. const img_1 = document.createElement('img')
  6. img_1.src = imgsrc_1
  7. img_1.style.cssText = 'width:100px; height:100px;'
  8. document.body.appendChild(img_1)

自定义输出文件名

默认情况下,asset/resource 模块以 [hash][ext][query] 文件名发送到输出目录。
(1) webpack 配置中设置 output.assetModuleFilename 来修改此模板字符串

  1. output: {
  2. filename: 'bundle.js',
  3. path: path.resolve(__dirname, './dist'),
  4. clean: true,
  5. // assetModuleFilename控制输出文件的文件名,还能指定目录(优先级低于generator)
  6. // [contenthash]:webpack自带的 自动生成名字
  7. // [ext]:webpack自带的 保留源文件扩展名
  8. assetModuleFilename: 'images/[contenthash][ext]'
  9. },

(2)另一种自定义输出文件名的方式是,将某些资源发送到指定目录

  1. {
  2. test: /\.jpg$/i,
  3. type: 'asset/resource',
  4. // generator.filename配置输出文件名
  5. generator: {
  6. filename: 'images/[contenthash][ext]'
  7. }
  8. },

配置好之后,我们npx webpack运行
image.pngimage.png

2. Inline 资源

只需要修改一下配置

  1. module: {
  2. rules: [
  3. {
  4. // 不会生成文件,但是在浏览器上能看到,路径是由一个base64的dataURL组成
  5. // data:image/png;base64,/9j/4AAQSkZJRgABAgEASABIAAD/…e1KjUqUqUW+vJTjCmu0IQj8MUl/TzXnHMFABQAUAFABQB/9k=
  6. test: /\.jpg$/i,
  7. type: 'asset/inline',
  8. generator: {
  9. filename: 'images/[contenthash][ext]'
  10. }
  11. },
  12. }

image.png没有生成额外的文件image.png

3. Source 资源

  1. module: {
  2. rules: [
  3. {
  4. // 导出一个资源的源代码
  5. test: /\.txt$/i,
  6. type: 'asset/source',
  7. },
  8. }
  1. // index.js
  2. import example from './asset/example.txt'
  3. const box = document.createElement('div')
  4. box.textContent = example
  5. box.style.cssText = 'width:100px; height:100px;border:1px solid;'
  6. document.body.appendChild(box)
  1. // example.txt
  2. godvoid6666
  3. <h1>2233</h1>

image.png
直接把源码输出到了页面上

4. Asset 通用资源类型

webpack 将按照默认条件,自动地在 resource 和 inline 之间进行选择:小于 8kb 的文件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。
可以通过在 webpack 配置的 module rule 层级中,设置 Rule.parser.dataUrlCondition.maxSize 选项来修改此条件:

  1. {
  2. // 在 resource 和 inline 之间自动选择
  3. // 没有指定 generator,会继承 output 内的 assetModuleFilename
  4. // 如何进行选择:(默认的大小是 8KB)
  5. // 当 文件大小 > 指定的大小时 => resource(创建一个单独文件)
  6. // 当 文件大小 < 指定的大小时 => inline(dataURL)
  7. test: /\.webp$/i,
  8. type: 'asset',
  9. parser: {
  10. dataUrlCondition: {
  11. maxSize: 4 * 1024 // 4K , 生成文件
  12. // maxSize: 4 * 1024 *1024 4M , 生成 dataURL
  13. }
  14. }
  15. },