I have been using a gulpfile which, I have now modified to try and add sourcemaps to my compiled css and minified css files.
I have the following task in the file:
gulp.task('sass', function () {
return gulp.src('./src/sass/zebra.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer({
browsers: autoprefixrBrowsers,
cascade: false
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(destination))
.pipe(cssnano())
.pipe(rename({
suffix: '.min'
}))
.pipe(gulp.dest(destination));
});
However, when trying to compile, I get the following error:
stream.js:74
throw er; // Unhandled stream error in pipe.
It's the sourcemap file that's causing the problem.
When you do sourcemaps.write('.') you emit a .map file into the stream. That means you now have two files in your stream: a CSS file and a sourcemaps file.
When the CSS file reaches cssnano() it gets minified. However when the sourcemaps file reaches cssnano() that's when the error happens. cssnano() tries to parse the file as CSS, but since sourcemaps files aren't valid CSS files, this fails and cssnano() throws up.
You have to remove the sourcemaps file from your stream after you have persisted it to disk with gulp.dest(). You can use the gulp-filter plugin for this:
var filter = require('gulp-filter');
gulp.task('sass', function () {
return gulp.src('./src/sass/zebra.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer({
browsers: autoprefixrBrowsers,
cascade: false
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(destination))
.pipe(filter('**/*.css'))
.pipe(cssnano())
.pipe(rename({
suffix: '.min'
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(destination));
});
In the above filter('**/*.css') only lets the CSS file through, not the sourcemaps file, which fixes the problem.
I have also added a second sourcemaps.write('.') right before the end since you probably want sourcemaps for both the minified and unminified CSS file.
If your running into pipeline errors, I found this to be very helpful
/**
* Wrap gulp streams into fail-safe function for better error reporting
* Usage:
* gulp.task('less', wrapPipe(function(success, error) {
* return gulp.src('less/*.less')
* .pipe(less().on('error', error))
* .pipe(autoprefixer().on('error', error))
* .pipe(minifyCss().on('error', error))
* .pipe(gulp.dest('app/css'));
* }));
*/
function wrapPipe(taskFn) {
return function(done) {
var onSuccess = function() {
done();
};
var onError = function(err) {
done(err);
}
var outStream = taskFn(onSuccess, onError);
if(outStream && typeof outStream.on === 'function') {
outStream.on('end', onSuccess);
}
}
}
If you wrap the task function with wrapPipe and put the .on(error, error) method on all your pipes like in the example above, it will copiously catch the error and point to the problem file, and line# generally. No gutil needed.
Related
I have the following Gulp Watch Task.
// Watch function
function watch() {
// browserSync.init({
// proxy: 'localhost/Unice/html'
// });
gulp.watch('assets/scss/**.*scss', style);
gulp.watch('./*.html').on('change', browserSync.reload);
gulp.watch('assets/css/**.css').on('change', browserSync.reload);
}
I have another task which converts SCSS to css as follows
//scss to css
function style() {
return gulp.src('assets/scss/**/*.scss', { sourcemaps: true })
.pipe(sass({
outputStyle: 'compressed'
}).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions'))
.pipe(gulp.dest('assets/css', { sourcemaps: '.' }))
.pipe(browserSync.reload({ stream: true }));
}
How can I run the style task automatically when running the watch command if I make modifications to any SCSS files.
The glob in your watch task contains an error and should be:
gulp.watch('assets/scss/**/*.scss', style);
I have updated Gulp 3.9 to 4 and my gulp task is now returning an Assertion Error: Task function must be specified.
Can anyone show how I could refactor the code below to work with Gulp 4?
Thanks in advance!
gulp.task('default', ['sass', 'browser-sync'], function () {
gulp.watch("./scss/**/*.scss", ['sass']);
gulp.watch("./js/main.js", ['javascript']);
});
gulp.task('default', gulp.series('sass', 'browser-sync', function () {
gulp.watch("./scss/**/*.scss", 'sass');
gulp.watch("./js/main.js", 'javascript');
}));
should do it. The function signature has changed (from 3 to 2 parameters) and you need to use gulp.series.
See Convert gulp watch in gulp#3.9.1 to gulp#4
// compile scss into css
function style() {
// 1. where is my scss file
return gulp.src('./app/scss/**/*.scss')
// 2. pass that file through sass compiler
.pipe(sass().on('error', sass.logError))
// 3. where do I save the compiled CSS?
.pipe(gulp.dest('./app/css'))
// 4. stream changes to all browser
.pipe(browserSync.stream());
}
function watch() {
browserSync.init({
server: {
baseDir: './app/'
}
});
gulp.watch('./app/scss/**/*.scss', style);
gulp.watch('./app/**/*.html').on('change', browserSync.reload);
gulp.watch('./app/js/**/*.js').on('change', browserSync.reload);
}
exports.style = style;
exports.watch = watch;
Faced same issue and I found this code in this youtube video
Hope this helps.
I generated a js file with a source map using the following gulp task. The original sources get loaded in Firefox but do not get loaded in Chrome. Can anyone point out why Chrome can't find the sources which are clearly included in the generated index-[hash].js.map?
gulp.task('browserify', function () {
// set up the browserify instance on a task basis
return browserify({ debug: true })
.transform(babelify)
.require('client/web/private/js/es6/index.js', {
entry: true
})
.bundle()
.on('error', function handleError(err) {
console.error(err.toString());
this.emit('end');
})
.pipe(source('index.js'))
.pipe(buffer())
.pipe(sourcemaps.init({
loadMaps: true
}))
// Add transformation tasks to the pipeline here.
.pipe(uglify())
.pipe(rev())
// .on('error', gutil.log)
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./client/web/public/dist/js'))
});
I'm getting this error when trying to run my gulp command. It worked fine last week. Any reason why I'm getting the following error now?
TypeError: Object #<Readable> has no method 'write'
This is what the JS task looks like.
// JS task
gulp.task('js', function () {
var browserified = transform(function(filename) {
var b = browserify(filename);
return b.bundle();
});
return gulp.src('./src/js/*.js')
.pipe(browserified)
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./Build/js'))
.pipe(reload({stream: true}))
});
Here's a link to the entire gulpfile.js: https://github.com/realph/gulp-zero/blob/master/gulpfile.js
Any help is appreciated. Thanks in advance!
What version of browserify do you have at the moment? Browserify changed recently to not accept inward streams, just creating some. This would be the correct, adapted code:
var source = require('vinyl-source-stream');
var buffer = require('gulp-buffer');
gulp.task('js', function () {
return browserify({entries:['./src/js/main.js']})
.bundle()
.pipe(source('bundle.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./Build/js'))
.pipe(reload({stream: true}))
});
Update I changed the filename to a real file. Note that browserify works best if you just have one file there. If you have to create multiple bundles, please refer to this article
When i use gulp-uglify with browserify i get a error
events.js:72
throw er; // Unhandled 'error' event
^
Error
at new JS_Parse_Error (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:189:18)
at js_error (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:197:11)
at croak (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:656:9)
at token_error (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:664:9)
at expect_token (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:677:9)
at expect (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:680:36)
at /home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:1222:13
at /home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:703:24
at expr_atom (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:1152:35)
at maybe_unary (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:1327:19)
at expr_ops (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:1362:24)
at maybe_conditional (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:1367:20)
at maybe_assign (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:1391:20)
at expression (/home/rkmax/my-project/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:1410:20)
this is my scripts task
gulp.task('scripts', function() {
var bundler = browserify({
entries: ['./src/scripts/main.js'],
debug: debug
}).transform(stringify()); // the error persist even without this transformation
bundler
.bundle()
.on('error', handleErrors)
.pipe(source(getBundleName() + '.js'))
.pipe(jshint())
.pipe(jshint.reporter('default', { verbose: true }))
.pipe(jshint.reporter('fail'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./web/js'));
});
uglify will parse the script content before minifying it. I suspect that one of the browserify source maps are being included in the stream down to uglify. Anyway to find the problem you can use gulp-util's log method to handle uglify's exceptions. Example:
...
var gulpUtil = require('gulp-util');
gulp.task('scripts', function() {
...
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(uglify().on('error', gulpUtil.log)) // notice the error event here
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./web/js'));
});
If you still have problems fixing the issue, post the details after incorporating the error log.
I encountered this same issue with gulp-concat-sourcemap and gulp-uglify. I solved it by ignoring map files with gulp-ignore:
gulp.task("uglify-src", function() {
gulp.src([ "src/js/**/*.js" ])
.pipe(concat("app.js"))
.pipe(ignore.exclude([ "**/*.map" ]))
.pipe(uglify())
.pipe(gulp.dest("dist/js"));
});
It could be a simple error in your source JavaScript file. Try disabling uglify by commenting it out in your gulpfile and see if your browser console spots the real issue.
gulp.task('minified', function () {
return gulp.src(paths.concatScripts)
.pipe(sourcemaps.init())
//.pipe(uglify())
.pipe(sourcemaps.write('.', { addComment: false }))
.pipe(gulp.dest(publishUrl));
});
Errors are not propagated by Node.js pipe. This article mentions #Marcos Abreu's uglify().on approach in addition to describing the use of pump instead of pipe.
https://github.com/terinjokes/gulp-uglify/blob/master/docs/why-use-pump/README.md#why-use-pump