Express页面刷新后/styles.css资源丢失问题及解决方法
/styles.css Disappears After Page Refresh in Production Build I ran into this exact issue recently—here's what was going wrong and how to resolve it:
When building the app with
npm run buildand serving it vianpm run serve,/styles.cssloads correctly on the initial page visit. But after refreshing the page, the request for/styles.cssgets cancelled. This problem only occurs in thedistversion of the app; restarting the server lets the stylesheet load once again, and the issue persists even in incognito mode.
Project Context & Configuration
package.json Build Scripts
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "clean": "rimraf dist", "start": "nodemon -e js,css,handlebars -i scss --watch app --exec babel-node app/app.js", "build": "npm run clean && mkdir -p dist && babel app -s -D -d dist", "serve": "node dist/app.js", "postinstall": "npm run build" }
Core app.js Setup
import bodyParser from 'body-parser' import express from 'express' import exphbs from 'express-handlebars' import path from 'path' import sassMiddleware from 'node-sass-middleware' const PORT = process.env.PORT || 3000 const app = express() // Config app.locals.config = require('./config.json') // Views and handlebars view engine const hbs = exphbs.create({ defaultLayout: 'main', layoutsDir: 'app/views/layouts', helpers: { sitename: function () { return app.locals.config.sitename }, ga: function () { if (process.env.NODE_ENV === 'production') { ... } }, }, }) app.engine('handlebars', hbs.engine) app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'handlebars') // Body parser app.use(bodyParser.json()) app.use(bodyParser.urlencoded({extended: false})) // Sass middleware (original config) app.use(sassMiddleware({ src: path.join(__dirname, 'public/scss'), dest: path.join(__dirname, 'public/css'), outputStyle: 'compressed', sourceMap: true, })) // Static folder app.use(express.static(path.join(__dirname, 'public'))) // Routes app.use(require('./routes/index.js')) const server = app.listen(PORT, () => console.log(`listening at port ${PORT}...`))
Template CSS Import (Original)
The styles were referenced in the Handlebars template like this:
<link rel="stylesheet" href="/styles.css">
Project Folder Structure
/app - public/ - css - js - scss - routes/ - ... - views/ - ...
Solution Steps
The root problem was a mismatch between where node-sass-middleware outputs the compiled CSS and the path used in the template. Here's how to fix it:
- Update the template's CSS path to point to the correct location in the
public/cssdirectory:
<link rel="stylesheet" href="/css/styles.css">
- Add the
prefixoption to thenode-sass-middlewareconfiguration to align the middleware's route with the static file serving path:
// Sass middleware (updated config) app.use(sassMiddleware({ src: path.join(__dirname, 'public/scss'), dest: path.join(__dirname, 'public/css'), prefix: '/css', // New line added to match the template path outputStyle: 'compressed', sourceMap: true, }))
This ensures both the middleware-generated CSS and the static file server use the consistent /css/ path, eliminating the request cancellation issue on page refresh.
内容的提问来源于stack exchange,提问作者hackerl33t

