refactor: HMR
This commit is contained in:
parent
4bed4730b9
commit
98bbaaa98f
|
@ -41,14 +41,16 @@ export const hooks = {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when a fleck is HMR'd
|
* Invoked when a module is HMR'd. Throw to abort hot reload and restart application.
|
||||||
|
* Must be synchronous.
|
||||||
|
*
|
||||||
* @param {string} path The path of the fleck
|
* @param {string} path The path of the fleck
|
||||||
* @param {Module} updatedFleck The updated fleck module.
|
* @param {Module} updated The updated module.
|
||||||
* @invoke
|
* @invokeSequential
|
||||||
*/
|
*/
|
||||||
'@flecks/core.hmr': (path, updatedFleck) => {
|
'@flecks/core.hmr': (path, updated) => {
|
||||||
if ('my-fleck' === path) {
|
if ('my-fleck' === path) {
|
||||||
updatedFleck.doSomething();
|
updated.doSomething();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -70,8 +70,16 @@ module.exports = async (config, env, argv, flecks) => {
|
||||||
// Hooks for each fleck.
|
// Hooks for each fleck.
|
||||||
resolvedPaths.forEach((path) => {
|
resolvedPaths.forEach((path) => {
|
||||||
source.push(` module.hot.accept('${path}', async () => {`);
|
source.push(` module.hot.accept('${path}', async () => {`);
|
||||||
source.push(` global.flecks.refresh('${path}', require('${path}'));`);
|
source.push(` const M = require('${path}')`);
|
||||||
source.push(` global.flecks.invoke('@flecks/core.hmr', '${path}');`);
|
source.push(' try {');
|
||||||
|
source.push(` global.flecks.invokeSequential('@flecks/core.hmr', '${path}', M);`);
|
||||||
|
source.push(` global.flecks.refresh('${path}', M);`);
|
||||||
|
source.push(' }');
|
||||||
|
source.push(' catch (error) {');
|
||||||
|
// eslint-disable-next-line no-template-curly-in-string
|
||||||
|
source.push(' console.error(`HMR failed for fleck: ${error.message}`);');
|
||||||
|
source.push(' module.hot.invalidate();');
|
||||||
|
source.push(' }');
|
||||||
source.push(' });');
|
source.push(' });');
|
||||||
});
|
});
|
||||||
source.push('}');
|
source.push('}');
|
||||||
|
|
|
@ -85,12 +85,23 @@ class StartServerPlugin {
|
||||||
args,
|
args,
|
||||||
...(inspectPort && {inspectPort}),
|
...(inspectPort && {inspectPort}),
|
||||||
});
|
});
|
||||||
this.worker = cluster.fork(env);
|
const setupListeners = (worker) => {
|
||||||
if (killOnExit) {
|
if (killOnExit) {
|
||||||
this.worker.on('exit', () => {
|
worker.on('exit', () => {
|
||||||
process.exit();
|
process.exit();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
worker.on('message', (message) => {
|
||||||
|
if ('hmr-restart' === message) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('[HMR] Restarting application...');
|
||||||
|
this.worker = cluster.fork(env);
|
||||||
|
setupListeners(this.worker);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
this.worker = cluster.fork(env);
|
||||||
|
setupListeners(this.worker);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.worker.on('error', reject);
|
this.worker.on('error', reject);
|
||||||
this.worker.on('online', resolve);
|
this.worker.on('online', resolve);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import cluster from 'cluster';
|
||||||
import {mkdir} from 'fs/promises';
|
import {mkdir} from 'fs/promises';
|
||||||
import {tmpdir} from 'os';
|
import {tmpdir} from 'os';
|
||||||
import {join} from 'path';
|
import {join} from 'path';
|
||||||
|
@ -30,3 +31,14 @@ import {D, Flecks} from '@flecks/core';
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
if (module.hot) {
|
||||||
|
module.hot.accept('./runtime', () => {
|
||||||
|
if (cluster.isWorker) {
|
||||||
|
cluster.worker.send('hmr-restart');
|
||||||
|
const error = new Error('Restart requested!');
|
||||||
|
error.stack = '';
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,18 @@ class SocketWrapper {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async waitForHmr() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.socket.on('error', reject);
|
||||||
|
this.socket.on('data', (data) => {
|
||||||
|
const action = JSON.parse(data.toString());
|
||||||
|
if ('hmr' === action.type) {
|
||||||
|
resolve(action);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listen() {
|
export async function listen() {
|
||||||
|
|
|
@ -5,8 +5,21 @@ const {
|
||||||
} = process.env;
|
} = process.env;
|
||||||
|
|
||||||
export const hooks = {
|
export const hooks = {
|
||||||
|
'@flecks/core.hmr': async (path, M, flecks) => {
|
||||||
|
if (!flecks.socket) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flecks.socket.write(JSON.stringify({
|
||||||
|
type: 'hmr',
|
||||||
|
payload: path,
|
||||||
|
}));
|
||||||
|
},
|
||||||
'@flecks/server.up': async (flecks) => {
|
'@flecks/server.up': async (flecks) => {
|
||||||
|
if (!FLECKS_SERVER_TEST_SOCKET) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const socket = createConnection({path: FLECKS_SERVER_TEST_SOCKET});
|
const socket = createConnection({path: FLECKS_SERVER_TEST_SOCKET});
|
||||||
|
flecks.socket = socket;
|
||||||
socket.on('connect', () => {
|
socket.on('connect', () => {
|
||||||
socket.on('data', (data) => {
|
socket.on('data', (data) => {
|
||||||
const {meta, payload, type} = JSON.parse(data);
|
const {meta, payload, type} = JSON.parse(data);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user