webpack 图片缓存-动态引入images-require()和import()

2023-09-16 0 2,553 百度已收录

如今,用webpack打包后端项目已经成为行业趋势。 然而,在这个模型的前提下,图像的引入对于我们来说是一个无法回避的问题。 正常的图片引入是使用img标签或者元素背景图片。 使用这些方法的图片可以通过webpack正常打包并显示。 而且webpack 图片缓存,如果直接在js文件中定义图片路径并赋值给图片元素,也是无法正常显示的。 这是因为webpack打包后,静态资源文件会放在dist/static/img下。 我们的网站实际上是使用 dist 目录作为根目录,从而在该目录下加载index.html所需的css、js、img等。 当我们在js文件中动态引入图片时,url-loader很难检测到图片路径。 我们构建后发现webpack 图片缓存,图片根本没有打包输出到dist目录(webpack按需打包)。

1. 要求

// html
// xxx.js
let imgList = [
    require('../images/a.png'),
    require('../images/b.jpg')
]

官方文档:如果你的请求包含丰富的表达式,则会创建一个上下文,因为在编译时并不清楚导出哪个模块

错误引用

上面的意思是通过下面的方法无法加载图片。 在这些方法下,webpack无法找到引入的特定模块(图像),因此无法对图像进行哈希并将其输出到dist文件。

let imgUrlStr = '../images/a.png'; 
let imgUrl = require(imgUrlStr);

正确引用

由于require在纯变量的情况下无法找到模块,因此我们至少必须在require参数中指定一个目录。 这种情况下,即使不知道具体的模块,webpack也会为我们做一些分析工作:

然而,在这种情况下,使用的是 webpack 生成的 context 模块。 它包含对目录中所有模块的引用。 它是一个通过请求解析的正则表达式,用于匹配目录中所有匹配的模块,然后将它们引入。这个 contextmodule 包含一个映射对象,它将把请求中的所有模块转换为相应的模块 id。 这意味着webpack可以支持动态require,但是会导致所有可能用到的模块都包含在bundle中。

let imgName = 'a'; 
let imgAllName = 'a.png';
// example 1
let imgUrl = require('../images/a.png');                // 纯字符串
// example 2
let imgUrl = require('../images/' + imgAllName);        // 目录 + 文件全名
// example 3
let imgUrl = require('../images/' + imgName + '.png');  // 目录 + 文件名 + 后缀

需要上下文

该方法可以理解为require方法的详细实现。 使用 require.context() 函数创建您自己的上下文。 可以向此函数传递三个参数:要搜索的目录、指示是否也搜索其子目录的标志以及匹配文件的正则表达式。

// 语法
require.context(directory, useSubdirectories = false, regExp = /^.//);
// example
// 创建出一个 context,其中所有文件都来自父文件夹及其所有子级文件夹,request 以 `.png` 结尾。
require.context('../images', true, /.png$/);

require.context返回值

上下文模块将导入一个(require)函数,该函数可以接收一个参数:request。

这个导入函数有三个属性:resolve、keys、id。

图片预加载

动态加载文件夹中的所有图像实例:

// example 
// 图片预加载, 
preloadAllImages () {
    let imgCounts = 0;      // 已加载图片计数,可实现真实进度条 
    let imgsFun = require.context('../images', true, /.(png|jpg)$/);
    let imgKeys = imgsFun.keys();
    imgKeys.forEach(item => {
        let Img = new Image();
        Img.src = imgsFun(item);
        Img.onload = function () {
            imgCounts++;
        }
        Img.onerror = function () {
            imgCounts++;
        };
    });
}

2. 导入

require是在运行时加载模块,但是import命令会被JavaScript引擎静态分析并在模块中的其他模块之前执行。 它无法在运行时加载。 因此,为了实现类似require的动态加载,建议实现一个 import() 功能模式,

import(specifier);

里面的代码中,import函数的参数说明符指定了要加载的模块的位置。 import 命令可以接受哪些参数,import() 函数可以接受哪些参数? 两者的主要区别在于前者是动态加载的。

import() 函数可以在任何地方使用,不仅是模块,还可以是非模块脚本。 它是在运行时执行的,也就是说,每当运行这句话时,指定的模块也会被加载。 另外,import()函数与加载的模块没有静态连接关系,这也是与import语句不同的地方。

import() 功能依赖于外部 Promise。 如果您想在旧版浏览器中使用 import(),请记住使用像 es6-promise 或 Promise-polyfill 这样的 polyfill 库来预填充(填充)Promise 环境。

// example
let imgUrl = '';
// 与require参数类似,不能通过纯参数的方式引入模块。正确的引入方式可查看以上require的引入方式
import('../assets/tree/tree.png').then(res => {
    imgUrl = res;
});

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 webpack webpack 图片缓存-动态引入images-require()和import() https://www.wkzy.net/game/196637.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务