Webpack tree shaking not working w/ vue-instantsearch

Hello! I’ve been working with the vue-instantsearch library and it has been absolutely great. For some reason though, I can’t get webpack to exclude the components I am not using.

This snippet from my code produces an asset that is 458kb.

import InstantSearch from 'vue-instantsearch'

Vue.use(InstantSearch)

When I attempt to only import the components I use, the asset is still 458kb

import {AisHits,AisSearchBox,AisInstantSearch,AisRefinementList,AisPagination} from 'vue-instantsearch'

Vue.component(AisInstantSearch.name, AisInstantSearch);

Vue.component(AisSearchBox.name, AisSearchBox);

Vue.component(AisHits.name, AisHits);

Vue.component(AisRefinementList.name, AisRefinementList);

Vue.component(AisPagination.name, AisPagination);

I am using webpack -p to build. My webpack version is 4.29.0

Here’s my webpack config file.

const path = require("path")
const webpack = require("webpack")

module.exports = {
  mode: "production",
  entry: {
      "members": "./src/members.js",
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].js",
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
    ]
  },
}

and babelrc

{
    "presets": [
      "@babel/preset-env"
    ],
    "plugins": ["@babel/plugin-transform-runtime","@babel/plugin-syntax-dynamic-import"]
}

Am I missing something obvious here?

Thanks!

I think you’ve highlighted a real stumbling block here. When I last looked at tree-shaking it seemed like things were correctly able to be tree-shaked, but this no longer seems to be the case, even if sideEffects: false would be added to the package.json.

This implies that there’s a lot of work still to make this work correctly, and won’t be able to be fixed in 1, 2, 3.

When experimenting I made a little experimental version of Vue InstantSearch where the source files were included in the build, so you could import them one-by-one, and you can see that we can get rid of some of the bigger parts of Vue InstantSearch.

If you install @haroenv/not-vue-instantsearch (same as 2.5.0, but with src included) you can temporarily already have tree-shaking. You will need to import and use the components like this:

import AisInstantSearch from '@haroenv/not-vue-instantsearch/src/components/InstantSearch';
import AisPagination from '@haroenv/not-vue-instantsearch/src/components/Pagination';
import AisHighlight from '@haroenv/not-vue-instantsearch/src/components/Highlight';
import AisHits from '@haroenv/not-vue-instantsearch/src/components/Hits';
import AisSearchBox from '@haroenv/not-vue-instantsearch/src/components/SearchBox';
import AisRefinementList from '@haroenv/not-vue-instantsearch/src/components/RefinementList';

export default {
  components: {
    AisInstantSearch,
    AisPagination,
    AisHighlight,
    AisHits,
    AisSearchBox,
    AisRefinementList,
  },
};

Note that by the end of the year Vue InstantSearch will migrate to InstantSearch v4, which will have a significant improvement of bundle size in general, so we will be able to see these numbers go down after that.

For now I have opened an issue so other people can chime in if they have more ideas: https://github.com/algolia/vue-instantsearch/issues/725

Hi @haroen, thanks for the detailed response!

I’ll give this a try right now!

Do I need to do anything special in order to import from your version?

I first did: yarn add @haroenv/not-vue-instantsearch

Here is my code:

import AisInstantSearch from '@haroenv/not-vue-instantsearch/src/components/InstantSearch';
import AisPagination from '@haroenv/not-vue-instantsearch/src/components/Pagination';
import AisHits from '@haroenv/not-vue-instantsearch/src/components/Hits';
import AisSearchBox from '@haroenv/not-vue-instantsearch/src/components/SearchBox';
import AisRefinementList from '@haroenv/not-vue-instantsearch/src/components/RefinementList';

But I get these errors when building.

ERROR in ./src/members.js
Module not found: Error: Can't resolve '@haroenv/not-vue-instantsearch/src/components/Hits' in '/Users/tyler/repos/dashboard/src'
 @ ./src/members.js 35:0-73 40:14-21 40:28-35

ERROR in ./src/members.js
Module not found: Error: Can't resolve '@haroenv/not-vue-instantsearch/src/components/Pagination' in '/Users/tyler/repos/dashboard/src'
 @ ./src/members.js 34:0-85 42:14-27 42:34-47

ERROR in ./src/members.js
Module not found: Error: Can't resolve '@haroenv/not-vue-instantsearch/src/components/RefinementList' in '/Users/tyler/repos/dashboard/src'
 @ ./src/members.js 37:0-93 41:14-31 41:38-55

ERROR in ./src/members.js
Module not found: Error: Can't resolve '@haroenv/not-vue-instantsearch/src/components/SearchBox' in '/Users/tyler/repos/dashboard/src'
 @ ./src/members.js 36:0-83 39:14-26 39:33-45

It’s possible .vue isn’t set up as a default extension for you, you can try with the extension. Outside of that, I used vue cli to try this out, you can try using their webpack config or checking what’s different than yours.