Reputation: 235
This weekend I started playing around with gulp. I wanted to set up a task which can
I got most of the steps but browser prefixes gave me a hard time Here is what I got so far
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var filter = require('gulp-filter');
var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var notify = require("gulp-notify");
var sourcemaps = require('gulp-sourcemaps');
var concat = require('gulp-concat');
var config = {
sassPath: './sass',
bower: './bower_components',
bootstrap: './bower_components/bootstrap-sass-official/assets/stylesheets',
fonts: './bower_components/bootstrap-sass-official/assets/fonts'
};
gulp.task('sass', function () {
return gulp.src(config.sassPath + '/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass({
//outputStyle: 'compressed',
outputStyle: 'nested',
precision: 10,
includePaths: [
config.sassPath,
config.bower,
config.bootstrap
],
onError: function (err) {
notify().write(err);
}
}))
.pipe(concat('app.css'))
.pipe(autoprefixer('last 2 version'))
.pipe(sourcemaps.write())
.pipe(gulp.dest('css'))
.pipe(filter('**/*.css')) // Filtering stream to only css files
.pipe(browserSync.reload({stream:true}));
});
gulp.task('browser-sync', function() {
browserSync({
logLevel: "info",
server: {
baseDir: './',
//directory: true,
routes: {
"/fonts": config.fonts
}
}
});
});
gulp.task('default', ['sass', 'browser-sync'], function () {
gulp.watch(['./**/*.html', 'js/**/*.js'], reload);
gulp.watch('sass/*.scss',['sass']);
});
The problem is that the autoprefixer gives me an error and messes up the sourcemaps
The error I get: "gulp-sourcemap-write: source file not found:C:\WEB\skilldrill_v1\skilldrill\sass\app.css"
So for some reason it tries to find the css files in the sass dir
[Edit]
I managed to locate the problem, but couldn't solve it yet.
The pipe this thing works: gulp-autoprefixer -> do some stuff -> prefixing tasks -> vinyl-sourcemaps-apply
On the 35th line of gulp-autoprefixer\index.js: applySourceMap(file, res.map.toString()); From this point the vinyl-sourmaps-apply understands that the current file (in my case app.css) becomes a source too.
Here are the problems: a) it thinks that the css file is in the same folder as specified in gulp.src() which is usually not true b) it doesn't work only with the lines added by the autoprefixer, but adds reference to every single line
Do you have any ideas based on this information ? I started digging in the gulp-concat which handles a similar issue properly.
Upvotes: 11
Views: 6027
Reputation: 20852
I know this is an old question, but for those who come here today:
I had no problems to get Sourcemaps and AutoPrefixer working together. So it looks as if this issue has been fixed. The following setup is what works for me:
const
gulp = require('gulp'),
sass = require('gulp-sass'),
autoprefixer = require('gulp-autoprefixer'),
concat = require('gulp-concat'),
sourcemaps = require('gulp-sourcemaps'),
browserSync = require('browser-sync').create();
var
scssSourcePath = './css/**/*.scss',
cssDestPath = './css/',
cssDestFile = 'styles.css';
// Task 'styles':
// Compile SASS to CSS
gulp.task('styles', function () {
return gulp.src(scssSourcePath)
.pipe(sourcemaps.init())
.pipe(sass({ outputStyle: 'compressed' }).on('error', sass.logError))
.pipe(autoprefixer())
.pipe(concat(cssDestFile))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(cssDestPath))
.pipe(browserSync.stream());
});
// Default task:
// Init Browser-Sync,
// Watch folders and start tasks on change
gulp.task('default', function () {
browserSync.init({
server: "."
});
return gulp.watch(scssSourcePath, gulp.series('styles'));
});
Side note:
Instead of Autoprefixer I actually recommend to use CSSnano. It includes Autoprefixer and does even more optimizations. Simply replace all occurrences of autoprefixer
in the above code with cssnano
and you will have that additional benefit.
Upvotes: 0
Reputation: 21
@philipb3 THANK YOU!! Spent the better part of 2 days trying to figure out why autoprefixer and gulp-sourcemaps weren't playing well together, then when I finally fixed that issue, browser-sync would fully reload, but wasn't injecting newly generated css. This seems to have resolved the issue.
For those who are confused as was I at first from the explanation, here is a sample of my sass task in my gulp file with comments on what's happening.
gulp.task('sass', function() {
// create postcss processors
var processors = [
mqpacker,
autoprefixer({ browsers: ['last 2 version'] })
];
return gulp.src(src.scss)
.pipe(sourcemaps.init()) // start sourcemaps
.pipe(sass({ outputStyle: 'expanded' }).on('error', sass.logError)) // compile sass
.pipe(sourcemaps.write()) // write map inline
.pipe(gulp.dest(src.css)) // pipe to css dir
.pipe(sourcemaps.init({loadMaps: true})) // init sourcemaps again after pipe to dest dir
.pipe(postcss(processors)) // run postcss stuff
.pipe(sourcemaps.write('./maps')) // write map to external dir instead of inline
.pipe(gulp.dest(src.css)) // pipe to dest dir again
.pipe(filter('**/*.css')) // filter out everything that isn't a css file
.pipe(reload({ stream: true })); // pipe result to browser-sync for reload
});
Edit: So eventually this also started to break again when I started adding some more tasks and plugins to my gulp build. I'm not entirely sure that it's necessary to load sourcemaps twice. I've rebuilt my gulp file, starting with gulp-sass and gulp-sourcemaps and this seems to work for me even after configuring other tasks after. Hope one of these two solutions will work for someone.
Relevant Plugins:
var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
//** Post CSS Modules **//
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer');
var mqpacker = require('css-mqpacker');
If you're using browser-sync: (also set up watch/serve tasks)
//** Browser-Sync **//
var browserSync = require('browser-sync').create();
var reload = browserSync.reload;
Sources: change these accordingly
var src = {
base: 'ROOT_FOLDER',
js: 'ROOT_FOLDER/js/**/*.js',
css: 'ROOT_FOLDER/css',
html: 'ROOT_FOLDER/*.html',
jsdir: 'ROOT_FOLDER/js',
maps: './maps',
scss: 'ROOT_FOLDER/scss/**/*.scss'
};
Task
gulp.task('sass', function () {
// load post-css plugins
var processors = [
mqpacker,
autoprefixer({
browsers: ['last 2 version']
})
];
// start sass task
return gulp.src(src.scss)
.pipe(sourcemaps.init()) // init sourcemaps
.pipe(sass.sync({outputStyle: 'expanded'}).on('error', sass.logError)) // compile scss
.pipe(postcss(processors)) // autoprefix and combine media queries
.pipe(sourcemaps.write(src.maps)) // write emaps relative to source dir
.pipe(gulp.dest(src.css)) // pipe to css folder
.pipe(browserSync.stream()); // send stream to browser-sync task
});
Upvotes: -1
Reputation: 279
I've had the same issues with autoprefixer and sourcemaps. I've changed my workflow to create sourcemaps after compiling sass, then loading into gulp-sourcemaps again when I run autoprefixer, and finally creating updated sourcemaps.
// Compile Sass
.pipe(sourcemaps.init())
.pipe(sass())
.pipe(sourcemaps.write())
.pipe(gulp.dest('../public/assets/css'))
// Autoprefix
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(autoprefixer('last 2 version', 'ie 8', 'ie 9'))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('../public/assets/css'))
And then only watching css files for style injection.
// CSS Injection
.pipe(filter('**/*.css'))
.pipe(browserSync.reload({stream:true}))
Upvotes: 6