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

How to automatically inject extracted svg file?

Open folmert opened this issue 7 years ago • 12 comments

Do you want to request a feature, report a bug or ask a question? Question.

What is the current behavior? I've extracted the svg sprites into separate file and it works, but I still have to manually inject it, and to make it worse, on production, development and Storybook it has to be done on 3 different ways. I'm currently using svg-sprite-injector but it doesn't work on Storybook.

What is the expected behavior? Generic way to automatically inject path to svg file into the app, so it can be cached.

The best way is to create repo with minimal setup to demonstrate a problem (package.json, webpack config and your code). package.json:

{
    test:    /\.svg$/,
    include: [path.resolve(__dirname, '../src/assets/svg-icons')],
    use:     [
        {
            loader:  'svg-sprite-loader',
            options: {
                extract:        true,
                spriteFilename: 'icons.svg'
            }
        },
        {
            loader:  'svgo-loader',
            options: svgoConfig,
        },
    ],
},

Icon.vue where I'm injecting the svg sprites:

const svgSpriteInjector = require('svg-sprite-injector');
const svgFiles = require.context('@/assets/svg-icons', true, /\.svg$/);
svgFiles.keys().forEach(key => svgFiles(key));
svgSpriteInjector('icons.svg', {revision: 1});

Please tell us about your environment:

  • Node.js version: 8.7.0
  • webpack version: 3.8.1
  • svg-sprite-loader version: 3.4.1
  • OS type & version: Win 10

folmert avatar Nov 24 '17 16:11 folmert

Why not use default way to work with sprite via JS?

kisenka avatar Nov 25 '17 08:11 kisenka

What's the default way? Can you elaborate? :)

folmert avatar Nov 25 '17 12:11 folmert

I mean import SVGs in JS so they will be automatically injected in DOM.

kisenka avatar Nov 25 '17 12:11 kisenka

You mean with require('icons.svg)? Or non-extract svg-sprite-loader? The first returns "module not found" and the latter works but won't cache the svg, will it?

folmert avatar Nov 27 '17 09:11 folmert

The first returns "module not found"

You should specify relative path to image, eg require('./icon.svg')

the latter works but won't cache the svg, will it?

It's cached as other resources.

kisenka avatar Nov 27 '17 10:11 kisenka

Regarding my main problem - I see now the svg is injected into iframe of the Storybook and still doesn't show icons, so it must be a problem within Storybook.

But what do you mean by "cached as other resources"? In dev tools I don't see it in any cache when I'm not using extract: true option. If it's not extracted to any file how can it be cached?

folmert avatar Nov 27 '17 10:11 folmert

so it must be a problem within Storybook

You can create git repo with your setup to demonstrate a problem and I'll help you.

In dev tools I don't see it in any cache

In default mode sprite and it's symbols are part of your JS code, so browser will cache them like other resources.

kisenka avatar Nov 27 '17 10:11 kisenka

Thank you!

It's here: https://github.com/folmert/storybook/tree/master/app/vue

Steps to reproduce:

  1. cd app/vue
  2. npm install
  3. npm run storybook
  4. UiButton doesn't have icon displayed:
<button type="button" class="btn btn-primary btn-lg"><svg data-v-71953609="" class="icon icon--small"><use data-v-71953609="" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="iconLeft"></use></svg> <span class="button__content pad--left">Text</span> <!----></button>

#shadow-root normally has svg contents, but now it says "closed"

folmert avatar Nov 27 '17 12:11 folmert

It works now, my button component template had a missing colon (:) before icon href, so the property value was in fact the variable name (iconLeft) instead value behind this variable (#envelope).

folmert avatar Nov 27 '17 15:11 folmert

@folmert sorry for dig delay, but I am having following error with your demo:

ERROR in /Users/kisenka/projects/svg-sprite-loader-testcases/218/addons/actions/register.js
Module not found: Error: Can't resolve './dist' in '/Users/kisenka/projects/svg-sprite-loader-testcases/218/addons/actions'
 @ /Users/kisenka/projects/svg-sprite-loader-testcases/218/addons/actions/register.js 1:0-17
 @ ./.storybook/addons.js
 @ multi ./dist/server/config/polyfills.js ./.storybook/addons.js ./dist/client/manager/index.js

ERROR in /Users/kisenka/projects/svg-sprite-loader-testcases/218/addons/links/register.js
Module not found: Error: Can't resolve './dist' in '/Users/kisenka/projects/svg-sprite-loader-testcases/218/addons/links'
 @ /Users/kisenka/projects/svg-sprite-loader-testcases/218/addons/links/register.js 1:0-17
 @ ./.storybook/addons.js
 @ multi ./dist/server/config/polyfills.js ./.storybook/addons.js ./dist/client/manager/index.js

ERROR in ./src/stories/index.js
Module not found: Error: Can't resolve '@storybook/addon-actions' in '/Users/kisenka/projects/svg-sprite-loader-testcases/218/app/vue/src/stories'
 @ ./src/stories/index.js 17:20-55
 @ ./.storybook/config.js
 @ multi ./dist/server/config/polyfills.js ./dist/server/config/globals.js (webpack)-hot-middleware/client.js?reload=true ./.storybook/config.js

ERROR in ./src/stories/index.js
Module not found: Error: Can't resolve '@storybook/addon-links' in '/Users/kisenka/projects/svg-sprite-loader-testcases/218/app/vue/src/stories'
 @ ./src/stories/index.js 19:18-51
 @ ./.storybook/config.js
 @ multi ./dist/server/config/polyfills.js ./dist/server/config/globals.js (webpack)-hot-middleware/client.js?reload=true ./.storybook/config.js

ERROR in ./dist/client/manager/provider.js
Module not found: Error: Can't resolve '@storybook/addons' in '/Users/kisenka/projects/svg-sprite-loader-testcases/218/app/vue/dist/client/manager'
 @ ./dist/client/manager/provider.js 39:14-42
 @ ./dist/client/manager/index.js
 @ multi ./dist/server/config/polyfills.js ./.storybook/addons.js ./dist/client/manager/index.js

ERROR in ./dist/client/preview/index.js
Module not found: Error: Can't resolve '@storybook/addons' in '/Users/kisenka/projects/svg-sprite-loader-testcases/218/app/vue/dist/client/preview'
 @ ./dist/client/preview/index.js 14:14-42
 @ ./dist/client/index.js
 @ ./.storybook/config.js
 @ multi ./dist/server/config/polyfills.js ./dist/server/config/globals.js (webpack)-hot-middleware/client.js?reload=true ./.storybook/config.js

ERROR in ./dist/client/manager/provider.js
Module not found: Error: Can't resolve '@storybook/channel-postmessage' in '/Users/kisenka/projects/svg-sprite-loader-testcases/218/app/vue/dist/client/manager'
 @ ./dist/client/manager/provider.js 43:26-67
 @ ./dist/client/manager/index.js
 @ multi ./dist/server/config/polyfills.js ./.storybook/addons.js ./dist/client/manager/index.js

ERROR in ./dist/client/preview/index.js
Module not found: Error: Can't resolve '@storybook/channel-postmessage' in '/Users/kisenka/projects/svg-sprite-loader-testcases/218/app/vue/dist/client/preview'
 @ ./dist/client/preview/index.js 18:26-67
 @ ./dist/client/index.js
 @ ./.storybook/config.js
 @ multi ./dist/server/config/polyfills.js ./dist/server/config/globals.js (webpack)-hot-middleware/client.js?reload=true ./.storybook/config.js

ERROR in ./dist/client/manager/provider.js
Module not found: Error: Can't resolve '@storybook/ui' in '/Users/kisenka/projects/svg-sprite-loader-testcases/218/app/vue/dist/client/manager'
 @ ./dist/client/manager/provider.js 37:10-34
 @ ./dist/client/manager/index.js
 @ multi ./dist/server/config/polyfills.js ./.storybook/addons.js ./dist/client/manager/index.js

ERROR in ./dist/client/manager/index.js
Module not found: Error: Can't resolve '@storybook/ui' in '/Users/kisenka/projects/svg-sprite-loader-testcases/218/app/vue/dist/client/manager'
 @ ./dist/client/manager/index.js 3:10-34
 @ multi ./dist/server/config/polyfills.js ./.storybook/addons.js ./dist/client/manager/index.js

ERROR in ./dist/client/preview/init.js
Module not found: Error: Can't resolve '@storybook/ui/dist/libs/key_events' in '/Users/kisenka/projects/svg-sprite-loader-testcases/218/app/vue/dist/client/preview'
 @ ./dist/client/preview/init.js 27:18-63
 @ ./dist/client/preview/index.js
 @ ./dist/client/index.js
 @ ./.storybook/config.js
 @ multi ./dist/server/config/polyfills.js ./dist/server/config/globals.js (webpack)-hot-middleware/client.js?reload=true ./.storybook/config.js

kisenka avatar Jan 09 '18 12:01 kisenka

Hi

In default mode sprite and it's symbols are part of your JS code, so browser will cache them like other resources.

JS code will change at every new release so if we want efficient cache we need to extract the sprite isn't it ? It is not clear for me how to load this extracted sprit with webpack then.

nboisteault avatar Mar 17 '20 08:03 nboisteault

Hello, I am having a similar issue with the svg-sprite-loader I am using storybook with vue js Screen Shot 2021-02-18 at 3 26 18 PM

My webpack config looks like this:

{
 test: /\.svg$/,
 loader: 'svg-sprite-loader',
 options: {
   extract: true,
   publicPath: '/'
 }
}

I also check out the git repository from @folmert and the HTML for the SVG isn't working.

nerisina avatar Feb 18 '21 22:02 nerisina