我正在关注this tutorial设置Webpack Angular 2项目。
我可以使用设置运行单元测试,但我尝试使用karma-coverage和remap-istanbul为项目添加代码覆盖,但似乎karma-coverage在coverage-final中没有输出任何内容。 JSON。
我需要在karma配置中添加什么才能使测试配置生效?
这是我当前的配置:
var webpackConfig = require('./webpack.test');
module.exports = function (config) {
var _config = {
basePath: '',
frameworks: ['jasmine'],
files: [
{pattern: './config/karma-test-shim.js', watched: false}
],
preprocessors: {
'./config/karma-test-shim.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['PhantomJS'],
singleRun: true
};
config.set(_config);
};
答案 0 :(得分:4)
您有两种选择,最简单的方法是使用angular-cli。最难的方法是基于该教程进行代码覆盖所需的更改,这是很多。你将被强迫的主要事情之一是改为Webpack 2,我无法使用Webpack 1使remapIstanbulReporter: {
reports: {
html: 'coverage',
lcovonly: './coverage/coverage.lcov'
}
},
与karma一起工作。代码覆盖率始终为空。我从angular-cli得到了一些灵感,而angular2-webpack-starter来自here,这里有一些变化:
karma.conf.js:添加此内容:
reporters: ['progress'],
并改变这一点:
reporters: ['progress', 'karma-remap-istanbul'],
到此:
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');
module.exports = {
entry: {
'polyfills': './src/polyfills.ts',
'vendor': './src/vendor.ts',
'app': './src/main.ts'
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
exclude: [/\.(spec|e2e)\.ts$/]
},
{
test: /\.html$/,
loader: 'html'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file?name=assets/[name].[hash].[ext]'
},
{
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader',
loader: 'css-loader'
})
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw'
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
// Optimizing ensures loading order in index.html
name: ['polyfills', 'vendor', 'app'].reverse()
}),
new webpack.optimize.CommonsChunkPlugin({
minChunks: Infinity,
name: 'inline',
filename: 'inline.js',
sourceMapFilename: 'inline.map'
}),
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
};
webpack配置有很多变化,所以我只是要粘贴整个配置文件,这样更容易:
<强> webpack.common.js 强>:
var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');
module.exports = webpackMerge(commonConfig, {
devtool: 'cheap-module-eval-source-map',
output: {
path: helpers.root('dist'),
filename: '[name].js',
chunkFilename: '[id].chunk.js',
sourceMapFilename: '[name].map',
library: 'ac_[name]',
libraryTarget: 'var'
},
plugins: [
new webpack.LoaderOptionsPlugin({
options: {
tslint: {
emitErrors: false,
failOnHint: false,
resourcePath: 'src'
},
}
}),
new ExtractTextPlugin('[name].css')
],
devServer: {
historyApiFallback: true,
stats: 'minimal',
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
outputPath: helpers.root('dist')
},
node: {
global: true,
crypto: 'empty',
process: true,
module: false,
clearImmediate: false,
setImmediate: false
}
});
<强> webpack.dev.js 强>
var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var WebpackMd5Hash = require('webpack-md5-hash');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
module.exports = webpackMerge(commonConfig, {
devtool: 'source-map',
output: {
path: helpers.root('dist'),
filename: '[name].[chunkhash].js',
sourceMapFilename: '[name].[chunkhash].bundle.map',
chunkFilename: '[id].[chunkhash].chunk.js'
},
plugins: [
new WebpackMd5Hash(),
new webpack.NoErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin({
mangle: { screw_ie8: true },
compress: { screw_ie8: true }
}),
new ExtractTextPlugin('[name].[hash].css'),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
}),
new webpack.LoaderOptionsPlugin({
options: {
tslint: {
emitErrors: true,
failOnHint: true,
resourcePath: helpers.root('src')
},
htmlLoader: {
minimize: true,
removeAttributeQuotes: false,
caseSensitive: true,
customAttrSurround: [
[/#/, /(?:)/],
[/\*/, /(?:)/],
[/\[?\(?/, /(?:)/]
],
customAttrAssign: [/\)?\]?=/]
}
}
}),
new webpack.ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
helpers.root('src')
)
],
node: {
fs: 'empty',
global: true,
crypto: 'empty',
process: true,
module: false,
clearImmediate: false,
setImmediate: false
}
});
<强> webpack.prod.js 强>:
var helpers = require('./helpers');
var path = require('path');
var atl = require('awesome-typescript-loader');
var webpack = require('webpack');
module.exports = {
devtool: 'inline-source-map',
context: path.resolve(__dirname, './'),
resolve: {
extensions: ['.ts', '.js'],
plugins: [
new atl.TsConfigPathsPlugin({
tsconfig: helpers.root('tsconfig.json')
})
]
},
entry: {
test: helpers.root('config/karma-test-shim')
},
output: {
path: './dist.test',
filename: '[name].bundle.js'
},
module: {
rules: [
{
test: /\.ts$/,
enforce: 'pre',
loader: 'tslint-loader',
exclude: [
helpers.root('node_modules')
]
},
{
test: /\.js$/,
enforce: 'pre',
loader: 'source-map-loader',
exclude: [
helpers.root('node_modules/rxjs'),
helpers.root('node_modules/@angular')
]
},
{
test: /\.ts$/,
loaders: [
{
loader: 'awesome-typescript-loader',
query: {
tsconfig: helpers.root('tsconfig.json'),
module: 'commonjs',
target: 'es5',
useForkChecker: true
}
},
{
loader: 'angular2-template-loader'
}
],
exclude: [/\.e2e\.ts$/]
},
{
test: /\.html$/,
loader: 'html'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'null'
},
{
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: 'null'
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw'
},
{
test: /\.(js|ts)$/, loader: 'sourcemap-istanbul-instrumenter-loader',
enforce: 'post',
exclude: [
/\.(e2e|spec)\.ts$/,
/node_modules/
],
query: { 'force-sourcemap': true }
},
]
},
plugins: [
new webpack.SourceMapDevToolPlugin({
filename: null, // if no value is provided the sourcemap is inlined
test: /\.(ts|js)($|\?)/i // process .js and .ts files only
}),
new webpack.LoaderOptionsPlugin({
options: {
tslint: {
emitErrors: false,
failOnHint: false,
resourcePath: `./src`
}
}
}),
new webpack.ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
helpers.root('src')
)
],
node: {
fs: 'empty',
global: true,
process: false,
crypto: 'empty',
module: false,
clearImmediate: false,
setImmediate: false
}
}
<强> webpack.test.js 强>:
"start": "webpack-dev-server --config config/webpack.dev.js --profile --watch --content-base src/",
<强>的package.json 强>:
您需要安装新软件包并将启动脚本更新为:
npm i -D extract-text-webpack-plugin@2.0.0-beta.4 karma-remap-istanbul source-map-loader sourcemap-istanbul-instrumenter-loader tslint tslint-loader webpack@2.1.0-beta.25 webpack-dev-server@2.1.0-beta.3 webpack-md5-hash
并安装这些软件包:
{
"compilerOptions": {
"buildOnSave": false,
"compileOnSave": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist/out-tsc",
"noImplicitAny": true,
"removeComments": false,
"sourceMap": true,
"suppressImplicitAnyIndexErrors": true,
"target": "es5"
}
}
最后但并非最不重要的是,我们只需要对 tsconfig.json 进行一些更改,因为我们现在正在使用 tslint ,我们添加了一个 tslint.json 档案。
<强> tsconfig.json 强>:
{
"rules": {
"member-access": false,
"member-ordering": [
true,
"public-before-private",
"static-before-instance",
"variables-before-functions"
],
"no-any": false,
"no-inferrable-types": false,
"no-internal-module": true,
"no-var-requires": false,
"typedef": false,
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "space",
"index-signature": "space",
"parameter": "space",
"property-declaration": "space",
"variable-declaration": "space"
}
],
"ban": false,
"curly": false,
"forin": true,
"label-position": true,
"label-undefined": true,
"no-arg": true,
"no-bitwise": true,
"no-conditional-assignment": true,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-debugger": true,
"no-duplicate-variable": true,
"no-empty": false,
"no-eval": true,
"no-null-keyword": false,
"no-shadowed-variable": true,
"no-string-literal": false,
"no-switch-case-fall-through": true,
"no-unreachable": true,
"no-unused-expression": true,
"no-unused-variable": false,
"no-use-before-declare": true,
"no-var-keyword": true,
"radix": true,
"switch-default": true,
"triple-equals": [
true,
"allow-null-check"
],
"use-strict": [
true,
"check-module"
],
"eofline": true,
"indent": [
true,
"spaces"
],
"max-line-length": [
true,
100
],
"no-require-imports": false,
"no-trailing-whitespace": true,
"object-literal-sort-keys": false,
"trailing-comma": [
true,
{
"multiline": false,
"singleline": "never"
}
],
"align": false,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"interface-name": false,
"jsdoc-format": true,
"no-consecutive-blank-lines": false,
"no-constructor-vars": false,
"one-line": [
true,
"check-open-brace",
"check-catch",
"check-else",
"check-finally",
"check-whitespace"
],
"quotemark": [
true,
"single",
"avoid-escape"
],
"semicolon": [true, "always"],
"variable-name": [
true,
"check-format",
"allow-leading-underscore",
"ban-keywords"
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
]
}
}
<强> tslint.json:强>
#!/bin/bash
year=`date +%Y`
month=`date +%m`
day=`date +%d`
prefixe=$month$day$year
logfile="/home/oracle/logs/exec_proc_daily_20_"$prefixe.log
sqlplus / "as sysdba" <<EOF
spool on
spool $logfile
execute Proc_RFC_MAJ_MV_ITIN;
execute Proc_RFC_MAJ_MV_REFGEO;
commit;
quit
EOF
如果您需要,可以检查Angular.io设置(左侧)与我为覆盖工作所做的更改(右侧)之间的差异is available on GitHub