Relative Assets in SASS aren't resolved correctly
andyexeter opened this issue · comments
Hey there,
There seems to be an issue in this bundle and/or its Vite configuration with relative asset paths in SASS.
With a directory structure like this:
assets
├── app.js
├── images
│ └── vite.svg
└── styles
├── pages
│ └── home.scss
└── style.scss
And home.scss
containing this:
#app {
width: 410px;
height: 404px;
background-image: url('../../images/vite.svg');
}
The background image does not load.
However, if you change the background image URL to ../images/vite.svg
then it does load - but this is incorrect because images/
is 2 levels above styles/pages
.
This used to be an issue in Vite itself, but was recently fixed in v3.2.3
I have created two demo projects to help debug this issue:
This is a standard Vite project, showing that the path is resolved correctly: https://stackblitz.com/edit/vitejs-vite-2btrkm
And this is a standard Symfony 6.1 project with this bundle installed: https://github.com/andyexeter/vite-bundle-issue-demo
If you install and run the Symfony project you'll see that the background image does not display unless you change the path to the incorrect one.
hi @andyexeter,
one solution could be to define an alias ?
// vite.config.js
import { resolve } from 'path';
export default defineConfig({
// ...
resolve: {
alias: {
'~': resolve(__dirname, 'assets'),
}
}
})
/* home.scss */
#app {
width: 410px;
height: 404px;
background-image: url('~/images/vite.svg');
}
this does not solve the problem but offers an elegant solution ?
Thanks for the suggestion @lhapaipai.
The reason we are trying to solve this in our team is because when the paths are correct, our IDE (PhpStorm/WebStorm) autosuggests paths to background images, and allows us to Ctrl+Click to the image. When the paths are incorrect this doesn't work:
Do you know why the paths aren't resolved correctly? I can't figure out what the cause is, but if I knew I could maybe look into it more and try to provide a PR.
hi @andyexeter
I've seen your issue : vitejs/vite#7651 but I don't think the symfony plugin has anything to do with it. It just generates an entrypoints.json
file (and some configuration helpers but no url rewriting).
I think you can help your IDE resolve the alias defined in your vite.config.js
using a jsconfig.json
or tsconfig.json
in the root of your project. it works with VSCode and I think it's the same with PHPStorm. (probably need to restart your ide for the config to be taken into account)
jsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"~/*": [
"assets/*"
],
}
}
}
Thanks @lhapaipai, I managed to resolve the issue with this config in vite.config.js:
resolve: {
alias: {
"..": "."
}
}
I'm not sure why this isn't required in a regular Vite project though: https://github.com/andyexeter/vitejs-vite-2btrkm
Maybe it's something to do with the assets being in the assets
directory as opposed to top level.
Waw your configuration scares me because this option is also used to resolve your js dependencies...
// cause the effect you want ?
import yourModule from '../lib/your-module.js';
I'm not using this in the wild just yet, it was just something I came up with during testing on the demo project I created.
I would really like our development team to be able to reference asset files naturally - the way they would in a regular Vite project or a Webpack project, with the file they are currently in being relative, e.g. with the original file structure I posted earlier:
assets
├── app.js
├── images
│ └── vite.svg
└── styles
├── pages
│ └── home.scss
└── style.scss
I want our developers to be able to reference vite.svg in home.scss as ../../images/vite.svg
and in style.scss as ../images/vite.svg
.
I'm really not sure why this works in my Vite demo project but not in my Symfony demo project
I'd really like to know why it doesn't work in my Symfony project, so I can come up with a solution to fix it properly.
Hy @andyexeter
very strange, I encounter the same issue with your Vite demo project if I move my js/scss files into a directory (assets
for example)
├── assets
│ ├── images
│ │ └── vite.svg
│ ├── main.js
│ └── styles
│ ├── pages
│ │ └── home.scss
│ └── style.scss
├── index.html
├── package.json
├── package-lock.json
├── public
│ └── vite.svg
└── README.md
I've just modified the index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
- <script type="module" src="main.js"></script>
+ <script type="module" src="assets/main.js"></script>
</body>
</html>
@lhapaipai you are absolutely right! Sorry for wasting your time with this.
Thanks for giving me a reproducer - I will bring this up on the Vite repo now :)
@lhapaipai in case you are interested in the progress, I created a new issue on the Vite repo: vitejs/vite#11012