fastify / fastify-vite

Fastify plugin for Vite integration.
MIT License
861 stars 72 forks source link

fastify-vite server is not esbuild friendly #19

Open IlyaSemenov opened 3 years ago

IlyaSemenov commented 3 years ago

Problem

fastify-vite server is not esbuild friendly, meaning that it's not possible to build it with esbuild into a single redistributable script.

To my thinking, this is a shame given that the project itself relies on vite/esbuild, but is not following its best practices.

Steps to reproduce

Take examples/vue-api from the dev branch, and run:

yarn esbuild server.js --bundle --platform=node --outfile=dist/server.js

you will get lots of errors of "Could not resolve" errors. When you resolve all of them, you'll end up with:

yarn esbuild server.js --bundle --platform=node --outfile=dist/server.js --external:consolidate --external:vite/dist/client/client.js --external:vite/dist/client/env.js --external:rollup  --external:acorn

if you run it, you will get:

❯ node dist/server.js
/Users/semenov/gh/fastify-vite/examples/vue-api/dist/server.js:30287
        throw new Error(`The esbuild JavaScript API cannot be bundled. Please mark the "esbuild" package as external so it's not included in the bundle.
              ^

Error: The esbuild JavaScript API cannot be bundled. Please mark the "esbuild" package as external so it's not included in the bundle.

now if you also add esbuild to externals, you'll get a build which will not run without node_modules:

❯ node dist/server.js
node:internal/modules/cjs/loader:943
  throw err;
  ^

Error: Cannot find module 'esbuild'
Require stack:
- /Users/semenov/gh/fastify-vite/examples/vue-api/dist/server.js

Suggestions

The library should be refactored to allow tree shaking to work:

Other notes

I'm currently using https://github.com/frandiox/vite-ssr which works fine with esbuild. Their approach is different - they use a binary script for dev mode (vite-ssr), and no helpers at all for production mode. (For example, this is the suggested boilerplate for Express production server.)

They however lack useServerData so I was looking for alternatives.

galvez commented 3 years ago

Interesting, will see what can be done about this.

This is a rather specific use case, I'd personally never use esbuild to bundle Fastify server code, that is, I'd use esbuild only where it's needed (typically for the client). But I'll study this carefully and see what can be done.

BTW New release is almost coming out from dev branch — stay tuned!

IlyaSemenov commented 3 years ago

Thank you 🙏. The justification for esbuilding is deploying to serverless platforms such as AWS Lambda. It's simpler and faster to distribute a single executable *.js file rather than maintain separate package.json and/or somehow publish parts of node_modules.

galvez commented 3 years ago

Ah, gotcha — maybe we should also look into https://github.com/fastify/aws-lambda-fastify

IlyaSemenov commented 3 years ago

aws-lambda-fastify is a wrapper that exposes a fastify app as a lambda entrypoint. I'm currently using serverless-http which does the same for Express and Koa. But these libraries are about runtime, not about building. They compile fine with esbuild, there is no problem with that.

The problem with fastify-vite is that the way it is designed, it needs vite builder in production runtime. That is what I'm trying to avoid. By using tree shaking, we can keep that dependency in dev mode but avoid in production, so that the server can be compiled with esbuild.

galvez commented 2 years ago

@IlyaSemenov JSYK at least part of these issues have been resolved in v3 — I'll look closely later. Keeping open.