Can dynamic import of @mdi/js icon work with tree-shaking in a vue template?

Viewed 574

I have the following component to dynamically import an icon from mdi/js. The only problem with this is that it doesn't do tree-shaking. Does anyone know how to make tree-shaking work with this kind of setup? I can use this anywhere like

<Icon name='mdiMagnify'>

Icon.vue

<template>
    <v-icon v-bind="$attrs">{{ icon }}</v-icon>
</template>

<script>
export default {
    name: 'Icon',
    props: {
        name: {
            required: true,
            type: String,
        },
    },
    data: () => ({
        icon: null,
    }),
    async created() {
        const { [this.name]: icon } = await import('@mdi/js')
        this.icon = icon
    },
}
</script>

The reason behind this is, I won't be needing to import each and every icon that i need in all my components and passing it to a data variable to be able to be utilized in vue template.

2 Answers

if you're using nuxt.js (which I suppose you do since you have the tag on your question), it's pretty easy, just add the following in your nuxt.config.js:

vuetify: {
  defaultAssets: false,
  treeShake: true,
  icons: {
    iconfont: 'mdiSvg',  // --> this should be enough

    // sideNote: you can also define custom values and have access to them
    // from your app and get rid of the imports in each component

    values: {
      plus: mdiPlus, // you have access to this like $vuetify.icons.values.plus from your component
    }
  }
}

for the values to work you just have to import the appropriate icon in the nuxt.config.js like:

import { mdiPlus } from '@mdi/js'

or if you don't like the custom values you can import the needed icons for each component in the component itself and use them there like:

import { mdiPlus } from 'mdi/js'
...
data() {
  return {
    plusIcon: mdiPlus
  }
}

What I ended up doing currently is to have all the svg in @mdi/svg package and use that as an img src. That way, I won't have to deal with dynamically importing it from @mdi/js and hoping for a treeshake.

Related