mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-14 04:31:07 +01:00
feat(dev): add hot-realoding proxy dev server on :30001
This commit is contained in:
parent
1b9defe4ad
commit
ddb4c29252
7 changed files with 315 additions and 40 deletions
86
tools/dev-proxy.mjs
Normal file
86
tools/dev-proxy.mjs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env node
|
||||
import http from 'http';
|
||||
import httpProxy from 'http-proxy';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import url from 'url';
|
||||
import { lookup as mimeLookup } from 'mime-types';
|
||||
|
||||
// Load .env
|
||||
const envPath = path.resolve(process.cwd(), '.env');
|
||||
if (fs.existsSync(envPath)) {
|
||||
const envFile = fs.readFileSync(envPath, 'utf8');
|
||||
envFile.split('\n').forEach(line => {
|
||||
const [key, value] = line.split('=');
|
||||
if (key && value) process.env[key] = value;
|
||||
});
|
||||
}
|
||||
|
||||
const systemId = 'daggerheart';
|
||||
const pkgBase = `/systems/${systemId}`;
|
||||
const devRoot = process.cwd();
|
||||
|
||||
// Foundry server target (reverse proxy)
|
||||
const targetPort = Number(process.env.DH_DEV_TARGET_PORT || process.env.FOUNDRY_PORT || 30000);
|
||||
const target = `http://localhost:${targetPort}`;
|
||||
|
||||
// Dev proxy port
|
||||
const proxyPort = Number(process.env.DH_DEV_PROXY_PORT || 30001);
|
||||
|
||||
// Asset overlay: serve files from repo for /systems/daggerheart/*
|
||||
function tryServeOverlay(req, res) {
|
||||
const parsed = url.parse(req.url);
|
||||
const pathname = parsed.pathname || '/';
|
||||
if (!pathname.startsWith(pkgBase + '/')) return false;
|
||||
|
||||
// Map /systems/daggerheart/... to local repo path
|
||||
const rel = pathname.replace(pkgBase + '/', '');
|
||||
|
||||
const serveCandidates = [
|
||||
// direct match in repo
|
||||
path.join(devRoot, rel),
|
||||
// common tree roots
|
||||
path.join(devRoot, 'assets', rel.replace(/^assets\//, '')),
|
||||
path.join(devRoot, 'build', rel.replace(/^build\//, '')),
|
||||
path.join(devRoot, 'lang', rel.replace(/^lang\//, '')),
|
||||
path.join(devRoot, 'module', rel.replace(/^module\//, '')),
|
||||
path.join(devRoot, 'styles', rel.replace(/^styles\//, '')),
|
||||
path.join(devRoot, 'templates', rel.replace(/^templates\//, '')),
|
||||
path.join(devRoot, 'system.json'),
|
||||
path.join(devRoot, 'daggerheart.mjs')
|
||||
];
|
||||
|
||||
for (const candidate of serveCandidates) {
|
||||
try {
|
||||
const stat = fs.statSync(candidate);
|
||||
if (stat.isFile()) {
|
||||
const stream = fs.createReadStream(candidate);
|
||||
stream.on('error', () => res.end());
|
||||
const contentType = mimeLookup(candidate) || 'application/octet-stream';
|
||||
res.writeHead(200, { 'Content-Type': contentType });
|
||||
stream.pipe(res);
|
||||
return true;
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const proxy = httpProxy.createProxyServer({ target, ws: true, changeOrigin: true, selfHandleResponse: false });
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
// If the request targets our system path, try to serve local overlay first
|
||||
if (tryServeOverlay(req, res)) return;
|
||||
proxy.web(req, res, { target });
|
||||
});
|
||||
|
||||
server.on('upgrade', (req, socket, head) => {
|
||||
proxy.ws(req, socket, head, { target });
|
||||
});
|
||||
|
||||
server.listen(proxyPort, () => {
|
||||
console.log(`Daggerheart dev proxy listening on http://localhost:${proxyPort} (target ${target})`);
|
||||
console.log(`Overlaying ${pkgBase} from ${devRoot}`);
|
||||
});
|
||||
|
||||
|
||||
|
|
@ -4,15 +4,18 @@ import fs from 'fs';
|
|||
const args = process.argv.slice(2);
|
||||
const foundryPath = args.find(arg => arg.startsWith('--foundry-path='))?.split('=')[1];
|
||||
const dataPath = args.find(arg => arg.startsWith('--data-path='))?.split('=')[1];
|
||||
const portArg = args.find(arg => arg.startsWith('--port='))?.split('=')[1];
|
||||
|
||||
if (!foundryPath || !dataPath) {
|
||||
console.log('Usage: npm run setup:dev -- --foundry-path="/path/to/foundry/main.js" --data-path="/path/to/data"');
|
||||
console.log('Usage: npm run setup:dev -- --foundry-path="/path/to/foundry/main.js" --data-path="/path/to/data" [--port=30000]');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const port = portArg || '30000';
|
||||
const envContent = `FOUNDRY_MAIN_PATH=${foundryPath}
|
||||
FOUNDRY_DATA_PATH=${dataPath}
|
||||
FOUNDRY_PORT=${port}
|
||||
`;
|
||||
|
||||
fs.writeFileSync('.env', envContent);
|
||||
console.log(`✅ Development environment configured: ${foundryPath}, ${dataPath}`);
|
||||
console.log(`✅ Development environment configured:\n Foundry main: ${foundryPath}\n Data path: ${dataPath}\n Port: ${port}`);
|
||||
|
|
|
|||
|
|
@ -16,12 +16,23 @@ if (fs.existsSync('.env')) {
|
|||
// Set defaults if not in environment
|
||||
const foundryPath = process.env.FOUNDRY_MAIN_PATH || '../../../../FoundryDev/main.js';
|
||||
const dataPath = process.env.FOUNDRY_DATA_PATH || '../../../';
|
||||
const foundryPort = process.env.FOUNDRY_PORT || '30000';
|
||||
|
||||
// Run the original command with proper environment
|
||||
const args = ['rollup -c --watch', `node "${foundryPath}" --dataPath="${dataPath}" --noupnp`, 'gulp'];
|
||||
const args = [
|
||||
'rollup -c --watch',
|
||||
`node "${foundryPath}" --dataPath="${dataPath}" --noupnp --port=${foundryPort}`,
|
||||
'gulp',
|
||||
'node ./tools/dev-proxy.mjs'
|
||||
];
|
||||
|
||||
spawn('npx', ['concurrently', ...args.map(arg => `"${arg}"`)], {
|
||||
stdio: 'inherit',
|
||||
cwd: process.cwd(),
|
||||
shell: true
|
||||
});
|
||||
|
||||
// Friendly hint
|
||||
console.log('\n\x1b[32mDev proxy: http://localhost:30001\x1b[0m (overlay)');
|
||||
console.log(`\x1b[36mFoundry: http://localhost:${foundryPort}\x1b[0m (installed)`);
|
||||
console.log('\nOpen http://localhost:30001 to see your dev version, or close it to return to the installed version.');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue