Coder Social home page Coder Social logo

araratispiroglu / react-native-source-maps Goto Github PK

View Code? Open in Web Editor NEW

This project forked from philipshurpik/react-native-source-maps

0.0 1.0 0.0 6 KB

Utilities to easily add support of Source Maps to your React Native project

JavaScript 100.00%

react-native-source-maps's Introduction

react-native-source-maps

Utilities to quickly add support of source-maps to your React Native project

As you probably already now, React Native minifies release code. It's perfect for bundle size and execution speed. But it can become a real pain to find production bug in such code.

For example error stack trace in your logging system can look like that:

0:file:///var/containers/Bundle/Application/B2C0D7FF-6CA3-4298-BDBF-10285CD4D88D/Debitoor.app/main.jsbundle:947:1763
1:u@file:///var/containers/Bundle/Application/B2C0D7FF-6CA3-4298-BDBF-10285CD4D88D/Debitoor.app/main.jsbundle:199:137
2:file:///var/containers/Bundle/Application/B2C0D7FF-6CA3-4298-BDBF-10285CD4D88D/Debitoor.app/main.jsbundle:199:891
...

And.... It's useless just to know about an error without a possibility to find it in the exact place of code. So we need source maps. By using source maps, we can map the code being executed to the original code source files, making fixing bug much, much easier.

To make it look like this:

0:file:///var/containers/Bundle/Application/B2C0D7FF-6CA3-4298-BDBF-10285CD4D88D/Debitoor.app/main.jsbundle:947:1763
1:u@file:///var/containers/Bundle/Application/B2C0D7FF-6CA3-4298-BDBF-10285CD4D88D/Debitoor.app/main.jsbundle:199:137
2:file:///var/containers/Bundle/Application/B2C0D7FF-6CA3-4298-BDBF-10285CD4D88D/Debitoor.app/main.jsbundle:199:891
...

Firstly I'd like to mention that React Native CLI has a flag to build source maps alongside with JS code bundle.

How can we do this?


Usage:

1. We need to modify how we JS code is bundled

For example, originally iOS builds use this packager script: ./node_modules/react-native/packager/react-native-xcode.sh Which call React Native CLI bundle command this way:

$NODE_BINARY "$REACT_NATIVE_DIR/local-cli/cli.js" bundle \
  --entry-file "$ENTRY_FILE" \
  --platform ios \
  --dev $DEV \
  --reset-cache \
  --bundle-output "$BUNDLE_FILE" \
  --assets-dest "$DEST"

We need to modify this script and add one line:

  --sourcemap-output "$BUNDLE_FILE.map"

It can be done with simple patching of this file in npm postinstall script. Or creating custom bundle script.

For Android builds, add this line to the build.gradle under app module to make js bundle name same with iOS build:

project.ext.react = [
    bundleAssetName: "main.jsbundle",
]

Then edit Android packager script: ./node_modules/react-native/react.gradle

and you need to add "--sourcemap-output" and bundle map file parameter to the build script,

def jsBundleMapFile = "${jsBundleFile}.map"
"--sourcemap-output", jsBundleMapFile

for example:

def jsBundleMapFile = "${jsBundleFile}.map"

def devEnabled = !targetName.toLowerCase().contains("release")
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
    commandLine("cmd", "/c", *nodeExecutableAndArgs, "node_modules/react-native/local-cli/cli.js", "bundle", "--platform", "android", "--dev", "${devEnabled}",
            "--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, "--sourcemap-output", jsBundleMapFile, *extraPackagerArgs)
} else {
    commandLine(*nodeExecutableAndArgs, "node_modules/react-native/local-cli/cli.js", "bundle", "--platform", "android", "--dev", "${devEnabled}",
            "--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, "--sourcemap-output", jsBundleMapFile, *extraPackagerArgs)
}
2. Install react-native-source-maps module

This module was built to map minified sources to original JS files. And to solve our pain to find actual place where an error occurred.

npm i react-native-source-maps

3. Initialize module at the app start with options
import {initSourceMaps} from 'react-native-source-maps';
initSourceMaps({sourceMapBundle: "main.jsbundle.map"});
4. Use it with your logging utilities to replace minified error stack with original

Example:

const stack = !__DEV__ && await getStackTrace(error);
if (stack) {
    error.stack = stack;
}
log.error({message: 'Error (' + error.message + ')', error});
5. Caught all uncaught errors in app by adding global error handler
import log from "../log";
import {getStackTrace} from 'react-native-source-maps';
import ErrorUtils from "ErrorUtils";

(async function initUncaughtErrorHandler() {
    const defaultGlobalHandler = ErrorUtils.getGlobalHandler();

    ErrorUtils.setGlobalHandler(async(error, isFatal) => {
        try {
            if (!__DEV__) {
                error.stack = await getStackTrace(error);
            }
            log.error({message: 'Uncaught error (' + error.message + ')', error, isFatal});
        }
        catch (error) {
            log.error({message: 'Unable to setup global handler', error});
        }

        if (__DEV__ && defaultGlobalHandler) {
            defaultGlobalHandler(error, isFatal);
        }
    });
})();

API:

Property Type Description Default value
sourceMapBundle string source map bundle, for example "main.jsbundle.map" undefined (Required)
collapseInLine bool Will collapse all stack trace in one line, otherwise return lines array false
projectPath string project path to remove from files path index undefined (Optional)

react-native-source-maps's People

Contributors

philipshurpik avatar

Watchers

Ararat Ispiroglu avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.