Sentry is a widely used error monitoring platform that tracks bugs or errors happening in a variety of applications. Among other pieces of information, it captures error stack traces which are essential for developers to figure out the source of the issue.
The code obfuscation makes your error stack traces very difficult for your developers to understand where the bug comes from. Thus, we can take advantage of Jscrambler source maps and Sentry's source-map upload feature to make stack traces readable.
This page explains how to upload Jscrambler source maps to the Sentry platform using a React application.
For the purposes of this tutorial, we will be using a create-react-app
boilerplate app.
npx create-react-app my-app
cd my-app
For further information check the create-react-app Getting Started Guide.
If you haven't tried Jscrambler out before reading this tutorial, please consider reading the Getting Started Guide which will walk you through the steps on how to protect your application. This will make this section easier to grasp. It will also teach you how to configure Jscrambler and use a custom configuration.
To complete the integration with Jscrambler, you need a JSON configuration file with your API credentials, application ID, and protection configuration. You may create your transformations recipe using Jscrambler Web application and download a JSON configuration file or use the following example for a quick test. This file should be named .jscramblerrc
and placed in the project's root folder. If you choose to try the following example, just make sure to fill in the missing information: accessKey
, secretKey
and applicationId
.
{
"keys": {
"accessKey": <ACCESS_KEY_HERE>,
"secretKey": <SECRET_KEY_HERE>
},
"applicationId": <APP_ID_HERE>,
"filesSrc": [
"./build/**/*.html",
"./build/**/*.js",
"./build/**/*.js.map"
],
"cwd": "./build",
"filesDest": "./build",
"params": [
{
"name": "objectPropertiesSparsing"
},
{
"name": "variableMasking"
},
{
"name": "whitespaceRemoval"
},
{
"name": "dotToBracketNotation"
},
{
"name": "stringConcealing"
},
{
"name": "functionReordering"
},
{
"name": "propertyKeysObfuscation",
"options": {
"encoding": [
"hexadecimal"
]
}
},
{
"name": "regexObfuscation"
},
{
"name": "controlFlowFlattening",
"options": {
"features": [
"opaqueSteps"
]
}
},
{
"name": "booleanToAnything"
},
{
"name": "identifiersRenaming"
},
{
"name": "globalVariableIndirection"
}
],
"areSubscribersOrdered": false,
"useRecommendedOrder": true,
"sourceMaps": true,
"jscramblerVersion": "stable"
}
You can also change filesSrc
to match the files you need/want to protect. For our example — and all React apps — we recommend protecting the .html
and .js
files. Certainly, with a better understanding of the project, you may identify what’s critical and essential to protect.
Notice that the filesSrc
also includes the source-maps ("./build/**/*.js.map"
) generated by the create-react-app tool which tells Jscrambler engine that a previous transformation (f.e. bundling) already take place and should be taken in account.
By using filesDest: './build'
and cwd: build
, the files we send to protect will be overwritten by their protected version using build
as the working directory.
The sourceMaps: true
instructs Jscrambler to produce source maps for this application.
You can integrate Jscrambler into the React build process with the CLI.
Install the Jscrambler API Client:
npm install jscrambler --save-dev
Create a CLI hook in the scripts section of package.json
. The section should look like this:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build && jscrambler",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
The "build": "react-scripts build && jscrambler"
hook will trigger the jscrambler
command after the build process is finished.
Jscrambler is now integrated into your build process and the protected production files will be placed on build/static/
.
Sentry's account is mandatory
Log into your Sentry account, create (if you don't already have one) a project and follow the set up instructions.
In case of an React Application, you should:
@sentry/react
dependencynpm install @sentry/react --save
src/index.js
file:import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
// ADD import sentry
import * as Sentry from '@sentry/react';
// ADD initialize Sentry
Sentry.init({
// <DSN_URL> can be found in the project settings on the Client Keys (DSN) section
dsn: "https://<DSN_URL>",
});
// rest of the code
@sentry/wizard
## When asked for "Which framework, bundler or build tool are you using?" select "Create React App"
## When asked for "Where are your build artifacts located?" type "build"
## When asked for "Do you want to automatically run the sentry:sourcemaps script after each production build?" select "No"
npx @sentry/wizard@latest -i sourcemaps
To produce an intentional error event on Sentry, please add the following button to the file src/App.js
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
{/* add next line */}
<button onClick={(e) => e.methodDoesNotExist()}>Break the world</button>
Build the application:
npm run build
Use Jscrambler api client to download the corresponding source maps for a specific protection.
The
protection-id
is printed on the console as the last entry after thenpm run build
script run successfully (f.e. 64cbb11def19a471ff6df88c)
jscrambler -m <protection id> -o ./
On the project root, you should see a folder called jscramblerSourceMaps
containing the generated source-maps.
Now, we updated the application source-maps with Jscrambler ones
cp -r jscramblerSourceMaps/* build
Run the sentry:sourcemaps
script
npm run sentry:sourcemaps
On the Source Map Upload Report
you should be able to see what was uploaded to the Sentry platform
Finally, we can run our application by spinning a web server pointing to the build
folder. You can use server
by typing:
npm i -g serve
serve -s build
Open a browser and navigate to the address allocated by the serve
tool (f.e. http://localhost:3000).
Once the page is loaded, hit on the Break the world
button, and you should see an error displayed on the browser's console.
Now, let's check the Sentry Issues page and you should see the error event we just triggered.
Navigate to the details of the error event, and in the Stack Trace section, you will see where the error occurred in the original source code.
Thanks to Jscrambler Source-maps and Sentry, your development team can quickly identify the bugs and errors that happened in your application.