node-sass-middleware only serving css file once

2019-06-27 18:43发布

I've made a really simple Express website that uses Jade and Sass, but I've run into a problem with my node-sass middleware. My server only serves a CSS file once, and then returns a 404 for every subsequent request. I have to restart the server to temporarily fix it. Here's my code; the server seems to be hang after outputting the css file (maybe, i'm not sure..)

app.js:

var express = require('express'), sassMiddleware = require('node-sass-middleware');

var app = express();

app.set('views', __dirname + '/views');
app.set('view engine', 'jade');

app.use(
    sassMiddleware({
        src: __dirname + '/public/styles/sass',
        dest: __dirname + '/public/styles',
        debug: true,
        outputStyle: 'compressed',
        prefix: '/public/styles'
    }),
    express.static(__dirname + '/public'),
    express.logger('dev')
);

app.get('/', function(req, res){
    res.render('index', { 
        title: 'Home' 
    });
});

app.listen(3000);

Here is the log from my server:

source: /Users/jasonzhao/Code/Github/isitjoysbirthday/public/styles/sass/main.scss
dest: /Users/jasonzhao/Code/Github/isitjoysbirthday/public/styles/main.css
read: /Users/jasonzhao/Code/Github/isitjoysbirthday/public/styles/main.css
render: /Users/jasonzhao/Code/Github/isitjoysbirthday/public/styles/sass/main.scss

source: /Users/jasonzhao/Code/Github/isitjoysbirthday/public/styles/sass/main.scss
dest: /Users/jasonzhao/Code/Github/isitjoysbirthday/public/styles/main.css

The first 4 lines of the log are form my first request and the next two are from my second request (refreshing the page) which fails.

And finally, here is my Jade template

doctype
html
  head
    title #{title} - isitjoysbirthday
    link(rel='stylesheet', href='/public/styles/main.css')
  body
    .container
      .main-content
        block content

Thanks!

2条回答
做个烂人
2楼-- · 2019-06-27 19:17

I realize this is an old question and may have already been answered a while ago by other means, but I see similar problems about this and just wanted to answer it for the record. If you're serving up the public folder then your file path should actually be /styles/main.css. Change your prefix option to just /styles and your HTML to <link href='/styles/main.css'>.

Here's an example setup of mine that works.

Directory structure:

static
  |
  - css
  |
  - scss

Middleware setup:

  app.use(sassMiddleware({
    src: __dirname + '/static/scss',
    dest: __dirname + '/static/css',
    debug: false,
    prefix: '/css',
    outputStyle: 'compressed'
  }));
  app.use('/', serveStatic('./static', {}));

HTML:

<link rel='stylesheet' href='/css/app.css'>

Bonus:

serveStatic will always serve this up at /css/my_css_file.css, but the problem is how the middleware interacts with the HTML link itself. Whenever a static file is requested, it looks at the file path it came in with and glues it to the end of the src and dest URLs. This is if you don't define a prefix option at all.

Without prefix:

Without proper prefix

With prefix:

With proper prefix

The prefix simply ignores the /css portion of my CSS <link> URL and allows the absolute path to be accurate for src and dest.

查看更多
劫难
3楼-- · 2019-06-27 19:25

What seems to be causing the problem is,

app.use(
    sassMiddleware({
        src: __dirname + '/public/styles/sass',
        dest: __dirname + '/public/styles',
        debug: true,
        outputStyle: 'compressed',

        /*you are removing public here (prefix tells the server that what ever
          request for CSS comes, remove '/public/styles' from it's src*/

        prefix: '/public/styles' 

    }),
express.static(__dirname + '/public'),//Now here you are telling it too look
                                      //for all static files in 'public' it will
                                     // prepend '/public' before every static src
express.logger('dev')
);

First Time Server Runs

First time the server runs CSS is not static, as it needs to be transpiled into CSS so it gets transpiled and served without problem. Now when file is requested, node-sass removes '/public/styles' and serves it easily.

On Refresh

Now CSS has been transpiled it is now static, so now internally express call your src as /public/public/styles/main.css which surely doesn't exist (try creating directory like this and you'll know for sure)

Solution

solution to your code is simple,

app.use(
    sassMiddleware({
        src: __dirname + '/public/styles/sass',
        dest: __dirname + '/public/styles',
        debug: true,
        outputStyle: 'compressed',

        prefix: '/styles' //remove '/public' from here

    }),
express.static(__dirname + '/public'),
express.logger('dev')
);

and Change link src to

link(rel='stylesheet', href='/styles/main.css')

Hope this helps lot of other guys like me, I just spent 4 hours trying to fix this for my self and here I'm. Further I'd like to suggest that you use serve-static instead of express.static(), as I tested it on serve-static here is the code to include it,

//place this where you include node modules
var serveStatic = require('serve-static');

//place following code instead of express.static()
app.use('/', serveStatic('./public'));

Hope this helps

查看更多
登录 后发表回答