Relative url not correctly rebased when using less
Describe the bug
Hello Vite,
When upgrading to Vite >=3.2.3 there is a problem when resolving variables inside an import that uses less.
The linked project demonstrates the bug. The project is made from a freshly created Vue+Vite project with following important changes for the bug:
./vite.config.tsalias./src/components/HelloWorld.vuerow 2 withimport 'thingy/style-thingy.less';./src/style.csswithfont-family: 'OSR';- And now for the code causing the bug: everything in
./src/thingy/*
This works in 3.2.2 but not in 3.2.3 and above, not even in 4.0.1.
So this got me to check for the diff between 3.2.2 and 3.2.3, there we find one commit that mentions less, checked that one and found something suspect (dont forget to scroll up since row linking seems to be a bit broken at the time writing this).
Commenting out that part (if (url.startsWith(variablePrefix)) return url) in the projects node_modules (after npm install) and rerun npm run dev it will start to work again.
Now maybe commenting out that part is not the best solution and there is probably a reason for that commit, but anyways thought it would help a bit in solving this.
If you have any questions please let me know
EDIT (bluwy): If anyone would like to fix this, a test has been created at https://github.com/vitejs/vite/pull/11709
Reproduction
https://github.com/warna720/vite-3.2.3-bug-example/commits/main
Steps to reproduce
- clone the linked project
- npm install
- npm run dev (Latest commit is using Vite 3.2.3 when the bug was introduced)
- Check console for error (and network tab)
- Downgrade to Vite 3.2.2 or checkout the first commit which already does this
- npm install
- npm run dev
- No errors in console and the font is now used
System Info
Vite 3.2.3+
Same problem in Vite 4.0.1
Used Package Manager
npm
Logs
No response
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to vuejs/core instead.
- [x] Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- [X] The provided reproduction is a minimal reproducible example of the bug.
Hey, any updates on this? @bluwy
This is a limitation of the current approach for URL-rebasing. (See https://github.com/vitejs/vite/issues/7651)
By implementing a different approach only for less (using rewriteUrls feature of less, https://github.com/vitejs/vite/issues/7651#issuecomment-1099510871), we can support this case, too.
In case it helps: this PR adds a test to repro the issue: https://github.com/vitejs/vite/pull/11709
how can you put label nice-to-have with tooltip "not breaking anything" when its clearly breaking?
From my perspective, this just happened to work in your case in past and was broken in most cases.
alright, any ETA for when this is fixed and released?
For me adding this to the vite config worked:

Confirming above
Looks like this is indeed intentional. If you have:
src: url('@{icon-font-path}/OpenSans-Regular.ttf?l4m091')
Vite doesn't know what the value of icon-font-path is ahead of time to correctly rebase it. It could be https://some-cdn.com for example, and that shouldn't be rebased. So any URLs that starts with a variable essentially tells Vite that "you're controlling how this path loads".
If you know this is a relative path, you can do something like this:
src: url('./@{icon-font-path}/OpenSans-Regular.ttf?l4m091')
(adjust the value of icon-font-path accordingly). Now Vite knows that this is relative and it can rebase it. I made this change in the repro and it works: Stackblitz.
As others suggested, the relativeUrls option work because it does the same as above, but automatically and applies to everywhere, which sometimes isn't what you want.
Closing as intended behaviour.
Actually sapphi mentioned that rewriteUrls could be used (and safe to turn on?) to fix this. Re-opening for now and I'll let him decide 😅
@bluwy
I guess ~~{ rewriteUrls: 'local' }~~{ rewriteUrls: true } is same with what we are doing. (edit: I noticed true is the same one)
What do you mean by "applies to everywhere, which sometimes isn't what you want."?
What do you mean by "applies to everywhere, which sometimes isn't what you want."?
I mean because it's a global option, it applies to all the less files by default, which I feel like could be breaking 🤔
I was thinking we could turn on rewriteUrls: true by default, if that's safe and doesn't break things.
IIRC we are already rebasing URLs in all less files (also all css and sass/scss files). So I think it's not a breaking change.