Skip to content

Commit 73a4174

Browse files
author
chenyongqing.cyq
committed
feat: sigint hooks (ice-lab#33)
1 parent be69e9a commit 73a4174

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

packages/build-scripts/bin/start.js

+40
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const chokidar = require('chokidar');
55
const detect = require('detect-port');
66
const path = require('path');
77
const log = require('../lib/utils/log');
8+
const fse = require('fs-extra');
89

910
let child = null;
1011
const rawArgv = parse(process.argv.slice(2));
@@ -65,9 +66,48 @@ function restartProcess() {
6566
process.exit(code);
6667
}
6768
});
69+
70+
process.on('SIGINT', () => {
71+
const rootDir = process.cwd();
72+
const SIGINThooksFileName = 'SIGINThooks.json';
73+
const hooksPath = path.resolve(rootDir, SIGINThooksFileName);
74+
let hooks = legalSIGINThooks(hooksPath);
75+
if (hooks) {
76+
applySIGINThooks(hooks, hooksPath);
77+
}
78+
process.exit(1);
79+
})
6880
})();
6981
}
7082

83+
const legalSIGINThooks = (hooksPath) => {
84+
let hooks;
85+
if (fse.existsSync(hooksPath)) {
86+
hooks = fse.readJsonSync(hooksPath);
87+
}
88+
return hooks;
89+
}
90+
91+
const applySIGINThooks = (hooks, hooksPath) => {
92+
93+
log.info('handleing SIGINThooks...');
94+
try {
95+
hooks.forEach(item => {
96+
try {
97+
const fn = eval(item);
98+
fn();
99+
} catch(e) {
100+
log.error('SIGINThook item error', e);
101+
}
102+
})
103+
} catch (e) {
104+
log.error('SIGINThooks error', e);
105+
}
106+
fse.removeSync(hooksPath);
107+
log.info('handleing SIGINThooks finished');
108+
return
109+
}
110+
71111
const onUserChange = () => {
72112
console.log('\n');
73113
log.info('build.json has been changed');

packages/build-scripts/src/commands/start.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ export = async function({
3333
log.verbose('OPTIONS', `${command} cliOptions: ${JSON.stringify(args, null, 2)}`);
3434
let serverUrl = '';
3535

36-
const { applyHook, webpack } = context;
36+
const {
37+
applyHook,
38+
webpack,
39+
removeSIGINThooks,
40+
} = context;
3741

3842
let configArr = [];
3943
try {
@@ -108,6 +112,8 @@ export = async function({
108112
isFirstCompile,
109113
stats,
110114
});
115+
116+
removeSIGINThooks();
111117
});
112118
// require webpack-dev-server after context setup
113119
// context may hijack webpack resolve

packages/build-scripts/src/core/Context.ts

+31
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ export interface IOnHook {
7272
(eventName: string, callback: IOnHookCallback): void;
7373
}
7474

75+
export interface IOnSIGINThooks {
76+
(callback: (() => void)): void;
77+
}
78+
7579
export interface IPluginConfigWebpack {
7680
(config: WebpackChain): void;
7781
}
@@ -678,6 +682,33 @@ class Context {
678682
this.configArr = this.configArr.filter((config) => !this.cancelTaskNames.includes(config.name));
679683
return this.configArr;
680684
}
685+
686+
public removeSIGINThooks: () => void = () => {
687+
const SIGINThooksFileName = 'SIGINThooks.json';
688+
const hooksPath = path.resolve(this.rootDir, SIGINThooksFileName);
689+
if (fs.existsSync(hooksPath)) {
690+
fs.removeSync(hooksPath);
691+
}
692+
}
693+
694+
public onSIGINThooks: IOnSIGINThooks = (fn) => {
695+
if (!fn || (typeof fn !== 'function')) {
696+
log.warn('siginthooks arg wrong', 'fn should be function or stringify function');
697+
return;
698+
}
699+
700+
fn = (fn as any).toString();
701+
702+
const SIGINThooksFileName = 'SIGINThooks.json';
703+
const hooksPath = path.resolve(this.rootDir, SIGINThooksFileName);
704+
if (!fs.existsSync(hooksPath)) {
705+
fs.ensureFileSync(hooksPath);
706+
fs.outputFileSync(hooksPath, JSON.stringify([]));
707+
}
708+
const hooks = fs.readJsonSync(hooksPath);
709+
hooks.push(fn);
710+
fs.outputFileSync(hooksPath, JSON.stringify(hooks));
711+
}
681712
}
682713

683714
export default Context;

0 commit comments

Comments
 (0)