Hi all! I am preparing to release big update, it's already accessible as [email protected].
Please read carefully about upcoming breaking changes, new features and bugfixes.
¯_(ツ)_/¯
If you think that Node.js < 6 should be supported, please vote up in this issue.
¯_(ツ)_/¯
If you think that Webpack 1 should be supported, please vote up in this issue.
Reason: architectural changes.
Migration: just add a plugin in your webpack config
// webpack.config.js
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
...
{
plugins: [
new SpriteLoaderPlugin()
]
}
name config option renamed to symbolIdReason: more obviously.
regExp config option was removedReason: symbolId should cover most of naming cases.
prefixize config option was removedReason: all symbol elements isolated by default.
angularBaseWorkaround config option was removedReason: Angular introduced ability to remove the base tag requirement, see correspondent issue comment. If you still need it check angular-svg-base-fix.
Instead of symbol id runtime module now returns an object (class instance actually) which contains id, viewBox and content fields. See SpriteSymbol class and runtime generator.
Reason: make runtime more flexible, also it was requested in #32.
Migration:
// old
import symbol from './image.svg';
const rendered = `
<svg>
<use xlink:href="${symbol}" />
</svg>`;
// new
import symbol from './image.svg';
// now .viewBox is available
const rendered = `
<svg viewBox="${symbol.viewBox}">
<use xlink:href="#${symbol.id}" />
</svg>`;
If you think that loader should provide compatibility in this case, please vote up in this issue.
Some magic now happens by default, viz:
module.exports = ... for webpack 1, export default ... for webpack 2.runtimeGenerator option (check default runtime generator for example).id, viewBox and content fields. See SpriteSymbol class.style attributes (via svg-baker-runtime).Great, trying to test it out now. Everything seems to compile well, but the sprite is not injecting into the body as with v1. Do I need to make an explicit call to trigger this now?
@eugene1g sprite should injects automatically. Which webpack version is used?
Webpack2.
{
test: /\.svg$/,
include: [faModulesSrcDir + "/fa-icon"],
use: [
{
loader: "svg-sprite-loader",
options: {
symbolId: "[name]_[hash:base64:8]",
spriteModule: "svg-sprite-loader/runtime/browser-sprite.build"
}
},
"svgo-loader"
]
}
If I leave out spriteModule, then nothing gets injected. If I manually specify it, then it get injected but .stringify() is called before any symbols get populated and the resulting SVG has no nodes
Ok two separate notes -
The default/parent spriteModule svg-sprite-loader/runtime/sprite.build does not have DOM mounting logic, so it makes sense that it doesn't get injected. Hence forcing it to use browser-sprite fixes that problem.
I include all JS scripts at the end of the page, so when browser-sprite gets loaded it immediately mounts because document.body exists but before my require("icon.svg") code gets executed (because webpack does not guarantee the order of execution of every module). Therefore, the sprite gets mounted with no symbols in it, as none are populated at runtime yet. If I force the mount to happen on DOMContentLoaded, then all symbols are populated as expected.
@eugene1g I need your setup for case №1, could you please create a gist/repo with minimal setup which can reproduce described behaviour.
If I force the mount to happen on DOMContentLoaded, then all symbols are populated as expected
You're right. Seems like logic if (document.body) { sprite.mount(document.body, true); } should be removed to avoid such cases.
Ok I made a simple demo, but there the injection works as described - so something must be weird within my main environment. Only the document.body point was illustrated - have to dig in a bit more. I can't do it now so will have to triage during the week :/
Okay, [email protected] is published, now browser sprite only renders when DOMContentLoaded happens.
Thanks! Fixes my use-case.
Perhaps there is merit in optimistic execution - especially if somebody is loading your script async, or on-demand, or lazily later on. In those cases DOMContentLoaded won't ever fire, and it's better to execute asap. Perhaps it's worth replacing that listener with domready - it will execute the mount for both use-cases, and the lib is small and well-tested across browsers.
[email protected] with domready is published :)
Also browser-sprite example added.
Hey @kisenka, I've just submitted a PR https://github.com/kisenka/svg-sprite-loader/pull/96
It's just related to where Sprite is imported in plugin.js and resolving the pathname as unix doesn't mind this but when we used a Linux system it caused an issue.
Love the work and let me know if there's anything I need to fix with my PR
@rocking42 merged, published as 2.0.0-alpha.4
I have a use-case which seems to be broken with the alpha builds. I've updated my webpack config to match the browser-sprite example.
const files = require.context('./glyphs', false, /.svg$/)
files.keys().forEach(files)
But when I run webpack I get this error.

All the source code can be found here (haven't pushed the alpha changes)
Should I use a different approach or is it a bug in the alpha versions?
Thanks!
@alexandernanberg there is an error in your webpack.config.js, you should replace module: { loaders: [ ... ] } to module: { rules: [ ... ] }
@kisenka Ahh... Weird that I haven't been affected by that until now. Thanks anyway! 😄
webpack 2 is surprisingly backwards compatible and as part of that translates all loaders to rules behind the scenes - that's why your config file (from webpack1 days!) was still working without issues.
Does anyone else have this error?
(node:38229) Warning: a promise was created in a handler at {path to}/node_modules/svg-sprite-loader/lib/plugin.js:95:23 but was not returned from it, see http://goo.gl/rRqMUw
at Function.Promise.cast ({path to}/node_modules/bluebird/js/release/promise.js:196:13)
Using [email protected] on Node v7.9.0
@oliverturner this is not an error, but I'll fix it.
@kisenka thank you! Much appreciated 👍