How to bundle external dependencies using gulp - gulp

I'm trying to bundle external commonjs modules (react, react-dom) together with some plain ES5 files, like pollyfills.js.
I can bundle the external modules using browserify.require
var externalBundler = browserify();
config.externalModules.forEach(externalBundler.bundle);
return externalBundler.bundle()
.pipe(source("external.js"))
.pipe(buffer())
.pipe(sourcemaps.init({ debug: true, loadMaps: true }))
.pipe(uglify())
.on('error', gutil.log)
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./dist/'));
and the other scripts using gulp.concat, however I struggle to put them toggether.

I was able to combine the pipes like this:
gulp.task('bundle-externalscripts', function () {
var externalBundler = browserify({ debug: true });
for (var module of config.externalModules) externalBundler.require(module);
var globalScripts = gulp.src(paths.scripts);
var externalModules = externalBundler.bundle()
.pipe(source("externalmodules.js")) //always convert to vinyl source stream
.pipe(buffer()); //in buffered mode
return merge(globalScripts, externalModules)
.pipe(sourcemaps.init({ debug: true, loadMaps: true }))
.pipe(concat("external.js"))
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./dist/'));
});

Related

Conditionally running transform on browserify

I have added the babelify transformation and i've noticed that my mainScripts task now takes around 10 seconds instead of 0.5s as before.
I would therefore like to apply .transform("babelify", {presets: ["es2015"]}) only when the environment is or prod in order to speed up the task during development.
My function for determining the current environment
var isLocal = function() {
return argv.env === 'localdev' || argv.env === 'dev';
};
My scripts task:
gulp.task('mainScripts', function() {
return browserify('./app/app.js', {
debug: true
})
.transform("babelify", {presets: ["es2015"]})
.bundle()
.on('error', function(err) {
console.log(err.toString());
this.emit("end");
})
.pipe(source('main.js'))
.pipe(buffer())
.pipe(gulpif(!condition, sourcemaps.init({
loadMaps: true
})))
.pipe(ngAnnotate())
.pipe(gulpif(!condition, uglify({
mangle: true
}).on('error', gutil.log)))
.pipe(gulpif(!condition, sourcemaps.write('./')))
.pipe(gulp.dest('./dist/js/')).
pipe(gulpif(isLocal(), connect.reload()));
});
How can this be achieved?
The call to browserify returns the bundler and the transform call is just chained off that, so you can optionally call transform by doing something like this:
gulp.task('mainScripts', function() {
var bundler = browserify('./app/app.js', {
debug: true
});
if (!isLocal()) {
bundler = bundler.transform("babelify", { presets: ["es2015"] });
}
return bundler
.bundle()
.on('error', function(err) {
...
}
...
Alternatively, you could have a look for some gulp recipes for watchify, which should greatly improve your incremental build times.
How about using .plugin?
var babelify = function (b) {
return isLocal()
? b
: b.transform("babelify", {presets: ["es2015"]});
};
// .plugin(babelify)
browserify Plugins section says: plugin take the bundle instance as their first parameter
For some more advanced use-cases, a transform is not sufficiently extensible. Plugins are modules that take the bundle instance as their first parameter and an option hash as their second.
Applying plugin will be formatted like this:
var babelify = function (b) {
return isLocal()
? b
: b.transform("babelify", {presets: ["es2015"]});
};
gulp.task('mainScripts', function() {
return browserify('./app/app.js', {
debug: true
})
.plugin(babelify)
.bundle()
.on('error', function(err) {
...
}
...

Gulp with Browserify: Bundle task seems to fail after Delete task when watching

Here are my tasks to delete, bundle and watch for changes. Everytime I bundle, it works fine (even if the file doesn't exist yet). However, with the watch task, it'll break when it deletes the file and won't rebuild. Thoughts?
gulp.task('delete', function() {
var path = 'app/public/bundle.js';
return del(path);
});
gulp.task('bundle', ['delete'], function() {
var projectFiles = glob.sync('./app/**/*.js')
return browserify({
entries: projectFiles,
extensions: ['.js']
})
.bundle()
.on('error', function(err){
gutil.log(err);
})
.pipe(source('bundle.js'))
.pipe(gulp.dest('./app/public/'))
.pipe(notify({message: 'Browserify bundlified!'}))
});
gulp.task('watch', function(){
gulp.watch('app/assets/sass/**/*', ['css']);
gulp.watch('./app/**/*.js', ['bundle']);
})

How to minify webpack output using gulp?

I have this task:
gulp.task('js', function() {
var webpackConfig = extend({}, require('./webpack.config.dev.js'), {
devtool: "source-map",
});
return gulp.src(config.paths.mainJs)
//.pipe(beautify({indent: {value: ' '}}))
.pipe(named())
.pipe(webpack(webpackConfig))
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(through.obj(function (file, enc, cb) {
// Dont pipe through any source map files as it will be handled
// by gulp-sourcemaps
var isSourceMap = /\.map$/.test(file.path);
if (!isSourceMap) this.push(file);
cb();
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./deployment/deployment/js'))
.pipe(uglify())//JS_Parse_Error
The output of the previous pipe ./deployment/deployment/js/ is two files: bundle.js and bundle.js.map. So I think my pipe to uglify is wrong. How can I minify webpacks output?
All I had to do was modify my './webpack.config.dev.js` file already referenced in gulp to add the UglifyJsPlugin:
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin({
mangle: {
except: ['$super', '$', 'exports', 'require']
}
})
],

Browserify Babelify Uglify source map sources do not get loaded in Google Chrome

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'))
});

Use gulp-plumber on sass task

Whenever there's an error in my .scss file, my gulp task stops and I have to run gulp in the Terminal again. I'm trying to use gulp-plumber to remedy this, but can't work out where to place it in the task.
I'm requiring it like this, at the top of my gulpfile:
var gulp = require('gulp'),
sass = require('gulp-sass'),
plumber = require('gulp-plumber'),
...
I'm trying to pipe it into the task like so:
gulp.task('pre-process', function(){
gulp.src('./sass/mnml.scss')
.pipe(plumber())
.pipe(watch(function(files) {
return files.pipe(sass())
.pipe(prefix())
.pipe(size({gzip: false, showFiles: true}))
.pipe(size({gzip: true, showFiles: true}))
.pipe(gulp.dest('css'))
.pipe(minifyCSS())
.pipe(rename('mnml.min.css'))
.pipe(size({gzip: false, showFiles: true}))
.pipe(size({gzip: true, showFiles: true}))
.pipe(gulp.dest('./css/'))
.pipe(browserSync.reload({stream:true}));
}));
});
But when I run gulp, I get this error:
stream.js:94
throw er; // Unhandled stream error in pipe.
^
Error: /Users/realph/Dropbox/temp/mnml/sass/base:4: error: unbound variable $b-color
Any idea what I'm doing wrong? Any help is appreciated. Thanks in advance!
You're creating another stream of files in the watch callback, and I don't think it's using the top plumber plugin.
To do so, you have to change your callback to use it like:
return files
.pipe(plumber())
.pipe(sass())
.pipe(prefix())
.pipe(size({gzip: false, showFiles: true}))
.pipe(size({gzip: true, showFiles: true}))
.pipe(gulp.dest('css'))
.pipe(minifyCSS())
.pipe(rename('mnml.min.css'))
.pipe(size({gzip: false, showFiles: true}))
.pipe(size({gzip: true, showFiles: true}))
.pipe(gulp.dest('./css/'))
.pipe(browserSync.reload({stream:true}));
You can also specify the errLogToConsole to your sass pipe
.pipe(sass({ errLogToConsole: true }))