vite-svg-loader
vite-svg-loader copied to clipboard
dynamically import not working when build
@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>
Hi, thanks for reporting. Could you share an example project so I can reproduce the problem, and investigate how to resolve it.
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
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:
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:
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.
@zinken7 does it work when omitting the ?component
param?
@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>
@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 thanks for posting your solution!
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 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()],
});
@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, invitest.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 you need install plugin
vite-require
; Invite.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, invitest.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 :)
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;
@silencerspirit Thank you for your reply. It will load all icons. I need to load on demand.