Skip to content

Commit ad04c7e

Browse files
committed
Merge pull request #2 from twada/gulp-sourcemaps
gulp-sourcemaps support
2 parents 41e446b + 879d31e commit ad04c7e

8 files changed

+304
-49
lines changed

README.md

+25
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,31 @@ gulp.src("./test/*.js")
3030
.pipe(gulp.dest("./dist"));
3131
```
3232

33+
34+
## Source maps
35+
36+
gulp-espower can be used with [gulp-sourcemaps](https://github.com/floridoo/gulp-sourcemaps) to generate source maps for the instrumented javascript code. Note that you should `init` gulp-sourcemaps prior to running the gulp-espower and `write` the source maps after. gulp-espower works well with some gulp plugins that supports [gulp-sourcemaps](https://github.com/floridoo/gulp-sourcemaps).
37+
38+
```javascript
39+
var espower = require("gulp-espower");
40+
var coffee = require("gulp-coffee");
41+
var concat = require("gulp-concat");
42+
var sourcemaps = require("gulp-sourcemaps");
43+
44+
// compile, instrument then concatinate
45+
gulp.src("./test/*test.coffee")
46+
.pipe(sourcemaps.init())
47+
.pipe(coffee())
48+
.pipe(espower())
49+
.pipe(concat('all_test.js'))
50+
.pipe(sourcemaps.write())
51+
.pipe(gulp.dest("./build"));
52+
// will write the source maps inline in the code
53+
```
54+
55+
For more information, see [gulp-sourcemaps](https://github.com/floridoo/gulp-sourcemaps).
56+
57+
3358
## API
3459

3560
### espower(options)

index.js

+69-8
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,92 @@
77
* Licensed under the MIT license.
88
* https://github.com/twada/gulp-espower/blob/master/LICENSE-MIT
99
*/
10+
'use strict';
11+
1012
var through = require('through2'),
1113
gutil = require('gulp-util'),
14+
extend = require('xtend'),
1215
BufferStreams = require('bufferstreams'),
13-
espowerSource = require('espower-source');
16+
espower = require('espower'),
17+
espowerSource = require('espower-source'),
18+
esprima = require('esprima'),
19+
escodegen = require('escodegen'),
20+
applySourceMap = require('vinyl-sourcemaps-apply'),
21+
transfer = require('multi-stage-sourcemap').transfer,
22+
convert = require('convert-source-map');
1423

15-
module.exports = function (opt) {
16-
'use strict';
24+
function mergeSourceMap(incomingSourceMap, outgoingSourceMap) {
25+
if (typeof outgoingSourceMap === 'string' || outgoingSourceMap instanceof String) {
26+
outgoingSourceMap = JSON.parse(outgoingSourceMap);
27+
}
28+
if (!incomingSourceMap) {
29+
return outgoingSourceMap;
30+
}
31+
return JSON.parse(transfer({fromSourceMap: outgoingSourceMap, toSourceMap: incomingSourceMap}));
32+
}
33+
34+
function transform (file, encoding, opt) {
35+
var inMap = file.sourceMap;
36+
var escodegenOptions = {};
37+
var jsCode = file.contents.toString(encoding);
1738

18-
var transform = function (code, path) {
19-
return new Buffer(espowerSource(code, path, opt));
20-
};
39+
// use file.relative to keep paths relative until the end of chain
40+
var jsAst = esprima.parse(jsCode, {tolerant: true, loc: true, source: file.relative});
41+
42+
var espowerOptions = extend(espower.defaultOptions(), opt, {
43+
destructive: true,
44+
path: file.path
45+
});
46+
if (inMap) {
47+
espowerOptions.sourceMap = inMap;
48+
escodegenOptions = extend(escodegenOptions, {
49+
file: file.relative,
50+
sourceMap: true,
51+
// do not set sourceMapRoot to keep paths relative until the end of chain
52+
// sourceMapRoot: file.base,
53+
sourceMapWithCode: true
54+
});
55+
}
56+
var modifiedAst = espower(jsAst, espowerOptions);
57+
var escodegenOutput = escodegen.generate(modifiedAst, escodegenOptions);
58+
if (inMap) {
59+
file.contents = new Buffer(escodegenOutput.code);
60+
var outMap = convert.fromJSON(escodegenOutput.map.toString());
61+
outMap.setProperty('sources', inMap.sources);
62+
outMap.setProperty('sourcesContent', inMap.sourcesContent);
2163

64+
var reMap;
65+
if (inMap.mappings === '') {
66+
applySourceMap(file, outMap.toJSON());
67+
reMap = convert.fromObject(file.sourceMap);
68+
} else {
69+
reMap = convert.fromObject(mergeSourceMap(inMap, outMap.toJSON()));
70+
}
71+
reMap.setProperty('sources', inMap.sources);
72+
reMap.setProperty('sourcesContent', inMap.sourcesContent);
73+
// do not set sourceMapRoot to keep paths relative until the end of chain
74+
// reMap.setProperty('sourceRoot', file.base);
75+
76+
file.sourceMap = reMap.toObject();
77+
} else {
78+
file.contents = new Buffer(escodegenOutput);
79+
}
80+
}
81+
82+
module.exports = function (opt) {
2283
return through.obj(function (file, encoding, callback) {
2384
encoding = encoding || 'utf8';
2485
if (file.isNull()) {
2586
this.push(file);
2687
} else if (file.isBuffer()) {
27-
file.contents = transform(file.contents.toString(encoding), file.path);
88+
transform(file, encoding, opt);
2889
this.push(file);
2990
} else if (file.isStream()) {
3091
file.contents = file.contents.pipe(new BufferStreams(function(err, buf, cb) {
3192
if(err) {
3293
cb(new gutil.PluginError('gulp-espower', err, {showStack: true}));
3394
} else {
34-
cb(null, transform(buf.toString(encoding), file.path));
95+
cb(null, new Buffer(espowerSource(buf.toString(encoding), file.path, opt)));
3596
}
3697
}));
3798
this.push(file);

package.json

+12-5
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,25 @@
3333
},
3434
"scripts": {
3535
"jshint": "jshint index.js",
36-
"test": "mocha"
36+
"test": "jshint index.js && mocha"
3737
},
3838
"dependencies": {
3939
"bufferstreams": "~0.0.2",
40-
"espower-source": "~0.8.0",
40+
"convert-source-map": "~0.4.1",
41+
"escodegen": "~1.4.0",
42+
"espower": "~0.9.0",
43+
"espower-source": "~0.9.0",
44+
"esprima": "~1.2.2",
4145
"gulp-util": "~3.0.0",
42-
"through2": "~1.0.0"
46+
"multi-stage-sourcemap": "~0.2.1",
47+
"through2": "~1.1.1",
48+
"vinyl-sourcemaps-apply": "~0.1.1",
49+
"xtend": "~4.0.0"
4350
},
4451
"devDependencies": {
4552
"event-stream": "~3.1.7",
46-
"jshint": "~2.5.2",
47-
"mocha": "~1.21.0"
53+
"jshint": "~2.5.5",
54+
"mocha": "~1.21.4"
4855
},
4956
"engines": {
5057
"node": ">=0.8.0",

test/expected/customized-with-sourcemap.js

+26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/expected/customized.js

-1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,3 @@ refute.same(refute._expr(refute._capt(truthy, 'arguments/0'), {
2323
filepath: 'test/fixtures/customized.js',
2424
line: 9
2525
}));
26-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZml4dHVyZXMvY3VzdG9taXplZC5qcyJdLCJuYW1lcyI6WyJlbXBvd2VyIiwicmVxdWlyZSIsImZvcm1hdHRlciIsImJ1c3RlckFzc2VydGlvbnMiLCJyZWZ1dGUiLCJ0YXJnZXRNZXRob2RzIiwib25lQXJnIiwidHdvQXJncyIsInRydXRoeSIsImZhbHN5IiwiX2V4cHIiLCJfY2FwdCIsImNvbnRlbnQiLCJmaWxlcGF0aCIsImxpbmUiLCJpc051bGwiLCJzYW1lIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxPQUFBLEdBQVVDLE9BQUEsQ0FBUSxTQUFSLENBQWQsRUFDSUMsU0FBQSxHQUFZRCxPQUFBLENBQVEsd0JBQVIsQ0FEaEIsRUFFSUUsZ0JBQUEsR0FBbUJGLE9BQUEsQ0FBUSxtQkFBUixDQUZ2QixFQUdJRyxNQUFBLEdBQVNKLE9BQUEsQ0FBUUcsZ0JBQUEsQ0FBaUJDLE1BQXpCLEVBQWlDRixTQUFBLEVBQWpDLEVBQThDO0FBQUEsUUFBRUcsYUFBQSxFQUFlO0FBQUEsWUFBRUMsTUFBQSxFQUFRLENBQUMsUUFBRCxDQUFWO0FBQUEsWUFBc0JDLE9BQUEsRUFBUyxDQUFDLE1BQUQsQ0FBL0I7QUFBQSxTQUFqQjtBQUFBLEtBQTlDLENBSGIsRUFJSUMsTUFBQSxHQUFTLE1BSmIsRUFLSUMsS0FBQSxHQUFRLE9BTFo7QUFNQUwsTUFBQSxDQUFPQSxNQUFBLENBQUFNLEtBQUEsQ0FBQU4sTUFBQSxDQUFBTyxLQUFBLENBQUFILE1BQUE7QUFBQSxJQUFBSSxPQUFBO0FBQUEsSUFBQUMsUUFBQTtBQUFBLElBQUFDLElBQUE7QUFBQSxFQUFQLEVBTkE7QUFPQVYsTUFBQSxDQUFPVyxNQUFQLENBQWNYLE1BQUEsQ0FBQU0sS0FBQSxDQUFBTixNQUFBLENBQUFPLEtBQUEsQ0FBQUYsS0FBQTtBQUFBLElBQUFHLE9BQUE7QUFBQSxJQUFBQyxRQUFBO0FBQUEsSUFBQUMsSUFBQTtBQUFBLEVBQWQsRUFQQTtBQVFBVixNQUFBLENBQU9ZLElBQVAsQ0FBWVosTUFBQSxDQUFBTSxLQUFBLENBQUFOLE1BQUEsQ0FBQU8sS0FBQSxDQUFBSCxNQUFBO0FBQUEsSUFBQUksT0FBQTtBQUFBLElBQUFDLFFBQUE7QUFBQSxJQUFBQyxJQUFBO0FBQUEsRUFBWixFQUFvQlYsTUFBQSxDQUFBTSxLQUFBLENBQUFOLE1BQUEsQ0FBQU8sS0FBQSxDQUFBRixLQUFBO0FBQUEsSUFBQUcsT0FBQTtBQUFBLElBQUFDLFFBQUE7QUFBQSxJQUFBQyxJQUFBO0FBQUEsRUFBcEIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZW1wb3dlciA9IHJlcXVpcmUoJ2VtcG93ZXInKSxcbiAgICBmb3JtYXR0ZXIgPSByZXF1aXJlKCdwb3dlci1hc3NlcnQtZm9ybWF0dGVyJyksXG4gICAgYnVzdGVyQXNzZXJ0aW9ucyA9IHJlcXVpcmUoXCJidXN0ZXItYXNzZXJ0aW9uc1wiKSxcbiAgICByZWZ1dGUgPSBlbXBvd2VyKGJ1c3RlckFzc2VydGlvbnMucmVmdXRlLCBmb3JtYXR0ZXIoKSwgeyB0YXJnZXRNZXRob2RzOiB7IG9uZUFyZzogWydpc051bGwnXSwgdHdvQXJnczogWydzYW1lJ10gfSB9KSxcbiAgICB0cnV0aHkgPSAndHJ1ZScsXG4gICAgZmFsc3kgPSAnZmFsc2UnO1xucmVmdXRlKHRydXRoeSk7XG5yZWZ1dGUuaXNOdWxsKGZhbHN5KTtcbnJlZnV0ZS5zYW1lKHRydXRoeSwgZmFsc3kpO1xuIl19

test/expected/example-with-sourcemap.js

+16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/expected/example.js

-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,3 @@ assert.equal(assert._expr(assert._capt(truthy, 'arguments/0'), {
1313
filepath: 'test/fixtures/example.js',
1414
line: 5
1515
}));
16-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvZml4dHVyZXMvZXhhbXBsZS5qcyJdLCJuYW1lcyI6WyJhc3NlcnQiLCJyZXF1aXJlIiwidHJ1dGh5IiwiZmFsc3kiLCJfZXhwciIsIl9jYXB0IiwiY29udGVudCIsImZpbGVwYXRoIiwibGluZSIsImVxdWFsIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxNQUFBLEdBQVNDLE9BQUEsQ0FBUSxjQUFSLENBQWIsRUFDSUMsTUFBQSxHQUFTLE1BRGIsRUFFSUMsS0FBQSxHQUFRLE9BRlo7QUFHQUgsTUFBQSxDQUFPQSxNQUFBLENBQUFJLEtBQUEsQ0FBQUosTUFBQSxDQUFBSyxLQUFBLENBQUFGLEtBQUE7QUFBQSxJQUFBRyxPQUFBO0FBQUEsSUFBQUMsUUFBQTtBQUFBLElBQUFDLElBQUE7QUFBQSxFQUFQLEVBSEE7QUFJQVIsTUFBQSxDQUFPUyxLQUFQLENBQWFULE1BQUEsQ0FBQUksS0FBQSxDQUFBSixNQUFBLENBQUFLLEtBQUEsQ0FBQUgsTUFBQTtBQUFBLElBQUFJLE9BQUE7QUFBQSxJQUFBQyxRQUFBO0FBQUEsSUFBQUMsSUFBQTtBQUFBLEVBQWIsRUFBcUJSLE1BQUEsQ0FBQUksS0FBQSxDQUFBSixNQUFBLENBQUFLLEtBQUEsQ0FBQUYsS0FBQTtBQUFBLElBQUFHLE9BQUE7QUFBQSxJQUFBQyxRQUFBO0FBQUEsSUFBQUMsSUFBQTtBQUFBLEVBQXJCIiwic291cmNlc0NvbnRlbnQiOlsidmFyIGFzc2VydCA9IHJlcXVpcmUoJ3Bvd2VyLWFzc2VydCcpLFxuICAgIHRydXRoeSA9ICd0cnVlJyxcbiAgICBmYWxzeSA9ICdmYWxzZSc7XG5hc3NlcnQoZmFsc3kpO1xuYXNzZXJ0LmVxdWFsKHRydXRoeSwgZmFsc3kpO1xuIl19

0 commit comments

Comments
 (0)