This article is published by the Cloud + community

On the front end, we often catch unhandled exceptions through the window.onerror event. Suppose an exception is caught and the stack reported is this:

TypeError: Cannot read property 'module' of undefined
    at Object.exec (https://my.cdn.com/dest/app.efe91e855d7432e402545e7d6c25d2d9.js:16:29828)
    at HTMLLIElement.<anonymous> (https://my.cdn.com/dest/app.efe91e855d7432e402545e7d6c25d2d9.js:25:6409)
    at HTMLDivElement.dispatch (https://my.cdn.com/dest/vendor.eb28ded1876760b8e90973c9f4813a2c.js:1:248887)
    at HTMLDivElement.y.handle (https://my.cdn.com/dest/vendor.eb28ded1876760b8e90973c9f4813a2c.js:1:245631)
Copy the code

Can you see anything wrong with this stack? The script files we publish to the CDN are generally compressed by UglifyJS, so the stack readability is quite poor. What if there was one of the following stack viewing tools?

Sharp-eyed students can spot a problem at a glance. Here p[e] may be undefined.

Such a tool greatly improves the efficiency of problem location.

Ok, we don’t sell melons here, so let’s see how this works.

Step by step:

  • Take the original stack string and use

    error-stack-parser

    Each stack frame contains the three most important fields:

    • url– URL of the source code
    • line– Stack position line number
    • col– Stack position column number
  • For the URL, we can use it to load the source content and get the source

  • Source uses UglifyJs to reverse beautify the multi-line prettysource and generate the Sourcemap at the same time

  • The line and col in the stack frame are backchecked by sourcemap to obtain the corresponding prettyLine and prettyCol after beautification

  • Render prettysource, PrettyLine and PrettyCol to the Monaco Editor to get the look of the above screenshot

So much for the code:

var result = UglifyJS.minify(source, {
  output: {
    beautify: true
  },
  sourceMap: {
    filename: 'pretty.js'.url: 'pretty.js.map'}});var code = result.code;
var rawSourceMap = JSON.parse(result.map);
var consumerPromise = new sourceMap.SourceMapConsumer(rawSourceMap);

resolve(
  consumerPromise.then(function(consumer) {
    return {
      code: code,
      sourceMapConsumer: consumer
    }
  })
);
Copy the code

The above is the use of UglifyJs compression code for the reverse beautification of the core code. SourceMap (SourceMap)

var code = result.code;
var consumer = result.sourceMapConsumer;

var position = consumer.generatedPositionFor({
  source: '0'.line: lineNumber,
  column: columnNumber
});

parent.postMessage({
  event: 'js-prettify-callback'.payload: {
    hash: payload.hash,
    result: 'success'.prettySource: code,
    prettyLineNumber: position.line,
    prettyColumnNumber: position.column + 1
  }
}, sourceOrigin);
Copy the code

Readers interested in the full source code can also come down to play:

js-loader.html.zip

The source code only contains the stack resolution implementation, the UI implementation is not discussed in this article, just draw a sketch with React.

This article has been published by Tencent Cloud + community authorized by the author

For more fresh technology dry goods, you can follow usTencent Cloud technology community – Cloud Plus community official number and Zhihu organization number