美文网首页
webpack5资源最佳加载方案

webpack5资源最佳加载方案

作者: 懂会悟 | 来源:发表于2022-06-18 16:33 被阅读0次

今天我们一起探讨学习下webpack5中关于Asset Modules的那些事

初始化基础项目

新建一个文件夹webpack-05-resource,

npm init -y 

我们安装项目一些基础支持的插件

npm i webpack webpack-cli webpack-dev-server html-webpack-plugin babel-loader @babel/core -D

在根目录新建webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'js/[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        options: {
          presets: ['@babel/env']
        }
      },
      {
        test: /\.(png|jpg)$/i,
        type: 'asset/resource'
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './public/index.html'
    })
  ]
};

注意我们加载图片没有使用file-loader与url-loader,我们使用的是webpack5内置的asset/rosource这个来处理

  module.exports = {
    module: {
      rules: [
        {
          test: /\.(png|jpg)$/i,
          type: 'asset/resource'
        }
      ]
    }
  }

在index.js中我们插入一张图片

import img1Src from '../assets/images/1.png';
var appDom = document.getElementById('app');
const img = new Image();
img.src = img1Src;
appDom.appendChild(img);

ok,运行npm run server,打开浏览器localhost:8080

我们会发现,生成的图片地址就是
<img src="http://localhost:8080/js/../b1640e009cff6a775ce5.png">

generator配置

现在我想配置图片的默认输出地址与名字,在module.rules中有一个generator的属性可以配置匹配图片输出的文件

// webpack.config.js
 module.exports = {
    module: {
      rules: [
        ...
        {
          test: /\.(png|jpg)$/i,
          type: 'asset/resource',
          generator: {
            filename: 'images/[name][ext]'
          }
        }
      ]
    }
  }

此时页面加载图片的路径就变成了
<img src="http://localhost:8080/js/../images/1.png">

如果你的图片地址是上传到cdn上的,那么你可以像下面一样这么做,但是这种做法是不是在项目中真的需要,还有待商榷,因为这样会导致应用的所有图片用cdn方式加载,如果项目中只是部分图片按需cdn加载,那么这种做法是不可取的。

 {
        test: /\.(png|jpg)$/i,
        // type: 'asset/resource'
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 40 * 1024
          }
        },
        generator: {
          publicPath: 'https://cdn/assets', // cdn域名前缀
          filename: 'images/[name][ext]'
        }
      }

自此页面的加载的图片就是
<img src="https://cdn/assets/images/3.png">

assetModuleFilename

除了generator.filename方式,你也可以在output中加入assetModuleFilename配置来修改图片默认的地址,不过注意这个属性只能是针对rule中设置的type''asset/resource' | 'asset'类型才生效。

module.exports = {
  output: {
    filename: 'js/[name].js',
    path: path.resolve(__dirname, 'dist'),
    assetModuleFilename: 'images/[name][ext]'
  }
}

通常项目里我们会把比较小的图片直接坐base64加载,大的图片就直接输出加载,或者上传到cdn直接加载图片地址,你可以在rules的generator.publicPath设置地址图片地址。

因此我引入两张大小不一样的图片测试,修改一下index.js

import img1Src from '../assets/images/1.png';
import img3Src from '../assets/images/3.png';

function renderImage(imageSource) {
  const weakMap = new WeakMap();
  var appDom = document.getElementById('app');
  imageSource.forEach((src) => {
    const img = new Image();
    weakMap.set(img, img);
    if (weakMap.has(img)) {
      weakMap.get(img).src = src;
      appDom.appendChild(img);
    }
  });
}
renderImage([img1Src, img3Src]);

我们再修改下webpack.config.js

module.exports = {
  module: {
    rules: [
       ...
       {
        test: /\.(png|jpg)$/i,
        // type: 'asset/resource'
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 40 * 1024
          }
        }
      }
    ]
  }
}

在rules中增加parser属性,并且将type改成asset,当我们设置一个dataUrlCondition: {maxSize: 40 * 1024},小于KB就用base64加载了,大于40KB就直接用图片路径加载



因此我们可以看到两张图片,一张图片是base64一张图片就走文件路径了。

所以在你的项目中你可以利用这个parser.dataUrlCondition.maxSize特性来优化图片资源,有些资源小图片就可以用base64来加载,这样可以减少页面图片的资源请求

但是并不是所有的图片都要base64,base64生成的字符串非常大,同时也是增加了html的体积,无法利用缓存机制加载图片。

所以在优化的网页加载过程中,并不是全部都用base64来加载图片。

关于内置模块的几个参数

主要参考官网

webpack5之前

  • row-loader 将文件导入为字符串,比如导入.txt类型的文件
  • url-loader 将文件作为Data Url嵌入到打包后bundle.js中,比如base64文件
  • file-loader 将文件输出目录,图片文件会被打包到指定目录中加载
    webpack5现在
  • asset/resource 导出单独的url,是file-loader的替代品
  • asset/inline 导出资源Data Url,是url-loader的替代品
  • asset/source 导出文件资源内容,是row-loader的替代品
  • asset 在url-loader和file-loader中选择,配置parse.dataUrlCondition.maxSize来输出图片资源是否base64输出

总结

  • 相比较webpack5之前我们加载图片资源文件使用file-loader或者url-loader在webpack5中可以使用内置模块type: 'assets/resource'
  • 基于webpack5内置模块asset module type来设置资源的加载
  • 图片资源base64处理,根据图片资源的大小parse.dataUrlCondition.maxSize来限制是否需要base64输出
  • 比较asset module type几种模式区别,代替以前row-loader、file-loader、url-loader方案,但是这仅仅是你的webpack版本在5以后。

转发 webpack5资源最佳加载方案
文中项目代码

相关文章

  • 本地资源加载方案

    replugin资源加载方案 基本原理: 通过调用PackageManager中getPackageArchive...

  • Android换肤方案

    换肤方案:(1)内部资源加载方案:定义几套主题,所有的图片,背景等资源都打包到apk里面,通过BaseActivi...

  • SPA(单页应用)首屏加载速度优化

    加载缓慢的原因 网络延时问题 前端资源文件体积过大 重复请求加载资源 加载脚本的时候,堵塞了渲染内容 解决方案 1...

  • 09:项目资源管理36

    数据分析(P356)备选方案分析----选择最佳解决方案以纠正资源使用偏差,可以将加班和增加团队资源等备选方案与延...

  • Bitmap的加载和Cache

    参考资料 Android DiskLruCache完全解析,硬盘缓存的最佳方案 目录 Bitmap的高效加载 An...

  • WWW同步加载资源方案

    AudioClip有从外部加载资源的方式,但是如果不知道采样率什么的就悲剧了。。Texture2D有从外部加载资源...

  • Unity3d常用两种加载资源方案:Resources.Load

    初步整理并且学习unity3d资源加载方法,预计用时两天完成入门学习Unity3d常用两种加载资源方案:Resou...

  • 10.24

    整合思考是让我们去找更好的资源,找到最好最佳的解决方案。

  • AssetBundle打包

    AssetBundle打包方案主要基于以下几方面考虑: 资源的归类划分,方便资源加卸载 避免重复打包重复加载 ab...

  • js 如何禁止选中文本

    js最佳方案 css最佳方案

网友评论

      本文标题:webpack5资源最佳加载方案

      本文链接:https://www.haomeiwen.com/subject/cqprvrtx.html