How to process SASS/LESS in GruntJS - sass

Is there a version of grunt-processhtml for SASS/LESS ?
In my scss I need to set variable $icon-font-path (yes, bootstrap) to different values depending whether we are in dev mode or we are assembling production code.
The last thing I want to do is to move the variable declaration to a separate file (dev & prod version) and substitute them in my build process.
My Gruntfile: https://github.com/vucalur/django-wibses/blob/master/wibses/yo/Gruntfile.js

Sure there is a way, use importPath option of https://github.com/gruntjs/grunt-contrib-compass, which would make files under the specified folder findable by Sass's #import directive.
compass: {
dev: {
options: {
importPath: 'src/sass/icon-path-dev',
}
},
prod: {
options: {
importPath: 'src/sass/icon-path-prod',
}
}
And icon-path-dev will have _filepathvar.scss which would have your variable as
$icon-font-path : 'dev-font/path';
And icon-path-prod will have _filepathvar.scss which would have your variable as
$icon-font-path : 'prod-font/path';
You can then use this under your main scss file like
#import "filepathvar";

Related

Importing external stylesheets globally with CSS modules

I'm struggling to add SASS with an external stylesheet (Bulma) to my React application. So far I have set up Parcel with CSS modules via postcss. This is my .postcssrc config:
{
"modules": true,
"plugins": {
"autoprefixer": {
"grid": true
},
"postcss-modules": {
"generateScopedName": "[name]_[local]_[hash:base64:5]"
}
}
}
I have installed node-sass and successfully added a .scss file to one of my components. External (Bulma) styles are added via #import "~bulma/bulma"; and are correctly resolved.
Unfortunately, imported styles are not applied globally and instead the class names are modified similarly to local definitions, e.g.:
/*! bulma.io v0.8.0 | MIT License | github.com/jgthms/bulma */
#-webkit-keyframes container_spinAround_28_Bz {
from {
transform: rotate(0deg); }
to {
transform: rotate(359deg); } }
#keyframes container_spinAround_28_Bz {
from {
transform: rotate(0deg); }
to {
transform: rotate(359deg); } }
Note the added prefixes and suffixes.
Ideally, I would like to import the stylesheet globally and do not modify their names. I'd like to continue using CSS modules and I think I also have to use SASS in order to globally modify Bulma stylesheet by overriding SASS variables.
Anyway, things I've tried so far:
Using postcss-nested and wrapping the import with :global block:
:global {
#import "~bulma/bulma";
}
However, this throws an exception:
main.scss:5018:5: Missing whitespace before :global
Creating a separate scss file included directly in HTML file via <link> rather than imported in a jsx/tsx file to avoid using CSS modules.
This seems to break Parcel entirely, as it fails to link correct files in the compiled HTML files, i.e. <LONG-HASH>.css instead of generated main.<HASH>.css.
Using postcss-import.
Either my setup is incorrect or it has no effect on SASS files.
You can define regular expressions to mark matched files as global stylesheets with the globalModulePaths setting.
"postcss-modules": {
"globalModulePaths": [
".*\\.global\\..*"
]
}
The example above would mark all files with .global. in their name, e.g. main.global.css.
Managed to figure it out while writing the question.
The only solution that worked for me to load global CSS styles from rollup (when applying preserveModules: true) was using the 'rollup-plugin-styles' plugin and the following configuration:
// rollup.config.js
plugins: [
styles({
extensions: ['.css'],
use: ['css'],
}), …
]
// In the package.json you have to add the proper side effects
{
"sideEffects": [
"**/*.css",
"**/*.css.js" //this one is very important too
],
}
// MyComponent.tx
import '../styles/myGlobal.css';

How to use functions in grunt-sass?

My current project uses grunt-sass to translate scss files into css.
According to the grunt-sass documentation, I can use any option that node-sass provides except for a few:
Options
See the node-sass options, except for file, outFile, success, error.
My project compiles two CSS files out of one SCSS file. The SCSS file has if-statements in it that provides different code depending on the value of the version variable ($bootstrap-version: 3; or $bootstrap-version: 4;).
I would like to use the node-sass option functions to return the bootstrap version to my SCSS files.
Here's my gruntfile. The functions: {...} path is how I would have expected the option to work.
// Compile Sass
sass: {
bootstrap3: {
options: {
style: 'expanded'
functions: {getBootstrapVersion: function(){return 3;}}
},
files: {
'dist/bootstrap3/css/my-bs3-variation.css': './bootstrap3/scss/my-bs3-variation.scss'
},
},
bootstrap4: {
options: {
style: 'expanded',
functions: {getBootstrapVersion: function(){return 4;}}
},
files: {
'dist/bootstrap4/css/my-bs4-variation.css': './bootstrap4/scss/my-bs4-variation.scss'
}
}
In the SCSS file, I call the function like this:
$bootstrap-version: getBootstrapVersion();
h1:before {
content: "Bootstrap " + $bootstrap-version + " Version of ";
}
However, when trying to compile it, I get the errir >> Error: error in C function getBootstrapVersion: A SassValue object was expected. for the line where I call the function.
The example in the node-sass documentation does not help me much. What did I do wrongly? Or are there any better examples out there that I just did not find?
I use grunt-sass version 2.0.0 and node-sass version 4.7.2
The functions must return a SassValue object.
Unfortunately, I don't believe it is possible to do that with grunt-sass alone because we need to wrap your returned numbers 4 and 3 in typing functions defined in node-sass (which grunt-sass does not expose...).
For example, with node-sass in javascript, one may use something like sass.types.Number(4) to declare 4 as a Number SassValue.
Here, sass is the node-sass import const sass = require('node-sass');, which is not available in grunt...

Unable to find source files

I've started working on an existing website at work that uses Sass and auto-prefixer with Grunt. I'm not 100% familiar with the files yet, but I don't want to change the structure to avoid breaking anything. The problem I'm having is that no matter what .scss files I edit, it doesn't affect the required .css file. The developers that originally built the site aren't here anymore.
The changes I make either affect file.css or file2.css, and I need to reach file.expanded.css, but there's no mention of this file in the Gruntfile, so it was either removed, or it's being compiled in another way. Obviously, I'm avoiding editing it directly. I'm just unsure if I have enough to figure this out.
In case it helps, here's the Gruntfile:
module.exports = function(grunt){
require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
build: {
files: {
'assets/css/file2.css': 'assets/sass/folder/file2.sass'
}
}
},
autoprefixer: {
build: {
src: 'assets/css/file.css',
dest: 'assets/css/file.css'
}
},
watch: {
css: {
files: ['assets/sass/**'],
tasks: ['buildcss']
}
},
// Browsersync
browserSync: {
dev: {
bsFiles: {
src: [
'assets/css/*.css',
'assets/images/*',
'assets/scripts/*.js',
'**/*.html'
]
},
options: {
watchTask: true,
proxy: "site.dev:8888",
}
}
},
});
grunt.registerTask('default', ['browserSync', 'watch']);
grunt.registerTask('buildcss', ['sass', 'autoprefixer']);
};
You should install a Grunt task for source maps and recompile your CSS. I personally use Gulp so, I'm unsure what the best solution for Grunt might be, but it's a similar set up. When your CSS is compiled with source maps, you'll be able to pinpoint with your inspector where in which partial or SASS file the style declarations are coming from.
http://thesassway.com/intermediate/using-source-maps-with-sass

Using Grunt.js to dynamically watch, and subsequently compile, a directory of SASS files into one CSS file

I'm brand new to Grunt.js, but I'm starting to get the hang of it. The main thing I'd like to do with it however, I can't seem to nail down.
My goal here, is to point grunt at a directory, and have it watch all of the matching files, and upon changes, compile them into a new single CSS file.
Here's my current gruntfile:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
// CONFIG =========================/
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
files: {
'assets/css/style.css' : 'assets/css/sass/*.scss'
}
}
},
watch: {
css: {
files: 'assets/css/sass/*.scss',
tasks: ['sass']
}
}
});
// DEPENDENT PLUGINS =========================/
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
// TASKS =====================================/
grunt.registerTask('default', ['watch']);
};
Thus far I've been using grunt-contrib-watch, and grunt-contrib-sass. I've tried compass, as well as directory import but I couldn't get either of them to do what I'm trying to do either.
At the end of the day, I'm really just trying to avoid writing an import file, both because source order isn't going to matter for the way I'm writing my SASS, and becuase I'd really like to know how to make this happen.
I'm not sure of a way to do exactly what you want to achieve by just using Sass and Grunt-Contrib-Sass but you can achieve something similar by using Sass-Globbing, a SASS plug-in that lets you import entire directories. To use the plug-in, you'd use the require option in Grunt-Contrib-Sass and you'd have it target a main styles.scss file that may look something like:
#import "vendor/*";
#import "modules/*";
#import "partials/*";
And then your grunt file would have something like:
sass: {
dist: {
options: {
require: 'sass-globbing'
},
files: {
'assets/css/style.css' : 'assets/css/sass/style.scss'
}
}
}

Grunt - DSS Plugin

I'm trying to get this Grunt plugin to work:
https://npmjs.org/package/dss
This documentation plugin ironically seems to be lacking proper documentation. Can someone help me out by giving me an example of something that worked for them. The main thing that's screwing me up is the "your_target" property. Not sure what's suppose to go in there.
Say I have a SASS file in the following path from the root directory:
sass/main.scss
What would my ouput be by default? And where would it output to? Also what format does it ouput to?
grunt.initConfig({
DSS: {
options: {
// Task-specific options go here.
},
your_target: {
// Target-specific file lists and/or options go here.
},
},
})
Is "your_target" property the path to my sass file or the path to the documentation file I'm trying to create? Would it be defined like this?
...
your_target: {
// Target-specific file lists and/or options go here.
sass: "sass/main.scss"
},
...
I don't know what the property name should be. :(
dss: {
docs: {
options: {
},
files: {
'api/': 'css/**/*.{css,scss,sass,less,styl}'
}
}
}

Resources