forked from izu/student-web-if-development-kit
fix: run RODA with Vite dev
This commit is contained in:
Generated
-13
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"name": "roda",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "roda",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,3 @@
|
||||
{
|
||||
"name": "roda",
|
||||
"version": "1.0.0",
|
||||
"description": "Project website untuk menampilkan sorotan dan prestasi karya mahasiswa program studi Informatika Universitas Tanjungpura.",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js",
|
||||
"dev": "node server.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
"type": "commonjs"
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
"type": "module",
|
||||
"description": "Student-safe static page assignment kit for Informatika UNTAN",
|
||||
"scripts": {
|
||||
"dev": "node groups/RODA/server.js",
|
||||
"dev": "node scripts/dev.js",
|
||||
"dev:vite": "vite",
|
||||
"dev:roda": "node groups/RODA/server.js",
|
||||
"build": "vite build",
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import { spawn } from 'node:child_process';
|
||||
|
||||
export function createDevProcessSpecs({
|
||||
nodeCommand = process.execPath,
|
||||
env = process.env,
|
||||
} = {}) {
|
||||
return {
|
||||
roda: {
|
||||
command: nodeCommand,
|
||||
args: ['groups/RODA/server.js'],
|
||||
options: {
|
||||
env: {
|
||||
...env,
|
||||
HOST: env.RODA_HOST || '127.0.0.1',
|
||||
PORT: env.RODA_PORT || '3000',
|
||||
},
|
||||
stdio: ['ignore', 'ignore', 'pipe'],
|
||||
},
|
||||
},
|
||||
vite: {
|
||||
command: nodeCommand,
|
||||
args: ['node_modules/vite/bin/vite.js'],
|
||||
options: {
|
||||
env: { ...env },
|
||||
stdio: 'inherit',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function startDevServers({
|
||||
spawnProcess = spawn,
|
||||
specs = createDevProcessSpecs(),
|
||||
} = {}) {
|
||||
const roda = spawnProcess(specs.roda.command, specs.roda.args, specs.roda.options);
|
||||
const vite = spawnProcess(specs.vite.command, specs.vite.args, specs.vite.options);
|
||||
let shuttingDown = false;
|
||||
let rodaErrorOutput = '';
|
||||
|
||||
roda.stderr?.on('data', (chunk) => {
|
||||
const message = String(chunk);
|
||||
rodaErrorOutput += message;
|
||||
if (!message.includes('EADDRINUSE')) {
|
||||
process.stderr.write(`[roda] ${message}`);
|
||||
}
|
||||
});
|
||||
|
||||
function stopChildren() {
|
||||
shuttingDown = true;
|
||||
if (!roda.killed) {
|
||||
roda.kill();
|
||||
}
|
||||
if (!vite.killed) {
|
||||
vite.kill();
|
||||
}
|
||||
}
|
||||
|
||||
vite.on('exit', (code, signal) => {
|
||||
shuttingDown = true;
|
||||
if (!roda.killed) {
|
||||
roda.kill();
|
||||
}
|
||||
|
||||
if (signal) {
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
process.exitCode = code ?? 0;
|
||||
});
|
||||
|
||||
roda.on('exit', (code, signal) => {
|
||||
if (shuttingDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rodaErrorOutput.includes('EADDRINUSE')) {
|
||||
process.stderr.write('[roda] Port 3000 is already in use; continuing with the existing RODA server.\n');
|
||||
return;
|
||||
}
|
||||
|
||||
const reason = signal ? `signal ${signal}` : `exit code ${code}`;
|
||||
process.stderr.write(`[roda] server stopped unexpectedly (${reason})\n`);
|
||||
if (!vite.killed) {
|
||||
vite.kill();
|
||||
}
|
||||
process.exitCode = code || 1;
|
||||
});
|
||||
|
||||
process.once('SIGINT', stopChildren);
|
||||
process.once('SIGTERM', stopChildren);
|
||||
|
||||
return { roda, vite };
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { startDevServers } from './dev-runner.js';
|
||||
|
||||
startDevServers();
|
||||
+16
-55
@@ -10,9 +10,11 @@ const rodaDashboardCacheTtlMs = 5 * 60 * 1000;
|
||||
const dashboardRequestHeaders = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36',
|
||||
};
|
||||
const rodaHost = process.env.RODA_HOST || '127.0.0.1';
|
||||
const rodaPort = process.env.RODA_PORT || '3000';
|
||||
const rodaTarget = `http://${rodaHost}:${rodaPort}`;
|
||||
|
||||
let rodaDashboardHtmlCache;
|
||||
let rodaDashboardDevCache = { html: '', timestamp: 0 };
|
||||
|
||||
function collectHtmlInputs(dir) {
|
||||
const inputs = {};
|
||||
@@ -124,61 +126,20 @@ function embedRodaDashboardData() {
|
||||
};
|
||||
}
|
||||
|
||||
function serveRodaDashboardApi() {
|
||||
return {
|
||||
name: 'serve-roda-dashboard-api',
|
||||
configureServer(server) {
|
||||
server.middlewares.use(async (req, res, next) => {
|
||||
const requestUrl = new URL(req.url || '/', 'http://localhost');
|
||||
if (requestUrl.pathname !== '/api/dashboard') {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
||||
res.writeHead(405, { 'Content-Type': 'text/plain; charset=utf-8' });
|
||||
res.end('METHOD_NOT_ALLOWED');
|
||||
return;
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
try {
|
||||
let html = rodaDashboardDevCache.html;
|
||||
let cacheStatus = 'HIT';
|
||||
|
||||
if (!html || (now - rodaDashboardDevCache.timestamp) >= rodaDashboardCacheTtlMs) {
|
||||
html = await requestRodaDashboardHtml();
|
||||
rodaDashboardDevCache = { html, timestamp: Date.now() };
|
||||
cacheStatus = 'MISS';
|
||||
}
|
||||
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/html; charset=utf-8',
|
||||
'X-Cache': cacheStatus,
|
||||
});
|
||||
res.end(req.method === 'HEAD' ? '' : html);
|
||||
} catch (error) {
|
||||
if (rodaDashboardDevCache.html) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/html; charset=utf-8',
|
||||
'X-Cache': 'STALE',
|
||||
});
|
||||
res.end(req.method === 'HEAD' ? '' : rodaDashboardDevCache.html);
|
||||
return;
|
||||
}
|
||||
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
console.warn(`[roda-dashboard] Dev dashboard fetch failed: ${message}`);
|
||||
res.writeHead(502, { 'Content-Type': 'text/plain; charset=utf-8' });
|
||||
res.end('DASHBOARD_FETCH_FAILED');
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [serveRodaDashboardApi(), embedRodaDashboardData(), copyStaticAssets()],
|
||||
plugins: [embedRodaDashboardData(), copyStaticAssets()],
|
||||
server: {
|
||||
proxy: {
|
||||
'/groups/RODA/api/dashboard': {
|
||||
target: rodaTarget,
|
||||
changeOrigin: true,
|
||||
},
|
||||
'/api/dashboard': {
|
||||
target: rodaTarget,
|
||||
changeOrigin: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: collectHtmlInputs(root),
|
||||
|
||||
Reference in New Issue
Block a user