Vue-instantsearch: Bundle Size / Nuxt: Why is vue-server-renderer included in Nuxt Frontend Build

Created on 21 Nov 2020  路  7Comments  路  Source: algolia/vue-instantsearch

Bug 馃悶

What is the current behavior?

Go to the folder examples/nuxt.
Add the following script to package.json
"analyze": "nuxt build --analyze"

This is the output:
image


The vue-server-renderer with the size of 334KB is added to the frontend bundle!

What is the expected behavior?

vue-server-renderer/basic.js should not be part of the Frontend Build in nuxt.js. It is part of nuxt.js anyway and not used in the frontend.

Does this happen only in specific situations?

No it happens always. Even on the commited example.

What is the proposed solution?

I have no idea.

What is the version you are using?

4.8.0

bug

Most helpful comment

I've looked through the code a bit and do not see any reason why webpack wouldn't bundle vue-server-render.
I guess this is the critical statement here:

try {
  _renderToString = require('vue-server-renderer/basic');
} catch (e) {
  // error is handled by regular if, in case it's `undefined`
}

I do not know how to fix it at the core, but I worked around it with some additional config:

In your nuxt config under build (https://nuxtjs.org/docs/2.x/configuration-glossary/configuration-build#extend):

extend(config, { isClient }) {
  // Extend only webpack config for client-bundle
  if (isClient) {
    config.plugins.push(
      new webpack.IgnorePlugin({
        checkResource(resource, context) {
          if (resource.includes('vue-server-renderer')) {
            return true
          }
          // do something with resource
          return false
        },
      })
    )
  }
},

The dependency is gone from the front-end and SSR still works.

Edit:
I forgot to mention you also have to import webpack in your nuxt.config.js:

import webpack from 'webpack'

All 7 comments

I also noticed the same issue though I'm using vue-instantsearch on the client-side only. Version [email protected]
Caused by including it in vue-instantsearch/es/src/util/createServerRootMixin.js
that's in turn included in vue-instantsearch/es/src/instantsearch.js

So I tried to import modules directly and it seems it worked this way and vue-server-renderer not included to the bundle anymore:

// old import
// import { AisInstantSearch, AisAutocomplete } from 'vue-instantsearch'
import AisInstantSearch from 'vue-instantsearch/es/src/components/InstantSearch.js'
import AisAutocomplete from 'vue-instantsearch/es/src/components/Autocomplete.vue.js'

( I'm not using Nuxt, but https://github.com/Akryum/vue-cli-plugin-ssr )

Unfortunatly this does not work for me. On Nuxt I have to include AisInstantSearchSsr instead of AisInstantSearch .
I tried to import it as you said but the bundle size is the same:
import AisInstantSearchSsr from 'vue-instantsearch/es/src/components/InstantSearchSsr.js'
As soon as I have this dependancy the build in frontend adds the view renderer.
Any other ideas? These unneeded 334kb hurt so much in the frontend.

image

@ayalon No ideas, unfortunately. SSR component seems to cause memory leak in our project (similar to the one in #834 ), so I didn't work with it.

Same issue here. Also the example from this repo pulls in the same dependency

image

Hmm, I could swear this wasn't the case when I wrote the code originally. I wonder if webpack, vue server side rendering or nuxt have changed something in module resolution.

I'm having a hard time finding the cause of this, maybe a separate method for the server-part should be used so it doesn't end up in the client build?

I've looked through the code a bit and do not see any reason why webpack wouldn't bundle vue-server-render.
I guess this is the critical statement here:

try {
  _renderToString = require('vue-server-renderer/basic');
} catch (e) {
  // error is handled by regular if, in case it's `undefined`
}

I do not know how to fix it at the core, but I worked around it with some additional config:

In your nuxt config under build (https://nuxtjs.org/docs/2.x/configuration-glossary/configuration-build#extend):

extend(config, { isClient }) {
  // Extend only webpack config for client-bundle
  if (isClient) {
    config.plugins.push(
      new webpack.IgnorePlugin({
        checkResource(resource, context) {
          if (resource.includes('vue-server-renderer')) {
            return true
          }
          // do something with resource
          return false
        },
      })
    )
  }
},

The dependency is gone from the front-end and SSR still works.

Edit:
I forgot to mention you also have to import webpack in your nuxt.config.js:

import webpack from 'webpack'

Thanks @reinoldus, this is a great workaround for the time being, and I'll see how we can update the documentation to show this.

It's unfortunate that this solution uses webpack to decide the dependency isn't meant for frontend, but I really can't find any way to indicate an import is server-only in vue

Was this page helpful?
0 / 5 - 0 ratings

Related issues

abattenburg picture abattenburg  路  4Comments

dulnan picture dulnan  路  5Comments

vasilestefirta picture vasilestefirta  路  4Comments

rayrutjes picture rayrutjes  路  4Comments

intrepidws picture intrepidws  路  5Comments