From 5ec134871e2df7f1c66404879fd118c3a82824ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Barr=C3=A9?= Date: Mon, 16 Oct 2023 21:40:49 +0200 Subject: [PATCH] feat(build)!: inline SVGs --- packages/vite/src/node/plugins/asset.ts | 35 ++++++++++++++++--- playground/assets/__tests__/assets.spec.ts | 7 +++- playground/legacy/vite.config.js | 1 + playground/worker/vite.config-es.js | 1 + playground/worker/vite.config-iife.js | 1 + .../worker/vite.config-relative-base-iife.js | 1 + .../worker/vite.config-relative-base.js | 1 + playground/worker/worker-sourcemap-config.js | 1 + 8 files changed, 43 insertions(+), 5 deletions(-) diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index 9a91234f9378f6..bbb4d17fefc74d 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -352,7 +352,8 @@ async function fileToBuiltUrl( let url: string if ( config.build.lib || - (!file.endsWith('.svg') && + // Don't inline SVG with fragments, as they are meant to be reused + (!(file.endsWith('.svg') && id.includes('#')) && !file.endsWith('.html') && content.length < Number(config.build.assetsInlineLimit) && !isGitLfsPlaceholder(content)) @@ -363,9 +364,20 @@ async function fileToBuiltUrl( ) } - const mimeType = mrmime.lookup(file) ?? 'application/octet-stream' - // base64 inlined as a string - url = `data:${mimeType};base64,${content.toString('base64')}` + if (file.endsWith('.svg')) { + const stringContent = content.toString() + // If the SVG contains some text, any transformation is unsafe, and given that double quotes would then + // need to be escaped, the gain to use a data URI would be ridiculous if not negative + if (stringContent.includes('', '%3e') + ) +} diff --git a/playground/assets/__tests__/assets.spec.ts b/playground/assets/__tests__/assets.spec.ts index ab482bcdef3d2b..a4a0663d4ec0d1 100644 --- a/playground/assets/__tests__/assets.spec.ts +++ b/playground/assets/__tests__/assets.spec.ts @@ -285,7 +285,12 @@ describe('svg fragments', () => { test('from js import', async () => { const img = await page.$('.svg-frag-import') - expect(await img.getAttribute('src')).toMatch(/svg#icon-heart-view$/) + expect(await img.getAttribute('src')).toMatch( + isBuild + ? // Assert trimmed (data URI starts with < and ends with >) + /^data:image\/svg\+xml,%3c.*%3e#icon-heart-view$/ + : /svg#icon-heart-view$/, + ) }) }) diff --git a/playground/legacy/vite.config.js b/playground/legacy/vite.config.js index 4f319e250eb729..d07d295a0a27d8 100644 --- a/playground/legacy/vite.config.js +++ b/playground/legacy/vite.config.js @@ -16,6 +16,7 @@ export default defineConfig({ cssCodeSplit: false, manifest: true, sourcemap: true, + assetsInlineLimit: 100, // keep SVG as assets URL rollupOptions: { input: { index: path.resolve(__dirname, 'index.html'), diff --git a/playground/worker/vite.config-es.js b/playground/worker/vite.config-es.js index bd82434b99ab89..0049c5357fa0af 100644 --- a/playground/worker/vite.config-es.js +++ b/playground/worker/vite.config-es.js @@ -21,6 +21,7 @@ export default defineConfig({ }, build: { outDir: 'dist/es', + assetsInlineLimit: 100, // keep SVG as assets URL rollupOptions: { output: { assetFileNames: 'assets/[name].[ext]', diff --git a/playground/worker/vite.config-iife.js b/playground/worker/vite.config-iife.js index c98f7433383ef4..98757b8c00d2fd 100644 --- a/playground/worker/vite.config-iife.js +++ b/playground/worker/vite.config-iife.js @@ -38,6 +38,7 @@ export default defineConfig({ }, build: { outDir: 'dist/iife', + assetsInlineLimit: 100, // keep SVG as assets URL manifest: true, rollupOptions: { output: { diff --git a/playground/worker/vite.config-relative-base-iife.js b/playground/worker/vite.config-relative-base-iife.js index 77712979781705..6b3c7c6895f46a 100644 --- a/playground/worker/vite.config-relative-base-iife.js +++ b/playground/worker/vite.config-relative-base-iife.js @@ -21,6 +21,7 @@ export default defineConfig({ }, build: { outDir: 'dist/relative-base-iife', + assetsInlineLimit: 100, // keep SVG as assets URL rollupOptions: { output: { assetFileNames: 'other-assets/[name]-[hash].[ext]', diff --git a/playground/worker/vite.config-relative-base.js b/playground/worker/vite.config-relative-base.js index dd5af51bd8e263..a09aafa3b841aa 100644 --- a/playground/worker/vite.config-relative-base.js +++ b/playground/worker/vite.config-relative-base.js @@ -21,6 +21,7 @@ export default defineConfig({ }, build: { outDir: 'dist/relative-base', + assetsInlineLimit: 100, // keep SVG as assets URL rollupOptions: { output: { assetFileNames: 'other-assets/[name]-[hash].[ext]', diff --git a/playground/worker/worker-sourcemap-config.js b/playground/worker/worker-sourcemap-config.js index 89178e952ef03b..4ea0162f705119 100644 --- a/playground/worker/worker-sourcemap-config.js +++ b/playground/worker/worker-sourcemap-config.js @@ -35,6 +35,7 @@ export default (sourcemap) => { }, build: { outDir: `dist/iife-${typeName}/`, + assetsInlineLimit: 100, // keep SVG as assets URL sourcemap: sourcemap, rollupOptions: { output: {