I am attempting to make the switch from GruntJS to Gulp and have run into a problem with my Gulp task for processing my SASS files via Compass. The files compile just fine into the single CSS file as they did under my GruntJS implementation, but I am missing the line number comments that show me where the CSS rules come from such as:
/* line 26, ../_components/sass/_base.scss */
The code from my gulpfile.js for the task is:
gulp.task('compass', function() {
gulp.src(sassSources)
.pipe(compass({
comments: true,
sass: '_components/sass',
image: 'builds/dev/images',
style: 'nested'
})
.on('error', gutil.log))
.pipe(gulp.dest('builds/dev/css'))
});
Am I missing something?
Be careful with gulp-compass, it is not a gulp plugin (albeit named so) and has been blacklisted by the Gulp community for quite a while. It does not what Gulp plugins are supposed to do (e.g. it's possible to run them without gulp.src and gulp.dest), and other plugins are already doing its work perfectly fine. One of those plugins is gulp-ruby-sass. This setup might work for you:
var sass = require('gulp-ruby-sass');
gulp.task('compass', function() {
return sass(sassSources, {
compass: true,
lineNumbers: true
}).on('error', gutil.log))
.pipe(gulp.dest('builds/dev/css'))
});
This uses gulp-ruby-sass which is able to run with the compass extension. You see that I activated lineNumbers here to give you said output.
I see from your Gulpfile that you might have some extension requiring some images, I don't know exactly what that does, but if it's mandatory to your setup, you might better call compass directly (the command line tool) using require('child_process').exec(...)
You should add sass_options = { :line_numbers => true } to your config.rb file even if gulp-compass module doesn't support lineNumbers as an option.
important part of config.rb file
css_dir = 'app/assets/style/'
sass_dir = 'app/assets/style/sass/'
images_dir = 'app/assets/image/'
javascripts_dir = 'app/assets/script/'
sass_options = { :line_numbers => true }
And your gulp task should look like this
important part of gulpfile.js file
return gulp.src('./app/assets/style/sass/*.scss')
.pipe(plugins.compass({
config_file: './config.rb', // if you don't use a config file , you should start using immediately
css: './app/assets/style/',
sass: './app/assets/style/sass/',
image: './app/assets/image/',
line_comments: true,
sourcemap: true
}))
.pipe(gulp.dest('./app/assets/style/'));
I had trouble generating the line number comments using gulp-compass also. I tried a lot of things including matching all the plugin versions to the sample code I used to even completely discarding my code and use the full sample instead to no avail.
On top of its lack of compliance with gulp standards as #ddprrt suggested, gulp-compass seems to be broken now. Besides generating a stylesheet on the destination folder, it also generates another under the {app_root}/css folder. I suspect, the latter is some sort of caching, but that functionality is currently broken. As can be seen here, if you delete that stylesheet and re-run the task, the line number comments will finally show up. Below, I automated this by installing and using the gulp-clean-dest plugin. I have no tried using other plugins, but this hack handles the issue.
var gulp = require("gulp")
, compass = require("gulp-compass")
, cleanDest = require("gulp-clean-dest")
;
gulp.task("compass", function() {
gulp.src("components/sass/style.scss")
.pipe(compass(
{ "sass": "components/sass"
, "image": "builds/development/images"
, "style": "expanded"
, "comments": true
})
.on("error", gutil.log)
)
.pipe(gulp.dest("builds/development/css"))
.pipe(cleanDest("css"))
});
Related
it's the fifth day when I'm fighting this and I'm almost ready to give up (but I can't). I picked up a project from someone else and I'm trying to make gulp work.
I ended up with "could not find an option named "sourcemap".
Starting 'watch'...
[11:48:54] Finished 'watch' after 2.75 s
[11:49:32] Starting 'styles'...
[11:49:33] Could not find an option named "sourcemap".
Usage: dart-sass <input>
in gulpfile.js I've got this:
gulp.task('styles', () => {
return sass(['_/sass/main.scss', '_/sass/editor.scss', '_/sass/career-form.scss'], {
sourcemap: true, style: "compact"
})
})
even when I delete the sourcemap: true part, the error is still there. Gulp works with js files, but not with CSS. not sure if that matter.
I use gulp-ruby-sass and I tried everything there were related to the issue, but no luck. (The guy that worked before on that is not helpful - "I don't know, go Google the error").
I already tried to rebuild node_modules, five times, maybe more, checked different versions of gulp-ruby-sass and gulp-sourcemaps. Looked for another usage of sourcemap but no luck.
From the gulp-ruby-sass sourcemap option documentation it looks like if you use the sourcemap option than you must also use gulp-sourcemaps.
sourcemap
Type: boolean
Default: false
Initialize and pass Sass sourcemaps to gulp-sourcemaps.
So their code:
const gulp = require('gulp');
const sass = require('gulp-ruby-sass');
const sourcemaps = require('gulp-sourcemaps');
gulp.task('sass', () =>
sass('source/file.scss', {sourcemap: true})
.on('error', sass.logError)
// for inline sourcemaps
.pipe(sourcemaps.write())
// for file sourcemaps
.pipe(sourcemaps.write('maps', {
includeContent: false,
sourceRoot: 'source'
}))
.pipe(gulp.dest('result'))
);
So try them together. [Why you still get an error message if you remove the sourcemap option is strange.]
A late answer but still hope it could help.
If you use gulp-ruby-sass, you will have to install ruby.
However, gulp-ruby-sass has been deprecated, so it's better to switch to gulp-sass to compile Sass files.
var paths = {
css: './public/apps/user/**/*.css'
}
var dest = {
css: './public/apps/user/css/'
}
// Minify and concat all css files
gulp.task('css', function(){
return gulp.src(paths.css)
.pipe(concatCSS('style.css'))
.pipe(minifyCSS({keepSpecialComments: 1}))
.pipe(rename({
suffix: '.min'
}))
.pipe(gulp.dest(dest.css))
});
When I first run the task it compiles alright and all changes are there.
After I change something and run it again it doesn't overwrite the existing minified css file. If I were to delete the minified css and run task again everything works perfect. Any insights?
Try and set the exact path, not a variable. Not that its not a good practice, just try without it.
Also , add a 'use strict'; to your task, so that you can be sure there are no serious errors with your settings. It will give you the right type of errors if there are any.
And, may I ask why are you concatenating your CSS before the production build?
Every file concatenation, minification and etc. should be performed in the 'build' task.
You have to delete your minified version of css before doing minify css.
To achieve this you can use gulp-clean
install gulp-clean as npm install gulp-clean
var gulp = require('gulp'),
concat = require('gulp-concat'),
cleanCSS = require('gulp-clean-css'), // this is to minify css
clean = require('gulp-clean'), //this is to delete files
gulp.task('del-custom-css', function(){
return gulp.src('./static/custom/css/custom.min.css',{force: true})
.pipe(clean())
});
gulp.task('minify-custom-css', ['del-custom-css'], function(){
return gulp.src(['./static/custom/css/*.css'])
.pipe(concat('custom.min.css'))
.pipe(cleanCSS())
.pipe(gulp.dest('./static/custom/css'))
});
Hope it helps.
I'm very new to using Node.js and using post processors for CSS. After reading several articles, I managed to install the following:
Node.js (which included npm)
Gulp
PostCSS
Pxtorem (a PostCSS plugin for Gulp)
What I would like to do is have the 'pxtorem' plugin convert my px units to rems for the following CSS properties: font-size, margin, padding, border, width, height etc. and out output the results in a new CSS stylesheet.
Question: What exactly do I need to have typed inside my gulpfile.js to make this work?
To reiterate, I'm brand new when it comes to typing variables and requirements and have been following video and blog examples, none of which specifically have the correct formula for converting pixels to rems (since there are many plugins for PostCSS).
This is what I currently have in my current gulpfile.js:
var gulp = require('gulp');
var postcss = require('gulp-postcss');
var pxtorem = require('gulp-pxtorem');
gulp.task('css', function() {
gulp.src('./css-1/*.css')
.pipe(pxtorem())
.pipe(gulp.dest('./dest'));
});
What the above is essentially doing is grabbing my "styles-1.css" stylesheet file located within my "css-1" folder and making a duplicate of it inside my "dest" folder. I typed this code in compliance with an article I was reading to get an idea of how PostCSS worked, but it obviously isn't the correct code for converting pixels to rem.
P.S. I'm currently using a Windows 10 O/S.
Based on the documentation for gulp-pxtorem, it states:
Options
Pass in two option objects. The first one for postcss-pxtorem
options...
After visiting the documentation for postcss-pxtorem, I found that the options block looks like this:
{
rootValue: 16,
unitPrecision: 5,
propWhiteList: ['font', 'font-size', 'line-height', 'letter-spacing'],
selectorBlackList: [],
replace: true,
mediaQuery: false,
minPixelValue: 0
}
Which is pretty self explanatory, but you can read more in the docs if you need to know what every option does. The option you want is propWhiteList.
So, in your gulpfile:
var gulp = require('gulp');
var postcss = require('gulp-postcss');
var pxtorem = require('gulp-pxtorem');
gulp.task('css', function() {
var opts = {
propWhiteList: [
'font-size',
'margin',
'padding',
'border',
'width',
'height',
...etc
]
};
gulp.src('./css-1/*.css')
.pipe(pxtorem(opts))
.pipe(gulp.dest('./dest'));
});
I don't believe you need to use the second option to achieve your desired result.
Good luck, and happy coding!
I have the need to compile a SASS file to a CSS file when saved, without having to compile every SASS file to a single CSS file.
I need the ability to:
- Run a 'watch' on a directory
- If a file is saved, a CSS of it's name is created. Example: 'main.scss' compiles to 'main.css'.
- It should not compile every single SASS if it doesn't need to.
The goal is to optimize the development process to avoid compiling every single SASS file in a directory when 'watching'.
My current SASS task looks a bit like this and results in a single CSS file:
//Compile Sass
gulp.task('styles', function() {
return gulp.src('app/scss/styles.scss')
.pipe(plugins.sass({ includePaths : [paths.sass], style: 'compressed'})
.pipe(plugins.autoprefixer('last 2 version'))
.pipe(plugins.rename({suffix: '.min'}))
.pipe(plugins.minifyCss())
.pipe(gulp.dest('build/css'));
});
Looks like gulp-changed is what you're looking for:
https://github.com/sindresorhus/gulp-changed
You add it as a dependency with npm install --save-dev gulp-changed and plug it into your gulpfile. From the gulp-changed ReadMe:
var gulp = require('gulp');
var changed = require('gulp-changed');
var ngAnnotate = require('gulp-ng-annotate'); // just as an example
var SRC = 'src/*.js';
var DEST = 'dist';
gulp.task('default', function () {
return gulp.src(SRC)
.pipe(changed(DEST))
// ngAnnotate will only get the files that
// changed since the last time it was run
.pipe(ngAnnotate())
.pipe(gulp.dest(DEST));
});
I'm using Webpack with the extract-text-webpack-plugin.
In my project, I have some build scripts. One of the build scripts is supposed to bundle and minify CSS only. As I'm using Webpack for the other scripts, I found it a good idea to use Webpack even when I only want to bundle and minify CSS.
It's working fine, except that I can't get rid of the output.js file. I don't want the resulting webpack output file. I just want the CSS for this particular script.
Is there a way to get rid of the resulting JS? If not, do you suggest any other tool specific for handling CSS? Thanks.
There is an easy way, no extra tool is required.
There is an easy way and you don't need extra libraries except which you are already using: webpack with the extract-text-webpack-plugin.
In short:
Make the output js and css file have identical name, then the css file will override js file.
A real example (webpack 2.x):
import path from 'path'
import ExtractTextPlugin from 'extract-text-webpack-plugin'
const config = {
target: 'web',
entry: {
'one': './src/one.css',
'two': './src/two.css'
},
output: {
path: path.join(__dirname, './dist/'),
filename: '[name].css' // output js file name is identical to css file name
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}
]
},
plugins: [
new ExtractTextPlugin('[name].css') // css file will override generated js file
]
}
Unfortunately, that is currently not possible by design. webpack started as a JavaScript bundler which is capable of handling other "web modules", such as CSS and HTML. JavaScript is chosen as base language, because it can host all the other languages simply as strings. The extract-text-webpack-plugin is just extracting these strings as standalone file (thus the name).
You're probably better off with PostCSS which provides various plugins to post-process CSS effectively.
One solution is to execute webpack with the Node API and control the output with the memory-fs option. Just tell it to ignore the resulting js-file. Set the output.path to "/" in webpackConfig.
var compiler = webpack(webpackConfig);
var mfs = new MemoryFS();
compiler.outputFileSystem = mfs;
compiler.run(function(err, stats) {
if(stats.hasErrors()) { throw(stats.toString()); }
mfs.readdirSync("/").forEach(function (f) {
if(f === ("app.js")) { return; } // ignore js-file
fs.writeFileSync(destination + f, mfs.readFileSync("/" + f));
})
});
You can clean up your dist folder for any unwanted assets after the done is triggered. This can be easily achieved with the event-hooks-webpack-plugin
//
plugins: [
new EventHooksPlugin({
'done': () => {
// delete unwanted assets
}
})
]
Good Luck...