seriousme / fastify-openapi-glue

A plugin for the Fastify webserver to autogenerate a Fastify configuration based on a OpenApi(v2/v3) specification.
MIT License
206 stars 33 forks source link

Bundled index JS with webpack or esbuild unrunnable #620

Open sudo-alexslater opened 1 week ago

sudo-alexslater commented 1 week ago

Hey there,

First of all, great package. Made things a lot easier for our API project.

I'm facing some issues using this package because of a dependency - specifically @seriousme/openapi-schema-validator. I believe looking at the code this is using a URL object and building a path to select a version of openapi to validate against (a JSON that is read in at runtime).

Problem with this is that if you'd like to bundle all your code into one file / runtime like we do, this file will not come with it. In fact, bundlers seem to replace the URL with an absolute path pointing at the module which is a bit weird for sure (see code at bottom taken from the compiled code).

Do you have any advice on this / perhaps we could consider importing it into this file in some way to make the connection easier for bundlers to understand? I will continue to look at options as I may be able to assist with a merge request on this library

`const openApiVersions = new Set(["2.0", "3.0", "3.1"]); const ajvVersions = { "http://json-schema.org/draft-04/schema#": dist, "https://json-schema.org/draft/2020-12/schema": _2020, }; const inlinedRefs = "x-inlined-refs";

function localFile(fileName) { return (0,external_nodeurl.fileURLToPath)(new external_nodeurl.URL(fileName, "file:///Users/XXXX/Documents/projects/XXXX/node_modules/@seriousme/openapi-schema-validator/index.js")); }

function importJSON(file) { return JSON.parse((0,external_node_fs_namespaceObject.readFileSync)(localFile(file))); }`

seriousme commented 1 week ago

Hi,

thanks for asking. Sorry to read that your bundler is having an issue with @seriousme/openapi-schema-validator.

To me it sounds like a bug in the bundler, but since I'm also the author of @seriousme/openapi-schema-validator. I will take a look to see if I can fix it.

Kind regards, Hans

seriousme commented 1 week ago

I just released fastify-openapi-glue@4.7.2 which contains @seriousme/openapi-schema-validator@2.2.4 @seriousme/openapi-schema-validator@2.2.4 has removed the dependency on node:url so it should work with your bundler.

Hope this helps. Kind regards, Hans

seriousme commented 1 week ago

Looking at it again I think that although the node:URL has been fixed,you will still run into issues with:

function importJSON(file) {
     return JSON.parse((0,external_node_fs_namespaceObject.readFileSync)(localFile(file)));
}

The reason for that is that build tools that are intended for browsers have no notion of filesystem and @seriousme/openapi-schema-validator@2.2.4 needs to read its schema definitions from file.

I might be able to fix this using import "file" with {type: 'json'} syntax, but I can't guarantee that this will work, nor that there will never be any updates that won't be able to work in a browser.

Just out of curiosity: why do you bundle serverside code using browser bundlers?

Kind regards, Hans

sudo-alexslater commented 5 days ago

Hey - thanks for the prompt response.

So, basically we bundle to reduce the size of the final artifact. Bundling allows us to just have one JS file as an artifact as opposed to having the entire repo + node_modules. Bundlers are commonly used for this purpose in backend node code, especially for ease of transpiling typescript etc.

So this hasn't fixed the particular problem - the import you've described would fix it I'm pretty certain. Reason being that as you've described this method of loading files doesn't play well with bundlers as the expectation is all the files are included in one runtime bundle.

I'm happy to give this a shot myself locally to make sure it works if that helps

sudo-alexslater commented 5 days ago

@seriousme for some reason even when reverting my changes i'm getting this on my local: image

seriousme commented 5 days ago

Alex,

I know what bundling is but I don't see the benefit server side bundling except when deploying to serverless platforms like AWS Lamba.

I did some searching and esbuild can specifically build for the Node platform: https://esbuild.github.io/getting-started/#build-scripts

This way I can continue my development without being constrained by the specifics of bundlers, while you can continue using esbuild. E.g. I already had to revert the URL fix because it broke deployment on windows.

Bundling the Openapi spec files means that all versions need to be loaded in memory where a project might only need one. So we are trading disk for memory here.

For a next major version of fastify-openapi-glue I plan to make it smaller by externalizing file access ( you will need to provide an object instead of a YAML or JSON file/string) and also externalize schema validation ( so one can decide oneself to do it or not).

I don't know how volatile your Openapi schema is but if it's pretty stable then you could try the generator with the standaloneJS template, this will generate fastify code that does not need fastify-openapi-glue anymore and therefore also not openapi-schema-validator. This template is rather new, so it could be a bit rough around the edges. Any feedback on the template will be much appreciated.

Kind regards, Hans