3.2-3.5 不太理解这几节中通过图片名动态加载图片路径的做法

来源:3-5 通过图片名动态加载图片代码实现-3

慕村510262

2022-08-18

本身我开发的经验并不多,刚接触 Vite,且对项目发布、部署等流程也不太了解,之后的章节也还没看。看了这几节后,提出下面的问题可能会有点过早。但现在实在想不通这种做法,于是就提出来了。


视频中用 Vite 来处理图片资源,那 npm run build 打包生成的 dist 目录中的 js 文件代码中含有图片名和对应的图片路径,而且我们还让用户前端在第一次打开网页时,本地缓存这些图片名和图片路径,之后再次打开网页时,从本地缓存中读取这些图片名和图片路径就可以了。
图片描述
这样打包上线,我的疑惑是这样不会有以下问题吗:

  1. 如果有上千万本图书,这样打包生成的 js 代码会不会过长?导致加载 js 代码时间长?
  2. 如果要新增图书图片,是不是每次都要重新打包一次?
  3. 如果图片路径发生了变化,用户前端本地缓存中保存的图书名以及对应的图书路径如何也变更?
  4. 此时 npm run preview 显示不了图片,比如我们想这样加载图片 <img :src="getImg('白夜行.png')" />,但打包生成的图片名已变成 白夜行.56b0275d.png,所以我们加载不了图片。而且,之后我们可能写这样的代码<img :src="getImg(bookitem.bookpicname)" />,我不知 Vite 每次打包生成的图片名是否都一样?如果不一样,存储在数据表中的图片名应该也应该变更?
写回答

2回答

keviny79

2022-08-19

  1. 显示图片没问题:npm run preview  使用过时的import.meta.globEager也能显示图片 ,今天我刚更新到高版本的 vite , import.meta.glob方法也测过了,也没问题:高版本的vite 编写的代码如下:

import storage from 'good-storage'

export class LmgLoader {

  static imgList: Record<string, any> = {}


  static async getimgList() {

    this.imgList = storage.get('imgList') || {}

    if (!LmgLoader.imgList || !LmgLoader.isNotEmptyimgList()) {

      this.imgList = LmgLoader.getImgAll()

      storage.set('imgList', LmgLoader.imgList)

    }

  }


  static isNotEmptyimgList() {

    return Object.getOwnPropertyNames(LmgLoader.imgList).length

  }

  static getImg(name: string): string {

    //console.log('name:', name)

    // LmgLoader.imgList = LmgLoader.isNotEmptyimgList() ? LmgLoader.imgList : storage.get('imgList')

    return LmgLoader.imgList[name] //

  }


  static getImgAll(): any {

    const imgList: any = {}

    const viewImgModules: Record<string, any> = import.meta.glob(`../assets/img/**/**/*.png`, { eager: true })

    // import.meta.globEager(`../assets/img/**/**/*.png`)

    for (const path in viewImgModules) {

      if (viewImgModules[path].default) {

        const pathName = path.substring(path.lastIndexOf('/') + 1)

        imgList[pathName] = viewImgModules[path].default

      }

    }

    storage.set('imgList', this.imgList)

    return imgList

  }

}


export default LmgLoader.getImg



0
0

keviny79

2022-08-19

同学:这样写动态加载图片能给项目的维护性和扩展性带来相当大的好处,你就放心用吧。

如果不动态加载,那么图片路径管理只有两种做法,做法1:把图片路径保存到数据表中,取出来即可,这会让数据表对图片的管理变得很繁琐,而且从后端数据表取出图片名的速度会下降,因为带着路径,这在高并发场景下无疑是一个损耗! 做法2:就是在项目中手动管理路径,因为一个大项目图片非常多,那么多路径都要管理,都要维护,这浪费了很多时间,大大增加了维护的负担!而且一旦图片路径变了,就需要修改代码,扩展性很不好!

做法2还有一个问题就是,你动态从数据表获取到一个图片,然后和你页面上的图片路路径连接,当打包后,vite 2.x 版本的npm run preview 获取不到图片,3.x 也测过了,没问题,代码已经贴在下方!

解答你的问题:

首先你说的正确,应该保存到缓存中,不用每次刷新都加载图片,视频中补讲了缓存

  1. 这个不会,因为加载的数据只是一些本地的一些key-value的数据,而不是真实图片,千万 key-value  加载也会很快,  而且用到了缓存,除了刚启动第一次加载,后面就不用再加载了, 加之 vite使用了 esbuild 预构建,基于 go 语言,其速度比之前的 webpack 快了上百倍,所以上万个key-value加载,也算不了什么

  2. 增加了图片,不管你用不用老师讲到的加载图片的方法, 都需要重新打包,打包的原因是你增加了新的资源。

  3. 实际开发时,图片路径一般保存好了,一般很少会变的,即使变了,删除下缓存,重新加载就ok了。对比传统的路径写到代码中,一旦路径变了,那远比咱们动态加载图片麻烦

  4. 显示图片没问题:npm run preview   使用过时的import.meta.globEager也能显示图片 ,今天更新到高版本的 vite 的glob的测过了,也没问题:高版本的vite 编写的代码如下:【缓存问题也解决了】

import storage from 'good-storage'

export class LmgLoader {

  static imgList: Record<string, any> = {}


  static async getimgList() {

    this.imgList = storage.get('imgList') || {}

    if (!LmgLoader.imgList || !LmgLoader.isNotEmptyimgList()) {

      this.imgList = LmgLoader.getImgAll()

      storage.set('imgList', LmgLoader.imgList)

    }

  }


  static isNotEmptyimgList() {

    return Object.getOwnPropertyNames(LmgLoader.imgList).length

  }

  static getImg(name: string): string {

    //console.log('name:', name)

    // LmgLoader.imgList = LmgLoader.isNotEmptyimgList() ? LmgLoader.imgList : storage.get('imgList')

    return LmgLoader.imgList[name] //

  }


  static getImgAll(): any {

    const imgList: any = {}

    const viewImgModules: Record<string, any> = import.meta.glob(`../assets/img/**/**/*.png`, { eager: true })

    // import.meta.globEager(`../assets/img/**/**/*.png`)

    for (const path in viewImgModules) {

      if (viewImgModules[path].default) {

        const pathName = path.substring(path.lastIndexOf('/') + 1)

        imgList[pathName] = viewImgModules[path].default

      }

    }

    storage.set('imgList', this.imgList)

    return imgList

  }

}


export default LmgLoader.getImg



0
1
rookie_white
老师,你说的第三点,图片路径发生改变了,删除缓存可以重新加载,这个要怎么弄?用户的我们控制不了吧,只能写上一行代码,判断有没有缓存图片,有的话就删除加载,那不是每次加载页面的时候都要删一遍在设置一遍吗?
2023-04-24
共1条回复

前端高手养成计划-从前端到后端,全栈开发大型项目

从纯前端到“真正懂后端的前端”

215 学习 · 134 问题

查看课程