对于Karma测试跑步者来说,我经历了非常缓慢的“启动”时间,并且在对运行进行分析之后,我意识到最大的减速是由源地图的创建引起的。
更具体地说,鉴于我正在使用karma-webpack
和webpack作为预处理器,每次测试文件由karma加载时,都会将其提供给webpack,后者会为其生成源地图。
鉴于我没有拆分/分块我的应用和供应商代码,每个测试文件都获得相同的供应商源地图(内联)。
我认为我可以通过简单地阻止node_modules/
文件的源映射来解决这个问题,但是我意识到你只能根据最终资产文件而不是输入源/模块来排除获取源映射的文件文件。
所以我找到了this插件来自动将我的应用和供应商代码拆分成单独的块(而不是必须手动列出每个供应商模块)。
但是在运行Karma时我开始遇到这个错误:
ReferenceError: Can't find variable: webpackJsonp
我很确定这是因为Karma没有意识到供应商和应用程序代码被拆分成单独的块,因此只包含配置了files
选项的代码(即测试文件本身而不是供应商文件)。
似乎在每个测试文件进行预处理之前解析并处理了files
配置选项,这意味着我认为不可能在files
选项中指定供应商块,因为Karma在尝试寻找它时不会知道它(太早)。
我能看到的唯一解决方案是:
karma-webpack
和预处理,而是在测试模式下构建应用程序,然后运行测试构建目录的Karma(以便供应商块能够及早存在)。有没有我错过的解决方案?
我觉得奇怪的是它似乎不是一个常见的问题。
修改1
我找到this,但那里的人建议在webpack配置中使用多个入口点(即一个用于app,一个用于供应商)。我会尝试看看这是否适用于Karma,但它仍然有一个很大的缺点(在我看来)你必须手动跟踪你放在vendor
数组中的内容。即每次安装软件包时都必须将其添加到阵列中,反之亦然。
修改2
在配置源映射webpack插件以排除供应商文件之前,使用多个入口点(在webpack配置中)甚至不起作用(而使用webpack-split-by-path
插件时)。
我将尝试实施“先构建然后测试”的方法。
答案 0 :(得分:1)
如果有其他人遇到这个问题,我得到了#34;构建然后休息"接近工作,即我放弃了karma-webpack
和Karma预处理,转而使用单独的构建和测试命令(一个接一个地运行)。
这是我的webpack配置,专门用于测试(例如webpack.config.babel.test.js):
import webpack from 'webpack';
import { join, resolve, parse } from 'path';
import SplitByPathPlugin from 'webpack-split-by-path';
import file from 'file';
const plugins = [
new SplitByPathPlugin([
{
name: 'vendor',
path: resolve(__dirname, 'node_modules')
}
]),
new webpack.SourceMapDevToolPlugin({
test: /\.jsx?$/,
exclude: [/vendor/]
})
];
const entryPoints = {};
const testFileRegex = new RegExp('\.test\.jsx?$');
const pathPrefixRegex = new RegExp('^src/js/?');
file.walkSync('src/js/', (dirPath, dirs, files) => {
for (const file of files) {
if (file.match(testFileRegex)) {
const parsedPath = parse(file);
const entryKey = join(
dirPath.replace(pathPrefixRegex, ''),
parsedPath.name
);
entryPoints[entryKey] = './' + join(dirPath, parsedPath.name);
}
}
});
const config = {
entry: entryPoints,
output: {
filename: '/[name]-[chunkhash].js',
chunkFilename: '/[name]-[chunkhash].js',
path: resolve(__dirname, 'dist-test'),
pathinfo: true
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader!eslint-loader',
exclude: [/node_modules/],
},
{
test: /\.json$/, loader: 'json'
}
],
},
bail: true,
resolve: {
extensions: ['', '.js', '.jsx', '.json'],
},
plugins: plugins,
stats: {
assets: false,
cached: false,
children: false,
chunks: false,
chunkModules: false,
chunkOrigins: false,
hash: false,
modules: false,
publicPath: false,
reasons: false,
source: false,
timings: false,
version: false,
warnings: false
},
node: {
child_process: 'empty',
fs: 'empty'
},
externals: {
'react/addons': true,
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': 'window'
}
};
export default config;
关键部分是它为每个测试文件创建一个入口点,并在生成块时使用webpack-split-by-path
插件自动将应用程序与供应商代码分开。
这是我参加的业力配置:
process.env.BABEL_ENV = 'test';
function karmaConfig(config) {
config.set({
basePath: '',
frameworks: ['mocha'],
files: [
{
pattern: 'dist-test/vendor-*.js',
watched: false
},
'dist-test/**/*.test-*js?(x)'
],
exclude: [],
reporters: ['progress'],
port: 9876,
colors: true,
browsers: ['Firefox', 'Chrome'],
singleRun: true,
logLevel: config.LOG_ERROR
})
}
export default karmaConfig;
关键部分是供应商文件首先列在files
配置选项中,并设置为不被监视,然后是测试文件。这可确保始终为每个测试用例加载/插入供应商代码。
我的问题是否有另一种方式,但这种方法效果很好。表现要好得多。
修改1
这种方法的唯一缺点(我最初没有意识到)是你无法像karma-webpack
和预处理那样真正实现测试观看(通过webpack),因为构建和测试步骤的分离。
修改2
每次更改应用程序代码时,此方法都会出现重新编译供应商代码的问题(即使您没有添加/删除任何供应商库)。这样可以减少冗余的速度。
您想要解决此问题以及能够再次开始测试的目的是:
dist-test/
目录中。dist-test/
目录中正在更新的所有测试文件。这个解决方案是完美的,除了你可以在一个npm / yarn命令中运行这两个东西的一个缺点。
注意:Webpack测试版本的输出文件名不应包含任何哈希值(即文件名在其内容更改之间应保持一致)。这样,当您更改测试文件时,您不会运行旧的和新的测试代码(因为Webpack不会删除旧文件)。。