title: Sourcemapping TypeScript in Karma
body: <p>I'm trying to set up a build process for TypeScript using Webpack. Everything's working fine for most parts. However I can't get source-maps to work properly in the Karma test runner.</p>
  
  <h1>Problem description</h1>
  
  <p>Let's say I have a typescript file <code>test.spec.ts</code> (1). This file is transpiled by TypeScript to some ES5 source with inline source-maps (2). Finally that ES5 source is bundled by Webpack 4 using <em>eval-source-maps</em> (3) and served to Chrome by the Karma test runner.</p>
  
  <p>By inspecting sources in the Karma Debug Runner in Chrome I can see that all three stages of transpilation are actually available to the browser:</p>
  
  <ul>
  <li>(1) is source-mapped as <code>webpack://test.spec.ts?c161</code></li>
  <li>(2) is source-mapped as <code>webpack-internal://test.spec.ts</code></li>
  <li>(3) is available as <code>localhost:9876/base/test.spec.ts</code></li>
  </ul>
  
  <p>In the Chrome console I also get proper stack traces for all errors thrown during test execution. These include line numbers source-mapped to (1) as I would expect. For example:</p>
  
  <pre><code>Error: Oh no!
      at Function.MyClass.myBadMethod (test.spec.ts?c161:9)
      at UserContext.eval (test.spec.ts?c161:21)
      at &lt;Jasmine&gt;
  </code></pre>
  
  <p>However Karma itself logs errors with line numbers only source-mapped to (2). For example:</p>
  
  <pre><code>Error: Oh no!
      at Function.MyClass.myBadMethod (webpack-internal:///./src/test.spec.ts:8:15)
      at UserContext.eval (webpack-internal:///./src/test.spec.ts:17:17)
      at &lt;Jasmine&gt;
  </code></pre>
  
  <p>This is totally unhelpful, since (2) is just some intermediary source and never even written to disk. In fact I don't need source-maps for (2) and don't understand why they are included in the first place. If possible I would like to try and disable them (while keeping proper source-maps for (1), of course).</p>
  
  <p>Anyways, the important thing is to get Karma to report stack traces with line numbers relative to the original files, just as it is done in the Chrome console. If necessary I'm also willing to trade execution speed for that</p>
  
  <p>If you can't think of a full-fledged solution, but have some insights into TypeScript / TS-Loader / Webpack / Karma-Webpack / Karma: I'm also interested in any arguments that help pinpoint the problem along that toolchain.</p>
  
  <h1>Minimal test configuration</h1>
  
  <h2>devDependencies from <code>package.json</code></h2>
  
  <pre><code>"devDependencies": {
      "@types/jasmine": "~2.8.7",
      "jasmine": "~3.1.0",
      "karma": "~2.0.2",
      "karma-chrome-launcher": "~2.2.0",
      "karma-jasmine": "~1.1.2",
      "karma-webpack": "~3.0.0",
      "ts-loader": "~4.3.0",
      "typescript": "~2.8.3",
      "webpack": "~4.8.3"
  }
  </code></pre>
  
  <h2><code>karma.conf.js</code></h2>
  
  <pre><code>module.exports = function(config) {
      config.set({
          frameworks: ['jasmine'],
          browsers: ['Chrome'],
          files: [
              './test.spec.ts'
          ],
          mime: {
              'text/x-typescript': ['ts']
          },
          preprocessors: {
              '**/*.ts': ['webpack']
          },
          plugins: [
              'karma-chrome-launcher',
              'karma-jasmine',
              'karma-webpack'
          ],
          webpack: {
              devtool: 'eval-source-map',
              mode: 'development',
              module: {
                  rules: [
                      {
                          test: /\.ts$/,
                          loader: 'ts-loader',
                      }
                  ]
              },
              resolve: {
                  extensions: [ '.ts' ]
              }
          },
          webpackMiddleware: {
              logLevel: 'error'
          }
      });
  };
  </code></pre>
  
  <h2><code>tsconfig.json</code></h2>
  
  <pre><code>{
      "compileOnSave": false,
      "compilerOptions": {
          "module": "es2015",
          "moduleResolution": "node",
          "sourceMap": true,
          "target": "es5",
          "types": [
          "jasmine"
          ]
      }
  }
  </code></pre>