I've just setup the following Gulp task for SASS, using gulp-autoprefixer which causing a problem handling font-awesome icon "content".
The way it works (without gulp-autoprefixer)
gulp.task('sass', function() {
gulp.src(['./src/vendor/style.scss',
'./src/app/style.scss'])
.pipe(sourcemaps.init())
.pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
.pipe(concat('style.css'))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./public/css'));
});
That works fine and it outputs the result I expect.
An example of the user-icon (without gulp-autoprefixer):
.fa-user:before {
content: "";
}
The way it breaks (with gulp-autoprefixer)
If I now add autoprefixer to this task - like:
gulp.task('sass', function() {
gulp.src(['./src/vendor/style.scss',
'./src/app/style.scss'])
.pipe(sourcemaps.init())
.pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
.pipe(concat('style.css'))
.pipe(prefix({
browsers: ['> 1%', 'last 2 versions', 'Firefox ESR', 'Opera 12.1'],
cascade: false
}))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./public/css'));
});
The output breaks now. This is what I get for fa-user (with gulp-autoprefixer):
.fa-user:before {
content: "";
}
It seems like there is a problem with the charset (UTF-8 / UTF-16).
Is there any possibility to avoid that behaviour with gulp-autoprefixer?
Well, even it was a strange behavior (because it worked well without the gulp-autoprefixer), the solution was easier than I thought.
I've missed to add the UTF-8 charset meta-tag in the documents <HEAD>.
So this tag fixed it:
<meta charset="UTF-8">
I also came across this issue, changing the order of the sass compiler and prefixer fixed it for me. Prefixer first, then sass compiler:
.pipe(
autoprefixer({
browsers: ['> 1%', 'last 3 versions'],
cascade: false
})
)
.pipe(
sass({
outputStyle: 'compressed',
includePaths: []
}).on('error', error)
)
Related
Trying to implement sass sourcemaps but for some reason it doesn't seem to be playing nice for sub folders. For example, below is the main.scss file that gets compiled:
#import 'test';
#import 'test1';
#import 'test2';
#import 'test3';
#import 'sub/test4';
The changes show up (using BrowserSync) and compile with no issues. However inspecting the code in dev tools. It does not seem to reference the last import, it references 'test3' instead. See screenshot Dev Tools Screen Shot
The sass file 'sub/test4' contains the salmon color for the body but the source map is saying that this is contained in the file 'test3'.
See below for the styles task that I am using:
gulp.task('styles', function(){
return gulp.src('assets/scss/**/*.scss')
.pipe(plumber({
errorHandler: function(err){
this.emit('end');
}
}))
.pipe(scssLint({ customReport: scssLintStylish }))
.pipe(sourcemaps.init())
.pipe(sass({outputStyle: 'compressed', errLogToConsole: true}))
.on('error', notify.onError({ message: 'SASS Compile Fail'}))
.pipe(autoprefixer({
browsers: ['last 2 versions']
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('assets/css'))
.pipe(uglifycss())
.pipe(browserSync.stream({match: '**/*.css'}));
});
Tried various different things but nothing seems to work at all. Any help greatly appreciated!
I've been trying to get gulp sass and gulp sourcemaps to do exactly what I want and I'm finding it hard. I want to take a sass entry file (src/sass/index.scss), generate an output file (dist/css/index.css) and a separate sourcemap for that index file (dist/css/index.css.map) which has a sourceRoot set to the project base (absolute path: /home/damon/projects/test) and the sourcemap entries to be relative to that path.
Here's what I tried:
attempt 1: straight example code from gulp-sass:
var sassEntry = 'src/sass/index.scss';
gulp.src(sassEntry)
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist/css'));
Outcome: this inlines the sourcemap into the CSS file so I can't tell if it's right or not.
attempt 2: write it to separate file
gulp.src(sassEntry)
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/css'));
Outcome: writes a separate sourcemap, but the sourceRoot says '/sources/' (WTF is that?!, it doesn't exist and I never configured it)
and the paths are all relative to the sass entry file, not the project base, which is also going to be meaningless when my browser tries to locate the source files.
attempt 3: try to fix the sourceroot (also I found includeContent: false)
gulp.src(sassEntry)
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write('.',{includeContent: false, sourceRoot: __dirname}))
.pipe(gulp.dest('dist/css'));
Outcome: the sourceroot is now my working folder which is nice, the content isn't included which is nice, but the files in the sourcemap are still relative to the sass entry file not to the sourceRoot, so my map is still useless
attempt 4: Set the gulp.src base
gulp.src(sassEntry, { base: __dirname })
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write('.',{includeContent: false, sourceRoot: __dirname}))
.pipe(gulp.dest('dist/css'));
Outcome: Infuriatingly, setting the base on gulp.src fixes the sourcemap - sourceRoot is still correct and the source file paths are relative to the sourceRoot, BUT it now outputs to dist/css/src/sass/index.css which is wrong. WTF!
attempt 5: use absolute paths
gulp.src(sassEntry, { base: __dirname })
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write('.',{includeContent: false, sourceRoot: __dirname}))
.pipe(gulp.dest(__dirname + '/dist/css'));
Outcome: no change, it still outputs to the same deep structure in dist.
If anyone can enlighten me on how to do this I would be forever grateful.
While Sven's answer is perfectly good, I also found an answer to my own question by getting a deeper understanding of how gulp works (which I was trying to avoid), and apparently gulp stores each matched file with a path, so adding:
{ base: __dirname }
in the gulp.src makes it that each matched file has the full path from the base, which then causes them to output with the full relative path from wherever you set the base to. The solution I ended up with was to use gulp-flatten, which removes those relative paths from files in the pipeline, so my eventual function looked like this:
gulp.src(sassEntry, { base: __dirname })
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write('.',{includeContent: false, sourceRoot: __dirname}))
.pipe(flatten())
.pipe(gulp.dest(__dirname + '/dist/css'));
easy once you understand more about what it's trying to do I guess.
Since your attempt 4 does everything you want except place the resulting files in the wrong location, the easiest fix would be to just change that location with gulp-rename after the sourcemaps have been generated:
gulp.src(sassEntry, { base: __dirname })
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: __dirname}))
.pipe(rename({dirname:''}))
.pipe(gulp.dest('dist/css'));
Im trying to get my head around Gulp and i am using.
Yeoman´s webapp
Im trying to add some css-files to the project and hopefully get it to end up in the dist/styles-folder.
When adding scss-files to my app/styles-folder and build the project, the files end up in a .tmp-folder. I suppose this is the task that does it:
gulp.task('styles', () => {
return gulp.src('app/styles/*.scss')
.pipe($.plumber())
.pipe($.sourcemaps.init())
.pipe($.sass.sync({
outputStyle: 'expanded',
precision: 10,
includePaths: ['.']
}).on('error', $.sass.logError))
.pipe($.autoprefixer({browsers: ['> 1%', 'last 2 versions', 'Firefox ESR']}))
.pipe($.sourcemaps.write())
.pipe(gulp.dest('.tmp/styles'))
.pipe(reload({stream: true}));
});
The get compiled from scss to css which should be a good thing but how do I get them from the .tmp-folder tom my dist/index?
I tried: <link rel="stylesheet" href="./.tmp/styles/style.css">
It returned a 404 but even so, I cant imagine that this is the right way? Or swill my dist-folder have access to the .tmp-folder? Help appreciated.
Thanks
It seems you want to set the destination folder to dist, not tmp:
.pipe(gulp.dest('dist/styles'))
I'm trying to create a gulp task to compress and create a source map at the same time. The compression and source map creation works, but I can't seem how to figure out how to get the output names right when using the gulp-rename plugin.
To simplify: I have a source.js file in the /src folder and I want to create both the .min.js and .js.map file in the /dist folder.
Here's what I have:
gulp.task('scripts', function () {
// compressed
gulp.src(['src/*.js'])
.pipe(sourcemaps.init({ includeContent: false, sourceRoot: './' }))
.pipe(uglify())
.pipe(sourcemaps.write('./', {
sourceMappingURL: function(file) {
return file.relative + '.map';
}
}))
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest('./dist'));
});
This works in that it creates the following in /dist:
jquery-resizable.min.js (all good - compressed, map ref and right name)
jquery-resizable.js.min.map (map is there, but name is bad - should be jquery-resizable.js.map)
I've tried a ton of variations but I can't figure out how to get the map and compression to build and get the correct file names.
I also tried renaming the files in a separate step, but due to the async nature of gulp, that doesn't work reliably - sometimes it works sometimes it doesn't so that doesn't seem like an option either.
What am I missing?
I'm not married to creating the sourcemaps in just this way, but what is the proper way to do this? All the examples I've seen seem to do what I do above, except they don't rename the output file to min.js which seems like an important part of the process.
I would suggest using gulp-filter to remove the .map files from the pipeline during the rename.
var jsFilter = require('gulp-filter')([ '*.js', ], { restore: true, });
gulp.src(['src/*.js'])
.pipe(sourcemaps.init({ includeContent: false, sourceRoot: './' }))
.pipe(uglify())
.pipe(sourcemaps.write('./', {
sourceMappingURL: function(file) {
return file.relative + '.map';
}
}))
.pipe(jsFilter)
.pipe(rename({ suffix: '.min' }))
.pipe(jsFilter.restore)
.pipe(gulp.dest('./dist'));
That said, our workflow does the rename before the sourcemaps and it generates the maps correctly.
gulp.src(['src/*.js'])
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(rename({ suffix: '.min', }))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./dist'));
#bdukes answer mostly solved my problem and led me to the right solution. I'm posting the actual solution that worked for me in the specific case I mentioned above which is based on his answer.
One of my issues was related to not being able to generate the raw sources files along with the compressed and map files. I was able to make it work with an extra step explicitly moving the files in a separate .pipe(gulp.dest('./dist')) operation:
gulp.task('scripts', function () {
// compress and source map
gulp.src(['src/*.js'])
.pipe(sourcemaps.init({ includeContent: false, sourceRoot: './' }))
.pipe(uglify())
.pipe(sourcemaps.write('.', {
sourceMappingURL: function(file) {
return file.relative + '.map';
}
}))
.pipe(jsFilter)
.pipe(rename({ suffix: '.min' }))
.pipe(jsFilter.restore)
.pipe(gulp.dest('./'));
// also copy source files
gulp.src(['src/*.js'])
.pipe(gulp.dest('./dist'));
});
Moral of the story - don't overthink things - I was trying to get it all to work in one operation.
I tried
gulp.task('sass', function () {
return gulp.src(['./scss/*.scss'])
.pipe($.replace(/_VIEWPORT_WIDTH_/g,conf.project.viewport||640))
.pipe($.sass({errLogToConsole: true}))
.pipe(gulp.dest('./resources/css/'));
});
still not working.
pipe replace after SCSS will work,but SCSS can not do math during the process.
gulp.task('sass', function () {
return gulp.src(['./scss/*.scss'])
.pipe($.sass({errLogToConsole: true}))
.pipe($.replace(/_VIEWPORT_WIDTH_/g,conf.project.viewport||640))
.pipe(gulp.dest('./resources/css/'));
});
any suggestion?I know there is an ugly way,but that's too Grunt
gulp.task('sass', function () {
return gulp.src(['./scss/*.scss'],{buffer:true})
.pipe($.replace(/_VIEWPORT_WIDTH_/g,conf.project.viewport||640))
.pipe(gulp.dest('./tmp/scss/'))
.pipe($.sass({errLogToConsole: true}))
.pipe(gulp.dest('./resources/css/')).on('end',function(){
del(['./tmp/scss/'], {force: true});
});
});
It's because the latest version of gulp-sass (and perhaps every previous version) has a serious bug / design flaw -- it discards changes to file contents from earlier in the pipeline. I reported this at dlmanning/gulp-sass#158 and it's supposed to be fixed in the next major version (v2) I believe.