Debugging TypeScript Source Files? #240

joewood opened this Issue May 31, 2016 · 17 comments


None yet

8 participants

joewood commented May 31, 2016

The source map issue has been discussed in the React Native repo a fair bit. The RN packager seems to consume source maps with a custom Transformer see here. My question is, is it possible to set-up the VS Code Extension so that TypeScript source files can be used through the debugger (e.g. set breakpoints etc.)?

If this is possible, could you describe what source map settings need to be used (e.g. inline source maps etc..)?

I'm using 0.1.4 of the React Native Extension with VS code 1.1.1.


@joewood we don't currently have a solution for this, we'll need to spend some time looking at it. Currently the team is busy with some non-related work, we'll add this to our backlog and get back to it when we can.

joewood commented Jun 1, 2016

Thanks for the response. It may be necessary to use a custom transformer for TypeScript. I'll keep investigating and post anything I find here.

joewood commented Jun 3, 2016 edited

Hi @hamiltonia
I've had some limited success in getting this to work. The approach I'm looking at is to replace the react-native transformer with a version that supplies the babel option inputSourceMap. I patched the transform.js file from RN's packager in two places, one to set the option for Babel and the other to read in the map file:

 * Copyright (c) 2015-present, Facebook, Inc.
'use strict';

const babel = require('babel-core');
const externalHelpersPlugin = require('babel-plugin-external-helpers');
const fs = require('fs');
const makeHMRConfig = require('babel-preset-react-native/configs/hmr');
const resolvePlugins = require('babel-preset-react-native/lib/resolvePlugins');
const inlineRequiresPlugin = require('fbjs-scripts/babel-6/inline-requires');
const json5 = require('json5');
const path = require('path');

const getBabelRC = (function () {
  let babelRC = null;

  return function _getBabelRC(projectRoots) {
    if (babelRC !== null) {
      return babelRC;

    babelRC = { plugins: [] }; // empty babelrc

    let projectBabelRCPath;
    if (projectRoots && projectRoots.length > 0) {
      projectBabelRCPath = path.resolve(projectRoots[0], '.babelrc');

    if (!projectBabelRCPath || !fs.existsSync(projectBabelRCPath)) {
      babelRC = json5.parse(
          path.resolve(__dirname, 'node_modules/react-native/packager/react-packager', 'rn-babelrc.json'))

      // Require the babel-preset's listed in the default babel config
      babelRC.presets = => require('babel-preset-' + preset));
      babelRC.plugins = resolvePlugins(babelRC.plugins);

    return babelRC;

 * Given a filename and options, build a Babel
 * config object with the appropriate plugins.
function buildBabelConfig(filename, options) {
  const babelRC = getBabelRC(options.projectRoots);

  const extraConfig = {
    sourceFileName: filename,
    inputSourceMap: options.inputSourceMap
  let config = Object.assign({}, babelRC, extraConfig);

  // Add extra plugins
  const extraPlugins = [externalHelpersPlugin];

  var inlineRequires = options.inlineRequires;
  var blacklist = inlineRequires && inlineRequires.blacklist;
  if (inlineRequires && !(blacklist && filename in blacklist)) {

  config.plugins = extraPlugins.concat(config.plugins);

  if ( {
    const hmrConfig = makeHMRConfig(options, filename);
    config = Object.assign({}, config, hmrConfig);

  return Object.assign({}, babelRC, config);

function transform(src, filename, options) {
  options = options || {};

  const babelConfig = buildBabelConfig(filename, options);

  const result = babel.transform(src, babelConfig);

  return {
    ast: result.ast,
    code: result.code,
    filename: filename,

module.exports = function (data, callback) {
  if (fs.existsSync(data.filename + ".map")) {
    console.log("Adding Map for " + data.filename);
    data.options = data.options || {};
    data.options.inputSourceMap = JSON.parse(fs.readFileSync(data.filename + ".map").toString());
    data.options.sourceMaps = true;
  let result;
  try {
    result = transform(data.sourceCode, data.filename, data.options);
  } catch (e) {

  callback(null, result);

// export for use in jest
module.exports.transform = transform;

All this is doing is sending the mapfile data to babel if it exists as a file (bit of an assumption, but this is just for testing). I can use this transform with VSCode if I change the RN Native Extension's Packager.start function. I simply add the arguments for the command line:

    .then(function () {
        var args = ["--port", Packager.PORT,"--transformer","c:\\code\\app\\transform.js"];
        var childEnvForDebugging = Object.assign({}, process.env, { REACT_DEBUGGER: "echo A debugger is not needed: " });

Note, there's a bug in RN where the transform module needs to specified with a full path.

This all seems to work OK, in that when I browse to look at the .map file in the browser the TypeScript source files are referenced correctly. However, the problem is that VSCode doesn't seem to be picking them up and loading the source files. Injecting a "debugger" statement just opens up the main bundle file. I've tried using sourceRoot and relative paths, but without success. So, it seems to be failing at the last step.

Any suggestions would be appreciated. Thanks.

joewood commented Jun 3, 2016

FYI - I tried debugging in DevTools, but I see the error "Failed to Parse SourceMap". However, this error could be related to the Chrome 51 bug logged here:

frogcjn commented Jun 4, 2016

So recently we cannot debug in typescript?

frogcjn commented Jun 5, 2016 edited

Here is my post to explain how to deal with this debugger problem with typescript:

Also refer to these two issues

frogcjn commented Jun 7, 2016

I have make some progress on debugging typescript in vscode
2016-06-07 16 43 04

frogcjn commented Jun 7, 2016

Success! I'll write a post to explain how to debug typescript file with react native in vscode.
2016-06-07 19 31 45

frogcjn commented Jun 9, 2016 edited


Here is my post to explain how to debug ReactNative project in VSCode with typescript:


Thanks a lot for looking into that and providing a detailed explanation @frogcjn!
We've been a bit busy on other projects so we haven't had a chance to look over your PR closely yet, but we'll try to get to that soon. We definitely want to get this working.


Thanks to @frogcjn for his PR implementing this: #259

Support will be in the next release.

@alfonsogarciacaro alfonsogarciacaro referenced this issue in fable-compiler/fable-react_native-demo Aug 6, 2016

Load core-js polyfill #5

forki commented Aug 6, 2016

when will we see the next release?



While you wait for the official release, you can check out this repo and build it yourself.

forki commented Aug 9, 2016

Thanks that's good enough for me. I'm way to deep down the wrong rabbit
hole already ;-)

On Aug 9, 2016 8:07 PM, "Jimmy Thomson" wrote:


While you wait for the official release, you can check out this repo and
build it yourself.

You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#240 (comment),
or mute the thread

mbraude commented Aug 23, 2016

Thanks @joewood - this change is in the repo and will go out in the next release.

@mbraude mbraude closed this Aug 23, 2016
Flavien commented Dec 23, 2016

I'm still struggling to get breakpoints to light up in VS Code with TypeScript on a react-native project. I followed the instructions and set sourceMap to true in .babelrc.

Am I missing something?


@Flavien, what instructions are you referring to? Could you please describe exact steps you have tried?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment