最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to configure karma so typescript source files would be debuggable - Stack Overflow

programmeradmin0浏览0评论

I've downloaded a seed project Angular2 Webpack Starter and got it up and running without an issue. One inconvenience that I have with it is debugging source files under unit tests. All *.spec.ts files are loaded into browser and debugable so map files are generated for them at least. When I step into a source file under test I get something like this:

karma config:

module.exports = function(config) {
var testWebpackConfig = require('./webpack.test.js');

config.set({
    basePath: '',
    frameworks: ['jasmine'],
    exclude: [ ],
    files: [ { pattern: './config/spec-bundle.js', watched: false } ],
    preprocessors: { './config/spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] },
    webpack: testWebpackConfig,
    coverageReporter: {
      dir : 'coverage/',
      reporters: [
        { type: 'text-summary' },
        { type: 'json' },
        { type: 'html' }
      ]
    },
webpackServer: { noInfo: true },
reporters: [ 'mocha', 'coverage' ],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: [
  'Chrome'
],
singleRun: false
});
};

webpack.test.js:

const helpers = require('./helpers');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const ENV = process.env.ENV = process.env.NODE_ENV = 'test';
module.exports = {
    devtool: 'inline-source-map',
    resolve: {
        extensions: ['', '.ts', '.js'],
        root: helpers.root('src'),
    },
    module: {
    preLoaders: [
      {
        test: /\.ts$/,
        loader: 'tslint-loader',
        exclude: [helpers.root('node_modules')]
      },
      {
        test: /\.js$/,
        loader: 'source-map-loader',
        exclude: [
            helpers.root('node_modules/rxjs'),
            helpers.root('node_modules/@angular2-material'),
            helpers.root('node_modules/@angular')
      ]}
   ],
loaders: [
{
    test: /\.ts$/,
    loader: 'awesome-typescript-loader',
    query: {
      compilerOptions: {
          removeComments: true
      }
    },
    exclude: [/\.e2e\.ts$/]
  },
  { test: /\.json$/, loader: 'json-loader', exclude: [helpers.root('src/index.html')] },
  { test: /\.css$/, loaders: ['to-string-loader', 'css-loader'], exclude: [helpers.root('src/index.html')] },
  { test: /\.html$/, loader: 'raw-loader', exclude: [helpers.root('src/index.html')] }
],
postLoaders: [
{
    test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader',
    include: helpers.root('src'),
    exclude: [
      /\.(e2e|spec)\.ts$/,
      /node_modules/
    ]
  }
]
},
plugins: [
new DefinePlugin({
  'ENV': JSON.stringify(ENV),
  'HMR': false,
  'process.env': {
    'ENV': JSON.stringify(ENV),
    'NODE_ENV': JSON.stringify(ENV),
    'HMR': false,
  }
}),
],
tslint: {
    emitErrors: false,
    failOnHint: false,
    resourcePath: 'src'
  },
node: {
    global: 'window',
    process: false,
    crypto: 'empty',
    module: false,
    clearImmediate: false,
    setImmediate: false
}
};

spec-bundle.js:

Error.stackTraceLimit = Infinity;
require('core-js/es6');
require('core-js/es7/reflect');
require('ts-helpers');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
require('zone.js/dist/sync-test');
require('rxjs/Rx');
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
testing.setBaseTestProviders(
  browser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
  browser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS
);
var testContext = require.context('../src', true, /\.spec\.ts/);
function requireAll(requireContext) {
  return requireContext.keys().map(requireContext);
}
var modules = requireAll(testContext);

This configuration is as in starter package with minor if any modifications. Could you tell me how to modify this configuration so the .ts source files would be debugable with coverage statistics.

I've downloaded a seed project Angular2 Webpack Starter and got it up and running without an issue. One inconvenience that I have with it is debugging source files under unit tests. All *.spec.ts files are loaded into browser and debugable so map files are generated for them at least. When I step into a source file under test I get something like this:

karma config:

module.exports = function(config) {
var testWebpackConfig = require('./webpack.test.js');

config.set({
    basePath: '',
    frameworks: ['jasmine'],
    exclude: [ ],
    files: [ { pattern: './config/spec-bundle.js', watched: false } ],
    preprocessors: { './config/spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] },
    webpack: testWebpackConfig,
    coverageReporter: {
      dir : 'coverage/',
      reporters: [
        { type: 'text-summary' },
        { type: 'json' },
        { type: 'html' }
      ]
    },
webpackServer: { noInfo: true },
reporters: [ 'mocha', 'coverage' ],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: [
  'Chrome'
],
singleRun: false
});
};

webpack.test.js:

const helpers = require('./helpers');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const ENV = process.env.ENV = process.env.NODE_ENV = 'test';
module.exports = {
    devtool: 'inline-source-map',
    resolve: {
        extensions: ['', '.ts', '.js'],
        root: helpers.root('src'),
    },
    module: {
    preLoaders: [
      {
        test: /\.ts$/,
        loader: 'tslint-loader',
        exclude: [helpers.root('node_modules')]
      },
      {
        test: /\.js$/,
        loader: 'source-map-loader',
        exclude: [
            helpers.root('node_modules/rxjs'),
            helpers.root('node_modules/@angular2-material'),
            helpers.root('node_modules/@angular')
      ]}
   ],
loaders: [
{
    test: /\.ts$/,
    loader: 'awesome-typescript-loader',
    query: {
      compilerOptions: {
          removeComments: true
      }
    },
    exclude: [/\.e2e\.ts$/]
  },
  { test: /\.json$/, loader: 'json-loader', exclude: [helpers.root('src/index.html')] },
  { test: /\.css$/, loaders: ['to-string-loader', 'css-loader'], exclude: [helpers.root('src/index.html')] },
  { test: /\.html$/, loader: 'raw-loader', exclude: [helpers.root('src/index.html')] }
],
postLoaders: [
{
    test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader',
    include: helpers.root('src'),
    exclude: [
      /\.(e2e|spec)\.ts$/,
      /node_modules/
    ]
  }
]
},
plugins: [
new DefinePlugin({
  'ENV': JSON.stringify(ENV),
  'HMR': false,
  'process.env': {
    'ENV': JSON.stringify(ENV),
    'NODE_ENV': JSON.stringify(ENV),
    'HMR': false,
  }
}),
],
tslint: {
    emitErrors: false,
    failOnHint: false,
    resourcePath: 'src'
  },
node: {
    global: 'window',
    process: false,
    crypto: 'empty',
    module: false,
    clearImmediate: false,
    setImmediate: false
}
};

spec-bundle.js:

Error.stackTraceLimit = Infinity;
require('core-js/es6');
require('core-js/es7/reflect');
require('ts-helpers');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
require('zone.js/dist/sync-test');
require('rxjs/Rx');
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
testing.setBaseTestProviders(
  browser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
  browser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS
);
var testContext = require.context('../src', true, /\.spec\.ts/);
function requireAll(requireContext) {
  return requireContext.keys().map(requireContext);
}
var modules = requireAll(testContext);

This configuration is as in starter package with minor if any modifications. Could you tell me how to modify this configuration so the .ts source files would be debugable with coverage statistics.

Share Improve this question asked Jul 13, 2016 at 6:29 RafalRafal 12.6k33 silver badges54 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 17

I had a similar issue with my project (which isn't the Angular2 Webpack Starter, but I believe has the same cause.)

WebPack, by default, doesn't pass source maps up to Karma unless the file extension is .js (or .jsx if you're using React). In a setup like this one, Karma+WebPack just transpiles the .ts files (or .tsx) straight from TypeScript to JavaScript and serves them under the same file name.

I found a solution that worked for me on the GitHub Issues page for karma-webpack. The trick is to inject webpack.SourceMapDevToolPlugin with a widened file filter into the webpack config. For you, that should look something like this:

var webpack = require('webpack');
// in your config.set:
plugins: [
  // existing plugins go here
  new webpack.SourceMapDevToolPlugin({
    filename: null, // if no value is provided the sourcemap is inlined
    test: /\.(ts|js)($|\?)/i // process .js and .ts files only
  })
]

You need to comment out Istanbul loader inside your webpack.test.config.js, like this

    // {
    //   enforce: 'post',
    //   test: /\.(js|ts)$/,
    //   loader: 'istanbul-instrumenter-loader',
    //   include: helpers.root('src'),
    //   exclude: [
    //     /\.(e2e|spec)\.ts$/,
    //     /node_modules/
    //   ]
    // }

then simply run:

 npm run watch:test
发布评论

评论列表(0)

  1. 暂无评论