Skip to content

Instantly share code, notes, and snippets.

@danharper
Last active September 25, 2024 09:04
Show Gist options
  • Save danharper/3ca2273125f500429945 to your computer and use it in GitHub Desktop.
Save danharper/3ca2273125f500429945 to your computer and use it in GitHub Desktop.
New ES6 project with Babel, Browserify & Gulp
var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var browserify = require('browserify');
var watchify = require('watchify');
var babel = require('babelify');
function compile(watch) {
var bundler = watchify(browserify('./src/index.js', { debug: true }).transform(babel));
function rebundle() {
bundler.bundle()
.on('error', function(err) { console.error(err); this.emit('end'); })
.pipe(source('build.js'))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./build'));
}
if (watch) {
bundler.on('update', function() {
console.log('-> bundling...');
rebundle();
});
}
rebundle();
}
function watch() {
return compile(true);
};
gulp.task('build', function() { return compile(); });
gulp.task('watch', function() { return watch(); });
gulp.task('default', ['watch']);
@ahoef
Copy link

ahoef commented Oct 7, 2015

@ee7klt you can include the gulp-connect node module to serve on localhost.

you'd just add another variable under the list of required modules:

var connect = require('gulp-connect');

and add this gulp task:

gulp.task('connect', function() {connect.server();});

the default port is localhost:8080

hope that helps!

@Tushant
Copy link

Tushant commented Oct 19, 2015

What if we want to bundle multiple files?

@akrawchyk
Copy link

@Tushant I haven't tried this but look into https://www.npmjs.com/package/factor-bundle. Look at the second API usage example for outputting writable streams https://www.npmjs.com/package/factor-bundle#api-plugin-example.

@aaronbeall
Copy link

I tried this, it results in a single source map file "main.js.map" which has the post-transpiled JS inline. Is it possible to have the source map point to the original ES6 files, or at least show the ES6 code in the source map?

@lincolndbryant
Copy link

I've been fighting the get the packaged UMD module plugin to work and there are several issues with the way CommonJS and globals work.

  1. Babel doesn't know how to order dependencies via the depdency tree, which both CommonJS and globals rely on.

  2. Globals do not work with the moduleRoot setting, it exports globals prefixed by this; strangely converted to camelCase identifier format. However, dependencies passed to factory() are not prefixed by the moduleRoot. Relative paths do not work correctly outside the top level. moduleRoot is really mandatory, since each of your top level modules are attached to window without prefix should no module system be on the page, attaching a module window.index is not workable.

It seems like the modules included with Babel really only work for 1 module or very simple project layouts. AMD and SystemJS have less issues, but many still need to package to support globals. I'm not crazy to add these deps, but browserify seems like the way to go for a working distribution right now, thanks for sharing.

@mstaicu
Copy link

mstaicu commented Dec 13, 2015

I'm trying to integrate another watch, for changes in all the .html files that represent the templates of all the directives, directives that are N levels deep. The task uses the gulp-angular-templatecache, and it's in its own function:

function buildTemplateCache() {
  gulp.src('./src/**/*.html')
    .pipe(templateCache('templates.js', {
      standalone: true
    }))
    .pipe(gulp.dest('./build'));
}

The goal here is to have a watch on all the .js files, which bundles it according to your example, and a watch for the .html files. The thing is that it goes into a really bad loop if I put the call to the buildTemplateCache in the:

 if (watch) {
    bundler.on('update', function() {
      console.log('-> bundling...');
      rebundle();
    });
  }

I tried to write the templates.js to another directory, and it seems that its working fine if I'm doing it like this, but I want all the files to be in one place, so, do you have any ideas on how I could approach this?

@hellohaoyu
Copy link

Hi guys, I tried to apply this code, but I got a error --Unexpected token error when I try to use it for ReactJS code. Can anyone help me out? Here is the details of question in stackoverflow -- Link. Thanks!

@cfrank
Copy link

cfrank commented Dec 25, 2015

If anyone has problems with code not trans compiling it might be because babel 6.x.x no longer ships with transformations enabled by default. You will need to install a transformation:

npm install --save-dev babel-preset-es2015

And add it to your gulpfile. For example:

let bundler = watchify(
    browserify({
        // Define the entry point for our application
        entries: [js_build + 'main.js'],
        // Debugging is nice
        debug: true,
        // Allow importing from the following extensions
        extensions: [' ', 'js', 'jsx']
    }).transform(babel.configure({
        // Use all of the ES2015 spec
        presets: ["es2015"]
    }))
);

The new part is

}).transform(babel.configure({
    // Use all of the ES2015 spec
    presets: ["es2015"]
}))

More presets are here http://babeljs.io/docs/plugins/#presets

@theredfish
Copy link

Thank you for sharing, perfect to start my project :)

@Tushant
Copy link

Tushant commented Jan 13, 2016

What should I do when I want to bundle and watch for multiple files? In this case just index.js is bundled and watched but I want it to be work with multiple files.

@martinsik
Copy link

@aaronbeall I'm scratching my head with the same issue. Did you solve it somehow?

@jswhisperer
Copy link

@Tushant you can add a watch function inside and call the watch or other tasks... maybe scss or jshint etc
gulp.task('watch', function() { gulp.watch(['index.html'], ['watch']); return watch(); });

https://scotch.io/tutorials/automate-your-tasks-easily-with-gulp-js

@ahmed-hamdy90
Copy link

adding a new notice about @cfrank comment
There another solution to add ES2015 preset options tobabelify, which Must add to Babel to enable transform ES6 code into ES5 code Since Babel 6.x.x.

).transform(babel, {
    // Use all of the ES2015 spec
    presets: ["es2015"]
})

As browserify.transform can pass options parameter for transformer as second parameter

@jakubbarczyk
Copy link

Following @ofiesh's suggestion, I've updated the compile function's internals accordingly:

function rebundle() {
    return bundler
        .bundle()
        .on('error', function (err) {
            console.error(err);
            this.emit('end');
        })
        .pipe(source('build.js'))
        .pipe(buffer())
        .pipe(sourcemaps.init({loadMaps: true}))
        .pipe(sourcemaps.write('./'))
        .pipe(gulp.dest('./build'));
}

if (watch) {
    bundler.on('update', function () {
        console.log('-> bundling...');
        rebundle();
    });

    rebundle()
} else {
    rebundle().pipe(exit());
}

@ivomarsan
Copy link

Thanks man!

@maxime-helen-sb
Copy link

maxime-helen-sb commented Apr 27, 2016

Thank you for this usefull code. I had to use instead .transform(babelify, { presets: ['es2015'] }) conf for making it working with "babel-preset-es2015": "^6.6.0", "babelify": "^7.3.0", node modules

@edin-m
Copy link

edin-m commented Jun 24, 2016

For gulp-livereload pipe() it after gupl.dest() [1]. Install chrome livereload extension as well.

var livereload = require('gulp-livereload');
...
    ...
    .pipe(gulp.dest('./build'))
    .pipe(livereload({ start: true }));

@dirkroorda
Copy link

Same question as @aaronbeall and @martinsik: how to get the sourcemaps pointing to the ES6 source.
I can't imagine that all users above are content to look at transpiled ES5 code as their sources.
So, how to init the sourcemaps before babel does the 6=>5 transform?

@dirkroorda
Copy link

Ah, I see. You do get ES6 sourcemaps, only Safari was not showing them te me. Safari expects source maps inline, or in the same directory as the build result. In my config I had the maps generated in '../maps'. Generating them in './' does the trick, also for Safari.

@fakiolinho
Copy link

Awesome work, thank you!!

@YuraRudkovskiy
Copy link

Do you have a problems when triggered

.transform(babel.configure({
        // Use all of the ES2015 spec
        presets: ["es2015"]
    }))

several times in a row?

@FranciscoG
Copy link

FranciscoG commented Feb 15, 2017

question,
Why does anyone need watchify at all if you're already using gulp that comes with its own file watching built in?

I need to test this out but I believe you could rewrite the whole gulpfile to this:

var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var browserify = require('browserify');
var babel = require('babelify');

gulp.task('build', function(){
  var bundler = browserify('./src/index.js', { debug: true }).transform(babel);

  bundler.bundle()
      .on('error', function(err) { console.error(err); this.emit('end'); })
      .pipe(source('build.js'))
      .pipe(buffer())
      .pipe(sourcemaps.init({ loadMaps: true }))
      .pipe(sourcemaps.write('./'))
      .pipe(gulp.dest('./build'));
});

gulp.task('watch', function () {
  gulp.watch('./src/**/*.js', ['build']);
});

gulp.task('default', ['watch']);

@yeomann
Copy link

yeomann commented Feb 19, 2017

@FranciscoG yes you are right! maybe it was needed since OP created this config based JS function instead gulp task. I have similar working configuration like yours at https://github.com/yeomann/GulPress/blob/master/gulpfile.js

@nicekiwi
Copy link

nicekiwi commented Mar 7, 2017

Here's my take on it, hacked, slashed and smashed to bundle and watch multiple files working right. :)

https://gist.github.com/nicekiwi/ca575492dfd83504aced26892c559d58

More info on that in the gulp recipes here too:
https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-multiple-destination.md

@luv2code
Copy link

Here is mine, it does uglify & sourcemaps. It uses watchify for increment builds plus livereload to notify the browser.
https://gist.github.com/luv2code/77ddbc79c02d40194f929841d0696ebc

@MaheshSasidharan
Copy link

Thanks a lot. This works great.

However I added a return statement on line 13 and 29 to show that the build task is completed
Finished 'build' after 749 ms;

However, still, the batch process is not ending. I still have to press CTRL+C to exit this process. :\

@kennblvnp
Copy link

can we see the package.json of these?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment