15

I am writing a plugin which creates a SVG sprite. It globs over the directories, merge SVG files in one image and returns the result. The idea is to dynamically create a module (which contains merged images) so that other modules can require it as an usual module. Or maybe you can suggest a more elegant solution?

Config

{
  plugins: [
    new SvgSpritePlugin({
      sprites: {
        icons: 'images/svg/icons/*.svg',
        logos: 'images/svg/logos/*.svg',
        socials: 'images/svg/logos/{twitter,youtube,facebook}.svg',
      }
    })
  ]
}

Somewhere in the application

var logosSprite = require('sprite/logos'); // require dynamically created module
document.body.appendChild(logoSprite);
Calcolat
  • 878
  • 2
  • 11
  • 22
kisenka
  • 171
  • 8
  • I'm trying to do a similar thing. Would love to know how to inject a module from a plugin. – 4m1r Jul 29 '15 at 17:26
  • Did you try [webpack-svgstore-plugin](https://github.com/lgordey/webpack-svgstore-plugin)? Looks like it solves the same problem. – Kreozot Sep 09 '15 at 11:21
  • @Kreozot svgstore-plugin does different thing - it emit assets during webpack compilation. I want to work with svg like with regular modules and build only required files. I write [svg-sprite-loader](http://github.com/kisenka/webpack-svg-sprite-loader) (highly experimental). – kisenka Sep 10 '15 at 12:11
  • 1
    @4m1r the right way to doing this is to write a loader (see the [comment](https://github.com/webpack/webpack/issues/1310#issuecomment-125997245) from Tobias Koppers, the webpack author). – kisenka Sep 10 '15 at 12:19
  • 1
    do you have a non-"elegant" solution for this already? Feels like you're trying to do too many things at once. You should be able to use webpack to combine all your svg and output a single svg with loaders and a plugin to bunch them all. Once you've figured it out, you need to determine how to make it available in the app. – Andrei R Nov 17 '15 at 23:02
  • I recommend to have a look at this plugin: https://github.com/rmarscher/virtual-module-webpack-plugin , which help you create a virtual file on the fly, and then you could include this file in entry config. – Evi Song Feb 08 '17 at 07:11

2 Answers2

3

Try taking a look at how external and delegated modules are provided in Webpack. A good place to start is the ExternalModuleFactoryPlugin or DllReferencePlugin.

Essentially, you create a plugin for the NormalModuleFactory which takes requests for modules, you match those which should resolve to the modules you are generating and you can asynchronously respond with a Module.

Filip Dupanović
  • 32,650
  • 13
  • 84
  • 114
1

I have a somewhat not-so-elegant solution.Combine all svgs(by iterating over folder)into one html and hide that html snippet with a display:none.Have the ids as the fileName and ucan then access them by getElementById(<yourID>).innerHTML. Sample of jsp based snippet..or write in whichever language you want..

<div id="hiddenSVGSprite" style="dispaly:none">
 <i><span id="Download" ><%@include file="svg/Download.svg" %>/span>Download</i>
 <i><span id="DownloadFAQs" ><%@include file="svg/DownloadFAQs.svg" %> </span>DownloadFAQs</i>
 <i><span id="DownloadQuickReferenceGuide" ><%@include file="svg/DownloadQuickReferenceGuide.svg" %> </span>DownloadQuickReferenceGuide</i>
 <i><span id="DownloadUserManual" ><%@include file="svg/DownloadUserManual.svg" %> </span>DownloadUserManual</i>
</div>
Koustav Ray
  • 1,112
  • 13
  • 26