[ReactNative] Support loading sourcemaps from sourceMappingURL

This commit is contained in:
Alex Kotliarskyi
2015-03-12 17:49:54 -07:00
parent 963bb036e0
commit 6299803081
7 changed files with 157 additions and 18 deletions

View File

@@ -57,6 +57,8 @@ function setupDocumentShim() {
}
}
var sourceMapPromise;
function handleErrorWithRedBox(e) {
var RKExceptionsManager = require('NativeModules').RKExceptionsManager;
var errorToString = require('errorToString');
@@ -73,13 +75,14 @@ function handleErrorWithRedBox(e) {
if (RKExceptionsManager) {
RKExceptionsManager.reportUnhandledException(e.message, errorToString(e));
if (__DEV__) {
try {
var sourceMapInstance = loadSourceMap();
var prettyStack = errorToString(e, sourceMapInstance);
RKExceptionsManager.updateExceptionMessage(e.message, prettyStack);
} catch (ee) {
GLOBAL.console.error('#CLOWNTOWN (error while displaying error): ' + ee.message);
}
(sourceMapPromise = sourceMapPromise || loadSourceMap())
.then(map => {
var prettyStack = errorToString(e, map);
RKExceptionsManager.updateExceptionMessage(e.message, prettyStack);
})
.then(null, error => {
GLOBAL.console.error('#CLOWNTOWN (error while displaying error): ' + error.message);
});
}
}
}

View File

@@ -2,23 +2,42 @@
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule loadSourceMap
* @flow
*/
'use strict';
var Promise = require('Promise');
var RCTSourceCode = require('NativeModules').RCTSourceCode;
var SourceMapConsumer = require('SourceMap').SourceMapConsumer;
var SourceMapURL = require('./source-map-url');
var sourceMapInstance;
var fetch = require('fetch');
function loadSourceMap() {
if (sourceMapInstance !== undefined) {
return sourceMapInstance;
function loadSourceMap(): Promise {
return fetchSourceMap()
.then(map => new SourceMapConsumer(map));
}
function fetchSourceMap(): Promise {
if (global.RAW_SOURCE_MAP) {
return Promise.resolve(global.RAW_SOURCE_MAP);
}
if (!global.RAW_SOURCE_MAP) {
return null;
if (!RCTSourceCode) {
return Promise.reject(new Error('RCTSourceCode module is not available'));
}
sourceMapInstance = new SourceMapConsumer(global.RAW_SOURCE_MAP);
return sourceMapInstance;
return new Promise(RCTSourceCode.getScriptText)
.then(extractSourceMapURL)
.then(fetch)
.then(response => response.text())
}
function extractSourceMapURL({url, text}): string {
var mapURL = SourceMapURL.getFrom(text);
var baseURL = url.match(/(.+:\/\/.*?)\//)[1];
return baseURL + mapURL;
}
module.exports = loadSourceMap;

View File

@@ -0,0 +1,73 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* This is a third-party micro-library grabbed from:
* https://github.com/lydell/source-map-url
*
* @nolint
*/
(function() {
var define = null; // Hack to make it work with our packager
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
void (function(root, factory) {
if (typeof define === "function" && define.amd) {
define(factory)
} else if (typeof exports === "object") {
module.exports = factory()
} else {
root.sourceMappingURL = factory()
}
}(this, function() {
var innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/
var regex = RegExp(
"(?:" +
"/\\*" +
"(?:\\s*\r?\n(?://)?)?" +
"(?:" + innerRegex.source + ")" +
"\\s*" +
"\\*/" +
"|" +
"//(?:" + innerRegex.source + ")" +
")" +
"\\s*$"
)
return {
regex: regex,
_innerRegex: innerRegex,
getFrom: function(code) {
var match = code.match(regex)
return (match ? match[1] || match[2] || "" : null)
},
existsIn: function(code) {
return regex.test(code)
},
removeFrom: function(code) {
return code.replace(regex, "")
},
insertBefore: function(code, string) {
var match = code.match(regex)
if (match) {
return code.slice(0, match.index) + string + code.slice(match.index)
} else {
return code + string
}
}
}
}));
/** End of the third-party code */
})();