Skip to content

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

Merged
merged 4 commits into from
Jun 20, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 97 additions & 53 deletions docs/sourcemaps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Contributor

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.

Copy link
Contributor Author

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.


2) Uploaded directly to Sentry (**recommended**).

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>

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

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

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
Expand Down Expand Up @@ -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``.
Expand Down Expand Up @@ -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
Expand All @@ -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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down