Skip to content

Commit 6972337

Browse files
committed
preExisting sourceMapping checks to not modify the original file
1 parent 25f5778 commit 6972337

File tree

9 files changed

+204
-52
lines changed

9 files changed

+204
-52
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ reports
44
*.tgz
55
.idea
66
*.lock
7+
tmp

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@
3434
"devDependencies": {
3535
"coveralls": "2.X",
3636
"faucet": "0.0.X",
37+
"gulp": "3.X",
3738
"hook-std": "0.2.X",
3839
"istanbul": "0.X",
3940
"jshint": "2.X",
41+
"object-assign": "^4.1.0",
4042
"tape": "4.X"
4143
},
4244
"files": [

src/init.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ function init(options) {
4040

4141
var fileContent = file.contents.toString();
4242
var sourceMap;
43+
var preExisting = utils.getPreExisting(fileContent);
4344

4445
if (options.loadMaps) {
4546
debug('loadMaps');
@@ -113,11 +114,11 @@ function init(options) {
113114
}
114115
sourceMap.sourcesContent[i] = sourceContent;
115116
}
116-
});
117117

118-
// remove source map comment from source
119-
file.contents = new Buffer(fileContent, 'utf8');
118+
});
120119
}
120+
// remove source map comment from source
121+
file.contents = new Buffer(fileContent, 'utf8');
121122
}
122123

123124
if (!sourceMap && options.identityMap) {
@@ -199,6 +200,8 @@ function init(options) {
199200
sourcesContent: [fileContent]
200201
};
201202
}
203+
else if(preExisting !== null && typeof preExisting !== 'undefined')
204+
sourceMap.preExisting = preExisting
202205

203206
sourceMap.file = unixStylePath(file.relative);
204207
file.sourceMap = sourceMap;

src/utils.js

+54-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
2-
var path = require('path');
2+
var path = require('path'),
3+
detectNewline = require('detect-newline');
34

45
function unixStylePath(filePath) {
56
return filePath.split(path.sep).join('/');
@@ -9,8 +10,59 @@ var PLUGIN_NAME = require('../package.json').name;
910

1011
var urlRegex = /^(https?|webpack(-[^:]+)?):\/\//;
1112

13+
var debug = require('debug-fabulous')()(PLUGIN_NAME + ':utils');
14+
15+
var sourceMapUrlRegEx = /\/\/\# sourceMappingURL\=.*/g
16+
17+
18+
var getCommentFormatter = function (file) {
19+
var extension = file.relative.split('.').pop(),
20+
fileContents = file.contents.toString(),
21+
newline = detectNewline.graceful(fileContents || ''),
22+
commentFormatter = function(url) {
23+
return '';
24+
};
25+
26+
if (file.sourceMap.preExisting){
27+
debug('preExisting commentFormatter');
28+
commentFormatter = function(url) {
29+
return file.sourceMap.preExisting;
30+
};
31+
return commentFormatter
32+
}
33+
34+
switch (extension) {
35+
case 'css':
36+
debug('css commentFormatter');
37+
commentFormatter = function(url) {
38+
return newline + "/*# sourceMappingURL=" + url + " */" + newline;
39+
};
40+
break;
41+
case 'js':
42+
debug('js commentFormatter');
43+
commentFormatter = function(url) {
44+
return newline + "//# sourceMappingURL=" + url + newline;
45+
};
46+
break;
47+
default:
48+
debug('unknown commentFormatter')
49+
}
50+
51+
return commentFormatter;
52+
}
53+
54+
var getPreExisting = function(fileContent){
55+
if(sourceMapUrlRegEx.test(fileContent)){
56+
debug('has preExisting');
57+
return fileContent.match(sourceMapUrlRegEx)[0];
58+
}
59+
}
60+
1261
module.exports = {
1362
unixStylePath: unixStylePath,
1463
PLUGIN_NAME: PLUGIN_NAME,
15-
urlRegex: urlRegex
64+
urlRegex: urlRegex,
65+
sourceMapUrlRegEx: sourceMapUrlRegEx,
66+
getCommentFormatter: getCommentFormatter,
67+
getPreExisting: getPreExisting
1668
};

src/write.js

+13-28
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ var utils = require('./utils'),
66
fs = require('graceful-fs'),
77
path = require('path'),
88
File = require('vinyl'),
9-
stripBom = require('strip-bom'),
10-
detectNewline = require('detect-newline');
9+
stripBom = require('strip-bom');
1110

1211
/**
1312
* Write the source map
@@ -92,34 +91,13 @@ function write(destPath, options) {
9291
delete sourceMap.sourcesContent;
9392
}
9493

95-
var extension = file.relative.split('.').pop();
96-
var newline = detectNewline.graceful(file.contents.toString());
97-
var commentFormatter;
98-
99-
switch (extension) {
100-
case 'css':
101-
commentFormatter = function(url) {
102-
return newline + "/*# sourceMappingURL=" + url + " */" + newline;
103-
};
104-
break;
105-
case 'js':
106-
commentFormatter = function(url) {
107-
return newline + "//# sourceMappingURL=" + url + newline;
108-
};
109-
break;
110-
default:
111-
/* jshint ignore:start */
112-
commentFormatter = function(url) {
113-
return "";
114-
};
115-
/* jshint ignore:end */
116-
}
117-
118-
var comment;
94+
var comment,
95+
commentFormatter = utils.getCommentFormatter(file);
11996

12097
if (destPath === undefined || destPath === null) {
12198
// encode source map into comment
12299
var base64Map = new Buffer(JSON.stringify(sourceMap)).toString('base64');
100+
debug("basic comment")
123101
comment = commentFormatter('data:application/json;charset=' + options.charset + ';base64,' + base64Map);
124102
} else {
125103
var mapFile = path.join(destPath, file.relative) + '.map';
@@ -174,16 +152,23 @@ function write(destPath, options) {
174152
}
175153
sourceMapPathRelative = prefix + path.join('/', sourceMapPathRelative);
176154
}
155+
debug("destPath comment")
177156
comment = commentFormatter(unixStylePath(sourceMapPathRelative));
178157

179158
if (options.sourceMappingURL && typeof options.sourceMappingURL === 'function') {
159+
debug("options.sourceMappingURL comment")
180160
comment = commentFormatter(options.sourceMappingURL(file));
181161
}
182162
}
183163

184164
// append source map comment
185-
if (options.addComment)
186-
file.contents = Buffer.concat([file.contents, new Buffer(comment)]);
165+
if (options.addComment){
166+
if(options.preExisting && utils.getPreExisting(String(file.contents))){
167+
//normally the comment is pre-stripped but this option lets us know it is not
168+
}
169+
else
170+
file.contents = Buffer.concat([file.contents, new Buffer(comment)]);
171+
}
187172

188173
this.push(file);
189174
callback();

test/assets/helloworld.map.js

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

test/init.js

+11-12
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ test('init: should import an existing inline source map', function(t) {
164164
t.ok(data, 'should pass something through');
165165
t.ok(data instanceof File, 'should pass a vinyl file through');
166166
t.ok(data.sourceMap, 'should add a source map object');
167+
t.notOk(/sourceMappingURL/.test(data.contents.toString()), 'should not have sourcemapping in data.contents');
167168
t.equal(String(data.sourceMap.version), '3', 'should have version 3');
168169
t.deepEqual(data.sourceMap.sources, [
169170
'test1.js', 'test2.js'
@@ -179,14 +180,6 @@ test('init: should import an existing inline source map', function(t) {
179180
}).write(makeFileWithInlineSourceMap());
180181
});
181182

182-
test('init: should remove inline sourcemap', function(t) {
183-
var pipeline = sourcemaps.init({loadMaps: true});
184-
pipeline.on('data', function(data) {
185-
t.notOk(/sourceMappingURL/.test(data.contents.toString()), 'should not have sourcemapping');
186-
t.end();
187-
}).write(makeFileWithInlineSourceMap());
188-
});
189-
190183
test('init: should load external source map file referenced in comment with the \/\/# syntax', function(t) {
191184
var file = makeFile();
192185
file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=helloworld2.js.map');
@@ -400,10 +393,16 @@ test('init: should output an error message if debug option is set and sourceCont
400393

401394
pipeline.on('data', function() {
402395
unhook();
403-
// debug.save(null);
404-
t.ok(history.length == 4, 'history len');
405-
t.ok(history[2].match(/No source content for \"missingfile\". Loading from file./), 'should log missing source content');
406-
t.ok(history[3].match(/source file not found: /), 'should warn about missing file');
396+
var hasRegex = function(regex){
397+
return function(s){
398+
return regex.test(s);
399+
};
400+
};
401+
t.ok(
402+
history.some(
403+
hasRegex(/No source content for \"missingfile\". Loading from file./)),
404+
'should log missing source content');
405+
t.ok(history.some(hasRegex(/source file not found: /)), 'should warn about missing file');
407406
t.end();
408407
}).write(file);
409408

test/integration.js

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'use strict';
2+
var gulp = require('gulp');
3+
var test = require('tape');
4+
var $ = require('..');
5+
var PLUGIN_NAME = require('../src/utils').PLUGIN_NAME;
6+
var debug = require('debug-fabulous')()(PLUGIN_NAME + ':test:integration');
7+
var join = require('path').join;
8+
var fs = require('fs');
9+
var sourceContent = fs.readFileSync(join(__dirname, 'assets/helloworld.js')).toString();
10+
11+
debug('running');
12+
13+
test('creates inline mapping', function(t) {
14+
15+
gulp.src(join(__dirname, './assets/helloworld.js'))
16+
.pipe($.init())
17+
.pipe($.write())
18+
// .pipe(gulp.dest('tmp'))
19+
.on('data', function(data) {
20+
t.ok(data.sourceMap, 'should add a source map object');
21+
t.deepEqual(
22+
data.contents.toString(),
23+
sourceContent + "\n//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJoZWxsb3dvcmxkLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gaGVsbG9Xb3JsZCgpIHtcbiAgICBjb25zb2xlLmxvZygnSGVsbG8gd29ybGQhJyk7XG59XG4iXSwiZmlsZSI6ImhlbGxvd29ybGQuanMifQ==\n",
24+
'file should be sourcemapped'
25+
);
26+
t.end();
27+
})
28+
.on('error', function() {
29+
t.fail('emitted error');
30+
t.end();
31+
})
32+
.on('close', function() {
33+
t.end();
34+
});
35+
});
36+
37+
test('creates re-uses existing mapping', function(t) {
38+
gulp.src(join(__dirname, './assets/helloworld.map.js'))
39+
.pipe($.init({loadMaps:true}))
40+
.pipe($.write())
41+
// .pipe(gulp.dest('tmp'))
42+
.on('data', function(data) {
43+
t.ok(data.sourceMap, 'should add a source map object');
44+
t.ok(!!data.sourceMap.preExisting, 'should know the sourcemap pre-existed');
45+
t.deepEqual(
46+
data.contents.toString(),
47+
sourceContent + "\n//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJoZWxsb3dvcmxkLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gaGVsbG9Xb3JsZCgpIHtcbiAgICBjb25zb2xlLmxvZygnSGVsbG8gd29ybGQhJyk7XG59XG4iXSwiZmlsZSI6ImhlbGxvd29ybGQuanMifQ==",
48+
'file should be sourcemapped'
49+
);
50+
t.end();
51+
})
52+
.on('error', function() {
53+
t.fail('emitted error');
54+
t.end();
55+
})
56+
.on('close', function() {
57+
t.end();
58+
});
59+
});

0 commit comments

Comments
 (0)