How to pre-load SASS custom utilities (variables and mixins) with webpack - sass

I am loading my utilities and assets in base.scss like so
#import "_variables";
#import "_mixins";
...
I have tons of modules in my application and we are doing so many changes in these modules.
so importing the base.scss in the header of each of the scss files is causing so much trouble and seems very redundant.
I tried using sass's includePaths but it didn't help as it only resolves the #import declarations.
Is there any way that I can auto import my utilities without having to #import it manually in each file?

This loader will do the job
https://github.com/shakacode/sass-resources-loader
by adding this to your webpack config
sassResources: [ './path/to/vars.scss', './path/to/mixins.scss' ]
Update
check the implementation out in action in this boilerplate

In Webpack 5, this is how I did it:
{
loader: 'sass-loader',
options: {
sourceMap: true,
additionalData: `#import "${__dirname}/src/int/css/_mixins.scss";`
},
Simply add the path to your e.g. SCSS Mixin or variable file to "additionalData".

Related

Using Rollup to process Sass as well as CSS Modules

we are using rollup to make the build. We've currently only had Sass, but are trying to also use css modules for some custom components. The configuration in the rollup.config.js is
postcss({
extract: false,
modules: true
}),
scss({
outputStyle: 'compressed'
}),
However on running the build we get an error saying 'default' is not exported by the css module file. The Css module file is foo.module.css and only defines the css classes. As its meant to be a css module, the classes should be put onto a default export, so not quite sure why rollup is complaining here.
This has worked by removing the scss configuration key and adding a key for use with value 'sass' into the postcss config key.
postcss({
extract: false,
modules: true,
use: ['sass']
}),

Include sass in gatsby globally

I have the following project structure:
gatsby-config.js
/src
/components
layout.jsx
/button
button.jsx
button.scss
/pages
/styles
styles.scss
_mixins.scss
_variables.scss
and gatsby-config.js and styles.scss are configured respectively in the following way:
...
plugins: [
...,
`gatsby-plugin-sass`
]
...
#import 'variables',
'mixins';
in order to access the mixins and variables, the styles.scss is being currently imported in all the components' scss files, e.g.:
//button.scss
#import './../styles/styles.scss'
This approach is working, but the problem is, as the project grows, the styles.scss is being imported multiple times and seems to be something wrong with this approach.
Is it possible to import styles.scss only once, and make all mixins and variables available across all the components?
You are able to pass options to Sass via gatsby-plugin-sass.
The following options would globally expose the contents of ./src/styles/_styles.scss to each Sass file in the project, without the need to explicitly import it.
module.exports = {
plugins: [
{
resolve: 'gatsby-plugin-sass',
options: {
data: `#import "${__dirname}/src/styles/styles";`,
}
},
],
}
Note: The below might be obvious to some but it's worth mentioning for future readers.
Only do this with Sass files that contain just variables, mixins, functions, etc (Sass features that do not output any actual CSS until they are consumed). Otherwise you will end up with CSS that is repeated multiple times across your project.
Example repo
Providing SCSS variables globally to your components
With #use
SCSS syntax
gatsby-plugin-sass
Component-Scoped Styles with CSS Modules
gatsby-plugin-sass config
gatsby-config.js file:
{
resolve: `gatsby-plugin-sass`,
options: {
implementation: require("sass"),
data: `#use "${__dirname}/src/global-styles/variables" as var;`
}
},
var will be used as namespace.
Providing variables to your scss files
./src/global-styles/_variables.scss
./src/components/main.jsx
./src/components/main.module.scss
Info about the underscore in _variables.scss, partials.
_variables.scss file:
$color-1: red;
$color-2: blue;
main.jsx file:
import React from 'react'
import style from './main.module.scss'
const Main = () => (
<div className={style.main}>Content</div>
)
export default Main
main.module.scss file:
.main {
color: var.$color-1;
}
But I need expose some global styles in gatsby-browser.js
Well, your are going to need #use, or follow other answers that use #import in gatsby-config.js. Mixing #import and #use may not work because of:
Heads up!
A stylesheet’s #use rules must come before any rules other than #forward, including style rules. However, you can declare variables before #use rules to use when configuring modules.
https://sass-lang.com/documentation/at-rules/use
I stopped using #import, only using #use.
global-styles.scss file:
#use "./variables" as var;
body {
color: var.$color-2;
}
gatsby-browser.js file:
import './src/global-styles/global-styles.scss'
Create a file named gatsby-browser.js in the root of your directory. Import the .scss file once and it will work perfectly .
In your gatsby-browser.js
import "./src/styles/styles.scss"
As Ankit Sinha mentioned, you can import your styles in gatsby-browser.js:
import './src/styles/styles.scss';
This method is mentioned in the Gatsby tutorial.
According to the docs (see Standard Styling with Global CSS Files):
The best way to add global styles is with a shared layout component.
Your project structure suggests that you are using one (layout.jsx). If that's the case, you can also import your styles in layout.jsx:
import './../styles/styles.scss';
I cant write comments yet. I dont have the reputation. But what a complete answer from Undefined Behavior.
Just to order a little bit:
Import your global-styles.scss in gatsby-browser.js
Configure something that's going to be exposed to all scss files, in your gatsby-config.js.
It can be an #import or an #use. With #import you access directly to your variables and mixins and with #use you reference it. I don't really know what are the benfits of both, but you could use any.

How to import global SCSS file in a React/Redux project?

I'm using react-redux-starter-kit for my project. I want to know how it is possible to create a global SCSS file that when imported in _base.scss, it will affect the whole project. I've tried to #import like in the examples within the file, but nothing works. Strangely, it seems to have worked with #import './fonts/*';
I have the following structure:
styles/
----/components/
--------/Dashboard
--------/Home
--------_default.scss
----/fonts/
----_base.scss
----core.scss
And therefore, the _base.scss is like this:
#import './components/_default'
But it doesn't work. No errors are shown. I've tried also to create a theme/default.scss, just like the example in the commentary within the file, but also no effect.
In your root component just import your main scss file like you would import a module:
require('path/to/styles/_base.scss')
or:
import 'path/to/styles/_base.scss'
Just make sure that in your webpack config there is:
{
test: /\.scss$/,
loader: 'style!css!sass',
}

Importing SASS partials from node_modules

Trying to build custom workflow with gulp, panini, mustache, sass and one of my problem is including partials from node_modules, here is example from main.scss file:
#import "node_modules/bootstrap/scss/mixins";
#import "settings";
How to avoid typing full path to _mixins.scss?
Your question is similar to this: Sass import not crawling node_modules to find appropriate package
You can include paths by passing the includePaths argument to gulp sass. e.g
.pipe($.sass({
includePaths: ['node_modules/bootstrap/scss/', 'another/path']
})
You can include node_modules in sass pathes:
.pipe(sass({
includePaths: ['node_modules']
})
Then you can import library's sass like this:
#import "bootstrap/scss/bootstrap";
Or, in case of material-components-web:
#import "#material/top-app-bar/mdc-top-app-bar";
This way:
you don't need to add each lib to path
the sub-dependencies imports will work seamlessly, e.g. mdc-top-app-bar in MDC example imports "#material/elevation/mixins".
Use includePaths or you could resolve NPM modules like this:
#import "~bootstrap/scss/mixins";
#import "settings";
There are some libraries for this sass-globbing, but I personally don't like this approach, because in CSS matters on import order.
Best practice is IMHO create some file vendor.scss;
#import "~bootstrap/scss/mixins";
#import "~bourbon/...";
and then import this vendor.scss:
#import "vendor.scss"
#import "partials/..."
For anyone else that stumbles here, if you're using gulp-ruby-sass instead of node-sass you would use
loadPath: ['node_modules/bootstrap/scss/']
instead of
includePaths: ['node_modules/bootstrap/scss/']

gulp sourcemaps generating last scss file only

I am new to gulp plugins and am trying to get sourcemaps to work
file structure
css/
sass/
theme/
_some-style.scss
_some-style-2.scss
_some-style-3.scss
style.scss
style.css
style.css.map
In my style.scss file I have
#import "theme/some-style";
#import "theme/some-style-2";
#import "theme/some-style-3";
great so I am only getting, _some-style-3.scss to appear in my dev tools when I inspect. I know I have a path issue here but not sure how to fix it.
Gulp file:
gulp.task('sass', function () {
return gulp.src(css/sass/theme/**/*.scss)
.pipe(sourcemaps.init())
.pipe(sass.sync().on('error', sass.logError))
.pipe(sourcemaps.write())
.pipe(gulp.dest(css));
});
Your input is a bit confusing as you have different paths in your file structure, your import statements, and your gulp file. I'll base my answer on the path you provided in the file structure.
Your file structure says "theme" is directly under "sass", so your #import statement should be #import "theme/_various-scss-file.scss"
You need to specify the scss file in gulp.src not just the path, for example gulp.src('css/sass/style.scss'). And output path, according to your file structure and assume your gulp file is in the same folder as the css folder, should be gulp.dest('css').
Figured it out. Unrelated to paths. I didn't include that I was also compressing my scss first and that is interfering with the sourcemapping

Resources