diff --git a/packages/playground/assets/__tests__/assets.spec.ts b/packages/playground/assets/__tests__/assets.spec.ts
index 04ba14afa17272..e5f7c6af1ff777 100644
--- a/packages/playground/assets/__tests__/assets.spec.ts
+++ b/packages/playground/assets/__tests__/assets.spec.ts
@@ -105,6 +105,11 @@ describe('css url() references', () => {
expect(bg).toMatch(iconMatch)
})
+ test('aliased', async () => {
+ const bg = await getBg('.css-url-aliased')
+ expect(bg).toMatch(assetMatch)
+ })
+
if (isBuild) {
test('preserve postfix query/hash', () => {
expect(findAssetFile(/\.css$/, 'foo')).toMatch(`woff2?#iefix`)
diff --git a/packages/playground/assets/css/css-url.css b/packages/playground/assets/css/css-url.css
index 683305fa687b95..ae2dff3f633405 100644
--- a/packages/playground/assets/css/css-url.css
+++ b/packages/playground/assets/css/css-url.css
@@ -31,7 +31,13 @@
}
.css-url-same-line {
- background: url('/nested/asset.png') top right / 10px no-repeat, url('/icon.png') bottom right / 10px no-repeat;
+ background: url('/nested/asset.png') top right / 10px no-repeat,
+ url('/icon.png') bottom right / 10px no-repeat;
+}
+
+.css-url-aliased {
+ background: url('@/asset.png');
+ background-size: 10px;
}
/*
diff --git a/packages/playground/assets/index.html b/packages/playground/assets/index.html
index eeed653201796c..1819dcf2b69a21 100644
--- a/packages/playground/assets/index.html
+++ b/packages/playground/assets/index.html
@@ -52,6 +52,9 @@
CSS url references
>CSS background (multiple urls on same line)
+
+ CSS background (aliased)
+
SVG Fragments
diff --git a/packages/playground/assets/vite.config.js b/packages/playground/assets/vite.config.js
index 10096153d865d2..113191c246a4a8 100644
--- a/packages/playground/assets/vite.config.js
+++ b/packages/playground/assets/vite.config.js
@@ -1,9 +1,16 @@
+const path = require('path')
+
/**
* @type {import('vite').UserConfig}
*/
module.exports = {
base: '/foo/',
publicDir: 'static',
+ resolve: {
+ alias: {
+ '@': path.resolve(__dirname, 'nested')
+ }
+ },
build: {
outDir: 'dist/foo',
manifest: true
diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts
index 7d368627aec5bb..0e426fd6e5d934 100644
--- a/packages/vite/src/node/plugins/asset.ts
+++ b/packages/vite/src/node/plugins/asset.ts
@@ -140,7 +140,7 @@ export function fileToUrl(
}
}
-export function fileToDevUrl(id: string, config: ResolvedConfig) {
+function fileToDevUrl(id: string, config: ResolvedConfig) {
let rtn: string
if (checkPublicFile(id, config)) {
// in public dir, keep the url as-is
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index 700eb90f90014b..c5bfdb97e1e5f8 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -27,9 +27,9 @@ import { ResolveFn, ViteDevServer } from '../'
import {
getAssetFilename,
assetUrlRE,
- fileToDevUrl,
registerAssetToChunk,
- urlToBuiltUrl
+ fileToUrl,
+ checkPublicFile
} from './asset'
import MagicString from 'magic-string'
import * as Postcss from 'postcss'
@@ -103,7 +103,12 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
const moduleCache = new Map>()
cssModulesCache.set(config, moduleCache)
- const resolvers = createCSSResolvers(config)
+ const resolveUrl = config.createResolver({
+ preferRelative: true,
+ tryIndex: false,
+ extensions: []
+ })
+ const atImportResolvers = createCSSResolvers(config)
return {
name: 'vite:css',
@@ -117,27 +122,38 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
return
}
- const urlReplacer: CssUrlReplacer = server
- ? (url, importer) => {
- if (url.startsWith('/')) {
- return config.base + url.slice(1)
- } else {
- const filePath = normalizePath(
- path.resolve(path.dirname(importer || id), url)
- )
- return fileToDevUrl(filePath, config)
- }
- }
- : (url, importer) => {
- return urlToBuiltUrl(url, importer || id, config, this)
- }
+ const urlReplacer: CssUrlReplacer = async (url, importer) => {
+ if (checkPublicFile(url, config)) {
+ return config.base + url.slice(1)
+ }
+ const resolved = await resolveUrl(url, importer)
+ if (resolved) {
+ return fileToUrl(resolved, config, this)
+ }
+ return url
+ }
+
+ // const urlReplacer: CssUrlReplacer = server
+ // ? (url, importer) => {
+ // if (url.startsWith('/')) {
+ // return config.base + url.slice(1)
+ // } else {
+ // const filePath = normalizePath(
+ // path.resolve(path.dirname(importer || id), url)
+ // )
+ // return fileToDevUrl(filePath, config)
+ // }
+ // }
+ // : (url, importer) => {
+ // return urlToBuiltUrl(url, importer || id, config, this)
+ // }
const { code: css, modules, deps } = await compileCSS(
id,
raw,
config,
urlReplacer,
- resolvers
+ atImportResolvers
)
if (modules) {
moduleCache.set(id, modules)
@@ -416,13 +432,13 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
}
}
-interface CSSResolvers {
+interface CSSAtImportResolvers {
css: ResolveFn
sass: ResolveFn
less: ResolveFn
}
-function createCSSResolvers(config: ResolvedConfig): CSSResolvers {
+function createCSSResolvers(config: ResolvedConfig): CSSAtImportResolvers {
let cssResolve: ResolveFn | undefined
let sassResolve: ResolveFn | undefined
let lessResolve: ResolveFn | undefined
@@ -471,7 +487,7 @@ async function compileCSS(
code: string,
config: ResolvedConfig,
urlReplacer: CssUrlReplacer,
- resolvers: CSSResolvers
+ atImportResolvers: CSSAtImportResolvers
): Promise<{
code: string
map?: SourceMap
@@ -530,7 +546,7 @@ async function compileCSS(
code,
config.root,
opts,
- resolvers
+ atImportResolvers
)
if (preprocessResult.errors.length) {
throw preprocessResult.errors[0]
@@ -557,7 +573,10 @@ async function compileCSS(
postcssPlugins.unshift(
(await import('postcss-import')).default({
async resolve(id, basedir) {
- const resolved = await resolvers.css(id, path.join(basedir, '*'))
+ const resolved = await atImportResolvers.css(
+ id,
+ path.join(basedir, '*')
+ )
if (resolved) {
return path.resolve(resolved)
}
@@ -799,7 +818,7 @@ type StylePreprocessor = (
additionalData?: PreprocessorAdditionalData
filename: string
},
- resolvers: CSSResolvers
+ resolvers: CSSAtImportResolvers
) => StylePreprocessorResults | Promise
export interface StylePreprocessorResults {
@@ -954,13 +973,13 @@ let ViteLessManager: any
function createViteLessPlugin(
less: typeof Less,
rootFile: string,
- resolvers: CSSResolvers
+ resolvers: CSSAtImportResolvers
): Less.Plugin {
if (!ViteLessManager) {
ViteLessManager = class ViteManager extends less.FileManager {
resolvers
rootFile
- constructor(rootFile: string, resolvers: CSSResolvers) {
+ constructor(rootFile: string, resolvers: CSSAtImportResolvers) {
super()
this.rootFile = rootFile
this.resolvers = resolvers