diff --git a/packages/playground/assets/index.html b/packages/playground/assets/index.html
index 9983d7fc4a5da7..6353270d303869 100644
--- a/packages/playground/assets/index.html
+++ b/packages/playground/assets/index.html
@@ -119,6 +119,18 @@
SVG Fragments via JS Import
+SVG Fragments via URL JS Import
+
+
Imported path:
+
![]()
+
+
+SVG Fragments via URL HASH JS Import
+
+
Imported path:
+
![]()
+
+
?raw import
@@ -159,6 +171,14 @@ new URL(`./${dynamic}`, import.meta.url)
text('.svg-frag-import-path', svgFrag)
document.querySelector('.svg-frag-import').src = svgFrag + '#icon-heart-view'
+ import svgFragUrl from './nested/fragment-for-url.svg?url'
+ text('.svg-frag-import-js-url', svgFragUrl)
+ document.querySelector('.svg-frag-import-url').style = `background: url("${svgFragUrl}") no-repeat;`
+
+ import svgFragUrlHash from './nested/fragment-for-url.svg?url#icon-heart-view'
+ text('.svg-frag-import-js-url-hash', svgFragUrlHash)
+ document.querySelector('.svg-frag-import-url-hash').style = `background: url("${svgFragUrlHash}") no-repeat;`
+
import rawSvg from './nested/fragment.svg?raw'
text('.raw', rawSvg)
diff --git a/packages/playground/assets/nested/fragment-for-url.svg b/packages/playground/assets/nested/fragment-for-url.svg
new file mode 100644
index 00000000000000..e7de6d86b6e2f5
--- /dev/null
+++ b/packages/playground/assets/nested/fragment-for-url.svg
@@ -0,0 +1,22 @@
+
+
+
+
diff --git a/packages/playground/assets/vite.config.js b/packages/playground/assets/vite.config.js
index 1ecd3318627521..54d869e26c2f0c 100644
--- a/packages/playground/assets/vite.config.js
+++ b/packages/playground/assets/vite.config.js
@@ -13,7 +13,7 @@ module.exports = {
},
build: {
outDir: 'dist/foo',
- manifest: true,
- watch: {}
+ manifest: true
+ // watch: {}
}
}
diff --git a/packages/vite/LICENSE.md b/packages/vite/LICENSE.md
index 5f63f6317a6e59..76a3c7bba3613b 100644
--- a/packages/vite/LICENSE.md
+++ b/packages/vite/LICENSE.md
@@ -2881,6 +2881,35 @@ Repository: sindresorhus/mimic-fn
---------------------------------------
+## mini-svg-data-uri
+License: MIT
+By: Taylor “Tigt” Hunt
+Repository: git+https://github.com/tigt/mini-svg-data-uri.git
+
+> MIT License
+>
+> Copyright (c) 2018 Taylor Hunt
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+---------------------------------------
+
## minimatch
License: ISC
By: Isaac Z. Schlueter
diff --git a/packages/vite/package.json b/packages/vite/package.json
index f438bd55e75bdb..24abee3513d7b9 100644
--- a/packages/vite/package.json
+++ b/packages/vite/package.json
@@ -101,6 +101,7 @@
"magic-string": "^0.25.7",
"micromatch": "^4.0.4",
"mime": "^3.0.0",
+ "mini-svg-data-uri": "^1.3.3",
"okie": "^1.0.1",
"open": "^8.4.0",
"periscopic": "^2.0.3",
diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts
index a10ec3094229e7..5b8d6b5453a91a 100644
--- a/packages/vite/src/node/plugins/asset.ts
+++ b/packages/vite/src/node/plugins/asset.ts
@@ -8,6 +8,7 @@ import { cleanUrl } from '../utils'
import { FS_PREFIX } from '../constants'
import { OutputOptions, PluginContext, RenderedChunk } from 'rollup'
import MagicString from 'magic-string'
+import svgToTinyDataUri from 'mini-svg-data-uri'
import { createHash } from 'crypto'
import { normalizePath } from '../utils'
@@ -156,7 +157,8 @@ export function fileToUrl(
config: ResolvedConfig,
ctx: PluginContext
): string | Promise {
- if (config.command === 'serve') {
+ const file = cleanUrl(id)
+ if (config.command === 'serve' && !file.endsWith('.svg')) {
return fileToDevUrl(id, config)
} else {
return fileToBuiltUrl(id, config, ctx)
@@ -283,17 +285,25 @@ async function fileToBuiltUrl(
return cached
}
+ const { search, hash } = parseUrl(id)
const file = cleanUrl(id)
const content = await fsp.readFile(file)
let url: string
if (
- config.build.lib ||
- (!file.endsWith('.svg') &&
- content.length < Number(config.build.assetsInlineLimit))
+ file.endsWith('.svg') ||
+ ((config.build.lib ||
+ Buffer.byteLength(content) < config.build.assetsInlineLimit) &&
+ hash == null)
) {
- // base64 inlined as a string
- url = `data:${mime.getType(file)};base64,${content.toString('base64')}`
+ // svgs can be inlined without base64
+ url = file.endsWith('.svg')
+ ? // The only difference between the default method and `toSrcset` is that
+ // the latter encodes spaces as `%20`, so it's safer to always use it
+ // to support `srcset` use-case even when svg is imported into JavaScript
+ svgToTinyDataUri.toSrcset(content.toString())
+ : // base64 inlined as a string
+ `data:${mime.getType(file)};base64,${content.toString('base64')}`
} else {
// emit as asset
// rollup supports `import.meta.ROLLUP_FILE_URL_*`, but it generates code
@@ -304,7 +314,6 @@ async function fileToBuiltUrl(
// https://github.com/rollup/rollup/issues/3415
const map = assetHashToFilenameMap.get(config)!
const contentHash = getAssetHash(content)
- const { search, hash } = parseUrl(id)
const postfix = (search || '') + (hash || '')
const output = config.build?.rollupOptions?.output
const assetFileNames =
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 63675a1a47e49f..ba67dc9080ee7a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -722,6 +722,7 @@ importers:
magic-string: ^0.25.7
micromatch: ^4.0.4
mime: ^3.0.0
+ mini-svg-data-uri: ^1.3.3
okie: ^1.0.1
open: ^8.4.0
periscopic: ^2.0.3
@@ -799,6 +800,7 @@ importers:
magic-string: 0.25.7
micromatch: 4.0.4
mime: 3.0.0
+ mini-svg-data-uri: 1.4.3
okie: 1.0.1
open: 8.4.0
periscopic: 2.0.3
@@ -6254,6 +6256,11 @@ packages:
tiny-warning: 1.0.3
dev: false
+ /mini-svg-data-uri/1.4.3:
+ resolution: {integrity: sha512-gSfqpMRC8IxghvMcxzzmMnWpXAChSA+vy4cia33RgerMS8Fex95akUyQZPbxJJmeBGiGmK7n/1OpUX8ksRjIdA==}
+ hasBin: true
+ dev: true
+
/miniflare/1.4.1:
resolution: {integrity: sha512-hJkMbTEM+sSiAo2yuPOucrdFYINLU7vvl9uVkRzAQ/h0CjmkYOCoyBn4jYzWtDZeQ0XrkyS6PGUCO277B5TsXA==}
engines: {node: '>=10.12.0'}