electron-userland / electron-compile

DEPRECATED: Electron supporting package to compile JS and CSS in Electron applications
1.01k stars 99 forks source link

TypeScript with Babel option breaks without source maps configured correctly #284

Open BlakeWilliams opened 6 years ago

BlakeWilliams commented 6 years ago

I spent a decent amount of time this morning debugging how to get babel and typescript to play nicely with one another so I'll document my journey here in case that helps anyone wandering into this issue.

Original Problem

I wanted to use import _ from 'lodash' instead of import * as _ from 'lodash' in TypeScript. Using options like allowSyntheticDefaultImports did nothing, setting "module": "es6" failed to execute in the Electron window throwing an error about an "invalid token import".

I tried many combinations of settings and then came upon the babel option for TypeScript while source diving here: https://github.com/electron-userland/electron-compilers/blob/master/src/js/typescript.js#L80 and here: https://github.com/electron-userland/electron-compilers/blob/master/src/js/typescript.js#L12

The Source Map Problem

After enabling the babel option (with true as it's value before I realized it was for the compiler options) I kept getting the following error:

Uncaught TypeError: Cannot read property 'apply' of null

Which comes from the following line: https://github.com/electron-userland/electron-compilers/blob/master/src/js/typescript.js#L107

This happens because Sorcery checks isOriginalSource which evaluates to true seemingly if babel does not create a separate (non-inline) source map. Relevant code here: https://github.com/Rich-Harris/sorcery/blob/master/src/index.js#L16

The Solution

To fix the problem and get the behavior I desired I ended up with a .compilerc as follows:

{
  "text/typescript": {
    "babel": {
      "presets": [
        "latest",
        "react"
      ],
      "sourceMaps": "both"
    },
    "jsx": "react",
    "module": "es6",
    "sourceMap": true
  }
}

Setting sourceMaps to "both" in the Babel config fixes the compile error and creates source maps for the Babel output but not your original TypeScript file. To get a source map for the original TypeScript file you have to set typescript's sourceMap compiler option to true (again, not inline, and this does make sense).

Next Steps

There's seemingly a lack of documentation on how to configure TypeScript. If there's a decent place to start documenting some of these quirks and usage I'd be happy to write down the information somewhere.

As for the error, I think it could be useful to raise our own error when Babel and/or TypeScript are missing source maps before calling Sorcery.