ds300/react-native-typescript-transformer

Source map line number is shifted

henrikra opened this issue · 20 comments

This produces at least on Android

I am generating source maps but adding extra packager args in my build.gradle like this

project.ext.react = [
    extraPackagerArgs: isCiBuilding
        ? ["--sourcemap-output", "pathtoMyFolder/index.android.bundle.map"]
        : []
]

After that I just upload that source map file to Bugsnag which is my crashreporter. The crash gives me right file .tsx extension but the line is wrong.

Can you help me to solve this? How to start debugging this? Do I have to pass some arguments to transformer or something?

ds300 commented

It should Just Work, so maybe there are some issues.

  1. Are the lines correct at dev time?
  2. Which versions of everything are you running?
  1. If I put debug mode to ON when running my app and look sources in Chrome debugger tools yeah they are correct. Even breakpoints work
  • TypeScript 2.7.1
  • react-native-typescript-transformer 1.2.3
  • React native 0.51.0
ds300 commented

Ahaa! Can you link me info that was related to this fix on RN 52? :D

ds300 commented

#11

tldr react-native used to have a spot in the production build pipeline where input source maps were ignored. That issue was resolved as a side effect of a big refactoring effort which landed in 0.52.

I have now upgraded to RN 0.52.2 and still the lines are off.

I am able to reproduce this locally now. Here is my process:

  1. Add some crash to the app that happens on button press
  2. Build app for Android in release mode
  3. Upload source maps to Bugsnag that were just generated by react-native bundle command
  4. Start the app and make it crash
  5. Find new crash on Bugsnag
  6. Notice source maps have been added successfully but the line is wrong ❌

Do you have ideas that I could try? Can I somehow validate the source map file? I have looked into it but it doesn't mean anything to me atm 🙉 How the source map file should look like? How can I validate it is correct?

Btw is this related: facebook/metro#104

@ds300 Do you have any ideas?

ds300 commented

I can't think of anything that you could do that might solve the problem in 'userland'. If the source maps line up during development but not in production releases, then it's probably the case that metro is still doing some mangling that ignores or misuses input source maps. Last time it was the constant folding and function inlining step. It would take some debugging to figure out where it's happening now. Maybe there's something this package can do to mitigate the issue without touching Metro.

Is there any solution for this problem?

ds300 commented

Sorry I haven't looked into this issue

For the record, I’m having no problems with source maps in production on react native 0.54.

Hmm, I have, and waiting patiently for the solution. React 0.55.4

Hmm could it be that I am also using ignite-ignore-reactotron plugin in production builds. @skellock

I try to avoid plugins like that. They rewrite code in a way that is pretty hard to trace. I’m basking in the irony of that advice since I wrote that lib.

You could rule out that by triggering a crash in a file that does have any console.tron statements (or anything else that might get man-handled by it).

I’ll post my relevent configs once I get back to my desk.

Truth be told, they’re pretty vanilla. The only babel shenanigans I’m up to is the one that injects environment vars.

Config

Here's the relevant snippets from what I'm using.

package.json
{
  "dependencies": {
    "appcenter": "1.4.0",
    "appcenter-crashes": "1.4.0",
    "react-native": "0.54.2",
  },
  "devDependencies": {
    "babel-plugin-transform-inline-environment-variables": "^0.3.0",
    "babel-preset-react-native": "4.0.0",
    "react-native-typescript-transformer": "^1.2.5",
    "tslint": "5.10.0",
    "tslint-config-prettier": "1.12.0",
    "typescript": "2.8.3"
  }
}
tsconfig.json
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "jsx": "react-native",
    "module": "es2015",
    "moduleResolution": "node",
    "noImplicitAny": false,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "allowJs": false,
    "target": "es2015",
    "sourceMap": true,
    "noImplicitReturns": true
  },
  "include": ["src", "test", "storybook"],
  "exclude": ["node_modules"]
}
rn-cli.config.js
module.exports = {
  getTransformModulePath() {
    return require.resolve("react-native-typescript-transformer")
  },
  getSourceExts() {
    return ["ts", "tsx"]
  },
}
babel.rc
{
  "presets": ["react-native"],
  "env": {
    "production": {}
  },
  "plugins": [
    [
      "transform-inline-environment-variables",
      {
        "include": []
      }
    ]
  ]
}

Crash In Action

App Center sample crash (see frame 2) image
Code that crashed image

I have put this comment on other issue (#11) but seems that one is closed. Since this one is related so putting it here.

I have tried to test this issue with new version of React Native and I am still able to reproduce it on both android and iOS. I have forked https://github.com/hffmnn/react-native-typescript-starter which is itself a fork of https://github.com/cbrevik/react-native-typescript-starter.

My changes just include changing various versions of dependencies in package.json

So here are the steps

git clone https://github.com/ankitmittal000/react-native-typescript-starter.git
cd react-native-typescript-starter
git checkout --track origin/feature/ts_map_with_new_version
yarn
yarn bundle:ios:release
yarn bundle:android:release

Once you get the bundle generated using above commands, you run the respective android and iOS projects.

For Android project

You will get the following exception which is right

 com.facebook.react.common.JavascriptException: undefined is not an object (evaluating '(void 0).value'), stack:
                                                                       <unknown>@346:460
                                                                       <unknown>@61:2003
                                                                       y@61:1110
                                                                       callTimers@61:3501
                                                                       value@27:4401
                                                                       <unknown>@27:1151
                                                                       value@27:3828
                                                                       value@27:1123

When you try

./symbolicate.js android/main.jsbundle.map 346 460

it will give you

/react_native/react-native-typescript-starter/src/index.tsx:20:10

However this is wrong. The correct result should be

/react_native/react-native-typescript-starter/src/index.tsx:22:10

For iPhone

When you run the app on iPhone you will get the following

typescriptStarter[81082:2398433] *** Terminating app due to uncaught exception 'RCTFatalException: Unhandled JS Exception: undefined is not an object (evaluating '(void 0).value')', reason: 'Unhandled JS Exception: undefined is not an object (evaluating '(void 0).va..., stack:
<unknown>@349:437
y@61:1110
callTimers@61:3501
value@27:4290
<unknown>@27:1040
value@27:3717
value@27:1012

When you try

./symbolicate.js ios/main.jsbundle.map 349 437

you get the following

/react_native/react-native-typescript-starter/src/index.tsx:18:0

However this is wrong. The correct result should be

/react_native/react-native-typescript-starter/src/index.tsx:22:10

Its worth mentioning here that the results generated with bundle using --dev true are correct. The issue reproduces only with --dev false.

From the other comments, it looks like this issue is resolved. Could somebody point to me where am I going wrong?
Thanks for the help.

Still having this problem like @ankitmittal000 What is this ./symbolicate.js located at? With that I can test source maps?

@henrikra Any resolution/workaround on this issue?

mbret commented

For some reason our app has the same issue. The sourcemaps when using debug remotely on chrome are ok but when debug remotely is turned off they are broken. Updating to 0.59 did not solve it.

the sourcemaps were also broken when using this package for jest and switching to ts-jest fixed that.

Still having this problem like @ankitmittal000 What is this ./symbolicate.js located at? With that I can test source maps?

I found one in metro-symbolicate. And was able to symbolicate my source maps. With it, you'll be able to verify if the source map is pointing back to the correct lines or not.

$ yarn add -D metro-symbolicate
$ npx metro-symbolicate ./index.map 346 460
../../node_modules/metro/src/lib/polyfills/require.js:412:<global>

Don't mind the output. That's a local test I did that doesn't match the code on previous comments.