frandiox / vite-ssr

Use Vite for server side rendering in Node
MIT License
830 stars 92 forks source link

Don't remove `client/index.html` during build #70

Closed Xenonym closed 3 years ago

Xenonym commented 3 years ago

vite-ssr build removes index.html from the client bundle:

https://github.com/frandiox/vite-ssr/blob/f376c925874661bc31e9bedf76b923b2c6676633/src/build/index.ts#L113-L119

I was not expecting this behaviour as a normal Vite SSR build would include the index.html in the client bundle.

For my purposes, I do want the index.html in my client bundle, since I am only selectively using SSR on a few routes on my site, and serving a regular SPA for the rest.

Would it be possible to remove this behaviour from vite-ssr? If the intention is to provide a easy to use SSR plugin for Vite users, I feel that it would be better if vite-ssr's behaviour does not deviate too much from Vite's own SSR support. I would also be happy with a vite-ssr CLI flag to retain index.html!

Happy to submit a PR for either option. Thanks again for this easy-to-use package!

frandiox commented 3 years ago

Yeah, since index.html is already embedded in the SSR bundle, we just remove it to avoid downloading it by mistake as an asset.

I guess we can have a flag for this, and perhaps a way to pass it as a plugin option. PRs are welcome! We can name this flag perhaps --keep-index-html? I'm open to suggestions 😅 To save plugin options for the build, there's an example here (for another project). Then, these options can be retrieved in the build like this. The plugin option could be options.build.keepIndexHtml as well.

Xenonym commented 3 years ago

@frandiox Thanks for the reference! I tried following it for this issue, but your example plugin is in JS and this project is in TS, which poses some issues since I am not actually familiar with TS 😓

If I add a build.keepIndexHtml to plugin.ts:

type ViteSsrPluginOptions = {
  build?: {
    /**
     * Keep the index.html generated from the client bundle
     * @default false
     */
    keepIndexHtml?: boolean
  },
  [...]
}
export = function ViteSsrPlugin(
  options: ViteSsrPluginOptions & SsrOptions = {}
) {
  return {
    name: pluginName,
    buildOptions: options.build || {},
    [...]
  } as Plugin
}

I can't actually pull it in build/index.ts. The code below will not compile since the Plugin type does not have a buildOptions property:

const { buildOptions = {} } = 
      viteConfig.plugins.find((plugin) => plugin.name === 'vite-ssr') || {}

Do you have a suggestion on how to pass the build option from plugin.ts to build/index.ts in a way that keeps TSC happy? Thanks for the help!

frandiox commented 3 years ago

@Xenonym You can simply add // @ts-ignore before the problematic line for now. I'll check how to improve it later 👍

frandiox commented 3 years ago

@Xenonym Released in 0.12.1. Thanks!