Documentation
https://symfony.com/doc/current/frontend/encore/copy-files.html
cases mentioned: using versioned images in js, in twig
cases not mentioned: using versioned images in styles (css/scss..)
example.scss
background: url(../images/bg.jpg);
It seems that they should work out of the box.. but problem is when you save background url in scss variable and distribute all over the modules... it is resolved in each module separately and it fails on error that it cannot found module... of course because relative path from each module is different... I was trying to solve it with alias and ~ prefix.. but process seems to be removing ~ from path and trying to resolve it then without it.. which of course fails again.
So I am wondering what is recommended way to have scss url defined in one place and used over any modules in project regarding standard webpack-encore setup.
We are using vue, but I think this is more general question applying also on other frameworks.
Thank you for your time!
Ctibor
Hum that's a good question, I've never faced this issue before.
What happens if you try to prefix with /?
Hi @luckylooke,
I'm not sure to understand what you're trying to do... would you be able to share a small repository that shows the issue you're facing?
Also, if you're using Scss maybe you could try disabling the resolve-url-loader when calling Encore.enableSassLoader()?
If I understand correctly, he has at least 4 files:
assets/images/bg.jpg, the background imageassets/css/_variables.scss which contains:$bg-var: background: url(../images/bg.jpg);
assets/css/file.scss which contains:@import "variables"
body { background: $bg-var } // resolves to "../images/bg.jpg" and it's fine
assets/css/foo/bar/file.scss which contains:@import "../../variables"
body { background: $bg-var } // resolves to "../images/bg.jpg" but the image is not here
But maybe I'm wrong?
That's kinda what I had in mind, and it fits the use of resolveUrlLoader: false:
// ./src/scss/index.scss
@import "_file1";
@import "subdirectory/_file2";
// ./src/scss/_variables.scss
$logo-url: '../images/logo.svg';
// ./src/scss/_file1.scss
@import "_variables";
header {
background: url(#{$logo-url});
}
// ./src/scss/subdirectory/_file2.scss
@import "../_variables";
footer {
background: url(#{$logo-url});
}
With resolveUrlLoader: true:
Running webpack ...
ERROR Failed to compile with 1 errors
error in ./src/scss/index.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleNotFoundError: Module not found: Error: Can't resolve './images/logo.svg' in '/(...)/src/scss'
With resolveUrlLoader: false:
Running webpack ...
DONE Compiled successfully in 470ms
I 3 files written to build
Another option that should work would be to create a Webpack alias of, for instance, the Scss root dir, and use it in the path prefixed by ~:
const path = require('path');
Encore.addAliases({
scssRootDir: path.resolve(__dirname, 'src/scss')
});
// ./src/scss/_variables.scss
$logo-url: '~scssRootDir/../images/logo.svg';
Thank you all.. I am going to solve this today, I will try your suggestions and let you know then. If I could not found the solution I will make a repo with reproduction. 馃憤
My case is more like @Kocal described in https://github.com/symfony/webpack-encore/issues/589#issuecomment-501688393
resolveUrlLoader: false
doe not seems to have any effect in my setup 馃
BUT
Today I have noticed that using ~ works for images, but I dont know the reason why it does not work for fonts.. thats why I have thought it does not work at all.. because I have seen those errors and did not notice that images are resolved correctly already.
Next, I have find out that commenting out svg font solves the problem.. so it is somehow *.svg font related. 馃
$fontsPath: '~client/fonts/';
@font-face {
font-family: 'Bebas Neue';
src: url('#{$fontsPath}BebasNeue-Regular.eot');
src: url('#{$fontsPath}BebasNeue-Regular.eot?#iefix')
format('embedded-opentype'),
url('#{$fontsPath}BebasNeue-Regular.woff2') format('woff2'),
url('#{$fontsPath}BebasNeue-Regular.woff') format('woff'),
url('#{$fontsPath}BebasNeue-Regular.ttf') format('truetype');
// url('#{$fontsPath}BebasNeue-Regular.svg#BebasNeue-Regular') format('svg');
font-weight: normal;
font-style: normal;
}
$imagesPath: '~client/images/';
$custom-select-indicator: url('#{$imagesPath}Icon_arrow-point-down.svg');
Ok, my bad... I have checked svg font and I have found out that it is really missing from disk 馃う鈥嶁檪
I dont understand why it did not fail before when I was not using hashes.. the svg font was already missing on the disk at that time.. but anyway.. from this point.. everything works. So thank you all for help you really did great job here.. 馃憤 馃憤 馃憤
So result:
use aliases and then prefix with ~
resolveUrlLoader can be in default value
Thanks again and wish you happy conding! :)
Ctibor
PS: Maybe some mention about images in scss/css would be good in docs.
For my defence a bit.. errors were misleading me
Module not found: Error: Can't resolve 'client/fonts/BebasNeue-Regular.svg' in '/home/node/client/app/components/recovery'
it really looked to me like it incorrectly tries to resolve path since there is no more ~ at the beginning... and I did not realised that in that step it is probably not needed anymore, that it is resolved like normally in *.js files then.
Most helpful comment
Ok, my bad... I have checked svg font and I have found out that it is really missing from disk 馃う鈥嶁檪
I dont understand why it did not fail before when I was not using hashes.. the svg font was already missing on the disk at that time.. but anyway.. from this point.. everything works. So thank you all for help you really did great job here.. 馃憤 馃憤 馃憤
So result:
use aliases and then prefix with
~resolveUrlLoader can be in default value
Thanks again and wish you happy conding! :)
Ctibor
PS: Maybe some mention about images in scss/css would be good in docs.