Gulp sass issue with importing node_modules that start with tilde - sass

I'm converting .scss files to .css through a gulp sass task. The issue is that the base .scss file contains imports that contain other imports. These imports start with
~#angular/material/core/etc/etc
The tilde results in the following error:
events.js:160
throw er; // Unhandled 'error' event
^
Error: node_modules\#covalent\core\chips\_chips-theme.scss
Error: File to import not found or unreadable: ~#angular/material/core/theming/theming.
Parent style sheet: C:/Users/laurensk/Documents/Playground/node_modules/#covalent/core/chips/_chips-theme.scss
on line 1 of node_modules/#covalent/core/chips/_chips-theme.scss
>> #import '~#angular/material/core/theming/theming';
^
There's a custom importer called node-sass-tilde-importer but I am unsure if it's possible to implement this into my gulp sass task.
My code:
var gulp = require("gulp"),
sass = require("gulp-sass");
//var replace = require('gulp-replace');
//var sassGlob = require('gulp-sass-glob');
//var tildeImporter = require('node-sass-tilde-importer');
gulp.task("sass", function () {
return gulp
.src('Styles/theme.scss')
.pipe(sass())
.pipe(gulp.dest('wwwroot/dist'));
});
I've tried replace to replace '~' with './node_modules' but it throws the same error.
Any input would be appreciated!

gulp-sass accept all node-sass properties.
So you just need to configure gulp-sass with the node-sass-tilde-importer importer:
var gulp = require("gulp"),
sass = require("gulp-sass");
var tildeImporter = require('node-sass-tilde-importer');
gulp.task("sass", function () {
return gulp
.src('Styles/theme.scss')
.pipe(sass({
importer: tildeImporter
}))
.pipe(gulp.dest('wwwroot/dist'));
});

Related

Node-Sass includes the #use directive when compiling

I'm new to sass in general and am using gulp to watch my directory. However I realized that when my CSS Compiles from SASS it includes the #use directive at the top. For instance where I use sass:map this is brought over in the final file. I'm aware that it may just be of nuisance value right now. But wondering how to have them excluded.
Here is the gulpfile that I use for watching/compiling
var gulp = require("gulp");
var sass = require("gulp-sass");
var sassGlobbing = require("gulp-sass-glob");
sass.compiler = require("node-sass");
var paths = {
styles:{
src:"src/scss/**/*.scss",
dest: "assets/css/",
index: "src/scss/styles.scss"
}
}
gulp.task("sass", function(){
return gulp
.src(paths.styles.index)
.pipe(sassGlobbing())
.pipe(sass().on("error", sass.logError))
.pipe(gulp.dest(paths.styles.dest))
})
gulp.task("watch", function(){
gulp.watch(paths.styles.src, gulp.series("sass"))
})
According to this and I am just copying some lines from there
https://sass-lang.com/documentation/at-rules/import#importing-css
"Note that only Dart Sass currently supports #use. Users of other implementations must use the #import rule instead.)"

Can't get simple Sass task to complete in Gulp

I'm new to Gulp and was attempting to convert my Sass to CSS via a simple Gulp task.
I've tried the following (return statement):
'use strict';
var gulp = require('gulp');
var sass = require('gulp-sass');
var uglifycss = require('gulp-uglifycss');
sass.compiler = require('node-sass');
//Compile Sass to CSS
function sass() {
return gulp.src('./assets/sass/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./assets/css'));
};
and (done)
//Complie Sass to CSS
function sass(done) {
gulp.src('./assets/sass/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./assets/css'))
done();
};
But both return with
[18:38:07] The following tasks did not complete: sass
[18:38:07] Did you forget to signal async completion?
I figured using the return statement or the done parameter would complete the task. I can't figure out why it's telling me the taks can't be completed.
I also have a very similar CSS minify task running (hence the uglify variable) that is working.
Any ideas?
Thanks!

Getting proper sourcemaps (gulp sass + cleanCss + prefixer + uncss)

What is best way to chain gulp for compiling sass into clean css (prefixed, un-CSSed and minified).
Following example creates sourcemaps, but they are pointing to wrong line numbers in source files when viewed in browser inspector.
var plugins = require('gulp-load-plugins')(),
bourbon = require('node-bourbon').includePaths,
neat = require('node-neat').includePaths;
gulp.task('default', function () {
return gulp.src('src/scss/**/*.scss')
.pipe(plugins.sourcemaps.init())
.pipe(plugins.sass({includePaths: bourbon, includePaths: neat}))
.on('error',plugins.util.log.bind(plugins.util, 'Sass Error'))
.pipe(plugins.concat('styles.css'))
.pipe(plugins.uncss({html: ['dist/**/*.html']}))
.pipe(plugins.autoprefixer())
.pipe(plugins.cleanCss())
.pipe(plugins.sourcemaps.write('.'))
.pipe(gulp.dest('dist/css/'));
});
In an attempt to fix this problem I tried to output sourcemaps before autoprefixer and cleanCss but it results in an error related to "Neat" and "Burbon" paths: Error: Broken #import declaration of "../neat" Broken #import declaration of "../colors" Broken #import declaration of "../variables" Broken #import declaration of "../grid" Broken #import declaration of "../tables"
i work with this task, using CSSO instead of your cleanCSS but use whatever you want, the tricky part is the sourcemaps, sometimes mess up the paths.
Declare a source path
Init SourceMaps
Compile SCSS into CSS
Add the right prefix support
Paste SourceMaps in the CSS file generated pointing to the SCSS files
Compress the CSS file ( this probably remove the sourcemaps unless you told package to save comments )
Declare a dest path
Gulpfile: SASS Task
const gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
csso = require('gulp-csso'),
sass = require('gulp-sass'),
sourcemaps = require('gulp-sourcemaps');
gulp.task('sass', ['sass'], () => {
return gulp
.src('src/scss/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer({ browser: ['last 2 version', '> 5%'] }))
.pipe(sourcemaps.write())
.pipe(csso())
.pipe(gulp.dest('dist/css'));
});

How to configure gulp-sass properly?

Here is my gulpfile.
var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var babel = require("gulp-babel");
// Gulp Sass Task
gulp.task('sass', function () {
console.log('called');
// gulp.src locates the source files for the process.
// This globbing function tells gulp to use all files
// ending with .scss or .sass within the scss folder.
gulp.src("scss/*.scss")
// Converts Sass into CSS with Gulp Sass
.pipe(sass().on('error', sass.logError))
// Outputs CSS files in the css folder
.pipe(gulp.dest("css"));
});
// Watch scss folder for changes
gulp.task('watch', function() {
// Watches the scss folder for all .scss and .sass files
// If any file changes, run the sass task
gulp.watch('./scss/**/*.{scss,sass}', ['sass'])
});
gulp.task("transpile", function () {
return gulp.src("js/*.js")
.pipe(babel())
.pipe(gulp.dest("./compile"));
});
// Creating a default task
gulp.task('build', ['sass', 'transpile']);
gulp sass runs successfully but does not create any css folder which I am expecting. Also when I run the sass manually,
sass --trace _picker.scss:css/_picker.css
I see the css being compiled properly. Not sure what is going wrong with gulpfile. Any help would be really appreciated.

gulp-sass: ERROR - file to import not found or unreadable

I am having problems getting my SASS files to compile having now split them out and importing ones I require in my main scss file.
I have a styles folder that contains:
main.scss
top_menu.scss
I have added some imports to my main.scss:
#import 'font-awesome';
#import 'bootstrap';
#import 'custom_bootstrap';
#import 'top_menu';
and my gulp-sass task looks like this
gulp.task('compile_sass', ['compile_bower_sass'], function () {
return gulp.src(paths.scss_files, {base:'src'})
.pipe(gulp.dest(paths.dist))
.on('error', gutil.log)
.pipe(sass().on('error', sass.logError))
.pipe(minifycss({
keepSpecialComments: false,
removeEmpty: true
}))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(paths.dist))
});
The paths.scss_files variable is set to:
scss_files: './src/assets/styles/**/*.scss'
When the task runs I receive an error:
file to import not found or unreadable: top_menu
I actually want to be able to split my scss out into separate related sub folders and then use #import: 'navigation\top_menu' kinda thing.
Why would this error be coming up?
Thanks
EDIT:
The compile_bower_sass task compiles some other scss files (font-awesome, bootstrap, custom_bootstrap) which are required as you can see from the #import lines on my main.scss.
When running the compile_sass task and watching the output (dist) folder, I see the css files get generated from the compile_bower_sass task (so font-awesome.css, bootstrap.css, custom_bootstrap.min.css). I notice that the top_menu.scss file gets copied across too, but does not get compiled, so I guess this is why the error occurs.
Do I need to specify an order in my task, so could I make sure it compiles main.scss last to ensure any required files such as my custom top_menu.scss get compiled first and are available for my main file to access?
EDIT 2
OK, so I think my thoughts this was down to the order of compilation is correct.
If I change my scss_files variable to explicitly set the order they get piped to the gulp-sass (this time I have further organised into folders)
scss_files: ['./src/assets/styles/custom_bootstrap.scss',
'./src/assets/styles/navigation/top_menu.scss',
'./src/assets/styles/navigation/user_toolbar.scss',
'./src/assets/styles/main.scss']
Now my original compile-sass task works as is.
So, my next question is how do I configure gulp-sass so that I can ensure my main.scss file is compiled last? Or am I going about this all the wrong way?
EDIT 3:
I should probably have added these extra task configs when first asking this question. So the compile_sass task requires compile_bower_sass to be run first.
/*-BOWER PACKAGEs INCLUSION --------------------------------------------*/
gulp.task('compile_bower_sass', ['compile_bower_css'], function(){
var sassFiles = mainBowerFiles('**/*.scss');
return gulp.src(sassFiles)
.pipe(rename(function(path){
path.basename = path.basename.replace(/^_/, '');
return path;
// required where the string begins with _ , meaning that sass won't compile it (bootstrap)
}))
.pipe(sass({onError: function(e) { console.log(e); } }))
.pipe(gulp.dest(paths.dist_styles));
});
gulp.task('compile_bower_css', function(){
var cssFiles = mainBowerFiles('**/*.css');
return gulp.src(cssFiles)
.pipe(gulp.dest(paths.dist_styles));
});
gulp.task('compile_sass', ['compile_bower_sass'], function () {
return gulp.src(paths.scss_files, {base:'src'})
.pipe(sass({outputStyle: 'compressed'})
.on('error', sass.logError))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(paths.dist))
});
Im now ending up with
file to import not found or unreadable: font-awesome
In my dist style folder I can see font-awesome.css has been generated. I am pretty new at gulp and sass compilation, so no doubt I have misunderstood something here.
When the #import statement is used, is the file looking for that named scss or css file?
I have been having the same issue (using a mac with Sierra) and it seemed to only happen when I was using the glob style of including.
It turns out it is due to a race condition, you can work around it by putting a short wait in like so...
var gulp = require('gulp');
var sass = require('gulp-sass');
var wait = require('gulp-wait');
gulp.task('scss', function () {
gulp.src('resources/scss/**/*.scss')
.pipe(wait(200))
.pipe(sass())
.pipe(gulp.dest('public/dist'));
});
Add line breaks between the #import lines.
I tried many other solutions, some suggested it's a SublimeText issue having to do with setting "atomic_save": true, that didn't work for me.
I even tried adding a .pipe(wait(500)). Didn't work either.
Then I just added a line break before the offending #import. So in your case if it's throwing an error regarding top_menu, put a line break so it becomes:
#import 'custom_bootstrap';
#import 'top_menu';
I have no idea why, but this is the only thing that worked for me.
As best-practice I would add line breaks between all the lines just in case.
I've tried to recreate the issue you're having, but for me it seems to run fine.
I'll attach my code, and a shot of the folder structure to compare.
The only omission is the ['compile_bower_sass'] part, as I'm not totally sure what you need here. Is it possible that's something that should be using a loadPath instead?
You'll also notice from the screenshot of the folders that your scss files are getting copied over to dist as well. This may not be desirable.
Here's the Gulp code:
var gulp = require('gulp');
var sass = require('gulp-sass');
var minifycss = require('gulp-minify-css');
var rename = require('gulp-rename');
var gutil = require('gulp-util');
var paths = {
scss_files: './src/assets/styles/**/*.scss',
dist: './dist'
};
gulp.task('compile_sass', function () {
return gulp.src(paths.scss_files, {base:'src'})
.pipe(gulp.dest(paths.dist))
.on('error', gutil.log)
.pipe(sass().on('error', sass.logError))
.pipe(minifycss({
keepSpecialComments: false,
removeEmpty: true
}))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(paths.dist))
});
Here's the folders:
http://take.ms/AOFND
Perhaps all you need is:
var gulp = require('gulp');
var sass = require('gulp-sass');
var rename = require('gulp-rename');
var paths = {
scss_files: './src/assets/styles/**/*.scss',
dist: './dist'
};
gulp.task('compile_sass', function () {
return gulp.src(paths.scss_files, {base:'src'})
.pipe(sass({outputStyle: 'compressed'})
.on('error', sass.logError))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(paths.dist))
});
I was getting the error trying to migrate from Gulp 3.9.1 to 4.0.2, which requires a different way of setting up the gulpfile.js. I tried the line breaks in my file and also the wait just incase it was a race condition.
Utilizing gulp-plumber, it took away the error and my compiling of sass was successful.
function compile_sass() {
return gulp
.src('./wwwroot/css/**/*.scss')
.pipe(plumber())
.pipe(sass())
.pipe(gulp.dest("./wwwroot/css"));
}
The important part was the
.pipe(plumber())

Resources