How to require generated sprite in JS file
See original GitHub issueHi i have a quiestion and canāt find solution anywhere. We want to add hash to the generated sprite, so when we add or change an icon, the browser will download newer spritefile.
This can be easily achieved with
.addPlugin(createSvgSpritemapPluginInstance('images/icons.[contenthash].svg'))
And this will generate the file and line in manifest.json
"dist/images/icons.svg": "/dist/images/icons.68e91515460ebaae.svg",
.
The problem is how to use this file in a React component or in any JS file? I am trying to do an import but canāt seem to find the right combination:
/import icons from '/dist/images/icons.svg';
The problem is that the file physicaly doesnāt exist and is generated during compilation.
Webpack will exit with
`This dependency was not found:
- dist/images/icons.svg in ./js/utilities/icon.js `
is there a way how to use file with hash in JS file?
Issue Analytics
- State:
- Created 3 years ago
- Comments:8 (4 by maintainers)
Top GitHub Comments
@cascornelissen Thanks a ton for the quick answer and detailed explanation š Youāre right about using the
[contenthash]
in the filename is a bit hard to figure out later cause the generated hash is not stored anywhere, plus you have to clean up the previously generated files and it seems lots of work. The third option ( using manifest file ) seems to be the way to go. Iāve already implemented using the method you mentioned :and then
The only ugly side of this approach was the mix webpack configuration because webpack doesnāt pick up the sprite file generated by this plugin for some reason š¤ So to tackle this issue I ended up generating the file at some unnecessary path like
'../resources/pre/sprite.svg'
and then usemix.copy
to copy it over to the public directory. Doing all that just to let webpack know: āthis is one of my assets you got to add to the manifest file and version it later in the productionā.Thanks a lot again anyway, great stuff šš
No problem, the main issue is that you want to bust the cache when the contents of the spritemap changes. The best way to do this is to use
[contenthash]
in the filename, this will insert a hash of the content in the filename which only changes when the content of the file changes. For example:sprite.95f18a53.svg
where95f18a53
is this contenthash that is injected by the plugin.Then the next, and probably harder-to-solve issue is that you now have a filename with a dynamic value. The solution to this really depends on your stack, which is why itās hard to answer this question as I havenāt worked with Laravel (mix) in a few years. I expect that both the second and third option in https://github.com/cascornelissen/svg-spritemap-webpack-plugin/issues/147#issuecomment-769412404 are possible in your case.
The second option describes a solution where you use the power of the templating engine thatās used by the project. The templating engine probably has access to the filesystem and should be able to figure out what the filename of the spritemap is. Then this templating engine injects the SVG directly into the HTML that itās generating, this way you donāt have to reference an external file but you can reference an element thatās available in the DOM already. The main downside of this approach is that youāre forcing users to download the entire spritemap because itās part of the HTML document, kind of defeating one of the main points on why youād want to use a spritemap in the first place.
The third option describes a solution that makes use of another webpack plugin. This plugin generates a manifest JSON file with original filenames as keys and hashed filenames as values, allowing you to basically do
manifest['sprite.svg']
to get to the value you need;sprite.95f18a53.svg
. You can do this approach both on the server and on the client. Since youāre using Laravel Iām guessing doing it on the server is the best way forward in your case, especially since doing it client-side also has some issues (e.g. https://github.com/cascornelissen/svg-spritemap-webpack-plugin/issues/170). In your template (Iām guessing at this point), you can import this generated manifest JSON file, and do something like:I hope this clears up the approaches you can take, Iām sure there are other ways to accomplish this but this should at least give you some insights.