2022-05-06 13:10:09 +08:00

124 lines
3.8 KiB
JavaScript

import { chokidar, winPath, lodash, getAppPath } from '@fesjs/utils';
import { watchPkg } from './watchPkg';
async function generateWhenFilesChange({ api }) {
const { paths } = api;
let watchers = [];
function unwatch() {
watchers.forEach((watcher) => {
watcher.close();
});
watchers = [];
}
function createWatcher(path) {
const watcher = chokidar.watch(path, {
// ignore .dotfiles and _mock.js
ignored: /(^|[/\\])(_mock.js$|\..)/,
ignoreInitial: true,
});
watcher.on(
'all',
lodash.throttle(async () => {
await api.applyPlugins({
key: 'onGenerateFiles',
type: api.ApplyPluginsType.event,
});
}, 100),
);
watchers.push(watcher);
}
const watcherPaths = await api.applyPlugins({
key: 'addTmpGenerateWatcherPaths',
type: api.ApplyPluginsType.add,
initialValue: [paths.absPagesPath, getAppPath(paths.absSrcPath)],
});
lodash.uniq(watcherPaths.map((p) => winPath(p))).forEach((p) => {
createWatcher(p);
});
return unwatch;
}
export async function startWatch(api) {
if (process.env.WATCH === 'none') return;
let unwatchs = [];
const restartServer = () => {
for (const unwatch of unwatchs) {
unwatch();
}
unwatchs = [];
api.restartServer();
};
// generate files
const unwatchGenerateFiles = await generateWhenFilesChange({ api });
unwatchs.push(unwatchGenerateFiles);
// watch pkg changes
const unwatchPkg = watchPkg({
cwd: api.cwd,
onChange() {
console.log();
api.logger.info('Plugins in package.json changed.');
restartServer();
},
});
unwatchs.push(unwatchPkg);
// watch config change
const unwatchConfig = api.service.configInstance.watch({
userConfig: api.service.userConfig,
onChange: async ({ pluginChanged, valueChanged }) => {
if (pluginChanged.length) {
console.log();
api.logger.info(`Plugins of ${pluginChanged.map((p) => p.key).join(', ')} changed.`);
restartServer();
}
if (valueChanged.length) {
let reload = false;
let regenerateTmpFiles = false;
const fns = [];
const reloadConfigs = [];
valueChanged.forEach(({ key, pluginId }) => {
const { onChange } = api.service.plugins[pluginId].config || {};
if (onChange === api.ConfigChangeType.regenerateTmpFiles) {
regenerateTmpFiles = true;
}
if (!onChange || onChange === api.ConfigChangeType.reload) {
reload = true;
reloadConfigs.push(key);
}
if (typeof onChange === 'function') {
fns.push(onChange);
}
});
if (reload) {
console.log();
api.logger.info(`Config ${reloadConfigs.join(', ')} changed.`);
restartServer();
} else {
api.service.userConfig = api.service.configInstance.getUserConfig();
await api.setConfig();
if (regenerateTmpFiles) {
await api.applyPlugins({
key: 'onGenerateFiles',
type: api.ApplyPluginsType.event,
});
} else {
fns.forEach((fn) => fn());
}
}
}
},
});
unwatchs.push(unwatchConfig);
}