Javascript 如何使量角器等待webpack开发服务器启动?
对于非Angular项目,我正在尝试复制Angular CLI在使用Javascript 如何使量角器等待webpack开发服务器启动?,javascript,node.js,webpack,protractor,end-to-end,Javascript,Node.js,Webpack,Protractor,End To End,对于非Angular项目,我正在尝试复制Angular CLI在使用ng e2e时所做的操作——不仅要运行量角器,还要首先启动开发服务器,并在完成量角器后完全关闭它 我已经有了一些可以工作的东西,但是我检查webpack dev服务器是否成功启动的方法——查找特定消息“webpack:Compiled successfully.”通过stdout——看起来像是一个丑陋的黑客。我通过pipe将stdout和stderr传递到节点进程的方式也不会产生我期望的所有输出 这是我迄今为止的grandor.
ng e2e
时所做的操作——不仅要运行量角器,还要首先启动开发服务器,并在完成量角器后完全关闭它
我已经有了一些可以工作的东西,但是我检查webpack dev服务器是否成功启动的方法——查找特定消息“webpack:Compiled successfully.”通过stdout
——看起来像是一个丑陋的黑客。我通过pipe
将stdout
和stderr
传递到节点进程的方式也不会产生我期望的所有输出
这是我迄今为止的grandor.conf.js
(还有一堆调试控制台语句,我稍后会清理这些语句):
如有任何改进建议,将不胜感激。我已经找到了一些与这个主题相关的其他线索,但没有得出明确的结论。由于还没有收到任何其他回复,我想我应该发布一个我以前的代码的清理版本,带有更好的
stderr
输出处理和其他改进,这是迄今为止我得到的最好答案:
const { SpecReporter } = require('jasmine-spec-reporter');
const spawn = require('child_process').spawn;
let webpackServerProcess;
let stderrBuffer = '';
function sendToStderr(s) {
// Undo console overstriking so that %-progress output appears on separate lines.
s = s.replace(/ \x08\x08/g, '\x08');
s = s.replace(/\x08+/g, '\n');
stderrBuffer += s;
let eol = stderrBuffer.lastIndexOf('\n');
if (eol >= 0) {
process.stderr.write(stderrBuffer.substring(0, eol + 1));
stderrBuffer = stderrBuffer.substring(eol + 1);
}
}
function flushStderr() {
if (stderrBuffer) {
process.stderr.write(stderrBuffer + '\n');
stderrBuffer = '';
}
}
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
beforeLaunch() {
return new Promise((resolve, reject) => {
let resolved = false;
let rejected = false;
webpackServerProcess = spawn('webpack-dev-server', ['--port=4200']);
webpackServerProcess.stdout.pipe(process.stdout);
webpackServerProcess.stdout.addListener('data', chunk => {
const msg = chunk.toString();
if (msg.indexOf('webpack: Compiled successfully.') >= 0) {
resolved = true;
flushStderr();
resolve();
}
else if (!resolved && msg.indexOf('webpack:') >= 0) {
rejected = true;
flushStderr();
reject(msg);
}
});
webpackServerProcess.stderr.addListener('data', chunk => {
sendToStderr(chunk.toString());
});
// This config is meant for small projects. Assume that if a minute goes by with no errors, webpack has finished
// building and webpack-dev-server is ready to go for e2e.
setTimeout(() => {
if (!resolved && !rejected) {
resolved = true;
resolve();
}
}, 60000);
function done() {
if (!resolved && !rejected) {
flushStderr();
reject('webpack-dev-server terminated unexpectedly');
}
}
webpackServerProcess.addListener('close', done);
webpackServerProcess.addListener('exit', done);
webpackServerProcess.addListener('disconnect', done);
});
},
onPrepare() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
},
onCleanUp() {
flushStderr();
if (webpackServerProcess && !webpackServerProcess.killed) {
try {
process.kill(webpackServerProcess.pid);
}
catch (error) {}
}
}
};
const { SpecReporter } = require('jasmine-spec-reporter');
const spawn = require('child_process').spawn;
let webpackServerProcess;
let stderrBuffer = '';
function sendToStderr(s) {
// Undo console overstriking so that %-progress output appears on separate lines.
s = s.replace(/ \x08\x08/g, '\x08');
s = s.replace(/\x08+/g, '\n');
stderrBuffer += s;
let eol = stderrBuffer.lastIndexOf('\n');
if (eol >= 0) {
process.stderr.write(stderrBuffer.substring(0, eol + 1));
stderrBuffer = stderrBuffer.substring(eol + 1);
}
}
function flushStderr() {
if (stderrBuffer) {
process.stderr.write(stderrBuffer + '\n');
stderrBuffer = '';
}
}
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
beforeLaunch() {
return new Promise((resolve, reject) => {
let resolved = false;
let rejected = false;
webpackServerProcess = spawn('webpack-dev-server', ['--port=4200']);
webpackServerProcess.stdout.pipe(process.stdout);
webpackServerProcess.stdout.addListener('data', chunk => {
const msg = chunk.toString();
if (msg.indexOf('webpack: Compiled successfully.') >= 0) {
resolved = true;
flushStderr();
resolve();
}
else if (!resolved && msg.indexOf('webpack:') >= 0) {
rejected = true;
flushStderr();
reject(msg);
}
});
webpackServerProcess.stderr.addListener('data', chunk => {
sendToStderr(chunk.toString());
});
// This config is meant for small projects. Assume that if a minute goes by with no errors, webpack has finished
// building and webpack-dev-server is ready to go for e2e.
setTimeout(() => {
if (!resolved && !rejected) {
resolved = true;
resolve();
}
}, 60000);
function done() {
if (!resolved && !rejected) {
flushStderr();
reject('webpack-dev-server terminated unexpectedly');
}
}
webpackServerProcess.addListener('close', done);
webpackServerProcess.addListener('exit', done);
webpackServerProcess.addListener('disconnect', done);
});
},
onPrepare() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
},
onCleanUp() {
flushStderr();
if (webpackServerProcess && !webpackServerProcess.killed) {
try {
process.kill(webpackServerProcess.pid);
}
catch (error) {}
}
}
};