84 lines
2.2 KiB
JavaScript
84 lines
2.2 KiB
JavaScript
/**
|
|
* LuckyChit Web Server
|
|
* Express server to serve Flutter web build with proper caching
|
|
*
|
|
* Usage:
|
|
* node web-server.js
|
|
* Or with PM2:
|
|
* pm2 start web-server.js --name "luckychit-web"
|
|
*/
|
|
|
|
const express = require('express');
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 8080;
|
|
const BUILD_DIR = path.join(__dirname, 'build/web');
|
|
|
|
// Check if build directory exists
|
|
if (!fs.existsSync(BUILD_DIR)) {
|
|
console.error('❌ Error: build/web directory not found!');
|
|
console.error(' Please run: flutter build web --release');
|
|
process.exit(1);
|
|
}
|
|
|
|
// Security headers
|
|
app.use((req, res, next) => {
|
|
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
|
|
res.setHeader('X-XSS-Protection', '1; mode=block');
|
|
next();
|
|
});
|
|
|
|
// Serve static files with caching strategy
|
|
app.use(express.static(BUILD_DIR, {
|
|
maxAge: '1y', // Cache static assets for 1 year
|
|
immutable: true,
|
|
setHeaders: (res, filePath) => {
|
|
// Don't cache HTML files (always serve fresh)
|
|
if (filePath.endsWith('.html')) {
|
|
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
res.setHeader('Pragma', 'no-cache');
|
|
res.setHeader('Expires', '0');
|
|
}
|
|
}
|
|
}));
|
|
|
|
// Handle Flutter routes (SPA - Single Page Application)
|
|
// Any route not found as a static file should serve index.html
|
|
app.get('*', (req, res) => {
|
|
res.sendFile(path.join(BUILD_DIR, 'index.html'));
|
|
});
|
|
|
|
// Error handling
|
|
app.use((err, req, res, next) => {
|
|
console.error('Error:', err);
|
|
res.status(500).send('Internal Server Error');
|
|
});
|
|
|
|
// Start server
|
|
app.listen(PORT, '0.0.0.0', () => {
|
|
console.log('');
|
|
console.log('✅ LuckyChit Flutter Web App');
|
|
console.log('============================');
|
|
console.log(`🌐 Running on: http://localhost:${PORT}`);
|
|
console.log(`📁 Serving: ${BUILD_DIR}`);
|
|
console.log('');
|
|
console.log('📝 Logs:');
|
|
console.log(' Access: http://localhost:' + PORT);
|
|
console.log('');
|
|
});
|
|
|
|
// Graceful shutdown
|
|
process.on('SIGTERM', () => {
|
|
console.log('SIGTERM received, shutting down gracefully...');
|
|
process.exit(0);
|
|
});
|
|
|
|
process.on('SIGINT', () => {
|
|
console.log('SIGINT received, shutting down gracefully...');
|
|
process.exit(0);
|
|
});
|
|
|