Giter Site home page Giter Site logo

Comments (5)

bensampaio avatar bensampaio commented on July 29, 2024

@mnpenner I used webpack-dev-server for the React example and it works. Could you have a look at it and see if it applies to your use case? Otherwise can you be more specific? Thank you :)

from external-svg-sprite-loader.

mnpenner avatar mnpenner commented on July 29, 2024

Just tested your React example. It does indeed work with webpack-dev-server like you said, but you're not running it on a separate port.

I believe I had to run mine on a separate port because my app is written in PHP and its behind nginx. So I have nginx running on port 8080 and webpack-dev-server serving my compiled assets from 8081.

Here's the relevant part of my config:

if(isWDS) {
    let wdsPort = 8081;

    module.exports = merge(commonConfig, {
        output: {
            publicPath: `http://localhost:${wdsPort}/assets/`,
            filename: '[name].js'
        },
        entry: {
            all: [
                `webpack-dev-server/client?http://0.0.0.0:${wdsPort}`,
                'webpack/hot/only-dev-server',
            ]
        },
        devServer: {
            hot: true,
            host: '0.0.0.0',
            port: wdsPort,
            stats: 'errors-only',
        },
        devtool: '#inline-source-map'
    });
}

So what ends up happening is that your SVG looks like this:

<svg viewBox="0 0 216 146">
    <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/img/sprite.svg#icon-example-867aa"></use>
</svg>

And mine looks like this:

<svg viewBox="0 0 100 100">
    <use xmlns:xlink="http://www.w3.org/1999/xlink"
         xlink:href="http://localhost:8081/assets/sprite-4faa5ef477.svg#icon-asterisk-50af6"></use>
</svg>

Which causes it to be blocked by the browser (with no useful information):

image

I'm still looking for workarounds, but right now it appears to only workaround is to AJAX-in the SVG.

This wouldn't just be a problem for people using webpack-dev-server like me, but anyone who wants to use a CDN.

from external-svg-sprite-loader.

mnpenner avatar mnpenner commented on July 29, 2024

I gave this some thought and worked out a hack I can use for development:

First, update the <Svg> component to rip off the file path, leaving only the #hash:

export default function Svg(props) {
    let attrs = _.omit(props, ['sprite','title','desc']);
    let symbol = props.sprite.symbol;
    if(__DEV__) {
        symbol = symbol.slice(symbol.indexOf('#'));
    }
    return (
        <svg viewBox={props.sprite.viewBox} {...attrs}>
            <use xlinkHref={symbol}>
                {props.title ? <title>{props.title}</title> : null}
                {props.desc ? <desc>{props.desc}</desc> : null}
            </use>
        </svg>
    );
}

Then, in one of your scripts that loads on every page, inject the sprite:

if(__DEV__) {
    let spritemap = require('../icons').asterisk.symbol;
    spritemap = spritemap.slice(0, spritemap.indexOf('#'));
    fetch(spritemap).then(res => res.text()).then(text => {
        let div = document.createElement('div');
        div.innerHTML = text;
        div.style.display = 'none';
        document.body.insertBefore(div, document.body.childNodes[0]);
    });
}

N.B. I've picked a random sprite here so that I could get the filename since it's not exported.

__DEV__ is a "constant" I'm injecting through webpack.config.js:

        plugins: [
            new webpack.DefinePlugin({
                __DEV__: JSON.stringify(true),
            }),
        ],

In theory, those chunks of code should be compiled out for production, but I haven't actually verified that yet :-)

This will work for me for now I think, but this would be much better as a loader option. Maybe something like inject=true would cause all the symbol and view URLs to contain only the hash, and then it could inject something like I've done into the bundle to fetch the sprite and inject it into the page. Maybe something a little more robust though.

My solution won't work for CSS.

from external-svg-sprite-loader.

bensampaio avatar bensampaio commented on July 29, 2024

@mnpenner, I understand the problem. I am not using webpack-dev-server yet so I never came across this problem. Can't webpack-dev-server be used as a proxy for your PHP app? In this way none of this would be necessary.

This loader has to work for CSS and JS. That's one of the reasons that made me write it, so I won't implement something that removes support to CSS (even if it's under a specific flag).

from external-svg-sprite-loader.

mnpenner avatar mnpenner commented on July 29, 2024

@bensampaio I think had problems proxying the requests last time I tried. Don't remember what issues I faced exactly.

I understand your position though. Being able to use SVGs in CSS is definitely a perk. It's a shame cross-domain <uses> still don't work in 2017. Browsers need to get their act together 😝

svgxuse works for HTML/JS. I was afraid it wouldn't work well with React because none of the SVGs are in my initial HTML, but it looks like it watches for DOM changes. However, it lets all the broken cross-domain requests fail before patching them which is kind of annoying.

I'm not sure what the answer is right now. If we AJAX-in the SVG, it doesn't help with CSS, and we have a FOMI (flash of missing icons). If we inline the spritemap, we lose out on caching. And if we use an external spritemap, we can't use a CDN/separate asset server. There's no winning!

from external-svg-sprite-loader.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.