Original link: https://blog.rxliuli.com/p/9eb3b1a6e46a4777b3661ce0bb890d69/
Scenes
At present, there is a bug in the function of inline media resources when vite is built. There has been a github issue since the end of 2020. I feel that it is unlikely to be solved in the short term, so I decided to use a plug-in to restore this function by myself.
Below is a dist built with vite, you can see that the svg is not correctly inlined into the code, but is split into a bundle separately, and the jpg image is correctly inlined.
Existing plugin
Why not use the plugin @rollup/plugin-image
- It doesn’t do special processing for vite, vite’s built-in plug-in handles svg earlier than it does, it will never have a chance to process images
- It does not handle resources from other modules in the monorepo project
It is not difficult to implement. The core is to intercept the load of .svg and replace it with a js file, which exports the svg dataUri string by default.
import { createFilter , FilterPattern } from "@rollup/pluginutils" ; import { readFile } from "fs-extra" ; import svgToMiniDataURI from "mini-svg-data-uri" ; import * as path from "path" ; import { optimize , OptimizedSvg } from "svgo" ; import { Plugin } from "vite" ; const defaults = { exclude : null , include : null , } ; export function svgPatch ( opts ? : { include ? : FilterPattern ; exclude ? : FilterPattern ; } ) : Plugin { const options = Object . assign ( { } , defaults , opts ) ; const filter = createFilter ( options . include , options . exclude ) ; return { name : "vite-plugin-svg-patch" , enforce : "pre" , resolveId ( id : string , importer : string ) { if ( this . meta . watchMode ) { return null ; } if ( id . endsWith ( ".svg" ) ) { return path . resolve ( path . dirname ( importer ) , id ) ; } } , async load ( id ) { if ( this . meta . watchMode ) { return null ; } if ( ! filter ( id ) || ! id . endsWith ( ".svg" ) ) { return null ; } const source = optimize ( ( await readFile ( id , "utf-8" ) ) . replace ( / [\r\n]+ / gm , "" ) ) ; if ( source . error || source . modernError ) { console . error ( "svg optimization failed: " , id ) ; } const dataUri = svgToMiniDataURI ( ( source as OptimizedSvg ) . data ) ; return ` export default " ${ dataUri } "; ` ; } , } ; }
use
Published as npm package @liuli-util/vite-plugin-svg-patch
import { defineConfig } from "vite" ; import vue from "@vitejs/plugin-vue" ; import { svgPatch } from "@liuli-util/vite-plugin-svg-patch" ; export default defineConfig ( { plugins : [ vue ( ) , svgPatch ( ) ] , } ) ;
The following is after using the plugin, you can see that the svg file is not divided into a separate file.
limitation
At present, I haven’t found a hook to process image resources using background-image: url("")
in vue style/css
files. It may be a hook that can only be accessed inside vite.
One idea is to use transformHook, but I don’t want to deal with things like sourcemap for the time being, so I haven’t tried it yet.
This article is reproduced from: https://blog.rxliuli.com/p/9eb3b1a6e46a4777b3661ce0bb890d69/
This site is for inclusion only, and the copyright belongs to the original author.