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

Should not rely on filesystem in order to be compatible with bundling system (webpack, ...) #114

Closed
marcelfalliere opened this issue Feb 8, 2019 · 8 comments

Comments

@marcelfalliere
Copy link

Related to #90 and #42.

Bundling server code is not a common practice, but it is used in some case.

Bundling swagger-ui-express is impossible because it reads from filesystem, like so (from memory) : fs.readFileSync(__dirname, 'indexTemplate.html'). The second problem is this indexTemplate.html references js that is path relative. So there's two problems that prevent us from bundling.

Possible solutions : with vulcanize, indexTemplate.html could be reduced to a single standalone file. For the other part of the problem, since there's no build phase in swagger-ui-express, well, maybe we should add one. A simple build phase where the result of indexTemplate.html vulcanized is inlined in the js souce code - therefore, no fs call.

@scottie1984
Copy link
Owner

I could place the templates in memory rather than read them from files. The reference to the relative path in indexTemplate.html is actually for the client to reference the files from the server so they will still work.

The main problem I for-see is that we depend on swagger-ui-dist for the swagger static assets which is sourced via swaggerUi.getAbsoluteFSPath() which I imagine also won't work with bundling. If there was a way to resolve this with moving the templates into memory I guess it could work.

I am unsure about a build step, would this be a performance as all of swagger would be served from one large html file and therefore bypass any caching etc?

@marcelfalliere
Copy link
Author

Hi Scottie, thanks.

we depend on swagger-ui-dist for the swagger static assets

Indeed, vulcanize would not work. Sorry, I did not took a lot of time to look into indexTemplate.html. It seems these reference

<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
<script src="./swagger-ui-bundle.js"> </script>
<script src="./swagger-ui-standalone-preset.js"> </script>

are not present in the repo, therefore vulcanize would not work.

I don't know why these deps are in a separate repo.

You raise a valid point about performance. Vulcanize is a good tool for bundling an html page. I've used it before with polymer, a library to make webcomponent. The idea is to make a web page standalone. It is what we want here. Performance wise, maybe the whole page could be cached ? Also, having one big request may be better than having X small ones : sometimes latency takes up to 95% of the total load time, depending on the network of course.

Also, the swagger ui is not a critical part of the api (right ?). I mean the business endpoints are. So, 500ms more to load the swagger ui may not be a problem ?

Tell me what do you think.

@scottie1984
Copy link
Owner

The deps are in a separate repo as they are developed by a completely different project. This module is just a wrapper around it for Express.

I don't think Vulcanize would therefore work within this module due to this.

My guess is that adding a build step to Webpack to Vulcanize is the way to go but this would sit outside the scope of this module.

@MisterMX
Copy link

MisterMX commented Dec 16, 2019

A possible workaround is to copy to asset files from node_modules/swagger-ui-dist to dist/node_modules/swagger-ui-dist using the copy-webpack-plugin:

// in your webpack.config.js
const CopyPlugin = require('copy-webpack-plugin');

// ...

plugins: [
        new CopyPlugin([
            {
                // Copy static asset files so that they can be served from output directory as swagger-ui-dist does not work
                // with webpack.
                from: path.resolve(__dirname, 'node_modules/swagger-ui-dist/'),
                to: 'node_modules/swagger-ui-dist',
                test: /\.(js|css|html|png)$/i,
                ignore: ['index.js', 'absolute-path.js', '*.map'],
            },
        ]),
    ],

To save disk space, you can ignore all the non-asset files such as package.json, index.js and absolute-path.js and so on.

If you use express you can then provide them to the user with a custom static handler:

router.use(
            'my-swagger-url',
            express.static('node_modules/swagger-ui-dist/', {index: false}),
            swaggerUi.serve,
            swaggerUi.setup(swaggerFile),
        );

Hope this helps. It at least worked for me.

@ramazansancar
Copy link

This is how I solved the problem.
Deploying Platform: Vercel

image

@shailendrabhargava93
Copy link

@ramazansancar could you please share details for above fix as i'm facing same issue while deploying my app with swagger on vercel ?

@ramazansancar
Copy link

@shailendrabhargava93

You need to open a folder as /{apiEndpoint}/swagger-ui.css where you broadcast from /.

@Mudasir1406
Copy link

express.static('node_modules/swagger-ui-dist/', {index: false}),

for me i made a public folder and make a folder with the route of swagger and put swagger-ui.css also i change the swagger-ui-express version from v5 to v4 and it worked for me deploying on vercel

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants