Перезапуск экспресс-сервера в esbuild
Я пытаюсь создать простой
express
сервер с
esbuild
. Это мой код
import express from "express";
const app = express();
const port = 3000;
const stopServer = {
stop: () => {},
};
export const createServer = async () => {
app.get("/", async (req, res) => {
res.json({
first: "Hello",
});
});
const server = app.listen(port, () => {
console.log(`Listening on port: ${port}`);
});
stopServer.stop = () => {
server.close();
};
};
export const stop = () => {
stopServer.stop();
stopServer.stop = () => {};
};
esbuild.config.js
const esbuild = require("esbuild");
const path = require("path");
const restartPlugin = () => {
return {
name: "restart-express",
setup(build) {
build.onEnd(async (res) => {
const { stop, createServer } = await import("../dist/server.js");
stop();
createServer();
});
},
};
};
const run = async () => {
await esbuild.build({
entryPoints: [path.resolve(__dirname, "../src/server.ts")],
outdir: path.resolve(__dirname, "../dist"),
platform: "node",
sourcemap: true,
format: "cjs",
watch: {
onRebuild: async (err, res) => {
if (err) {
console.error(err);
} else {
console.log("There is some change");
}
},
},
plugins: [restartPlugin()],
});
};
run();
Ссылка на плагин: https://github.com/evanw/esbuild/issues/1258#issuecomment-834676530
Если бы вы запустили это приложение, я сначала буду работать, но когда вы измените код, сервер не будет обновляться, даже если вы обновите страницу.
Я не совсем уверен, где я делаю ошибку, Любая помощь, пожалуйста
3 ответа
Проблема в том, что
node
кэшировать
import("..dist/server.js")
, в результате он никогда не вернет новый модуль. Для решения этой проблемы напишем функцию
const purgeAppRequireCache = (buildPath) => {
for (let key in require.cache) {
if (key.startsWith(buildPath)) {
delete require.cache[key];
}
}
};
Что удалит кеш из узла. Мы также можем использовать эту функцию таким же образом. Что решает мою проблему
const esbuild = require("esbuild");
const path = require("path");
const startPlugin = () => {
return {
name: "startPlugin",
setup(build) {
build.onEnd((res) => {
const serverPath = path.resolve(__dirname, "../dist/server.js");
const { stop } = require("../dist/server.js");
stop();
purgeAppRequireCache(serverPath);
purgeAppRequireCache(path.resolve(__dirname, "../src"));
const { listen } = require("../dist/server");
listen();
});
},
};
};
const run = async () => {
await esbuild.build({
entryPoints: [path.resolve(__dirname, "../src/server.tsx")],
outdir: path.resolve(__dirname, "../dist"),
platform: "node",
sourcemap: true,
format: "cjs",
watch: true,
bundle: true,
plugins: [startPlugin()],
});
};
run();
const purgeAppRequireCache = (buildPath) => {
for (let key in require.cache) {
if (key.startsWith(buildPath)) {
delete require.cache[key];
}
}
};
Если вы не перезагрузите среду выполнения, глобальный объект и дочерний объект будут иметь одинаковую ошибку. Вы можете использовать при изменении кода, это так же быстро, как
require(xxx)
, есть примеры кодов: https://github.com/ymzuiku/bike/blob/master/lib/index.js
Если вам нужно увидеть
kill and fork cluster
Например, вот тот же пакет функций, также использующий esbuild, но использующий fs.watch: https://www.npmjs.com/package/bike
Надеюсь, это может вам помочь :)
@es-exec/esbuild-plugin-serve
или@es-exec/esbuild-plugin-start
два альтернативных плагина esbuild, которые вы можете попробовать. Они запускают ваши пакеты или любой сценарий командной строки для вас после сборки вашего проекта (поддерживает режим наблюдения для перестроения при изменении файла).
Документацию можно найти по следующему адресу:
Отказ от ответственности: я являюсь автором этих пакетов.