Default user avatar Evgeny 6 years ago

Hello!
Could you please explain me one thing that I can't understand.
In assets/css/app.scss we firstly import _variables.scss, where we overload the bootsrap's $info variable, and after that we import ~bootstrap itself, where the $info is declared.
So we managed to overload the variable which hasn't been declared yet. How did we do that? :)

1 | Reply |

Hey Evgeny,

Good question! :) The answer is in "!default" flag, see the docs for more context: https://getbootstrap.com/do...

Cheers!

1 | Reply |
CDesign avatar CDesign 5 years ago edited

I had great difficulty getting node-sass to install without errors (Nov 2020; Symfony 4.2.5, webpack-encore-bundle 1.8.0, yarn 1.22.4, npm 6.14.8). The sass-loader installed ok, but the node-sass command kept giving me: gyp ERR! stack Error: make failed with exit code: 2
(and sometimes error code 1).

After much travail, I finally got it to work by manually adding the following two devDependencies to package.json:

"sass-loader": "^9.0.1",
"node-sass": "^4.5.0"

and then running yarn install

Hope this helps someone else :)

John

| Reply |

Hey John christensen!

Ah, sorry about the trouble! Ok, so the short story is that node-sass is kind of a pain in the butt. Whenever new operating systems comes out, you need to upgrade to a new version of node-sass, otherwise it won't build. So, our code download gets quickly out of date.

The solution (and I've just updated the "finished" code download to reflect this and we'll soon add a note to the video and script) is to install "sass" instead of node-sass. It's a drop-in replacement written entirely in JavaScript. So, the command to install would be something like:


yarn add sass-loader sass --dev

Anyways, sorry you hit the issue, but I appreciate the comment - it bumped me to get the out of our tutorial to make life easier.

Cheers!

| Reply |

Hello World!

I'm trying to override Bootstrap's variable $custom-select-indicator to change the url().

I can't seem to find how to refer to that image in my scss file.

My directory structure is the following.

`
assets
├── css
│ ├── component
│ │ ├── theme-colors
│ │ └── widgets
│ ├── core
│ │ ├── animation
│ │ ├── breadcrumb
│ │ ├── buttons
│ │ ├── extra
│ │ ├── layout
│ │ ├── loader
│ │ ├── scafholdings
│ │ ├── sidebar
│ │ ├── topbar
│ │ └── wave-effects
│ ├── helper
│ │ └── mixins
│ └── lib
├── images
│ └── users
└── js

└── pages
    └── dashboards

`

My variable file is in assets/css/helper and my image is in assets/images.

So in my _variables.scss I refer to it like this.

$custom-select-indicator: url(../../images/custom-select.png) !default;

But when I compile I get.

Syntax Error: ModuleNotFoundError: Module not found: Error: Can't resolve '../../node_modules/bootstrap/images/custom-select.png' in '/home/julien/dev/project/symfony/assets/css'

Can any one help me with that?

Thanks,

Julien

| Reply |

Hey Julien,

Hm, first of all, I suppose you're missing quotes in the path, did you try:
$custom-select-indicator: url("../../images/custom-select.png") !default;

Does it help? Or do you see the exact same error?

Cheers!

| Reply |

No it does not help... I really don't understand how it resolves the path.

See tests and results which really don't make sense to me.


Test 1
$custom-select-indicator: url('../../images/custom-select.png') !default;

Result
Syntax Error: ModuleNotFoundError: Module not found: Error: Can't resolve '../../node_modules/bootstrap/images/custom-select.png' in '/home/julien/dev/project/symfony/assets/css'<br />


Test 2
$custom-select-indicator: url('../../../images/custom-select.png') !default;

Result
Syntax Error: ModuleNotFoundError: Module not found: Error: Can't resolve '../../images/custom-select.png' in '/home/julien/dev/project/symfony/assets/css'<br />

node_modules and bootstrap are gone from the path


Test 3
$custom-select-indicator: url('../../../../images/custom-select.png') !default;

Result
Syntax Error: ModuleNotFoundError: Module not found: Error: Can't resolve '../../../images/custom-select.png' in '/home/julien/dev/project/symfony/assets/css'<br />

node_modules and bootstrap are gone from the path and extra ../ is added


In theory if the path where it looks for the image is relative to '/home/julien/dev/project/symfony/assets/css' then Test 2 should be very close to what I'm looking for but I would need to add assets/ to my path. So let's try it

Test 4
$custom-select-indicator: url('../../../assets/images/custom-select.png') !default;

Result
Syntax Error: ModuleNotFoundError: Module not found: Error: Can't resolve '../../node_modules/assets/images/custom-select.png' in '/home/julien/dev/project/symfony/assets/css'<br />

node_modules is back but bootstrap is still gone from the path.

What the...?

I'm kinda lost here...

| Reply |

Hey Julien,

Hm, this sounds like the path was resolved first, and then the already resolved path was passed to different spots, but looks like for some spots it should be different? I'd recommend you to comment out all places where you use that $custom-select-indicator var except one place, and try to get it working for that spot. When it's done, uncomment one more line and check if it still works. Probably path will be different for different files where you use that var... Really not sure how rewriting paths works with variables. Also, you can try to start the path with "./", e.g:
$custom-select-indicator: url('./../../assets/images/custom-select.png') !default;

It should work the same was as starting with "../", but just in case will be good to check I think.

I hope this helps!

Cheers!

| Reply |

Well, that's my problem... This variable is only used in Bootstrap (which is in node_modules)... I'm overriding Bootstrap default with that one. So the path I'm using is the one relative to my file, but once Bootstrap uses it Webpack explodes. I will keep digging but so far I don't have a suitable solution.

| Reply |

Holly smoke! I can't believe it. I found a working solution.

It's kind of an ugly (or least weird) hack. But it works.

Since that variable is only used in Bootstrap but the image is in my assets folder, well I'm "hacking" my way into and... It works!

$custom-select-indicator: url(~bootstrap/scss/../../../assets/images/custom-select.png);

<!-- insert joy emoji -->

Cheers!

1 | Reply |

Oh, and one more suggestion... I think you can simplify your path to:

$custom-select-indicator: url(~bootstrap/../../assets/images/custom-select.png);<br />

I.e. in theory, you don't need to go inside scss/ dir and then go back... but that's just in theory, I won't be surprised too much if you say that it does not work this way :)

Cheers!

| Reply |

Yeah, I thought I tried that already it didn't work thus ending up with that extra /scss but apparently I was wrong. It does work without it.

| Reply |

Hey Julien,

Great! Fairly speaking, if it didn't work - I would be surprised :) Anyway, I'm glad this workaround works for you!

Cheers!

| Reply |

Hey Julien,

Woh, thanks for sharing this solution with others! We do talk about "~" here: https://symfonycasts.com/sc... - this helps to point to the files that are in node_modules/ directory. But I've never heard that it might help in this case too, so good catch! So yeah, it looks weird to me too fairly speaking, but if it works as you need - great, that's really nice workaround I think :)

Cheers!

| Reply |

Hey Julien,

Ah, I see... yeah, this complicates things a bit.

Cheers!

| Reply |
Akavir S. avatar Akavir S. 5 years ago edited

Hello,
Looks like overriding the $info variable is not working for me. (the $lightgray worked correctly)
here is my variables file
<br />$info: darken(#17a2b8, 10%);<br />$lightgray:red;<br />

here is my app.scss
<br />@import './helper/_variables.scss';<br />@import '~bootstrap/dist/css/bootstrap.css';<br />@import '~font-awesome';<br />@import '/layout/_footer.scss';<br />@import '/layout/_header.scss';<br />@import '/components/_ad.scss';<br />@import '/components/_article.scss';<br />@import '/components/_profile.scss';<br />@import '/components/_sortable.scss';<br />

| Reply |

Hi Virgile,

If you are trying to override bootstrap variables, you'll have to import bootstrap SCSS file. You are importing a compiled css file, thus it is not going to work.

Try with

@import '~bootstrap/scss/bootstrap';

1 | Reply |

Hey julien_bonnier

That's correct! Thank you for replying on this thread, sometimes happens that we can miss comments (it's not too often) and it's awesome that users help each other!

Cheers! Have a nice day!

| Reply |
Default user avatar Anton Bagdatyev 6 years ago

How does `$info: darken(...)` in helper/_variables.scss override the bootstrap's one if `@import './helper/variables'` is imported before `@import '~bootstrap'`? Thank you!

| Reply |

Hey @Anton!

SUCH a good question - because the order doesn’t make any sense, right? This works because of a special Sasa feature. In bootstrap, when those variables are set, they are set with a special flag that says “only use this value if nobody else ever sets this variable”. THAT is why it works. Otherwise, you’re right, bootstrap would override *our* values :).

Cheers!

| Reply |
Default user avatar Anton Bagdatyev weaverryan 6 years ago edited

Just checked the Bootstrap SCSS sources:
<br />$info: $cyan !default;<br />

You rock man!

| Reply |
Default user avatar Anton Bagdatyev 6 years ago

Are you using PHPStorm? I'm using VS Code, and there Command/Ctrl + click trick on `~bootstrap` to jump to the node_modules/bootstrap dir doesn't seem to work in VS Code. Maybe you know if there is a way to enable it? Thanks!

| Reply |

Hey @Anton!

Yep - I’m using phpstorm! The whole ~ thing to refer to css files in the node_modules directory is, I believe, a special thing that Webpack does. Phpstorm is aware of this Webpack trick, but apparently VSCode is not. If you can manually configure Webpack aliases in VSCode, you might be able to map ~ to node_modules... but if that doesn’t work, I’m afraid that there won’t be much you can do (but I could be wrong!).

Let me know if you find anything out!

Cheers!

| Reply |

Hey Ryan,
Nice tuto. Thank.

Why when you call variables.scss, you write @import "helper/variables"; while when you call others scss you write @import "./layout/header";
I realise when I clean ./ it's working.

| Reply |

Hey Stephane,

Nice catch! Yeah, that was a misprint, it should be `@import "./helper/variables"`, you can check it with related code blocks below the video: https://symfonycasts.com/sc... . Unfortunately, that part in the video was not re-recorded, but we fixed it in the code.

But actually, looks like it works both ways, so it's kinda matter of preference, but we do recommend to prefix with "./" in such cases.

Cheers!

| Reply |