From d11d6eaeeaa0fc9da05ae7b9b6e7cce33567762d Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 20 Jun 2022 23:28:45 +0200 Subject: [PATCH] fix: non-relative base public paths in CSS files (#8682) --- packages/vite/src/node/plugins/css.ts | 23 ++++++++++-------- playground/assets/__tests__/assets.spec.ts | 10 ++++++-- playground/css/package.json | 5 +++- playground/css/vite.config-relative-base.js | 26 +++++++++++++++++++++ playground/css/vite.config.js | 1 - 5 files changed, 51 insertions(+), 14 deletions(-) create mode 100644 playground/css/vite.config-relative-base.js diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index ef112d7083cca5..0cf680e6616a30 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -458,7 +458,8 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { // resolve asset URL placeholders to their built file URLs function resolveAssetUrlsInCss(chunkCSS: string, cssAssetName: string) { const encodedPublicUrls = encodePublicUrlsInCSS(config) - const assetsBase = config.experimental.buildAdvancedBaseOptions.assets + const { assets: assetsBase, public: publicBase } = + config.experimental.buildAdvancedBaseOptions const cssAssetDirname = encodedPublicUrls || assetsBase.relative ? getCssAssetDirname(cssAssetName) @@ -475,23 +476,25 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { ? relativePath : './' + relativePath } else { - if (assetsBase.runtime) { - // config.logger.error('Error TODO:base')... absolute + runtime - } + // assetsBase.runtime has no effect for assets in CSS return (assetsBase.url ?? config.base) + filename } }) - // resolve public URL from CSS paths, TODO:base + // resolve public URL from CSS paths if (encodedPublicUrls) { const relativePathToPublicFromCSS = path.posix.relative( cssAssetDirname!, '' ) - chunkCSS = chunkCSS.replace( - publicAssetUrlRE, - (_, hash) => - relativePathToPublicFromCSS + publicAssetUrlMap.get(hash)! - ) + chunkCSS = chunkCSS.replace(publicAssetUrlRE, (_, hash) => { + const publicUrl = publicAssetUrlMap.get(hash)! + if (publicBase.relative) { + return relativePathToPublicFromCSS + publicUrl + } else { + // publicBase.runtime has no effect for assets in CSS + return (publicBase.url ?? config.base) + publicUrl.slice(1) + } + }) } return chunkCSS } diff --git a/playground/assets/__tests__/assets.spec.ts b/playground/assets/__tests__/assets.spec.ts index fda5e4e4c83ef1..c815714469b63b 100644 --- a/playground/assets/__tests__/assets.spec.ts +++ b/playground/assets/__tests__/assets.spec.ts @@ -179,8 +179,14 @@ describe('css url() references', () => { expect(bg).toMatch(assetMatch) }) - test.runIf(isBuild)('preserve postfix query/hash', () => { - expect(findAssetFile(/\.css$/, 'foo')).toMatch(`woff2?#iefix`) + test.runIf(isBuild)('generated paths in CSS', () => { + const css = findAssetFile(/\.css$/, 'foo') + + // preserve postfix query/hash + expect(css).toMatch(`woff2?#iefix`) + + // generate non-relative base for public path in CSS + expect(css).not.toMatch(`../icon.png`) }) }) diff --git a/playground/css/package.json b/playground/css/package.json index d78baa07c8d752..9663843f43097e 100644 --- a/playground/css/package.json +++ b/playground/css/package.json @@ -6,7 +6,10 @@ "dev": "vite", "build": "vite build", "debug": "node --inspect-brk ../../packages/vite/bin/vite", - "preview": "vite preview" + "preview": "vite preview", + "dev:relative-base": "vite --config ./vite.config-relative-base.js dev", + "build:relative-base": "vite --config ./vite.config-relative-base.js build", + "preview:relative-base": "vite --config ./vite.config-relative-base.js preview" }, "devDependencies": { "css-dep": "link:./css-dep", diff --git a/playground/css/vite.config-relative-base.js b/playground/css/vite.config-relative-base.js new file mode 100644 index 00000000000000..ae09766c0768ac --- /dev/null +++ b/playground/css/vite.config-relative-base.js @@ -0,0 +1,26 @@ +/** + * @type {import('vite').UserConfig} + */ + +const baseConfig = require('./vite.config.js') +module.exports = { + ...baseConfig, + base: './', // relative base to make dist portable + build: { + ...baseConfig.build, + outDir: 'dist/relative-base', + watch: false, + minify: false, + assetsInlineLimit: 0, + rollupOptions: { + output: { + entryFileNames: 'entries/[name].js', + chunkFileNames: 'chunks/[name].[hash].js', + assetFileNames: 'other-assets/[name].[hash][extname]' + } + } + }, + testConfig: { + baseRoute: '/relative-base/' + } +} diff --git a/playground/css/vite.config.js b/playground/css/vite.config.js index 0c2432ec40cf38..639a1302debb88 100644 --- a/playground/css/vite.config.js +++ b/playground/css/vite.config.js @@ -4,7 +4,6 @@ const path = require('path') * @type {import('vite').UserConfig} */ module.exports = { - base: './', build: { cssTarget: 'chrome61' },