When running the final build step in GULP, I am trying to use uglify with a wildcard in the gulp.src, but seeing an error.
This works:
gulp.task('build', ['lint','karma','clean'], function () {
return gulp.src('./src/js/file.js')
.pipe(gulp.dest('./dist'))
.pipe(uglify())
.pipe(size())
.pipe(gulp.dest('./dist'));
});
But this doesn't:
gulp.task('build', ['lint','karma','clean'], function () {
return gulp.src('./src/js/*.js')
.pipe(gulp.dest('./dist'))
.pipe(uglify())
.pipe(size())
.pipe(gulp.dest('./dist'));
});
The only difference being that I select a specific file in the working gulp.src, but use a wildcard in the non-working version. I have narrowed this down to uglify() because if I comment it out, I don't get the error, and everything completes without issue.
Any help would be greatly appreciated
Related
I have such a gulp task
gulp.task("js-min", function () {
browserify(config.paths.mainJs)
.transform(reactify)
.bundle()
.pipe(source('tec.min.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(uglify())
.pipe(sourcemaps.write(config.paths.dist))
.pipe(gulp.dest(config.paths.dist));
});
that create the minified version of the application. It runs periodically by the gulp-watch task. The problem I see, is that gulp tells me this task finishes in 30ms, but if I check the file being generated, it takes another 30s to see the actual new file being updated.
How shall I change the gulp task js-min so I know exactly when the file was finished updating in file system.
There are two solutions, and without knowing what browserify package you are using.
If it is promise based, then simply edit your code to return that promise:
gulp.task("js-min", function () {
return browserify(config.paths.mainJs)
If it is not promise-based, then it will have some kind of an onend or done method that takes a callback. In that case, it would be like this:
gulp.task("js-min", function (done) {
browserify(config.paths.mainJs)
.transform(reactify)
.bundle()
.pipe(source('tec.min.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(uglify())
.pipe(sourcemaps.write(config.paths.dist))
.pipe(gulp.dest(config.paths.dist))
// THIS IS THE LINE TO CHANGE
.onfinish(done);
});
I'm using the following code because grabbing the whole js folder won't honor file sequence. So I select file by file, but it won't produce the site.min.js file even though no error is given.
gulp.task("minjs", function () {
gulp.src([
'js/site.js',
'js/directives/navbar.js',
'js/directives/Select.Lang.js'
])
.pipe(concat('site.min.js'))
.pipe(uglify())
.pipe(gulp.dest("wwwroot/js/"));
});
Updated:
No, it's not the return. I tried that too. I also searched trough my PC if a file was generated, but there's no file and the weirdest thing is that the gulp task shows no error.
Notice the return statement:
gulp.task("minjs", function () {
return gulp.src([
'js/site.js',
'js/directives/navbar.js',
'js/directives/Select.Lang.js'
])
.pipe(concat('site.min.js'))
.pipe(uglify())
.pipe(gulp.dest("wwwroot/js/"));
});
I'm still fairly new to gulp, so this might be a misunderstanding on my part.
I have gulp pipeline I'm trying to create that does something like this:
gulp.src('src/**/*.html')
.pipe(html2js({some:options}))
.pipe(concat('templates.js'))
.pipe(gulp.src('src/**/*.js'))
.pipe(uglify())
.pipe(gulp.dest('build/'))
When I run this however, the second glob does not catch all the .js files. If I run two separate piplines as:
gulp.src('src/**/*.html')
.pipe(html2js({some:options}))
.pipe(concat('template.js'))
.pipe(gulp.dest('build/'));
gulp.src(['src/**/*.js', 'build/template.js'])
.pipe(uglify())
.pipe(gulp.dest('build/'));
It works as expected. No errors appear to be thrown and in the first case, the template.js is added to the end of the file list as I would expect.
Any suggestions would be greatly appreciated.
You should check out gulp-merge. It's designed to combine gulp pipelines:
var gulpMerge = require('gulp-merge');
gulp.task('build', function() {
return gulpMerge(
gulp.src('src/**/*.html')
.pipe(html2js({some:options}))
.pipe(concat('template.js')),
gulp.src('src/**/*.js')
)
.pipe(uglify())
.pipe(gulp.dest('build/'));
});
Gulp.src accepts a glob and options so it can't handle the stream that's piped into it in your first sample script.
You may use an approach similar to your first one using gulp-filter:
var filter = gulpFilter('**/*.html');
gulp.src(['src/**/*.html', 'src/**/*.js'])
.pipe(filter)
.pipe(html2js({some:options}))
.pipe(concat('templates.js'))
.pipe(filter.restore())
.pipe(uglify())
.pipe(gulp.dest('build/'))
Otherwise, following the lines of your second sample, you can use merge-stream for merging the streams before uglifying:
var merge = require('merge-stream');
var htmlStream = gulp.src('src/**/*.html')
.pipe(html2js({some:options}))
.pipe(concat('template.js'));
return merge(htmlStream, gulp.src('src/**/*.js'))
.pipe(uglify())
.pipe(gulp.dest('build/'));
I'd like to grab my vendor js files from bower dependencies, and, along with my own js files, pipe through some other tasks and concat them into one .js file. And then do the same for Sass files.
How could I achieve that? I tried this, but it doesn't work:
gulp.task('scripts', function () {
return gulp.src([
mainBowerFiles(gulpFilter('*.js')),
'app/js/*.js'
])
.pipe(uglify())
.pipe(concat('app.js'))
.pipe(gulp.dest('./dist/js'));
});
It throws this error:
TypeError: Arguments to path.resolve must be strings
But it works if I have this, for example:
gulp.src([
'app/js/etc.js',
'app/js/main.js'
])
..and in the following case, it throws a different error (but no error without uglify()):
gulp.src(mainBowerFiles(gulpFilter('*.js')))
error:
events.js:72
throw er; // Unhandled 'error' event
How do I better debug this? Should I separate vendor / own js files in different streams?
update
I'm working now with two streams, and merging them later on with event-stream, like this:
gulp.task('scripts', function () {
var jsFilter = gulpFilter('*.js');
var vendorFiles = gulp.src(mainBowerFiles()) // don't read
.pipe(jsFilter)
.pipe(concat('vendor.js'));
var appFiles = gulp.src('app/js/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(concat('app.js'));
return es.concat(vendorFiles, appFiles)
.pipe(uglify())
.pipe(concat('app.js'))
.pipe(gulp.dest('./dist/js'));
});
It works great, but I'm not able to handle the order of the files. Obviously I'd like that the vendor code come before my code at the destination's app.js, but that's doesn't happen. I created a thread about that here.
Solved it with gulp-event-stream and gulp-order. Intrigues me a little that gulp-order is trending downward at https://www.npmjs.org, though.
gulp.task('scripts', function () {
var jsFilter = gulpFilter('*.js');
var vendorFiles = gulp.src(mainBowerFiles())
.pipe(jsFilter)
.pipe(concat('vendor.js'));
var appFiles = gulp.src('app/js/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(concat('app.js'));
return eventStream.concat(vendorFiles, appFiles)
.pipe(order([
"vendor.js",
"app.js"
]))
.pipe(concat('app.js'))
.pipe(uglify())
.pipe(gulp.dest('./dist/js'));
});
mainBowerFiles() returns an array. gulp.src is expecting an array of strings, not nested arrays, which is likely the cause of the first problem. You could try the following instead:
gulp.src(mainBowerFiles(gulpFilter('*.js')).push('app/js/*.js'))
I'm not sure what's causing the unhandled error event, but you could try using gulp-debug to get more information.
Please find the content of the gulpfile.js as below.
The task uglify depends on the task jshint. Currently when I run gulp, both the tasks get executed, irrespective of the outcome of the jshint task. I don't want the uglify task to get executed when there are 'jshint' error(s).
In other words, when ever there are dependent tasks, I don't want the subsequent tasks to get executed, if there are error detected by the preceding task.
Is it possible in gulp?
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var uglify = require('gulp-uglify');
gulp.task('jshint', function () {
return gulp.src(['assets/js/**/*.js'])
.pipe(jshint('.jshintrc'))
.pipe(jshint.reporter('jshint-stylish'));
});
gulp.task('uglify', ['jshint'], function() {
return gulp.src('assets/js/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('assets-min/js/'));
});
gulp.task('default', ['jshint', 'uglify']);
Please refer the below console output - not desired. Though there had been jshint error, the uglify task ran successfully.
I have also created a GitHub repository with the boilerplate code for the above mentioned.
Please find the same at #sarbbottam/gulp-workflow.
Console out of the undesired workflow
Console out of the expected workflow
For JSHint, there is a built-in reporter for this purpose, fail. If an error occurs, it will stop your gulp process.
You just have to redefine your task like :
gulp.task('jshint', function () {
return gulp.src(['assets/js/**/*.js'])
.pipe(jshint('.jshintrc'))
.pipe(jshint.reporter('jshint-stylish'))
.pipe(jshint.reporter('fail'))
})
With other tasks, you can add an error callback on it and exit the process to prevent subsequent tasks to run.
Here is an example with ngmin (cause uglify is hard to break, but it will be the same) :
function handleError (err) {
console.log(err.toString())
process.exit(-1)
}
gulp.task('min', function () {
return gulp.src(['assets/js/**/*.js'])
.pipe(ngmin())
.on('error', handleError)
})
To complement Aperçu's answer, if you don't want gulp to just exit (because you have watcher running) then you can do the following:
gulp.task('min', function(done) {
return gulp.src(['assets/js/**/*.js'])
.pipe(ngmin())
.on('error', done);
});
This will prevent the next task that depends on this one to run but your watchers will still be running.