lwsjs / local-web-server

A lean, modular web server for rapid full-stack development.
MIT License
1.2k stars 85 forks source link

help with using custom middleware + default stack to set cookies #100

Closed thescientist13 closed 5 years ago

thescientist13 commented 5 years ago

Was exploring the middleware docs to see if I could use it to set a cookie for all requests but was running into some issues when adding a --stack.

What I have working was this:

// lws.config.js
module.exports = {

  directory: 'dist',

  spa: 'index.html',

  stack: [
    'body-parser',
    'request-monitor',
    'log',
    'cors',
    'json',
    'rewrite',
    'blacklist',
    'conditional-get',
    'mime',
    'compress',
    'mock-response',
    'spa',
    'static',
    'index'
  ],

  compress: true,

  rewrite: [{
    from: '/api/*',
    to: 'http://www.domain.com/api/$1'
  }]

};

Running it as

$ ./node_modules/.bin/ws

And everything is good ✅

When I try to add a simple middleware

// middleware.js
module.exports = MiddlewareBase => class Example extends MiddlewareBase {

  middleware (options) {
    return (ctx, next) => {
      ctx.cookies.set('MY_KEY', 'MY_VALUE');
    };
  }

};
$ ./node_modules/.bin/ws --stack middleware.js

All I get is a white page that says Not Found 🚫

screen shot 2018-09-12 at 5 58 00 pm

If I follow the example from the docs, I can confirm that I see Hello on the page.

module.exports = MiddlewareBase => class Example extends MiddlewareBase {
  middleware (options) {
    return (ctx, next) => {
      ctx.response.body = 'Hello'
    }
  }
}

It does appear that I can see my middleware in the output from ws when using Chrome in Incognito mode to load the site

ctx { method: 'GET',
  url: '/favicon.ico',
  header:
   { host: 'localhost:4445',
     connection: 'keep-alive',
     'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36',
     accept: 'image/webp,image/apng,image/*,*/*;q=0.8',
     referer: 'http://localhost:4445/',
     'accept-encoding': 'gzip, deflate, br',
     'accept-language': 'en-US,en;q=0.9,es;q=0.8,it;q=0.7',
     cookie: 'MY_KEY=MY_VALUE' } }

Thanks for any help you may be able to lend! Let me know if you need anymore info

75lb commented 5 years ago

Hi, this stack specifies that your middleware only is loaded (and nothing else):

$ ./node_modules/.bin/ws --stack middleware.js

Is that what you intended? Don't you at least need static file hosting downstream of your custom middleware? E.g.

$ ./node_modules/.bin/ws --stack middleware.js lws-static

Run this command to see the middleware options built into ws, you can include any of these in your stack to create a custom server:

$ ws middleware-list
[ 'lws-basic-auth',
  'lws-body-parser',
  'lws-request-monitor',
  'lws-log',
  'lws-cors',
  'lws-json',
  'lws-compress',
  'lws-rewrite',
  'lws-blacklist',
  'lws-conditional-get',
  'lws-mime',
  'lws-range',
  'lws-mock-response',
  'lws-spa',
  'lws-static',
  'lws-index' ]
thescientist13 commented 5 years ago

Ah, I see.

So are you saying the lws.config.js file would not be respected in this case? Or do i need to "chain" stacks via the CLI instead? (or both?)

75lb commented 5 years ago

lws.config.js options are respected unless overridden on the command line - CLI args take precedence..

thescientist13 commented 5 years ago

Ah, ok I think I see what you mean now.

Is there a way to load a middleware via the stack option in lws.config.js? e.g.

module.exports = {
  ... 

  stack: [
    'body-parser',
    'request-monitor',
    'log',
    'cors',
    'json',
    'rewrite',
    'blacklist',
    'conditional-get',
    'mime',
    'compress',
    'mock-response',
    'spa',
    'static',
    'index',
    'my-middleware'  // my-middleware.js
  ],

  ...
}
thescientist13 commented 5 years ago

Thanks, so this gets the local web server running correctly now with my app and with my middleware loading (i know I can probably prune extra stacks I don't actually need)

./node_modules/.bin/ws --stack body-parser request-monitor log cors json rewrite blacklist conditional-get mime compress mock-response spa static index ./middleware.js

However, the return function never executes?

module.exports = MiddlewareBase => class Example extends MiddlewareBase {

  middleware (options) {
    console.log('options', options);  // this executes

    return (ctx, next) => {
      console.log('ctx', ctx); // this doesn't log???
    };
  }

};

This may be more in the realm of Koa at this point though, but any thoughts would be much appreciated!

75lb commented 5 years ago

it's because you have put your custom middleware right at the end of the stack - after static and index (one of which must be response middleware as it's terminating the request without forwarding it on to your custom middleware).

thescientist13 commented 5 years ago

Great, changing the ordering of --stack has my custom middleware running now. Still getting Not Found but I think I can take it from here now.

Thanks for all your help!