felixmosh / bull-board

🎯 Queue background jobs inspector

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Usage with Nuxt 3

AidanHibbard opened this issue · comments

Has there been a method found to get this working with Nuxt 3? Most of what I've found to get an express instance working with Nuxt, was using Nuxt 2.

I tried to setup an express app as a middleware in my nuxt server then passing the express app to the event context so I could try to render the UI ejs in my route file but that didn't work, and wasn't very pretty.

Nuxt is built off of Nitro, and h3. So I was thinking we may need an adapter for h3?

Once the adapter is setup it would need to have a catch all handler for a queues route for the adapter to take over routing. Server routes don't support a [...] route yet, so it may have to exist under the server/api routes.

Maybe a Nuxt module is the right way to go?

I'm happy to spend the time creating an adapter, or module, whatever is needed, but I thought I'd open an issue in-case anyone else has some input on how this should be tackled...

Hi @AidanHibbard, I'm not familiar with Nuxt, does it have "raw" handling of request? if so, you can prepare an adapter for Nuxt, it is pretty straightforward thing to do.

Ping me if you need my help

Hey @felixmosh,

Thanks for the response, I meant to add an update here earlier, but I've been busy.

Nuxt does not support accessing the (req, res) values of an H3 event anymore.

I found that they have a node handler for legacy requests but they strongly advise against using it

export default defineEventHandler((event) => {
  return {
    req: event.node.req,
    res: event.node.res
  };
});

or 

export default fromNodeMiddleware((req, res) => {
  res.end('Legacy handler')
});

We'd assign that route handler to a router following the docs here ->
https://nuxt.com/docs/guide/directory-structure/server#using-a-nested-router

So I don't think this will be a Nuxt or UnJS specific adapter, we might just need a node:http adapter?

I'll try to get a PR started for this soon.

I would like this!

I've had to put this on pause, we're having an issue with Nuxt as our framework. The goal is to eventually run separate pods for our BullMQ workers, and start them with a separate run command.

Nuxt doesn't support this, so we'll be looking into a solution like Express.

I created a PR for an H3 adapter. Its still a work in progress, as I haven't fully tested it.

If you're still interested in the effort @AidanHibbard please have a look at #669

Once we're able to get the H3 adapter working, integrating into Nuxt should be smooth.

@genu I'll check this out. I also figured going for a Router setup with useBase would work, but spun my wheels trying to use serveStatic.

@genu I'll check this out. I also figured going for a Router setup with useBase would work, but spun my wheels trying to use serveStatic.

Yeah, I went in circles with serveStatic myself. I tried the built in h3 serveStatic and the library you're using serve-static and I just couldn't get an elegant solution.

As you'll see in my PR, I ended up just compiling the EJS template using ejs (Other adapters do the same thing, and rely on the ejs dependency), and for the rest of the static assets I just match them using wildcards -- I think this would generally work, as there aren't that many.

It is better to use some lib for static serving, your current code is vulnerable to arbitrary file read!

It is better to use some lib for static serving, your current code is vulnerable to arbitrary file read!

Hmm, I figured it wouldn't be an issue since we're limited to the static folder from the ui package 🤔

Attacker don't play by your rules, they will make a request to the server without going through ui ;)

I wonder if we could use express here to serve statics without having to pass a H3 event like serveStatic?

We don't have to instantiate an express app to use it.

const staticsAbsolutePath = path.join(this.viewPath, _staticsPath);
this.uiHandler.get(
  `${this.basePath}${staticsRoute}/**`,
  eventHandler(async (event) => {
    const { _ } = getRouterParams(event);

    setResponseHeader(event, "Content-Type", `${this.getContentType(_)}; charset=UTF-8`);
    // Example:
    return express.static(staticsAbsolutePath);
  })
);