update ttl, use file based hashing to prevent stale data.

This commit is contained in:
Evan
2025-03-05 20:14:49 -08:00
parent 3a0bc594ae
commit dacd9607e4
3 changed files with 164 additions and 28 deletions
+93 -10
View File
@@ -40,24 +40,107 @@ server {
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Static file caching for the "static" directory
location ~ ^/static/(.*)$ {
# Static file handling with proper MIME types and consistent caching
location ~* ^/static/(.*)$ {
proxy_pass http://127.0.0.1:3000;
# Include MIME types
include /etc/nginx/mime.types;
# Cache configuration for static files
proxy_cache STATIC;
proxy_ignore_headers Cache-Control;
proxy_cache_valid 200 302 60m;
proxy_cache_valid 200 302 24h; # Cache successful responses for 24 hours
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
# Show cache status in response headers
add_header X-Cache-Status $upstream_cache_status;
# Standard proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Default cache policy for static files
add_header Cache-Control "public, max-age=86400"; # 24 hours
}
# Binary files caching
location ~* \.(bin|dat|exe|dll|so|dylib)$ {
proxy_pass http://127.0.0.1:3000;
add_header Cache-Control "public, max-age=31536000, immutable"; # 1 year for binary files
proxy_cache STATIC;
proxy_cache_valid 200 302 24h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status;
# Cache bypass if needed (for development/debugging)
proxy_cache_bypass $http_pragma $http_authorization;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Specific file type caching rules (outside the /static/ location)
location ~* \.js$ {
proxy_pass http://127.0.0.1:3000;
add_header Content-Type application/javascript;
add_header Cache-Control "public, max-age=31536000, immutable"; # 1 year for JS files
# No TTL as requested (browser will check each time)
expires -1;
add_header Cache-Control "no-cache";
proxy_cache STATIC;
proxy_cache_valid 200 302 24h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status;
# Standard proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~* \.css$ {
proxy_pass http://127.0.0.1:3000;
add_header Content-Type text/css;
add_header Cache-Control "public, max-age=31536000, immutable"; # 1 year for CSS files
proxy_cache STATIC;
proxy_cache_valid 200 302 24h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~* \.html$ {
proxy_pass http://127.0.0.1:3000;
add_header Content-Type text/html;
add_header Cache-Control "public, max-age=86400"; # 24 hours for HTML files
proxy_cache STATIC;
proxy_cache_valid 200 302 24h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Root location - make sure index.html is the default
location = / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+19 -2
View File
@@ -23,8 +23,25 @@ const server = http.createServer(app);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
app.use(express.json());
// Serve static files from the 'out' directory
app.use(express.static(path.join(__dirname, "../../static")));
app.use(
express.static(path.join(__dirname, "../../static"), {
maxAge: "1y", // Set max-age to 1 year for all static assets
setHeaders: (res, path) => {
// You can conditionally set different cache times based on file types
if (path.endsWith(".html")) {
// HTML files get shorter cache time
res.setHeader("Cache-Control", "public, max-age=60");
} else if (path.match(/\.(js|css|svg)$/)) {
// JS, CSS, SVG get long cache with immutable
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
} else if (path.match(/\.(bin|dat|exe|dll|so|dylib)$/)) {
// Binary files also get long cache with immutable
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
}
// Other file types use the default maxAge setting
},
}),
);
app.use(express.json());
app.set("trust proxy", 3);
+52 -16
View File
@@ -14,7 +14,7 @@ export default (env, argv) => {
entry: "./src/client/Main.ts",
output: {
publicPath: "/",
filename: "static/js/bundle.js",
filename: "js/[name].[contenthash].js", // Added content hash
path: path.resolve(__dirname, "static"),
clean: true,
},
@@ -22,11 +22,17 @@ export default (env, argv) => {
rules: [
{
test: /\.bin$/,
use: "raw-loader",
type: "asset/resource", // Changed from raw-loader
generator: {
filename: "binary/[name].[contenthash][ext]", // Added content hash
},
},
{
test: /\.txt$/,
use: "raw-loader",
type: "asset/resource", // Changed from raw-loader
generator: {
filename: "text/[name].[contenthash][ext]", // Added content hash
},
},
{
test: /\.ts$/,
@@ -57,7 +63,7 @@ export default (env, argv) => {
test: /\.(png|jpe?g|gif)$/i,
type: "asset/resource",
generator: {
filename: "static/images/[name]-[hash:8][ext]",
filename: "images/[name].[contenthash][ext]", // Added content hash
},
},
{
@@ -66,20 +72,17 @@ export default (env, argv) => {
},
{
test: /\.svg$/,
type: "asset/inline",
type: "asset/resource", // Changed from asset/inline for caching
generator: {
filename: "images/[name].[contenthash][ext]", // Added content hash
},
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "static/fonts/",
publicPath: "../fonts/",
},
},
],
type: "asset/resource", // Changed from file-loader
generator: {
filename: "fonts/[name].[contenthash][ext]", // Added content hash and fixed path
},
},
],
},
@@ -96,6 +99,17 @@ export default (env, argv) => {
new HtmlWebpackPlugin({
template: "./src/client/index.html",
filename: "index.html",
// Add optimization for HTML
minify: isProduction
? {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
}
: false,
}),
new webpack.DefinePlugin({
"process.env.WEBSOCKET_URL": JSON.stringify(
@@ -107,13 +121,35 @@ export default (env, argv) => {
}),
new CopyPlugin({
patterns: [
{ from: "resources", to: path.resolve(__dirname, "static") },
{
from: "resources",
to: ".", // Copy to the output directory (static)
// Add content hashing to copied files
transform: function (content, path) {
return content; // Return unmodified content
},
// Don't hash HTML files from resources
noErrorOnMissing: true,
},
],
options: {
concurrency: 100,
},
}),
],
optimization: {
// Add optimization configuration for better caching
runtimeChunk: "single",
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all",
},
},
},
},
devServer: isProduction
? {}
: {