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"
}
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