webpack基础篇(二):资源模块asset module(asset/resource、asset/inline、asset/source、asset)

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

在webpack出现之前,前端开发人员会使用gruntgulp等工具来处理资源,并将它们从/src文件夹移动到/dist/build目录中。

webpack最出色的功能之一就是,除了引入JavaScript,还可以内置的资源模块asset module引入任何其他类型的文件。

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

webpack 5 之前,通常使用:

资源模块类型(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,并且配置资源体积限制实现。

1. asset/resource

修改 webpack.config.js 配置:

module: {
    
    
    rules: [
      {
    
    
        test: /\.png$/,
        type: 'asset/resource'
      }
    ]
  }

index.js 引入图片资源

// src/index.js
import icon from './assets/icon.png'
const iconImg = document.createElement('img')
iconImg.style.cssText = 'width: 200px;'
iconImg.src = icon
document.body.appendChild(iconImg)

执行webpack可以在dist中可以看到有一个.png文件出现,即为asset/resource 发送一个单独的文件
在这里插入图片描述

执行npx webpack-dev-server可以看到图片已经出现,打开控制台查看elements可以看到改img标签的加载了url资源,即为asset/resource 导出 URL
在这里插入图片描述

2. 自定义输出文件名

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

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

webpack.config.js

const path = require('path');

module.exports = {
    
    
  entry: './src/index.js',
  output: {
    
    
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
+   assetModuleFilename: 'images/[hash][ext][query]'
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.png$/,
        type: 'asset/resource'
      }
    ]
  },
};

执行webpack可以看到dist/images
在这里插入图片描述

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

onst path = require('path');

module.exports = {
    
    
  entry: './src/index.js',
  output: {
    
    
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
+   assetModuleFilename: 'images/[hash][ext][query]'
  },
  module: {
    
    
    rules: [
			{
    
    
        test: /\.png$/,
        type: 'asset/resource',
+       generator: {
    
    
+         filename: 'images/[hash][ext][query]'
+       }
      }
    ]
  },
};

使用此配置,所有 png 文件都将被发送到输出目录中的 images 目录中。

Rule.generator.filenameoutput.assetModuleFilename 相同,并且仅适用于 assetasset/resource 模块类型。

Rule.generator.filename 优先级高于 output.assetModuleFilename


3. asset/inline

webpack.config.js

module.exports = {
    
    
  // ...
  module: {
    
    
    rules: [
      {
    
    
        test: /\.png$/,
        type: 'asset/resource',
        generator: {
    
    
          filename: 'images/[hash][ext][query]'
        }
      },
+     {
    
    
+       test: /\.svg$/,
+       type: 'asset/inline'
+     }
    ]
  }
}

idnex.js

import empty from './assets/empty.svg'
const emptyImg = document.createElement('img')
emptyImg.style.cssText = 'width: 200px;'
emptyImg.src = empty
document.body.appendChild(emptyImg)

执行webpack,可以看到dist中并没有新增加任何资源,
在这里插入图片描述

执行npx webpack-dev-server可以看到图片显示出来了,并且图片base:64
在这里插入图片描述

asset/inline只导出一个资源的 data URI,不会导出文件


4. asset/source

webpack.config.js

module.exports = {
    
    
  // ...
  module: {
    
    
    rules: [
      {
    
    
        test: /\.png$/,
        type: 'asset/resource',
        generator: {
    
    
          filename: 'images/[hash][ext][query]'
        }
      },
      {
    
    
        test: /\.svg$/,
        type: 'asset/inline'
      },
+     {
    
    
+       test: /\.txt$/,
+       type: 'asset/source'
+     }
    ]
  }
}

assets下新建 hello-webapck.txt

src/index.js

import helloWebpack from './assets/hello-webapck.txt'
const text = document.createElement('p')
text.style.cssText = 'width: 200px;height: 200px;background-color: pink;'
text.innerText = helloWebpack
document.body.appendChild(text)

执行webpack,在dist/images中没有新增资源

执行npx webpack-dev-server可以看到hello webpack显示在页面上了
在这里插入图片描述

asset/source 导出资源的源代码


5. asset 通用资源类型

webpack.config.js

module.exports = {
    
    
  // ...
  module: {
    
    
    rules: [
      {
    
    
        test: /\.png$/,
        type: 'asset/resource',
        generator: {
    
    
          filename: 'images/[hash][ext][query]'
        }
      },
      {
    
    
        test: /\.svg$/,
        type: 'asset/inline'
      },
      {
    
    
        test: /\.txt$/,
        type: 'asset/source'
      },
+     {
    
    
+       test: /\.jpeg$/,
+       type: 'asset'
+     }
    ]
  }
}

src/index.js

import figure from './assets/figure.jpeg'
const figureImg = document.createElement('img')
figureImg.style.cssText = 'width: 200px;'
figureImg.src = figure
document.body.appendChild(figureImg)

执行webpack,在dist/images可以看到有新的图片,打开可以看到是我们刚刚加载的图片
在这里插入图片描述

执行npx webpack-dev-server可以看到新图片显示在页面上了
在这里插入图片描述

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

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

webpack.config.js

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


源码地址:https://gitee.com/yanhuakang/webpack-test

如果有用,就点个赞吧(*^▽^*)

猜你喜欢

转载自blog.csdn.net/qq_41887214/article/details/121631683