fastify-swagger-ui: Esbuild and fastify-swagger-ui build output can't access the swagger-ui-dist static files.

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.17.0

Plugin version

1.8.1

Node.js version

18.16.0

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

12.6.5

Description

Attempting to run code built with esbuild, fastify, fastify-swagger-ui results in the error:

node:internal/modules/cjs/loader:1075
  const err = new Error(message);
              ^

Error: Cannot find module './static/logo.svg'
Require stack:
- /Users/david/workspace/fastifySwaggerTest/dist/index.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
    at Function.resolve (node:internal/modules/cjs/helpers:116:19)
    at NE (file:///Users/david/workspace/fastifySwaggerTest/dist/index.js:533:3585)
    at lo.exec (file:///Users/david/workspace/fastifySwaggerTest/dist/index.js:17:1196)
    at Et.om (file:///Users/david/workspace/fastifySwaggerTest/dist/index.js:17:2907)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/Users/david/workspace/fastifySwaggerTest/dist/index.js' ]
}

Supplying a valid logo will run the server, but the assets served at static will 404.

In the provided esbuild.config.mjs, we are defining __filename and __dirname for integration with commonjs libraries.

Steps to Reproduce

Clone repo

run yarn start and observe that it doesn’t error run yarn buildandrun and observe that it errors

Expected Behavior

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 4
  • Comments: 17 (7 by maintainers)

Most upvoted comments

You can bundle, but then handle the copying of the files to the expected places yourself.

This seems normal and expected. I do not even know how this could be fixed or handled on our part.

I would recommend to not bundle your servers.

no clue

@mcollina happily! Just straight into the README?

I’m at capacity right now but can submit that PR in ~1 week

Adding onto @Uzlopak’s comment, there’s a popular esbuild plugin, esbuild-plugin-copy, which can handle this task. I’m personally bundling through esbuild and then compiling to a Docker image, so I added a COPY directive in my Dockerfile.

Regardless of how you get the files into your final bundle, the location you’ll want to copy from is node_modules/@fastify/swagger-ui/static.

Advantages to bundling your fastify apps: 1). Smaller image size which is less for Serverless compute to load and size in Storage 2). Smaller memory footprint.

If I run my application with TS-Node, it takes just over 600MB of memory.
If I build with esbuild and run the result, it takes just over 100MB of memory.

Deploying to Google Cloud Run with the unbuilt version requires a larger instance as I get a “heap error: out of memory” with the unbuilt version. I returned my app to being built and will try to find a different solution.

FYI I am getting 404s for other assets besides the index.html, swagger-initializer.js, hook.js when doing this.

I was having the same issue and I could only get it to work by applying the following patch:

   // serve swagger-ui with the help of @fastify/static
   fastify.register(fastifyStatic, {
-    root: path.join(__dirname, '..', 'static'),
+    root: opts.baseDir || path.join(__dirname, '..', 'static'),
     prefix: staticPrefix,
     decorateReply: false
   })

Then defining the baseDir option

  await server.register(fastifySwaggerUi, {
    baseDir: process.env.ASSETS_ROOT ? path.resolve(process.env.ASSETS_ROOT) : undefined,
	// ...
  })

Copying the assets in my Dockerfile

COPY ./node_modules/@fastify/swagger-ui/static ./assets
ENV ASSETS_ROOT=/app/assets/

Thanks for the suggestions! I appreciate it.

@arimgibson would you like to add a small guide in this repo on how to do this?