Skip to content

Commit

Permalink
feat: add perf init output (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
czy88840616 authored Nov 8, 2024
1 parent 1e675b8 commit 54ee471
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 75 deletions.
67 changes: 9 additions & 58 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ const { forkTsc, forkRun } = require('./process');
const {
parseArgs,
debounce,
getIp,
deleteFolderRecursive,
readJSONCFile,
copyFilesRecursive,
output,
colors,
debug,
getRelativeDir,
triggerMessage,
suffixMapping,
output,
colors,
} = require('./util');
const path = require('path');
const { replaceTscAliasPaths } = require('tsc-alias');
const chokidar = require('chokidar');
const fs = require('fs');
const { startProxyServer } = require('./proxy');
const consoleOutput = require('./output');

function run() {
const { cmdPath, tscArgs, parentArgs, childArgs } = parseArgs(process.argv);
Expand Down Expand Up @@ -231,67 +231,18 @@ function run() {
async (serverReportOption, isFirstCallback, during, debugUrl) => {
if (isFirstCallback) {
// 第一次启动把端口等信息打印出来
console.log('');
output(
`${colors.green('Node.js server')} ${colors.dim(
'started in'
)} ${during} ms ${
hasPaths
? colors.dim('and enable compile with ') + 'tsc-alias'
: ''
}\n`
consoleOutput.renderServerFirstReady(
serverReportOption,
during,
hasPaths,
debugUrl
);
if (serverReportOption && serverReportOption.port) {
const protocol = serverReportOption.ssl ? 'https' : 'http';
output(
`${colors.green('➜')} Local: ${colors.cyan(
`${protocol}://127.0.0.1:${colors.bright(
serverReportOption.port
)}${colors.cyan('/')}`
)} `
);
const netWorkIp = getIp();
if (netWorkIp) {
output(
`${colors.green('➜')} ${colors.dim(
`Network: ${protocol}://${netWorkIp}:${serverReportOption.port}/ `
)}`
);
}
if (debugUrl) {
output(
`${colors.green('➜')} ${colors.dim(
`Debugger: devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${debugUrl.replace(
'ws://',
''
)}`
)}`
);
}
console.log('');
}
if (proxyServer) {
proxyServer.start();
}
triggerMessage('server-first-ready');
} else {
output('');
output(
`${colors.green('Node.js server')} ${colors.dim(
'restarted in'
)} ${during} ms`
);
if (debugUrl) {
output(
`${colors.green('➜')} ${colors.dim(
`Debugger: devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${debugUrl.replace(
'ws://',
''
)}`
)}`
);
}
output('');
consoleOutput.renderServerReady(during, debugUrl);
triggerMessage('server-ready');
}
}
Expand Down
104 changes: 104 additions & 0 deletions lib/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const Table = require('cli-table3');
const { EventEmitter } = require('events');
const { colors, getIp, output } = require('./util');

class ConsoleOutput extends EventEmitter {
constructor() {
super();
}

renderPerfInit(items) {
const table = new Table({
head: ['name', 'duration(ms)'],
});

for (const item of items) {
if (item.entryType === 'measure') {
table.push([item.name.replace('MidwayInitialize:', ''), (item.duration).toFixed(2)]);
}
}

console.log(table.toString());
}

renderKeepAlive() {
output(colors.red('*'.repeat(120)));
output(
`A ${colors.red(
`${colors.bright(
'Critical unhandledRejection or uncaughtException'
)}`
)} was detected and the process has exited automatically.`
);
output('Please make sure to handle it.');
output(
'The --keepalive parameter was enabled, we will do our best to ensure the process remains normal.'
);
output(colors.red('*'.repeat(120)));
}

renderServerFirstReady(serverReportOption, during, hasPaths, debugUrl) {
// 第一次启动把端口等信息打印出来
console.log('');
output(
`${colors.green('Node.js server')} ${colors.dim(
'started in'
)} ${during} ms ${
hasPaths
? colors.dim('and enable compile with ') + 'tsc-alias'
: ''
}\n`
);
if (serverReportOption && serverReportOption.port) {
const protocol = serverReportOption.ssl ? 'https' : 'http';
output(
`${colors.green('➜')} Local: ${colors.cyan(
`${protocol}://127.0.0.1:${colors.bright(
serverReportOption.port
)}${colors.cyan('/')}`
)} `
);
const netWorkIp = getIp();
if (netWorkIp) {
output(
`${colors.green('➜')} ${colors.dim(
`Network: ${protocol}://${netWorkIp}:${serverReportOption.port}/ `
)}`
);
}
if (debugUrl) {
output(
`${colors.green('➜')} ${colors.dim(
`Debugger: devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${debugUrl.replace(
'ws://',
''
)}`
)}`
);
}
console.log('');
}
}

renderServerReady(during, debugUrl) {
output('');
output(
`${colors.green('Node.js server')} ${colors.dim(
'restarted in'
)} ${during} ms`
);
if (debugUrl) {
output(
`${colors.green('➜')} ${colors.dim(
`Debugger: devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${debugUrl.replace(
'ws://',
''
)}`
)}`
);
}
output('');
}
}

module.exports = new ConsoleOutput();
30 changes: 13 additions & 17 deletions lib/process.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ const { fork, spawn } = require('child_process');
const {
filterFileChangedText,
debug,
output,
colors,
convertPosixToGnu,
} = require('./util');
const { CHILD_PROCESS_EXCEPTION_EXIT_CODE } = require('./constants');
const path = require('path');
const fs = require('fs');
// is windows
const isWin = process.platform === 'win32';
const consoleOutput = require('./output');

/**
*
Expand Down Expand Up @@ -104,7 +103,9 @@ const forkTsc = (tscArgs = [], options = {}) => {
const forkRun = (runCmdPath, runArgs = [], options = {}) => {
// 判断路径是否是包名还是路径
if (!runCmdPath.startsWith('.') && !runCmdPath.startsWith('/')) {
runCmdPath = require.resolve(runCmdPath);
runCmdPath = require.resolve(runCmdPath, {
paths: [options.cwd || process.cwd()],
});
}
let runChild;
let onServerReadyCallback;
Expand All @@ -126,6 +127,8 @@ const forkRun = (runCmdPath, runArgs = [], options = {}) => {
filterExecArgv.some(filterArg => arg.startsWith(filterArg))
);

const isPerfInit = runArgs.includes('--perf-init');

function innerFork(isFirstFork = false) {
const startTime = Date.now();

Expand Down Expand Up @@ -157,10 +160,14 @@ const forkRun = (runCmdPath, runArgs = [], options = {}) => {
Date.now() - startTime,
currentDebugUrl
));
runChild.removeListener('message', onServerReady);
lastBootstrapStatus = true;
} else if (data.title === 'debug-url') {
currentDebugUrl = data.debugUrl;
} else if (data.title === 'perf-init') {
if (isPerfInit && isFirstFork) {
// perf init
consoleOutput.renderPerfInit(data.data);
}
}
} catch (err) {
console.error(err);
Expand All @@ -171,19 +178,7 @@ const forkRun = (runCmdPath, runArgs = [], options = {}) => {
if (runArgs.includes('--keepalive')) {
runChild.once('exit', code => {
if (code === CHILD_PROCESS_EXCEPTION_EXIT_CODE) {
output(colors.red('*'.repeat(120)));
output(
`A ${colors.red(
`${colors.bright(
'Critical unhandledRejection or uncaughtException'
)}`
)} was detected and the process has exited automatically.`
);
output('Please make sure to handle it.');
output(
'The --keepalive parameter was enabled, we will do our best to ensure the process remains normal.'
);
output(colors.red('*'.repeat(120)));
consoleOutput.renderKeepAlive();
if (lastBootstrapStatus === undefined || lastBootstrapStatus) {
// 只有上一次启动成功了,才继续保活拉起,如果启动就失败了,就停止重启
innerFork(false);
Expand All @@ -198,6 +193,7 @@ const forkRun = (runCmdPath, runArgs = [], options = {}) => {
innerFork(true);

const killRunningChild = async signal => {
runChild.removeAllListeners('message');
if (isWin) {
await new Promise(resolve => {
if (!runChild || runChild.exitCode !== null) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"dependencies": {
"@midwayjs/glob": "^1.1.1",
"chokidar": "^3.6.0",
"cli-table3": "^0.6.5",
"compare-versions": "^6.1.0",
"source-map-support": "^0.5.21",
"tar": "^7.4.0",
Expand Down

0 comments on commit 54ee471

Please sign in to comment.