4

I'll begin straight off with an example of my code structure. Assume the following three trivial files reside inside the same directory called /path/from/root/js/src

module1.js:

console.log(1);

module2.js:

console.log(2);

app.js:

require('./module1');
require('./module2');

Then, I am using the following gulp task to compile javascript into one file with gulp:

var gulp = require('gulp');
var sourcemaps  = require('gulp-sourcemaps');
var path = require('path');
var browserify = require('gulp-browserify');

gulp.task('default', function() {
    gulp.src(['./js/src/app.js'])
        .pipe(sourcemaps.init())
        .pipe(browserify()).on('error', function(err){
            console.log(err);
        })
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(function( file ) {
            file.base = path.dirname(file.path);
            return path.join(path.dirname(file.path), '/../');
        }))
});

After running gulp I am getting the compiled javascript app.js which just logs 1 2 and an app.js.map as expected, but there is no reference to the original file in the browser.

You can check that by looking at the console lines 1 and 2, they are referenced by app.js, not by module1|2.js. If I needed to fix a bug I'd have no idea which file is generating the console notations in the future as the files grow bigger in my project.

What am I doing wrong? Am I not using the sourcemaps correctly?

The app.js.map file doesn't reference the modules, it looks like this:

{
    "version":3,
    "names":[],
    "mappings":"",
    "sources":["app.js"],
    "sourcesContent":["require('./module1');\r\nrequire('./module2');"],
    "file":"app.js"
}
eush77
  • 3,870
  • 1
  • 23
  • 30
George Dimitriadis
  • 1,681
  • 1
  • 18
  • 27

2 Answers2

1

Using rollup
After trying various stuff and build packages online, I have found a solution to my problem with the use of rollup instead of browserify. In case someone is interested, I will add here my trivial build in basic usage with rollup :

module1.js and module2.js remain as are.

app.js becomes

import {m1} from './module1';
import {m2} from './module2';

And my gulpfile becomes

var gulp = require('gulp'),
    rollup = require('rollup')
;

gulp.task('default', function () {
    return rollup.rollup({
        entry: "./js/src/app.js",
    })
    .then(function (bundle) {
        bundle.write({
            format: "umd",
            moduleName: "library",
            dest: "./js/app.js",
            sourceMap: true
        });
    })
});

Now open your html file which includes /js/app.js and you'll see in your console 1 referenced by module1.js and 2 referenced by module2.js

Looks like rollup doesn't support require by default, but the import {...} from ... syntax is more minimalistic and part of ES6, so it might be better for me to start using it instead.

Source from official documentation: https://rollupjs.org/#using-rollup-with-gulp

Further reading for a more complex build (I haven't walked through these steps yet, but looks promising): https://github.com/rollup/rollup-starter-project

All hail mighty messy malicious Javascript for the troubles it leads upon us !

George Dimitriadis
  • 1,681
  • 1
  • 18
  • 27
0

I have found a more relative solution to the problem, so I'm creating a new answer for it. I have noticed that the gulp-browserify package I was using was deprecated, so I checked for an updated usage.

My package.json dependencies are:

"devDependencies": {
    "babel-preset-es2015": "^6.24.1",
    "babelify": "^7.3.0",
    "browserify": "^14.4.0",
    "gulp": "^3.9.1",
    "gulp-sourcemaps": "^2.6.0",
    "gulp-uglify": "^3.0.0",
    "gulp-util": "^3.0.8",
    "vinyl-buffer": "^1.0.0",
    "vinyl-source-stream": "^1.1.0"
}

My gulpfile.js for a basic build looks like this:

'use strict';

var browserify = require('browserify');
var gulp = require('gulp');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var gutil = require('gulp-util');

gulp.task('default', function () {
    // set up the browserify instance on a task basis
    var b = browserify({
        entries: './js/src/app.js',
        debug: true
    }).transform("babelify", {presets: ["es2015"]});

    return b.bundle()
        .pipe(source('app.js'))
        .pipe(buffer())
        .pipe(sourcemaps.init({loadMaps: true}))
        // Add transformation tasks to the pipeline here.
        //.pipe(uglify())
        .on('error', gutil.log)
        .pipe(sourcemaps.write('./'))
        .pipe(gulp.dest('./js/'));
});

For a production build, you can uncomment the uglify command. Babelify is there to allow ES5 syntax (didn't test, but probably you can instead use the *2017 package too).

Sources:
1. Gulp setup for Browserify
2. Babel setup for Browserify

George Dimitriadis
  • 1,681
  • 1
  • 18
  • 27