Skip to content

Commit

Permalink
fix(build): fix source maps
Browse files Browse the repository at this point in the history
  • Loading branch information
vsavkin committed Nov 24, 2015
1 parent 8daa9b2 commit 87d56ac
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 119 deletions.
7 changes: 2 additions & 5 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ function launchKarmaWithExternalBrowsers(reporters, browsers, done) {

gulp.task('!test.unit.js/karma-server', function(done) {
var watchStarted = false;
var server = new karma.Server({configFile: __dirname + '/karma-js.conf.js', reporters: 'dots'});
var server = new karma.Server({configFile: __dirname + '/karma-js.conf.js'});
server.on('run_complete', function() {
if (!watchStarted) {
watchStarted = true;
Expand All @@ -548,10 +548,7 @@ gulp.task('test.unit.router', function(done) {
});

gulp.task('!test.unit.router/karma-server', function() {
new karma.Server({
configFile: __dirname + '/modules/angular1_router/karma-router.conf.js',
reporters: 'dots'
})
new karma.Server({configFile: __dirname + '/modules/angular1_router/karma-router.conf.js'})
.start();
});

Expand Down
16 changes: 16 additions & 0 deletions karma-js.conf.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var browserProvidersConf = require('./browser-providers.conf.js');
var internalAngularReporter = require('./tools/karma/reporter.js');

// Karma configuration
// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT)
Expand Down Expand Up @@ -35,6 +36,21 @@ module.exports = function(config) {

customLaunchers: browserProvidersConf.customLaunchers,

plugins: [
'karma-jasmine',
'karma-browserstack-launcher',
'karma-sauce-launcher',
'karma-chrome-launcher',
'karma-sourcemap-loader',
'karma-dart',
internalAngularReporter
],

preprocessors: {
'**/*.js': ['sourcemap']
},

reporters: ['internal-angular'],
sauceLabs: {
testName: 'Angular2',
startConnect: false,
Expand Down
8 changes: 7 additions & 1 deletion modules/playground/e2e_test/sourcemap/sourcemap_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ describe('sourcemaps', function() {
expect(errorColumn).not.toBeNull();


var sourceMapData = fs.readFileSync('dist/js/prod/es5/playground/src/sourcemap/index.js.map');
const content =
fs.readFileSync('dist/js/dev/es5/playground/src/sourcemap/index.js').toString("utf8");
const marker = "//# sourceMappingURL=data:application/json;base64,";
const index = content.indexOf(marker);
const sourceMapData =
new Buffer(content.substring(index + marker.length), 'base64').toString("utf8");

var decoder = new sourceMap.SourceMapConsumer(JSON.parse(sourceMapData));

var originalPosition = decoder.originalPositionFor({line: errorLine, column: errorColumn});
Expand Down
3 changes: 3 additions & 0 deletions npm-shrinkwrap.clean.json
Original file line number Diff line number Diff line change
Expand Up @@ -12153,6 +12153,9 @@
}
}
},
"karma-sourcemap-loader": {
"version": "0.3.6"
},
"lodash": {
"version": "2.4.2"
},
Expand Down
213 changes: 109 additions & 104 deletions npm-shrinkwrap.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"karma-dart": "^0.3.0",
"karma-jasmine": "^0.3.6",
"karma-sauce-launcher": "^0.2.14",
"karma-sourcemap-loader": "^0.3.6",
"lodash": "^2.4.1",
"madge": "0.5.0",
"merge": "^1.2.0",
Expand Down
2 changes: 2 additions & 0 deletions tools/broccoli/angular_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export class AngularBuilder {
{
name: 'dev',
typeAssertions: true,
sourceMaps: true,
projects: opts.projects,
noTypeChecks: opts.noTypeChecks,
generateEs6: opts.generateEs6
Expand All @@ -84,6 +85,7 @@ export class AngularBuilder {
{
name: 'prod',
typeAssertions: false,
sourceMaps: false,
projects: opts.projects,
noTypeChecks: opts.noTypeChecks,
generateEs6: opts.generateEs6
Expand Down
33 changes: 30 additions & 3 deletions tools/broccoli/broccoli-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
output.outputFiles.forEach(o => {
let destDirPath = path.dirname(o.name);
fse.mkdirsSync(destDirPath);
fs.writeFileSync(o.name, o.text, FS_OPTS);
fs.writeFileSync(o.name, this.fixSourceMapSources(o.text), FS_OPTS);
});
}
});
Expand Down Expand Up @@ -145,9 +145,9 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {

private doFullBuild() {
let program = this.tsService.getProgram();
let emitResult = program.emit(undefined, function(absoluteFilePath, fileContent) {
let emitResult = program.emit(undefined, (absoluteFilePath, fileContent) => {
fse.mkdirsSync(path.dirname(absoluteFilePath));
fs.writeFileSync(absoluteFilePath, fileContent, FS_OPTS);
fs.writeFileSync(absoluteFilePath, this.fixSourceMapSources(fileContent), FS_OPTS);
});

if (emitResult.emitSkipped) {
Expand Down Expand Up @@ -176,6 +176,33 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
}
}

/**
* There is a bug in TypeScript 1.6, where the sourceRoot and inlineSourceMap properties
* are exclusive. This means that the sources property always contains relative paths
* (e.g, ../../../../angular2/src/di/injector.ts).
*
* Here, we normalize the sources property and remove the ../../../
*
* This issue is fixed in https://github.com/Microsoft/TypeScript/pull/5620.
* Once we switch to TypeScript 1.8, we can remove this method.
*/
private fixSourceMapSources(content: string): string {
try {
const marker = "//# sourceMappingURL=data:application/json;base64,";
const index = content.indexOf(marker);
if (index == -1) return content;

const base = content.substring(0, index + marker.length);
const sourceMapBit =
new Buffer(content.substring(index + marker.length), 'base64').toString("utf8");
const sourceMaps = JSON.parse(sourceMapBit);
const source = sourceMaps.sources[0];
sourceMaps.sources = [source.substring(source.lastIndexOf("../") + 3)];
return `${base}${new Buffer(JSON.stringify(sourceMaps)).toString('base64')}`;
} catch (e) {
return content;
}
}

private removeOutputFor(tsFilePath: string) {
let absoluteJsFilePath = path.join(this.cachePath, tsFilePath.replace(/\.ts$/, '.js'));
Expand Down
11 changes: 5 additions & 6 deletions tools/broccoli/trees/browser_tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
const modules = options.projects;
const noTypeChecks = options.noTypeChecks;
const generateEs6 = options.generateEs6;
const sourceMaps = options.sourceMaps;

if (modules.angular2) {
var angular2Tree = new Funnel('modules/angular2', {
Expand Down Expand Up @@ -147,14 +148,13 @@ module.exports = function makeBrowserTree(options, destinationPath) {
declaration: false,
emitDecoratorMetadata: true,
experimentalDecorators: true,
mapRoot: '', // force sourcemaps to use relative path
module: 'commonjs',
moduleResolution: 'classic',
noEmitOnError: !noTypeChecks,
rootDir: './',
rootFilePaths: ['angular2/manual_typings/globals.d.ts'],
sourceMap: true,
sourceRoot: '.',
inlineSourceMap: sourceMaps,
inlineSources: sourceMaps,
target: 'es5'
});

Expand Down Expand Up @@ -276,12 +276,11 @@ module.exports = function makeBrowserTree(options, destinationPath) {
declaration: false,
emitDecoratorMetadata: true,
experimentalDecorators: true,
mapRoot: '', // force sourcemaps to use relative path
noEmitOnError: false,
rootDir: './',
rootFilePaths: ['angular2/manual_typings/globals-es6.d.ts'],
sourceMap: true,
sourceRoot: '.',
inlineSourceMap: sourceMaps,
inlineSources: sourceMaps,
target: 'es6'
});

Expand Down
59 changes: 59 additions & 0 deletions tools/karma/reporter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
var SourceMapConsumer = require('source-map').SourceMapConsumer;
var DotsReporter = require('karma/lib/reporters/dots_color');

var createErrorFormatter = function (basePath, emitter, SourceMapConsumer) {
var lastServedFiles = [];
emitter.on('file_list_modified', function (files) {
lastServedFiles = files.served
});
function findFile(path) {
return lastServedFiles.filter(_ => _.path === path)[0];
}

var URL_REGEXP = new RegExp('(?:https?:\\/\\/[^\\/]*)?\\/?' +
'(base|absolute)' + // prefix
'((?:[A-z]\\:)?[^\\?\\s\\:]*)' + // path
'(\\?\\w*)?' + // sha
'(\\:(\\d+))?' + // line
'(\\:(\\d+))?' + // column
'', 'g')

return function (msg, indentation) {
msg = (msg || '').replace(URL_REGEXP, function (_, prefix, path, __, ___, line, ____, column) {
if (prefix === 'base') {
path = basePath + path;
}
line = parseInt(line || '0', 10);
column = parseInt(column || '0', 10);

var file = findFile(path)
if (file && file.sourceMap) {
try {
var original = new SourceMapConsumer(file.sourceMap).originalPositionFor({
line: line,
column: column
});
return process.cwd() + "/modules/" + original.source + ":" + original.line + ":" + original.column;
} catch (e) {
log.warn('SourceMap position not found for trace: %s', msg);
}
}
return path + ':' + line + ':' + column;
});

// indent every line
if (indentation) {
msg = indentation + msg.replace(/\n/g, '\n' + indentation)
}
return msg + '\n';
}
}


var InternalAngularReporter = function (config, emitter) {
var formatter = createErrorFormatter(config.basePath, emitter, SourceMapConsumer);
DotsReporter.call(this, formatter, false)
}
InternalAngularReporter.$inject = ['config', 'emitter']

module.exports = {'reporter:internal-angular': ['type', InternalAngularReporter]};

0 comments on commit 87d56ac

Please sign in to comment.