Integrating Jscrambler with React Native

Last updated: 09 May 2019

Framework versions tested: 0.57.1 ● 0.59

Github: React Native repository

Introduction

React Native is a React-based open-source mobile application framework developed by Facebook. Applications built with React Native look and feel native because they use the same controls that other native applications use, instead of HTML/CSS simulations in embedded web pages.

The purpose of this document is to explain how to integrate Jscrambler with React Native. The approach presented in this document is not guaranteed to keep working in future versions.

This document assumes you already have some knowledge of the framework and how to build a project. Still, if you have any doubt please read this official getting started guide. The React Native guide suggests two approaches: one based on the Expo CLI, recommended for programmers with a web background, and one based on the React Native CLI, recommended for programmers with a native development background. Our suggested approach to integrate Jscrambler with your build process only works with the React Native CLI, so this page also explains how to migrate out of Expo.

The Example

We adapted React Native Grocery List App, which is an example of a simple React Native application prepared with React-Native CLI. In this guide, we explain how to add Jscrambler support to Grocery List App.

Expo Eject

The approach presented in this guide does not work with Expo, so if your project makes use of Expo Cli, please run:

# expo eject will ask a few questions
expo eject

After this process, the application no longer depends on Expo, and we are ready to integrate Jscrambler

Integrating Jscrambler in the build process

You can integrate Jscrambler into the React-Native build process with Metro.

Configure Jscrambler

Create a .jscramblerrc file on the project's root folder.

Select the desired configuration. To do it quickly, visit the Jscrambler Web App and create a new app. In the Application Modes tab, select the Language Specifications and application type. Select the transformations you want (check the Templates and Fine-Tuning tabs). In this tutorial, we used the Obfuscation template. For further help, see our guide.

Download the JSON config file.

Download Jscrambler JSON

Open jscrambler.json and copy all its contents to .jscramblerrc. Your final .jscramblerrc file should look like this:

{
 "keys": {
   "accessKey": <ACCESS_KEY_HERE>,
   "secretKey": <SECRET_KEY_HERE>
 },
 "applicationId": <APP_ID_HERE>,
 "params": [
   {
     "name": "whitespaceRemoval"
   },
   {
     "name": "identifiersRenaming",
     "options": {
       "mode": "SAFEST"
     }
   },
   {
     "name": "dotToBracketNotation"
   },
   {
     "name": "deadCodeInjection"
   },
   {
     "name": "stringConcealing"
   },
   {
     "name": "functionReordering"
   },
   {
     "options": {
       "freq": 1,
       "features": [
         "opaqueFunctions"
       ]
     },
     "name": "functionOutlining"
   },
   {
     "name": "propertyKeysObfuscation"
   },
   {
     "name": "regexObfuscation"
   },
   {
     "name": "booleanToAnything"
   }
 ],
 "areSubscribersOrdered": false,
 "applicationTypes": {
   "webBrowserApp": true,
   "desktopApp": false,
   "serverApp": false,
   "hybridMobileApp": false,
   "javascriptNativeApp": false,
   "html5GameApp": false
 },
 "languageSpecifications": {
   "es5": true,
   "es6": false,
   "es7": false
 },
 "useRecommendedOrder": true
}

Integrating Jscrambler via Metro

Installing the Jscrambler Metro Plugin:

npm install jscrambler-metro-plugin --save-dev

Create a metro.config.js file on the project's root folder.

const jscramblerMetroPlugin = require('jscrambler-metro-plugin')();

module.exports = jscramblerMetroPlugin;

Build the application:

# installDebug requires an attached android device or emulator
# otherwise you can use assembleDebug

cd android && ./gradlew installDebug

or

# generate JavaScript bundle
react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ios/main.jsbundle --assets-dest ios

# install and run your code with Xcode

This will create the mobile application package for android (apk) or ios (ipa) on <android|ios>/app/build/outputs/<apk!ipa>/debug.

Known Problems

Custom Callbacks may not be triggered

We recommend that custom callbacks are placed on the project's entry file (usually, index.js file), attached to the window global object:

window.myCustomCallback = () => {
    alert('Custom Callback called!');
};

// My Code

Depending on dependency load graph, the custom callback might not be defined or called. Please make sure that custom callback is in fact being triggered, before releasing your mobile application.

Some or all of my annotations are not working

Metro removes all comments before Jscrambler has even a chance of processing the code (this can be turned off but due to a Metro Configuration issue, it is not possible at this time), so instead string annotations should be used.

This may be insufficient, as the minifier used by Metro also removes strings that appear to be unused (Dead Code), meaning that only string annotations that appear at the top of each function or file are preserved. The solution is to disable the metro minifier, since Jscrambler itself is capable of minifying code. At metro.config.js, add or modify the existing exports to include the following:

module.exports = {
  transformer: {
    minifierPath: require('path').resolve('./dummy-minification')
  }
};

Additionally, create a dummy-minification.js file at the root of the project with the following:

module.exports = {
  withSourceMap: (code, map, filename, options) => ({ code, map })
};

Metro should now preserve string annotations.

OS Lock doesn't work with Mobile OS (Android/IOS)

React-Native by default, don't expose a global API to get information about the Operating System and Device. It requires the import of Platform module.

Resources