在 Vue CLI 3 中从原始图像创建 webp 图像(作为替代版本)

Create webp images (as alternative version) from original images in Vue CLI 3

我在最新的 Vue CLI 3 上有一个简单的 Vue 项目(我在这两个方面都是新手)。在 src 中,我有 100% 质量的 jpg / png 图像。默认情况下,cli while build 将使用我的图像创建 dist 目录添加哈希(image.jpg 到图像。7a97ca45.jpg)但没有任何压缩。

所以我添加了 imagemin-webpack-plugin 和 imagemin-mozjpeg 以及 imagemin-pngquant 来获得优化。它有效。在 dist 现在我有更小的 jgp 和 png。

const ImageminPlugin = require('imagemin-webpack-plugin').default
const ImageminMozjpeg = require('imagemin-mozjpeg')
const ImageminPngquant = require('imagemin-pngquant')

module.exports = {
  configureWebpack: {
    plugins: [
      new ImageminPlugin({
        plugins: [
          ImageminMozjpeg({
            quality: 70
          }),
          ImageminPngquant({
            quality: '80-90'
          })
        ]
      })
    ]
  }
}

但现在我还想拥有从原始 jpg 创建的 .webp 图像。所以我应该同时获取 image.7a97ca45.jpg 和 image.7a97ca45.jpg.webp(或 image.7a97ca45.webp),这样我就可以检测浏览器并提供正确的格式。

但我不明白如何在 vue.config.js 中强制 webpack 创建这些文件。 例如,我尝试了 imagemin-webp-webpack-plugin 但这没有任何作用("imagemin-webp-webpack-plugin: 0 MB saved - in console")。 我还尝试将 imagemin-webp 添加到 imageminplugin 配置中,但这也不起作用,因为我的源中没有原始 webp,只想转换新的。

我能找到的关于 webp 的所有主题都是针对普通 webpack 或旧版 vue-cli 的,我取得的最好成绩是通过优化复制整个图像目录或从已经压缩的 jpg(非原始文件)创建 webp 图像。但是我想保留所有散列等的普通加载器。最好的方法是什么?

回答我自己2年的问题,因为有一些看法。

如果您赶时间,请简答:

如果您将 Nuxt 与 Vue 一起使用,则使用 nuxt-optimized-images,对于图像路径,请使用查询 ?webp 而不是 .webp 扩展名。完成。

长答案:

我正在使用 Nuxt,我的答案是针对这个,但它肯定可以通过手动使用 webpack 加载程序在原始 Vue 上完成。

所以有模块 nuxt-optimized-images,它简单地将多个 webpack 加载器和 imagemin 与每种格式的插件结合在一起。如果您没有使用 Nuxt,甚至没有使用 Vue,那么只需检查文档或源代码以获取依赖项并手动 install/configure webp 支持。

它有 webp-loader 我们需要 build-in。问题是,如何使用 nuxt-optimized-images 正确使用它。我们不能简单地在代码路径 image.webpimage.jpg.webp 的某个地方键入,因为 webpack 会抛出文件不存在的错误(这是我之前也遇到过的问题)。 相反,我们需要在文件路径中使用查询 ?webp,例如 <img src="@/assets/images/photo.jpg?webp" />。库会将请求的文件转换为 webp,一切正常。与其他解决方案相比,此解决方案的优点在于它不会转换项目中的所有 png/jpg 图像,而只会转换我们选择的文件。感谢这个编译速度更快。 (docs)

Webp 支持和检测

如果您正在阅读本文,那么您想要同时支持 .webp 和 .jpg/.png。在 2018 年,这是正常做法,因为只有 Chrome 支持这种格式。但是今天(2020 年)几乎所有主流浏览器都可以处理 webp,包括来自 Microsoft (Edge) 的浏览器。 IE 永远不会支持它(但是拜托...),Safari 仍然落后,但在最新的 Mac OS 中也引入了它。随着时间的推移,覆盖范围只会更大。那么支持多种格式值得麻烦吗? Caninuse.com.

这不是对每个网站都是最好的主意,但可以在您的场景中考虑这一点。假设我们有 .jpg 和 .webp 作为网站背景。我们真的需要旧浏览器的 .jpg 回退吗?也许只是在 CSS 中制作纯色作为回退将是 better/easier/faster 解决方案?

但是,如果我们需要同时支持 .webp 和 .jpg/.webp 格式,那么可以通过检测用户代理、headers 等在 JS 中(在 Vue 中)以多种方式完成。 Nuxt(SSR - 服务器端渲染)会出现问题,因此适用于任何地方(不仅仅是在 Vue 中)的最佳解决方案是 HTML5 <picture> 标签(docs)。

<picture>
  <source srcset="@/assets/images/screen.png?webp" type="image/webp">
  <img src="@/assets/images/screen.png" alt="Screen">
</picture>