1 | ## gulp-sourcemaps [![NPM version][npm-image]][npm-url] [![build status][travis-image]][travis-url] [![Test coverage][coveralls-image]][coveralls-url]
|
2 |
|
3 | ### Branching
|
4 |
|
5 | __2.X now supports node 0.10+ due to switching out a dependency.__
|
6 |
|
7 | ### Usage
|
8 |
|
9 | #### Write inline source maps
|
10 | Inline source maps are embedded in the source file.
|
11 |
|
12 | Example:
|
13 | ```javascript
|
14 | var gulp = require('gulp');
|
15 | var plugin1 = require('gulp-plugin1');
|
16 | var plugin2 = require('gulp-plugin2');
|
17 | var sourcemaps = require('gulp-sourcemaps');
|
18 |
|
19 | gulp.task('javascript', function() {
|
20 | gulp.src('src/**/*.js')
|
21 | .pipe(sourcemaps.init())
|
22 | .pipe(plugin1())
|
23 | .pipe(plugin2())
|
24 | .pipe(sourcemaps.write())
|
25 | .pipe(gulp.dest('dist'));
|
26 | });
|
27 | ```
|
28 |
|
29 | 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](https://github.com/gulp-sourcemaps/gulp-sourcemaps/wiki/Plugins-with-gulp-sourcemaps-support).
|
30 |
|
31 |
|
32 | #### Write external source map files
|
33 |
|
34 | To write external source map files, pass a path relative to the destination to `sourcemaps.write()`.
|
35 |
|
36 | Example:
|
37 | ```javascript
|
38 | var gulp = require('gulp');
|
39 | var plugin1 = require('gulp-plugin1');
|
40 | var plugin2 = require('gulp-plugin2');
|
41 | var sourcemaps = require('gulp-sourcemaps');
|
42 |
|
43 | gulp.task('javascript', function() {
|
44 | gulp.src('src/**/*.js')
|
45 | .pipe(sourcemaps.init())
|
46 | .pipe(plugin1())
|
47 | .pipe(plugin2())
|
48 | .pipe(sourcemaps.write('../maps'))
|
49 | .pipe(gulp.dest('dist'));
|
50 | });
|
51 | ```
|
52 |
|
53 | #### Load existing source maps
|
54 |
|
55 | To load existing source maps, pass the option `loadMaps: true` to `sourcemaps.init()`.
|
56 |
|
57 | Example:
|
58 | ```javascript
|
59 | var gulp = require('gulp');
|
60 | var plugin1 = require('gulp-plugin1');
|
61 | var plugin2 = require('gulp-plugin2');
|
62 | var sourcemaps = require('gulp-sourcemaps');
|
63 |
|
64 | gulp.task('javascript', function() {
|
65 | gulp.src('src/**/*.js')
|
66 | .pipe(sourcemaps.init({loadMaps: true}))
|
67 | .pipe(plugin1())
|
68 | .pipe(plugin2())
|
69 | .pipe(sourcemaps.write())
|
70 | .pipe(gulp.dest('dist'));
|
71 | });
|
72 | ```
|
73 |
|
74 | #### Handle large files
|
75 |
|
76 | To handle large files, pass the option `largeFile: true` to `sourcemaps.init()`.
|
77 |
|
78 | Example:
|
79 | ```javascript
|
80 | var gulp = require('gulp');
|
81 | var plugin1 = require('gulp-plugin1');
|
82 | var plugin2 = require('gulp-plugin2');
|
83 | var sourcemaps = require('gulp-sourcemaps');
|
84 |
|
85 | gulp.task('javascript', function() {
|
86 | gulp.src('src/**/*.js')
|
87 | .pipe(sourcemaps.init({largeFile: true}))
|
88 | .pipe(plugin1())
|
89 | .pipe(plugin2())
|
90 | .pipe(sourcemaps.write())
|
91 | .pipe(gulp.dest('dist'));
|
92 | });
|
93 | ```
|
94 |
|
95 | #### Handle source files from different directories
|
96 |
|
97 | Use the `base` option on `gulp.src` to make sure all files are relative to a common base directory.
|
98 |
|
99 | Example:
|
100 | ```javascript
|
101 | var gulp = require('gulp');
|
102 | var plugin1 = require('gulp-plugin1');
|
103 | var plugin2 = require('gulp-plugin2');
|
104 | var sourcemaps = require('gulp-sourcemaps');
|
105 |
|
106 | gulp.task('javascript', function() {
|
107 | gulp.src(['src/test.js', 'src/testdir/test2.js'], { base: 'src' })
|
108 | .pipe(sourcemaps.init())
|
109 | .pipe(plugin1())
|
110 | .pipe(plugin2())
|
111 | .pipe(sourcemaps.write('../maps'))
|
112 | .pipe(gulp.dest('dist'));
|
113 | });
|
114 | ```
|
115 |
|
116 | #### Alter `sources` property on sourcemaps
|
117 |
|
118 | The exported `mapSources` method 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 and the original vinyl file.
|
119 |
|
120 | Example:
|
121 | ```javascript
|
122 | gulp.task('javascript', function() {
|
123 | var stream = gulp.src('src/**/*.js')
|
124 | .pipe(sourcemaps.init())
|
125 | .pipe(plugin1())
|
126 | .pipe(plugin2())
|
127 | // be careful with the sources returned otherwise contents might not be loaded properly
|
128 | .pipe(sourcemaps.mapSources(function(sourcePath, file) {
|
129 | // source paths are prefixed with '../src/'
|
130 | return '../src/' + sourcePath;
|
131 | }))
|
132 | .pipe(sourcemaps.write('../maps')
|
133 | .pipe(gulp.dest('public/scripts'));
|
134 | });
|
135 | ```
|
136 |
|
137 | #### Generate Identity Sourcemap
|
138 |
|
139 | The exported `identityMap` method allows you 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.__
|
140 |
|
141 | Example:
|
142 | ```javascript
|
143 | gulp.task('javascript', function() {
|
144 | var stream = gulp.src('src/**/*.js')
|
145 | .pipe(sourcemaps.init())
|
146 | // An identity sourcemap will be generated at this step
|
147 | .pipe(sourcemaps.identityMap())
|
148 | .pipe(plugin1())
|
149 | .pipe(plugin2())
|
150 | .pipe(sourcemaps.write('../maps')
|
151 | .pipe(gulp.dest('public/scripts'));
|
152 | });
|
153 | ```
|
154 |
|
155 |
|
156 | ### Init Options
|
157 |
|
158 | - `loadMaps`
|
159 |
|
160 | Set to true to load existing maps for source files. Supports the following:
|
161 | - inline source maps
|
162 | - source map files referenced by a `sourceMappingURL=` comment
|
163 | - source map files with the same name (plus .map) in the same directory
|
164 |
|
165 |
|
166 | - `identityMap`
|
167 |
|
168 | __This option is deprecated. Upgrade to use our [`sourcemap.identityMap`](#generate-identity-sourcemap) API.__
|
169 |
|
170 |
|
171 | ### Write Options
|
172 |
|
173 | - `addComment`
|
174 |
|
175 | 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).
|
176 |
|
177 | Example:
|
178 | ```javascript
|
179 | gulp.task('javascript', function() {
|
180 | var stream = gulp.src('src/**/*.js')
|
181 | .pipe(sourcemaps.init())
|
182 | .pipe(plugin1())
|
183 | .pipe(plugin2())
|
184 | .pipe(sourcemaps.write('../maps', {addComment: false}))
|
185 | .pipe(gulp.dest('dist'));
|
186 | });
|
187 | ```
|
188 |
|
189 | - `includeContent`
|
190 |
|
191 | By default the source maps include the source code. Pass `false` to use the original files.
|
192 |
|
193 | 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`.
|
194 |
|
195 | - `sourceRoot`
|
196 |
|
197 | 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.
|
198 | 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).
|
199 | 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.
|
200 |
|
201 | Example:
|
202 | ```javascript
|
203 | gulp.task('javascript', function() {
|
204 | var stream = gulp.src('src/**/*.js')
|
205 | .pipe(sourcemaps.init())
|
206 | .pipe(plugin1())
|
207 | .pipe(plugin2())
|
208 | .pipe(sourcemaps.write({includeContent: false, sourceRoot: '/src'}))
|
209 | .pipe(gulp.dest('dist'));
|
210 | });
|
211 | ```
|
212 |
|
213 | Example (using a function):
|
214 | ```javascript
|
215 | gulp.task('javascript', function() {
|
216 | var stream = gulp.src('src/**/*.js')
|
217 | .pipe(sourcemaps.init())
|
218 | .pipe(plugin1())
|
219 | .pipe(plugin2())
|
220 | .pipe(sourcemaps.write({
|
221 | includeContent: false,
|
222 | sourceRoot: function(file) {
|
223 | return '/src';
|
224 | }
|
225 | }))
|
226 | .pipe(gulp.dest('dist'));
|
227 | });
|
228 | ```
|
229 |
|
230 | Example (relative path):
|
231 | ```javascript
|
232 | gulp.task('javascript', function() {
|
233 | var stream = gulp.src('src/**/*.js')
|
234 | .pipe(sourcemaps.init())
|
235 | .pipe(plugin1())
|
236 | .pipe(plugin2())
|
237 | .pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: '../src'}))
|
238 | .pipe(gulp.dest('dist'));
|
239 | });
|
240 | ```
|
241 | 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`).
|
242 |
|
243 | - `destPath`
|
244 |
|
245 | Set the destination path (the same you pass to `gulp.dest()`). If the source map destination path is not a sub path of the destination path, this is needed to get the correct path in the `file` property of the source map.
|
246 | In addition, it allows to automatically set a relative `sourceRoot` if none is set explicitly.
|
247 |
|
248 | - `sourceMappingURLPrefix`
|
249 |
|
250 | Specify a prefix to be prepended onto the source map URL when writing external source maps. Relative paths will have their leading dots stripped.
|
251 |
|
252 | Example:
|
253 | ```javascript
|
254 | gulp.task('javascript', function() {
|
255 | var stream = gulp.src('src/**/*.js')
|
256 | .pipe(sourcemaps.init())
|
257 | .pipe(plugin1())
|
258 | .pipe(plugin2())
|
259 | .pipe(sourcemaps.write('../maps', {
|
260 | sourceMappingURLPrefix: 'https://asset-host.example.com/assets'
|
261 | }))
|
262 | .pipe(gulp.dest('public/scripts'));
|
263 | });
|
264 | ```
|
265 |
|
266 | This will result in a source mapping URL comment like `sourceMappingURL=https://asset-host.example.com/assets/maps/helloworld.js.map`.
|
267 |
|
268 | - `sourceMappingURL`
|
269 |
|
270 | 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).
|
271 |
|
272 | Example:
|
273 | ```javascript
|
274 | gulp.task('javascript', function() {
|
275 | var stream = gulp.src('src/**/*.js')
|
276 | .pipe(sourcemaps.init())
|
277 | .pipe(plugin1())
|
278 | .pipe(plugin2())
|
279 | .pipe(sourcemaps.write('../maps', {
|
280 | sourceMappingURL: function(file) {
|
281 | return 'https://asset-host.example.com/' + file.relative + '.map';
|
282 | }
|
283 | }))
|
284 | .pipe(gulp.dest('public/scripts'));
|
285 | });
|
286 | ```
|
287 |
|
288 | This will result in a source mapping URL comment like `sourceMappingURL=https://asset-host.example.com/helloworld.js.map`.
|
289 |
|
290 | - `mapFile`
|
291 |
|
292 | 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.
|
293 |
|
294 | Example:
|
295 | ```javascript
|
296 | gulp.task('javascript', function() {
|
297 | var stream = gulp.src('src/**/*.js')
|
298 | .pipe(sourcemaps.init())
|
299 | .pipe(plugin1())
|
300 | .pipe(plugin2())
|
301 | .pipe(sourcemaps.write('../maps', {
|
302 | mapFile: function(mapFilePath) {
|
303 | // source map files are named *.map instead of *.js.map
|
304 | return mapFilePath.replace('.js.map', '.map');
|
305 | }
|
306 | }))
|
307 | .pipe(gulp.dest('public/scripts'));
|
308 | });
|
309 | ```
|
310 |
|
311 | - `mapSources`
|
312 |
|
313 | __This option is deprecated. Upgrade to use our [`sourcemap.mapSources`](#alter-sources-property-on-sourcemaps) API.__
|
314 |
|
315 | - `charset`
|
316 |
|
317 | Sets the charset for inline source maps. Default: `utf8`
|
318 |
|
319 | - `clone`
|
320 |
|
321 | Clones the original file for creation of the map file. Could be important if file history is important. See [file.clone()](https://github.com/gulpjs/vinyl#filecloneoptions) for possible options. Default: `{deep:false, contents:false}`
|
322 |
|
323 | ### Plugin developers only:
|
324 |
|
325 | - **How to add source map support to plugins**
|
326 |
|
327 | - Generate a source map for the transformation the plugin is applying
|
328 | - **Important**: Make sure the paths in the generated source map (`file` and `sources`) are relative to `file.base` (e.g. use `file.relative`).
|
329 | - Apply this source map to the vinyl `file`. E.g. by using [vinyl-sourcemaps-apply](https://github.com/gulp-sourcemaps/vinyl-sourcemaps-apply).
|
330 | This combines the source map of this plugin with the source maps coming from plugins further up the chain.
|
331 | - Add your plugin to the [wiki page](https://github.com/gulp-sourcemaps/gulp-sourcemaps/wiki/Plugins-with-gulp-sourcemaps-support)
|
332 |
|
333 | #### Example:
|
334 |
|
335 | ```js
|
336 | var through = require('through2');
|
337 | var applySourceMap = require('vinyl-sourcemaps-apply');
|
338 | var myTransform = require('myTransform');
|
339 |
|
340 | module.exports = function(options) {
|
341 |
|
342 | function transform(file, encoding, callback) {
|
343 | // generate source maps if plugin source-map present
|
344 | if (file.sourceMap) {
|
345 | options.makeSourceMaps = true;
|
346 | }
|
347 |
|
348 | // do normal plugin logic
|
349 | var result = myTransform(file.contents, options);
|
350 | file.contents = new Buffer(result.code);
|
351 |
|
352 | // apply source map to the chain
|
353 | if (file.sourceMap) {
|
354 | applySourceMap(file, result.map);
|
355 | }
|
356 |
|
357 | this.push(file);
|
358 | callback();
|
359 | }
|
360 |
|
361 | return through.obj(transform);
|
362 | };
|
363 | ```
|
364 |
|
365 | - **Verify sourcemaps are working**
|
366 |
|
367 | See example below or refer to [test/write.js](./test/write.js)
|
368 |
|
369 | #### Example:
|
370 | ```js
|
371 | var stream = plugin();
|
372 | var init = sourcemaps.init();
|
373 | var write = sourcemaps.write();
|
374 |
|
375 | init.pipe(stream).pipe(write);
|
376 |
|
377 | write.on('data', function (file) {
|
378 | assert(...);
|
379 | cb();
|
380 | });
|
381 |
|
382 | init.write(new gutil.File(...));
|
383 | init.end();
|
384 | ```
|
385 |
|
386 | ### Debugging
|
387 |
|
388 | All debugging output relies on [visionmedia/debug](https://github.com/visionmedia/debug). Follow the directions to set the
|
389 | environment variable `$DEBUG`.
|
390 |
|
391 | For a few examples of debug you could use:
|
392 |
|
393 | ```sh
|
394 | DEBUG='gulp-sourcemaps:*' #everything
|
395 | DEBUG='gulp-sourcemaps:init' #init/index.js
|
396 | DEBUG='gulp-sourcemaps:init:*' #init/index.internals.js
|
397 | DEBUG='gulp-sourcemaps:write:' #write/index.js
|
398 | DEBUG='gulp-sourcemaps:write:*' #write/index.internals.js
|
399 | DEBUG='gulp-sourcemaps:write:,gulp-sourcemaps:init:**' #write/index.internals.js and init/index.internals.js
|
400 | ```
|
401 |
|
402 | [npm-image]: https://img.shields.io/npm/v/gulp-sourcemaps.svg
|
403 | [npm-url]: https://www.npmjs.com/package/gulp-sourcemaps
|
404 | [travis-image]: https://img.shields.io/travis/gulp-sourcemaps/gulp-sourcemaps.svg
|
405 | [travis-url]: https://travis-ci.org/gulp-sourcemaps/gulp-sourcemaps
|
406 | [coveralls-image]: https://img.shields.io/coveralls/gulp-sourcemaps/gulp-sourcemaps.svg
|
407 | [coveralls-url]: https://coveralls.io/r/gulp-sourcemaps/gulp-sourcemaps?branch=master
|