vite-svg-loader icon indicating copy to clipboard operation
vite-svg-loader copied to clipboard

dynamically import not working when build

Open zinken7 opened this issue 2 years ago • 13 comments

@jpkleemans Hi, I used this but failed when build for production. It's working in dev mode

<script lang="ts">
  import { computed, defineComponent, defineAsyncComponent } from 'vue'
  export default defineComponent({
    props: {
      name: {
        type: String,
        default: undefined,
      },
    },
    setup(props) {
      const currentIcon = computed(() => defineAsyncComponent(() => import(`../../icons/${props.name}.svg?component`))).value
      return {
        currentIcon
      }
    }
  })
</script>

zinken7 avatar Aug 25 '21 04:08 zinken7

Hi, thanks for reporting. Could you share an example project so I can reproduce the problem, and investigate how to resolve it.

jpkleemans avatar Sep 10 '21 13:09 jpkleemans

I made an example here: https://github.com/zinken7/vite_svg_inline It only working on dev mode. It's not working when build. Live example: https://codesandbox.io/s/epic-williamson-sfmb5

zinken7 avatar Sep 14 '21 07:09 zinken7

Hi @jpkleemans as I mentioned my another issue in https://github.com/jpkleemans/vite-svg-loader/issues/25#issuecomment-953545959 another thing I was trying to do is dynamically load SVG from a public directory(I ask for user input so I have to make it dynamic).

I write const Logo = () => import('../public/logo.svg'); I get error in console: Screenshot 2021-10-27 at 11 44 53 PM

but if I turn it in to import Logo from '../public/logo.svg'; it works fine.

However, using ../public/logo.svg still gives a warning: Screenshot 2021-10-27 at 11 46 45 PM

This is related to https://github.com/jpkleemans/vite-svg-loader/issues/25

If I turn url from ../public/logo.svg to /logo.svg I get error atttached in this comment https://github.com/jpkleemans/vite-svg-loader/issues/25#issuecomment-953545959

BTW I am using nuxt + TS if you are going to test it.

jd-solanki avatar Oct 28 '21 06:10 jd-solanki

@zinken7 does it work when omitting the ?component param?

jpkleemans avatar Apr 24 '22 10:04 jpkleemans

@jpkleemans

Hi! All imports on server-side (raw,url,component) calling error.

500 Cannot read properties of undefined (reading 'stubModule')

On client-side - its working;

Code example:

<template>
<component :is="icon" />
</template>

<script>
let icon = await import(`../../assets/svg/${props.name.toLowerCase()}.svg?component`).then((_) => _.default);
</script>

silencerspirit avatar Jun 21 '22 08:06 silencerspirit

@jpkleemans

Hi! All imports on server-side (raw,url,component) calling error.

500 Cannot read properties of undefined (reading 'stubModule')

On client-side - its working;

Code example:

<template>
<component :is="icon" />
</template>

<script>
let icon = await import(`../../assets/svg/${props.name.toLowerCase()}.svg?component`).then((_) => _.default);
</script>

Resolve this problem, create a functional component:

import { h } from 'vue';

const CommonIcon = (props, context) => {
 const svg = require(`../../assets/svg/${props.name}.svg`).default;
 return h('span', {...context.attrs, class: 'common-icon', }, [
    h(svg, { class: 'h-[inherit] w-[inherit]' }, [h(svg)]),
  ]);
}

CommonIcon.props = {
  name: {
    type: String,
    required: true,
  },
  width: {
    type: String,
    default: '',
  },
  height: {
    type: String,
    default: '',
  },
  size: {
    type: String,
    default: '',
  },
};

export default CommonIcon;

silencerspirit avatar Jun 21 '22 18:06 silencerspirit

@silencerspirit thanks for posting your solution!

jpkleemans avatar Jun 22 '22 12:06 jpkleemans

import { h } from 'vue';

const CommonIcon = (props, context) => { const svg = require(../../assets/svg/${props.name}.svg).default; return h('span', {...context.attrs, class: 'common-icon', }, [ h(svg, { class: 'h-[inherit] w-[inherit]' }, [h(svg)]), ]); }

CommonIcon.props = { name: { type: String, required: true, }, width: { type: String, default: '', }, height: { type: String, default: '', }, size: { type: String, default: '', }, };

export default CommonIcon;

require is not defined

cdwmhcc avatar Jun 22 '22 13:06 cdwmhcc

@cdwmhcc you need install plugin vite-require;

In vite.config.ts:

import svgLoader from 'vite-svg-loader';
import { viteRequire } from 'vite-require';

export default {
  ...,
  plugins: [svgLoader(), viteRequire()]
};

and if you use vitest as test platform, in vitest.config.ts:

import { viteRequire } from 'vite-require';
import svgLoader from 'vite-svg-loader';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  ...,
  plugins: [vue(), viteRequire(), svgLoader()],
});

silencerspirit avatar Jun 22 '22 14:06 silencerspirit

@cdwmhcc you need install plugin vite-require;

In vite.config.ts:

import svgLoader from 'vite-svg-loader';
import { viteRequire } from 'vite-require';

export default {
  ...,
  plugins: [svgLoader(), viteRequire()]
};

and if you use vitest as test platform, in vitest.config.ts:

import { viteRequire } from 'vite-require';
import svgLoader from 'vite-svg-loader';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  ...,
  plugins: [vue(), viteRequire(), svgLoader()],
});

Not working in nuxt.js 3

cdwmhcc avatar Jul 03 '22 05:07 cdwmhcc

@cdwmhcc you need install plugin vite-require; In vite.config.ts:

import svgLoader from 'vite-svg-loader';
import { viteRequire } from 'vite-require';

export default {
  ...,
  plugins: [svgLoader(), viteRequire()]
};

and if you use vitest as test platform, in vitest.config.ts:

import { viteRequire } from 'vite-require';
import svgLoader from 'vite-svg-loader';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  ...,
  plugins: [vue(), viteRequire(), svgLoader()],
});

Not working in nuxt.js 3

U welcome https://stackblitz.com/edit/github-1ck5ek?file=app.vue :)

silencerspirit avatar Jul 04 '22 12:07 silencerspirit

I know the reason.

Cannot use defineComponent:

export default defineComponent({
    async setup(props, { emit, attrs, slots }) {
        return () => {
            return ()
        };
    },
});

Must use:

import { h } from 'vue';

const CommonIcon = (props, context) => {
 const svg = require(`../../assets/svg/${props.name}.svg`).default;
 return h('span', {...context.attrs, class: 'common-icon', }, [
    h(svg, [h(svg)]),
  ]);
}

CommonIcon.props = {
  name: {
    type: String,
    required: true,
  },
};

export default CommonIcon;

cdwmhcc avatar Jul 09 '22 21:07 cdwmhcc

@silencerspirit Thank you for your reply. It will load all icons. I need to load on demand.

cdwmhcc avatar Jul 09 '22 21:07 cdwmhcc