2016-08-24 130 views
17

我正在使用Karma-Webpack来运行我的Angular 2规范。Karma Webpack源代码映射不工作

https://github.com/webpack/karma-webpack

当我执行在Chrome中使用的业力测试,我的规格源文件出现在调试器读取。但是,被测系统文件(我的应用程序源)是不可读的。

我正在使用karma-sourcemap-loader,并根据指示将devtool设置为'inline-source-map'。什么可能导致这个问题?

此构建模仿AngularClass angular2-webpack-starter。在调试器 https://github.com/AngularClass/angular2-webpack-starter

规格文件:在调试器

enter image description here

SUT文件:

enter image description here

webpack.test.js

const helpers = require('./helpers'); 

/** 
* Webpack Plugins 
*/ 
const ProvidePlugin = require('webpack/lib/ProvidePlugin'); 
const DefinePlugin = require('webpack/lib/DefinePlugin'); 

/** 
* Webpack Constants 
*/ 
const ENV = process.env.ENV = process.env.NODE_ENV = 'test'; 

/** 
* Webpack configuration 
* 
* See: http://webpack.github.io/docs/configuration.html#cli 
*/ 
module.exports = { 

    /** 
    * Source map for Karma from the help of karma-sourcemap-loader & karma-webpack 
    * 
    * Do not change, leave as is or it wont work. 
    * See: https://github.com/webpack/karma-webpack#source-maps 
    */ 
    devtool: 'inline-source-map', 

    /** 
    * Options affecting the resolving of modules. 
    * 
    * See: http://webpack.github.io/docs/configuration.html#resolve 
    */ 
    resolve: { 

    /** 
    * An array of extensions that should be used to resolve modules. 
    * 
    * See: http://webpack.github.io/docs/configuration.html#resolve-extensions 
    */ 
    extensions: ['', '.ts', '.js'], 

    /** 
    * Make sure root is src 
    */ 
    root: helpers.root('src'), 

    }, 


    /** 
    * Options affecting the normal modules. 
    * 
    * See: http://webpack.github.io/docs/configuration.html#module 
    */ 
    module: { 

    /** 
    * An array of applied pre and post loaders. 
    * 
    * See: http://webpack.github.io/docs/configuration.html#module-preloaders-module-postloaders 
    */ 
    preLoaders: [ 

     /** 
     * Tslint loader support for *.ts files 
     * 
     * See: https://github.com/wbuchwalter/tslint-loader 
     */ 
     { 
     test: /\.ts$/, 
     loader: 'tslint-loader', 
     exclude: [helpers.root('node_modules')] 
     }, 

     /** 
     * Source map loader support for *.js files 
     * Extracts SourceMaps for source files that as added as sourceMappingURL comment. 
     * 
     * See: https://github.com/webpack/source-map-loader 
     */ 
     { 
     test: /\.js$/, 
     loader: 'source-map-loader', 
     exclude: [ 
     // these packages have problems with their sourcemaps 
     helpers.root('node_modules/rxjs'), 
     helpers.root('node_modules/@angular') 
     ] 
     } 

    ], 

    /** 
    * An array of automatically applied loaders. 
    * 
    * IMPORTANT: The loaders here are resolved relative to the resource which they are applied to. 
    * This means they are not resolved relative to the configuration file. 
    * 
    * See: http://webpack.github.io/docs/configuration.html#module-loaders 
    */ 
    loaders: [ 

     /** 
     * Typescript loader support for .ts and Angular 2 async routes via .async.ts 
     * 
     * See: https://github.com/s-panferov/awesome-typescript-loader 
     */ 
     { 
     test: /\.ts$/, 
     loader: 'awesome-typescript-loader', 
     query: { 
      compilerOptions: { 

      // Remove TypeScript helpers to be injected 
      // below by DefinePlugin 
      removeComments: true 

      } 
     }, 
     exclude: [/\.e2e\.ts$/] 
     }, 

     /** 
     * Json loader support for *.json files. 
     * 
     * See: https://github.com/webpack/json-loader 
     */ 
     { test: /\.json$/, loader: 'json-loader', exclude: [helpers.root('src/index.html')] }, 

     /** 
     * Raw loader support for *.css files 
     * Returns file content as string 
     * 
     * See: https://github.com/webpack/raw-loader 
     */ 
     { test: /\.css$/, loaders: ['to-string-loader', 'css-loader'], exclude: [helpers.root('src/index.html')] }, 

     /** 
     * Raw loader support for *.html 
     * Returns file content as string 
     * 
     * See: https://github.com/webpack/raw-loader 
     */ 
     { test: /\.html$/, loader: 'raw-loader', exclude: [helpers.root('src/index.html')] } 

    ], 

    /** 
    * An array of applied pre and post loaders. 
    * 
    * See: http://webpack.github.io/docs/configuration.html#module-preloaders-module-postloaders 
    */ 
    postLoaders: [ 

     /** 
     * Instruments JS files with Istanbul for subsequent code coverage reporting. 
     * Instrument only testing sources. 
     * 
     * See: https://github.com/deepsweet/istanbul-instrumenter-loader 
     */ 
     { 
     test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader', 
     include: helpers.root('src'), 
     exclude: [ 
      /\.(e2e|spec)\.ts$/, 
      /node_modules/ 
     ] 
     } 

    ] 
    }, 

    /** 
    * Add additional plugins to the compiler. 
    * 
    * See: http://webpack.github.io/docs/configuration.html#plugins 
    */ 
    plugins: [ 

    /** 
    * Plugin: DefinePlugin 
    * Description: Define free variables. 
    * Useful for having development builds with debug logging or adding global constants. 
    * 
    * Environment helpers 
    * 
    * See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin 
    */ 
    // NOTE: when adding more properties make sure you include them in custom-typings.d.ts 
    new DefinePlugin({ 
     'ENV': JSON.stringify(ENV), 
     'HMR': false, 
     'process.env': { 
     'ENV': JSON.stringify(ENV), 
     'NODE_ENV': JSON.stringify(ENV), 
     'HMR': false, 
     } 
    }), 


    ], 

    /** 
    * Static analysis linter for TypeScript advanced options configuration 
    * Description: An extensible linter for the TypeScript language. 
    * 
    * See: https://github.com/wbuchwalter/tslint-loader 
    */ 
    tslint: { 
    emitErrors: false, 
    failOnHint: false, 
    resourcePath: 'src' 
    }, 

    /** 
    * Include polyfills or mocks for various node stuff 
    * Description: Node configuration 
    * 
    * See: https://webpack.github.io/docs/configuration.html#node 
    */ 
    node: { 
    global: 'window', 
    process: false, 
    crypto: 'empty', 
    module: false, 
    clearImmediate: false, 
    setImmediate: false 
    } 

}; 

karma.conf.js

/** 
* @author: @AngularClass 
*/ 

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

    var configuration = { 

    // base path that will be used to resolve all patterns (e.g. files, exclude) 
    basePath: '', 

    /* 
    * Frameworks to use 
    * 
    * available frameworks: https://npmjs.org/browse/keyword/karma-adapter 
    */ 
    frameworks: ['jasmine'], 

    // list of files to exclude 
    exclude: [], 

    /* 
    * list of files/patterns to load in the browser 
    * 
    * we are building the test environment in ./spec-bundle.js 
    */ 

    files: [{ pattern: './spec-bundle.js', watched: false }], 

    /* 
    * preprocess matching files before serving them to the browser 
    * available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 
    */ 
    preprocessors: { 
     './spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] 
    }, 

    // Webpack Config at ./webpack.test.js 
    webpack: testWebpackConfig, 

    coverageReporter: { 
     dir: './../karma_html/coverage/', 
     reporters: [ 
     { type: 'text-summary' }, 
     { type: 'json' }, 
     { type: 'html' } 
     ] 
    }, 

    // Webpack please don't spam the console when running in karma! 
    webpackServer: { noInfo: true }, 

    /* 
    * test results reporter to use 
    * 
    * possible values: 'dots', 'progress' 
    * available reporters: https://npmjs.org/browse/keyword/karma-reporter 
    */ 
    reporters: ['mocha', 'coverage'], 

    // web server port 
    port: 9876, 

    // enable/disable colors in the output (reporters and logs) 
    colors: true, 

    /* 
    * level of logging 
    * possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 
    */ 
    logLevel: config.LOG_INFO, 

    // enable/disable watching file and executing tests whenever any file changes 
    autoWatch: false, 

    /* 
    * start these browsers 
    * available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 
    */ 
    browsers: [ 
     'PhantomJS' 
    ], 

    customLaunchers: { 
     Chrome_travis_ci: { 
     base: 'Chrome', 
     flags: ['--no-sandbox'] 
     } 
    }, 

    /* 
    * Continuous Integration mode 
    * if true, Karma captures browsers, runs the tests and exits 
    */ 
    singleRun: true 
    }; 

    if (process.env.TRAVIS) { 
    configuration.browsers = ['Chrome_travis_ci']; 
    } 

    config.set(configuration); 
}; 

SPEC-bundle.js

/** 
* @author: @AngularClass 
*/ 

/* 
* When testing with webpack and ES6, we have to do some extra 
* things to get testing to work right. Because we are gonna write tests 
* in ES6 too, we have to compile those as well. That's handled in 
* karma.conf.js with the karma-webpack plugin. This is the entry 
* file for webpack test. Just like webpack will create a bundle.js 
* file for our client, when we run test, it will compile and bundle them 
* all here! Crazy huh. So we need to do some setup 
*/ 
Error.stackTraceLimit = Infinity; 

require('core-js/es6'); 
require('core-js/es7/reflect'); 

// Typescript emit helpers polyfill 
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'); 

// RxJS 
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 
); 

/* 
* Ok, this is kinda crazy. We can use the the context method on 
* require that webpack created in order to tell webpack 
* what files we actually want to require or import. 
* Below, context will be an function/object with file names as keys. 
* using that regex we are saying look in ./src/app and ./test then find 
* any file that ends with spec.js and get its path. By passing in true 
* we say do this recursively 
*/ 
var testContext = require.context('../src', true, /\.spec\.ts/); 

/* 
* get all the files, for each file, call the context function 
* that will require the file and load it up here. Context will 
* loop and require those spec files here 
*/ 
function requireAll(requireContext) { 
    return requireContext.keys().map(requireContext); 
} 

// requires and returns all modules that match 
var modules = requireAll(testContext); 

回答

9

问题来自istanbul-instrumenter-loader

一种解决方案是配置karma和webpack以在手表模式下运行测试时跳过代码覆盖检测。

根据在angular2-的WebPack起动回购的最新版本,您可以修改以下2个文件:

karma.conf.js

/** 
* @author: @AngularClass 
*/ 

const autowatch = process.env.npm_lifecycle_script.indexOf('--auto-watch') !== -1; 

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

    var configuration = { 

    // base path that will be used to resolve all patterns (e.g. files, exclude) 
    basePath: '', 

    /* 
    * Frameworks to use 
    * 
    * available frameworks: https://npmjs.org/browse/keyword/karma-adapter 
    */ 
    frameworks: ['jasmine'], 

    // list of files to exclude 
    exclude: [ ], 

    /* 
    * list of files/patterns to load in the browser 
    * 
    * we are building the test environment in ./spec-bundle.js 
    */ 
    files: [ { pattern: './config/spec-bundle.js', watched: false } ], 

    /* 
    * preprocess matching files before serving them to the browser 
    * available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 
    */ 
    // skip coverage in watch mode 
    preprocessors: { './config/spec-bundle.js': autowatch ? ['webpack', 'sourcemap'] : ['coverage', 'webpack', 'sourcemap'] }, 

    // Webpack Config at ./webpack.test.js 
    webpack: testWebpackConfig, 

    // Webpack please don't spam the console when running in karma! 
    webpackServer: { noInfo: true }, 

    /* 
    * test results reporter to use 
    * 
    * possible values: 'dots', 'progress' 
    * available reporters: https://npmjs.org/browse/keyword/karma-reporter 
    */ 
    reporters: [ 'mocha'], 

    // web server port 
    port: 9876, 

    // enable/disable colors in the output (reporters and logs) 
    colors: true, 

    /* 
    * level of logging 
    * possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 
    */ 
    logLevel: config.LOG_INFO, 

    // enable/disable watching file and executing tests whenever any file changes 
    autoWatch: false, 

    /* 
    * start these browsers 
    * available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 
    */ 
    browsers: [ 
     'Chrome' 
    ], 

    customLaunchers: { 
     ChromeTravisCi: { 
     base: 'Chrome', 
     flags: ['--no-sandbox'] 
     } 
    }, 

    /* 
    * Continuous Integration mode 
    * if true, Karma captures browsers, runs the tests and exits 
    */ 
    singleRun: true 
    }; 

    if (process.env.TRAVIS){ 
    configuration.browsers = ['ChromeTravisCi']; 
    } 

    // skip coverage in watch mode 
    if (!autowatch) { 
     configuration.reporters.push('coverage'); 
     configuration.coverageReporter = { 
     dir : 'coverage/', 
     reporters: [ 
     { type: 'text-summary' }, 
     { type: 'json' }, 
     { type: 'html' } 
     ] 
    }; 

    } 

    config.set(configuration); 
}; 

webpack.test。js

/** 
* @author: @AngularClass 
*/ 

const helpers = require('./helpers'); 

/** 
* Webpack Plugins 
*/ 
const ProvidePlugin = require('webpack/lib/ProvidePlugin'); 
const DefinePlugin = require('webpack/lib/DefinePlugin'); 

/** 
* Webpack Constants 
*/ 
const ENV = process.env.ENV = process.env.NODE_ENV = 'test'; 

const autowatch = process.env.npm_lifecycle_script.indexOf('--auto-watch') !== -1; 

/** 
* Webpack configuration 
* 
* See: http://webpack.github.io/docs/configuration.html#cli 
*/ 
module.exports = function(options) { 
    let config = { 

    /** 
    * Source map for Karma from the help of karma-sourcemap-loader & karma-webpack 
    * 
    * Do not change, leave as is or it wont work. 
    * See: https://github.com/webpack/karma-webpack#source-maps 
    */ 
    devtool: 'inline-source-map', 

    /** 
    * Options affecting the resolving of modules. 
    * 
    * See: http://webpack.github.io/docs/configuration.html#resolve 
    */ 
    resolve: { 

     /** 
     * An array of extensions that should be used to resolve modules. 
     * 
     * See: http://webpack.github.io/docs/configuration.html#resolve-extensions 
     */ 
     extensions: ['', '.ts', '.js'], 

     /** 
     * Make sure root is src 
     */ 
     root: helpers.root('src'), 

    }, 

    /** 
    * Options affecting the normal modules. 
    * 
    * See: http://webpack.github.io/docs/configuration.html#module 
    */ 
    module: { 

     /** 
     * An array of applied pre and post loaders. 
     * 
     * See: http://webpack.github.io/docs/configuration.html#module-preloaders-module-postloaders 
     */ 
     preLoaders: [ 

     /** 
     * Tslint loader support for *.ts files 
     * 
     * See: https://github.com/wbuchwalter/tslint-loader 
     */ 
     { 
      test: /\.ts$/, 
      loader: 'tslint-loader', 
      exclude: [helpers.root('node_modules')] 
     }, 

     /** 
     * Source map loader support for *.js files 
     * Extracts SourceMaps for source files that as added as sourceMappingURL comment. 
     * 
     * See: https://github.com/webpack/source-map-loader 
     */ 
     { 
      test: /\.js$/, 
      loader: 'source-map-loader', 
      exclude: [ 
      // these packages have problems with their sourcemaps 
      helpers.root('node_modules/rxjs'), 
      helpers.root('node_modules/@angular') 
     ]} 

     ], 

     /** 
     * An array of automatically applied loaders. 
     * 
     * IMPORTANT: The loaders here are resolved relative to the resource which they are applied to. 
     * This means they are not resolved relative to the configuration file. 
     * 
     * See: http://webpack.github.io/docs/configuration.html#module-loaders 
     */ 
     loaders: [ 

     /** 
     * Typescript loader support for .ts and Angular 2 async routes via .async.ts 
     * 
     * See: https://github.com/s-panferov/awesome-typescript-loader 
     */ 
     { 
      test: /\.ts$/, 
      loader: 'awesome-typescript-loader', 
      query: { 
      compilerOptions: { 

       // Remove TypeScript helpers to be injected 
       // below by DefinePlugin 
       removeComments: true 

      } 
      }, 
      exclude: [/\.e2e\.ts$/] 
     }, 

     /** 
     * Json loader support for *.json files. 
     * 
     * See: https://github.com/webpack/json-loader 
     */ 
     { test: /\.json$/, loader: 'json-loader', exclude: [helpers.root('src/index.html')] }, 

     /** 
     * Raw loader support for *.css files 
     * Returns file content as string 
     * 
     * See: https://github.com/webpack/raw-loader 
     */ 
     { test: /\.css$/, loaders: ['to-string-loader', 'css-loader'], exclude: [helpers.root('src/index.html')] }, 

     /** 
     * Raw loader support for *.html 
     * Returns file content as string 
     * 
     * See: https://github.com/webpack/raw-loader 
     */ 
     { test: /\.html$/, loader: 'raw-loader', exclude: [helpers.root('src/index.html')] } 

     ], 

     /** 
     * An array of applied pre and post loaders. 
     * 
     * See: http://webpack.github.io/docs/configuration.html#module-preloaders-module-postloaders 
     */ 
     postLoaders: [] 
    }, 

    /** 
    * Add additional plugins to the compiler. 
    * 
    * See: http://webpack.github.io/docs/configuration.html#plugins 
    */ 
    plugins: [ 

     /** 
     * Plugin: DefinePlugin 
     * Description: Define free variables. 
     * Useful for having development builds with debug logging or adding global constants. 
     * 
     * Environment helpers 
     * 
     * See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin 
     */ 
     // NOTE: when adding more properties make sure you include them in custom-typings.d.ts 
     new DefinePlugin({ 
     'ENV': JSON.stringify(ENV), 
     'HMR': false, 
     'process.env': { 
      'ENV': JSON.stringify(ENV), 
      'NODE_ENV': JSON.stringify(ENV), 
      'HMR': false, 
     } 
     }), 


    ], 

    /** 
    * Static analysis linter for TypeScript advanced options configuration 
    * Description: An extensible linter for the TypeScript language. 
    * 
    * See: https://github.com/wbuchwalter/tslint-loader 
    */ 
    tslint: { 
     emitErrors: false, 
     failOnHint: false, 
     resourcePath: 'src' 
    }, 

    /** 
    * Include polyfills or mocks for various node stuff 
    * Description: Node configuration 
    * 
    * See: https://webpack.github.io/docs/configuration.html#node 
    */ 
    node: { 
     global: 'window', 
     process: false, 
     crypto: 'empty', 
     module: false, 
     clearImmediate: false, 
     setImmediate: false 
    } 

    }; 

    // skip coverage in watch mode 
    if (!autowatch) { 
    config.module.postLoaders.push(/** 
     * Instruments JS files with Istanbul for subsequent code coverage reporting. 
     * Instrument only testing sources. 
     * 
     * See: https://github.com/deepsweet/istanbul-instrumenter-loader 
     */ 
     { 
      test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader', 
      include: helpers.root('src'), 
      exclude: [ 
      /\.(e2e|spec)\.ts$/, 
      /node_modules/ 
      ] 
     }); 
    } 

    return config; 
} 

现在,您应该能够在运行npm run watch:test时看到源Typescript文件。

+0

此替代方法适用于我。谢谢! – Llyle

+0

我更新了这些文件,并得到以下错误:配置文件错误! [SyntaxError:在严格模式外尚不支持块范围声明(let,const,function,class)] SyntaxError:严格模式之外还不支持块范围声明(let,const,function,class) –

+0

在webpack.test.js中添加'严格使用'来让你的例子工作..谢谢! –

2

这看起来完全就像this Stack Overflow question,所以它可能确实有相同的解决方案。

默认情况下,WebPack不会将源地图传递到Karma,除非文件扩展名为.js(或者如果您使用的是React,则为.jsx)。在像这样的设置中,Karma + WebPack只是将.ts文件(或.tsx)直接从TypeScript转换为JavaScript,并以相同的文件名提供它们。

我发现了一个适用于我的解决方案on the GitHub Issues page for karma-webpack。诀窍是将webpack.SourceMapDevToolPlugin与一个扩展文件过滤器注入到webpack配置中。对你来说,应该是这个样子:

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 
    }) 
] 

给一个尝试,看看它不能解决问题。

+0

这不适用于angular2-webpack-starter,结果是查看devtools中任何源文件的能力完全消失(webpack://消失) –

+0

它的工作原理。 webpack的东西刚从本地主机移到了“base”目录中,但是在将它添加到工作区之后,它就不再重要了。断点最重要的工作! (角4.3.6) –