-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Update source map docs for 2016 #613
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,69 +3,109 @@ | |
Source Maps | ||
=========== | ||
|
||
In various browsers Sentry supports deminifying JavaScript via source | ||
maps. A source map is a file generated by your minifier which compresses a | ||
mapping of the minified file to the original uncompressed version(s). | ||
Sentry supports un-minifying JavaScript via `Source Maps | ||
<http://blog.getsentry.com/2015/10/29/debuggable-javascript-with-source-maps.html>`_. This lets you | ||
view source code context obtained from stack traces in their original untransformed form, which is | ||
is particularly useful for debugging minified code (e.g. UglifyJS), or transpiled code from a higher-level | ||
language (e.g. TypeScript, ES6). | ||
|
||
One important thing to note is that even though we support mapping files, | ||
a users browser may not actually be able to collect the required | ||
information for the server to generate a sourcemap. | ||
Generating a Source Map | ||
----------------------- | ||
|
||
Sentry requires the following to be able to map tracebacks to their source: | ||
Most modern JavaScript transpilers support source maps. Below are instructions for some common tools. | ||
|
||
* A source map header or footer | ||
* A publicly accessible uncompressed version of the source | ||
* A line of context that includes a line number, column number, and filename | ||
UglifyJS | ||
~~~~~~~~ | ||
|
||
The first two items are the responsibility of you, the end-user, and you | ||
can take care of publishing them as part of your build process. The latter | ||
however, with an individual line of context, is severely crippled in many | ||
browsers. | ||
UglifyJS is a popular tool for minifying your source code for production. It can dramatically | ||
reduce the size of your files by eliminating whitespace, rewriting variable names, removing dead code branches, | ||
and more. | ||
|
||
One thing to note is that Sentry will attempt to process the source map | ||
before storing (or grouping) an event. This ensures that if we are able to | ||
deminify the source, we'll be able to more effectively group similar | ||
events over time. | ||
If you are using UglifyJS to minify your source code, the following command will additionally generate a source map | ||
that maps the minified code back to the original source: | ||
|
||
Browser Support | ||
--------------- | ||
:: | ||
|
||
In our experiences, the only browser that routinely delivers usable error | ||
reports is **Google Chrome**. | ||
node_modules/uglify-js/bin/uglifyjs {input} \ | ||
--source-map-root={relroot}/ \ | ||
--source-map-url={name}.map.js \ | ||
--source-map={relpath}/{name}.map.js -o {output} | ||
|
||
For additional information, see this more up-to-date `wiki page | ||
<https://github.com/ryanseddon/source-map/wiki/Source-maps:-languages,-tools-and-other-info>`_. | ||
|
||
Generating a Source Map | ||
----------------------- | ||
Webpack | ||
~~~~~~~ | ||
|
||
While there are several compression libraries which support source maps, | ||
as of writing our recommendation is to use `UglifyJS | ||
<https://github.com/mishoo/UglifyJS2>`_. That said, many tools such as | ||
`webpack <http://webpack.github.io/>`_ and `browserify | ||
<http://browserify.org/>`_. | ||
Webpack is a powerful build tool that resolves and bundles your JavaScript modules into files fit for running in the | ||
browser. It also supports many different "loaders" which can convert higher-level languages like TypeScript and | ||
ES6/ES2015 into browser-compatible JavaScript. | ||
|
||
As an example, we can look at how we used to do things with Sentry (pre-webpack): | ||
Webpack can be configured to output source maps by editing webpack.config.js. | ||
|
||
:: | ||
|
||
node_modules/uglify-js/bin/uglifyjs {input} \ | ||
--source-map-root={relroot}/ \ | ||
--source-map-url={name}.map.js \ | ||
--source-map={relpath}/{name}.map.js -o {output} | ||
module.exports = { | ||
// ... other config above ... | ||
entry: { | ||
"app": "src/app.js" | ||
}, | ||
output: { | ||
path: path.join(__dirname, 'dist'), | ||
filename: "[name].js", | ||
sourceMapFilename: "[name].map.js", | ||
} | ||
}; | ||
|
||
We won't attempt to go into the complexities of source maps, so we | ||
recommend taking a stab at compiling them, and running them against a | ||
validator. | ||
Making Source Maps Available to Sentry | ||
-------------------------------------- | ||
|
||
Validating a Source Map | ||
----------------------- | ||
Source maps can be either: | ||
|
||
We maintain an online validation tool that can be used to test your source | ||
(and sourcemaps) against: `sourcemaps.io <http://sourcemaps.io>`_. | ||
1) Served publicly over HTTP alongside your source files. | ||
|
||
2) Uploaded directly to Sentry. | ||
|
||
Hosting Source Map Files | ||
~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
By default, Sentry will look for source map directives in your compiled JavaScript files, which are located | ||
on the last line and have the following format: | ||
|
||
.. code-block:: javascript | ||
|
||
//# sourceMappingURL: <url> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is wrong syntax. |
||
|
||
When Sentry encounters such a directive, it will resolve the source map URL relative the source file in which | ||
it is found, and attempt an HTTP request to fetch it. | ||
|
||
So for example if you have a minified JavaScript file located at ``http://example.org/js/app.min.js``. And in that file, | ||
on the last line, the following directive is found: | ||
|
||
.. code-block:: javascript | ||
|
||
//# sourceMappingURL: app.map.js | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wrong syntax |
||
|
||
Sentry will attempt to fetch ``app.map.js`` from http://example.org/js/app.map.js. | ||
|
||
Alternatively, during source map generation you can specify a fully qualified URL where your source maps are located: | ||
|
||
.. code-block:: javascript | ||
|
||
//# sourceMappingURL: http://example.org/js/app.map.js | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wrong syntax |
||
|
||
While making source maps available to Sentry from your servers is the easiest integration, it is not always advisable: | ||
|
||
* Sentry may not always be able to reach your servers. | ||
* If you do not specify versions in your asset URLs, there may be a version mismatch | ||
* The additional latency may mean that source mappings are not available for all errors. | ||
|
||
For these reasons, it is recommended to upload source maps to Sentry beforehand (see below). | ||
|
||
.. admonition:: Working Behind a Firewall | ||
|
||
While the recommended solution is to upload your source artifacts to Sentry, sometimes it’s necessary to allow communication from Sentry’s internal IPs. For more information on Sentry’s public IPs, :ref:`ip-ranges`. | ||
|
||
Uploading Source Maps to Sentry | ||
------------------------------- | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
In many cases your application may sit behind firewalls or you simply | ||
can't expose source code to the public. Sentry provides an abstraction | ||
|
@@ -105,7 +145,7 @@ sourcemaps point to. | |
|
||
When uploading the file, you'll need to reference it just as it would be referenced | ||
if a browser (or filesystem) had to resolve its path. So for example, if your sourcemap | ||
reference is just a relative path, it's relative to the location of the referencing file. | ||
reference is just a relative path, it's **relative to the location of the referencing file**. | ||
|
||
So for example, if you have ``http://example.com/app.min.js``, and the file contains the | ||
reference to ``app.map.js``, the name of the uploaded file should be ``http://example.com/app.map.js``. | ||
|
@@ -213,7 +253,7 @@ automatically uploaded to the release `2da95dfb052f477380608d59d32b4ab9` | |
in this case. If you want to use other extensions you can provide it with | ||
the ``--ext`` parameter. | ||
|
||
.. admonition:: Validating Sourcemaps | ||
.. admonition:: Validating Sourcemaps with Sentry CLI | ||
|
||
Unfortunately it can be quite challenging to ensure that sourcemaps | ||
are actually valid themselves and uploaded correctly. To ensure | ||
|
@@ -236,18 +276,22 @@ the ``--ext`` parameter. | |
|
||
.. sentry:edition:: hosted | ||
|
||
Working Behind a Firewall | ||
------------------------- | ||
|
||
While the recommended solution is to upload your source artifacts to | ||
Sentry, sometimes it's necessary to allow communication from Sentry's | ||
internal IPs. For more information on Sentry's public IPs, see :ref:`ip-ranges`. | ||
|
||
Troubleshooting | ||
--------------- | ||
|
||
Source maps can sometimes be tricky to get going. If you're having trouble, try the following tips. | ||
|
||
|
||
Verify your source maps are built correctly | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
We maintain an online validation tool that can be used to test your source | ||
(and sourcemaps) against: `sourcemaps.io <http://sourcemaps.io>`_. | ||
|
||
Alternatively, if you are using Sentry CLI to upload source maps to Sentry, you can use the `--validate` | ||
command line option to verify your source maps are correct. | ||
|
||
|
||
Verify sourceMappingURL is present | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd flip the order of these since we recommend uploading over us fetching them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather put a "recommended" tag by #2. I think #1 logically is the first thing to explain to someone, and it's far easier to set up.