What is gulp-sourcemaps?
The gulp-sourcemaps package is a plugin for Gulp that allows you to generate source maps for your files. Source maps are files that map from the transformed source to the original source, enabling you to debug your code more easily by seeing the original source in your browser's developer tools.
What are gulp-sourcemaps's main functionalities?
Initialize Source Maps
This feature initializes the source map generation process. The `sourcemaps.init()` method is called before any transformations are applied to the files, and `sourcemaps.write('.')` writes the source maps to the same directory as the transformed files.
const gulp = require('gulp');
const sourcemaps = require('gulp-sourcemaps');
gulp.task('default', function () {
return gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist'));
});
Write Inline Source Maps
This feature writes the source maps inline within the transformed files. The `sourcemaps.write()` method without any arguments will embed the source map directly into the output file.
const gulp = require('gulp');
const sourcemaps = require('gulp-sourcemaps');
gulp.task('default', function () {
return gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist'));
});
Custom Source Map Path
This feature allows you to specify a custom path for the source maps. The `sourcemaps.write('../maps')` method writes the source maps to a directory named 'maps' that is one level up from the output directory.
const gulp = require('gulp');
const sourcemaps = require('gulp-sourcemaps');
gulp.task('default', function () {
return gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(sourcemaps.write('../maps'))
.pipe(gulp.dest('dist'));
});
Other packages similar to gulp-sourcemaps
gulp-sourcemap
The gulp-sourcemap package is another plugin for generating source maps in Gulp. It is similar to gulp-sourcemaps but is less popular and has fewer features. It is a simpler alternative for basic source map generation needs.
gulp-babel
The gulp-babel package is primarily used for transpiling JavaScript using Babel, but it also has built-in support for generating source maps. It is a good choice if you are already using Babel for transpilation and want to generate source maps as part of the same process.
gulp-uglify
The gulp-uglify package is used for minifying JavaScript files. It can also generate source maps for the minified files. It is useful if you want to combine minification and source map generation in a single step.
gulp-sourcemaps
Usage
Write inline source maps
Inline source maps are embedded in the source file.
Example:
var gulp = require('gulp');
var plugin1 = require('gulp-plugin1');
var plugin2 = require('gulp-plugin2');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('javascript', function() {
gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist'));
});
All plugins between sourcemaps.init()
and sourcemaps.write()
need to have support for gulp-sourcemaps
. You can find a list of such plugins in the wiki.
Write external source map files
To write external source map files, pass a path relative to the destination to sourcemaps.write()
.
Example:
var gulp = require('gulp');
var plugin1 = require('gulp-plugin1');
var plugin2 = require('gulp-plugin2');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('javascript', function() {
gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write('../maps'))
.pipe(gulp.dest('dist'));
});
Load existing source maps
To load existing source maps, pass the option loadMaps: true
to sourcemaps.init()
.
Example:
var gulp = require('gulp');
var plugin1 = require('gulp-plugin1');
var plugin2 = require('gulp-plugin2');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('javascript', function() {
gulp.src('src/**/*.js')
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist'));
});
Handle large files
To handle large files, pass the option largeFile: true
to sourcemaps.init()
.
Example:
var gulp = require('gulp');
var plugin1 = require('gulp-plugin1');
var plugin2 = require('gulp-plugin2');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('javascript', function() {
gulp.src('src/**/*.js')
.pipe(sourcemaps.init({largeFile: true}))
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist'));
});
Handle source files from different directories
Use the base
option on gulp.src
to make sure all files are relative to a common base directory.
Example:
var gulp = require('gulp');
var plugin1 = require('gulp-plugin1');
var plugin2 = require('gulp-plugin2');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('javascript', function() {
gulp.src(['src/test.js', 'src/testdir/test2.js'], { base: 'src' })
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write('../maps'))
.pipe(gulp.dest('dist'));
});
Init Options
-
loadMaps
Set to true to load existing maps for source files. Supports the following:
- inline source maps
- source map files referenced by a
sourceMappingURL=
comment - source map files with the same name (plus .map) in the same directory
-
identityMap
Set to true to generate a full valid source map encoding no changes (slower, only
for Javascript and CSS) instead of the default empty source map (no mappings, fast).
Use this option if you get missing or incorrect mappings, e.g. when debugging.
-
debug
Set this to true
to output debug messages (e.g. about missing source content).
Write Options
-
addComment
By default a comment containing / referencing the source map is added. Set this to false
to disable the comment (e.g. if you want to load the source maps by header).
Example:
gulp.task('javascript', function() {
var stream = gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write('../maps', {addComment: false}))
.pipe(gulp.dest('dist'));
});
-
includeContent
By default the source maps include the source code. Pass false
to use the original files.
Including the content is the recommended way, because it "just works". When setting this to false
you have to host the source files and set the correct sourceRoot
.
-
sourceRoot
Set the location where the source files are hosted (use this when includeContent
is set to false
). This is usually a URL (or an absolute URL path), not a local file system path.
By default the source root is '' or in case destPath
is set, the relative path from the source map to the source base directory (this should work for many dev environments).
If a relative path is used (empty string or one starting with a .
), it is interpreted as a path relative to the destination. The plugin rewrites it to a path relative to each source map.
Example:
gulp.task('javascript', function() {
var stream = gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write({includeContent: false, sourceRoot: '/src'}))
.pipe(gulp.dest('dist'));
});
Example (using a function):
gulp.task('javascript', function() {
var stream = gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write({
includeContent: false,
sourceRoot: function(file) {
return '/src';
}
}))
.pipe(gulp.dest('dist'));
});
Example (relative path):
gulp.task('javascript', function() {
var stream = gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: '../src'}))
.pipe(gulp.dest('dist'));
});
In this case for a file written to dist/subdir/example.js
, the source map is written to dist/subdir/example.js.map
and the sourceRoot will be ../../src
(resulting in the full source path ../../src/subdir/example.js
).
-
destPath
Set the destination path (the same you pass to gulp.dest()
). If the source map destination path is not a subpath of the destination path, this is needed to get the correct path in the file
property of the source map.
In addition, it allows to automatically set a relative sourceRoot
if none is set explicitly.
-
sourceMappingURLPrefix
Specify a prefix to be prepended onto the source map URL when writing external source maps. Relative paths will have their leading dots stripped.
Example:
gulp.task('javascript', function() {
var stream = gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write('../maps', {
sourceMappingURLPrefix: 'https://asset-host.example.com/assets'
}))
.pipe(gulp.dest('public/scripts'));
});
This will result in a source mapping URL comment like sourceMappingURL=https://asset-host.example.com/assets/maps/helloworld.js.map
.
-
sourceMappingURL
If you need full control over the source map URL you can pass a function to this option. The output of the function must be the full URL to the source map (in function of the output file).
Example:
gulp.task('javascript', function() {
var stream = gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write('../maps', {
sourceMappingURL: function(file) {
return 'https://asset-host.example.com/' + file.relative + '.map';
}
}))
.pipe(gulp.dest('public/scripts'));
});
This will result in a source mapping URL comment like sourceMappingURL=https://asset-host.example.com/helloworld.js.map
.
-
mapFile
This option allows to rename the map file. It takes a function that is called for every map and receives the default map path as a parameter.
Example:
gulp.task('javascript', function() {
var stream = gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write('../maps', {
mapFile: function(mapFilePath) {
return mapFilePath.replace('.js.map', '.map');
}
}))
.pipe(gulp.dest('public/scripts'));
});
-
mapSources
This option gives full control over the source paths. It takes a function that is called for every source and receives the default source path as a parameter.
Example:
gulp.task('javascript', function() {
var stream = gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write('../maps', {
mapSources: function(sourcePath) {
return '../src/' + sourcePath;
}
}))
.pipe(gulp.dest('public/scripts'));
});
-
debug
Set this to true
to output debug messages (e.g. about missing source content).
-
charset
Sets the charset for inline source maps. Default: utf8
Plugin developers only:
-
How to add source map support to plugins
- Generate a source map for the transformation the plugin is applying
- Important: Make sure the paths in the generated source map (
file
and sources
) are relative to file.base
(e.g. use file.relative
). - Apply this source map to the vinyl
file
. E.g. by using vinyl-sourcemaps-apply.
This combines the source map of this plugin with the source maps coming from plugins further up the chain. - Add your plugin to the wiki page
Example:
var through = require('through2');
var applySourceMap = require('vinyl-sourcemaps-apply');
var myTransform = require('myTransform');
module.exports = function(options) {
function transform(file, encoding, callback) {
if (file.sourceMap) {
options.makeSourceMaps = true;
}
var result = myTransform(file.contents, options);
file.contents = new Buffer(result.code);
if (file.sourceMap) {
applySourceMap(file, result.map);
}
this.push(file);
callback();
}
return through.obj(transform);
};
Example:
var stream = plugin();
var init = sourcemaps.init();
var write = sourcemaps.write();
init.pipe(stream).pipe(write);
write.on('data', function (file) {
assert(...);
cb();
});
init.write(new gutil.File(...));
init.end();