Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fastify-vite server is not esbuild friendly #19

Open
IlyaSemenov opened this issue Jun 27, 2021 · 5 comments
Open

fastify-vite server is not esbuild friendly #19

IlyaSemenov opened this issue Jun 27, 2021 · 5 comments
Assignees
Labels
bug Something isn't working

Comments

@IlyaSemenov
Copy link
Contributor

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:

  • fastify-vite must export two fastify plugins: one for dev mode and one for production, and let the user decide which to run based on whatever logic they prefer, such as based on process.env.NODE_ENV. You may also continue to export the default implementation which follows the current logic of looking into options.dev - but it must be tree shakeable.
  • Same goes for fastify-vite-vue, there must be two separate renderers, so that in production mode vite.ssrLoadModule is excluded by tree shaking.
  • Magic build mode should be provided not by fastifyVite.app (a property on function! completely non tree-shakeable) but by a separately exported function.
  • getViteOptions should probably not be used at all. After all, with fastify-vite, vite.config.js is half broken anyway (e.g. one must remove @vitejs/plugin-vue from plugins, or face cryptic errors). Let the user import it manually and feed to fastify.register(fastifyVite, { vite }), it's not a big deal.

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
Copy link
Member

galvez commented Jun 27, 2021

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
Copy link
Contributor Author

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
Copy link
Member

galvez commented Jun 27, 2021

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

@IlyaSemenov
Copy link
Contributor Author

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 galvez self-assigned this Jun 27, 2021
@galvez galvez added the enhancement New feature or request label Jun 27, 2021
@galvez galvez added bug Something isn't working and removed enhancement New feature or request labels Oct 7, 2021
@galvez
Copy link
Member

galvez commented May 17, 2022

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants