Coder Social home page Coder Social logo

Comments (26)

hyatt03 avatar hyatt03 commented on May 20, 2024 4

Hi everyone! I've run into a similar issue, however I didn't want to webpack my entire backend so I came up with a kinda hacky solution.

I was already using ignore-styles as I import relevant stylesheets into my react components, so in order to generate the correct server side markup I just needed to add the following to my bootstrapping file:

const path = require('path');
const crypto = require('crypto');

require('ignore-styles').default(['.scss', '.css', '.svg'], (module, filename) => {
  const base = path.basename(filename);
  if (base.indexOf('.svg') > 0) {
    module.exports = '#' + crypto.createHash('md5').update(filename).digest("hex");
  }
});

Note this works with the following webpack config:

{
  ...
  module: {
    loaders: [
      {
        test: /\.svg$/,
        loader: 'svg-sprite?' + JSON.stringify({
          name: '[pathhash]',
          prefixize: true
        })
      }
    ]
  },
  ...
}

I hope this helps somebody! 😃

from svg-sprite-loader.

danilobuerger avatar danilobuerger commented on May 20, 2024 3

Shouldn't something like SSR live in the default sprite impl? The very least it should do on a node environment it just return the symbol id (without using document) instead of failing.

from svg-sprite-loader.

qur2 avatar qur2 commented on May 20, 2024 2

I believe for SSR, we need a node require hook that will generate the correct ID for a given path, then it should all work fine since the sprite will be loaded client-side.
I would give it a go, but I'm first trying to get a sprite generated at all.

from svg-sprite-loader.

lrojas94 avatar lrojas94 commented on May 20, 2024 1

Thing is I'm using a server side rendered Application, which is why this loader is failing when going through the app initialization. In the meantime, I managed to make it work by only requiring the plugin if typeof window !== 'undefined', it's a temporal fix, but works, so will be looking forward to the alpha version next week :)

Thanks for taking the time to look out my problem here 👍

from svg-sprite-loader.

kisenka avatar kisenka commented on May 20, 2024

@oliverox you can implement your own sprite behaviour via spriteModule option. Something like this:

webpack.config.js

...
  module: {
    loaders: [
      {
        test: /\.svg/,
        // define path to custom sprite module
        loader: 'svg-sprite?spriteModule=' + path.resolve(__dirname, 'server-side-rendering-sprite-module.js')
      }
    ]
  }

server-side-rendering-sprite-module.js

// simple sprite implementation which renders into string
function Sprite() {
  this.symbols = [];
}

Sprite.prototype.add = function(image) {
  this.symbols.push(image);
};

Sprite.styles = ['position:absolute', 'width:0', 'height:0', 'visibility:hidden'];

Sprite.prototype.render = function() {
  return [
    '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="'+ Sprite.styles.join(';') +'">',
      '<defs>',
        this.symbols.join(''),
      '</defs>',
    '</svg>'
  ].join('');
};

module.exports = new Sprite();

my-app.js

require('./image.svg');

var sprite = require('./server-side-rendering-sprite-module');
var renderedSprite = sprite.render();
console.log(renderedSprite);

from svg-sprite-loader.

kisenka avatar kisenka commented on May 20, 2024

@oliverox does it helped?

from svg-sprite-loader.

oliverox avatar oliverox commented on May 20, 2024

@kisenka Thanks for the help in the right direction. I have not had enough time to implement it yet as I've been moving over the new year. Will try it soon. Thanks again.

from svg-sprite-loader.

olegakbarov avatar olegakbarov commented on May 20, 2024

@kisenka I stumbled upon same problem. Could you please elaborate on process of implementing the server-sider rendering module for React app?

My node app generates sprite and inlines it into html (this works well):

app.use((req, res, next) => {
  const html = renderToString(
    <Root />
  );

  let renderedSprite = Root.sprite;

  res.send(template({ html, env, renderedSprite }));
});

and my components looks like this

import svg_aws from './img/aws.svg';

class Icon extends React.Component {
  render() {
    let { glyph } = this.props;
    return (
      <svg
        className="icon"
        width="81px"
        height="81px"
        dangerouslySetInnerHTML={{__html: '<use xlink:href="' + glyph + '"></use>'}}
      />
    )
  }
}

<Icon glyph={svg_react} />

The problem is that when webpack compiles it (with target: node) the svg_aws is undefined. So to my understanding the problem boils down to getting the sprite xlink:href at compile time. Any thoughts on this?

from svg-sprite-loader.

olegakbarov avatar olegakbarov commented on May 20, 2024

Well.. i came up with crappy solution actually:

const sprite = require('../../utils/svg-server-rendering.js');

...

let ids = sprite.symbols.map(i => {
   return i.match(/id="(.*?)"/g)
});

let arr = ids.map(j => j[0].replace('id=', '#').replace(/\"/g, ""))

arr.map(el => <Icon glyph={el} />)

Pretty sure that it is not only ugly, but also wrong somewhere 😐

UPD:

aaaand it does not work on webpack dev server

from svg-sprite-loader.

kisenka avatar kisenka commented on May 20, 2024

import svg_aws from './img/aws.svg';
<Icon glyph={svg_react} />
svg_aws
svg_react

Maybe wrong var reference?

from svg-sprite-loader.

olegakbarov avatar olegakbarov commented on May 20, 2024

No, i map all of them and they all undefined when render on server. Also initial version based on docs worked perfectly on development server (without SSR).

from svg-sprite-loader.

kisenka avatar kisenka commented on May 20, 2024

@olegakbarov sorry, I am vacation till 21 March so I can't help you now

from svg-sprite-loader.

olegakbarov avatar olegakbarov commented on May 20, 2024

No problem, i'll write up if got some results on this.

from svg-sprite-loader.

qur2 avatar qur2 commented on May 20, 2024

Also struggling with server-side rendering. Initially, the error I got was a type error because React is undefined. Found out that it seems it's the babel-loader trying to do its job (there is no webpack when running with node -r babel-register). I then tried to just get the correct id generated by node, assuming the sprite would already be setup thanks to the webpack build, but I don't get any svg file in my build output anyway and I'm now very confused.

from svg-sprite-loader.

kisenka avatar kisenka commented on May 20, 2024

Sorry for delay. I am working on it

from svg-sprite-loader.

danilobuerger avatar danilobuerger commented on May 20, 2024

@kisenka do you still intend to work on this?

from svg-sprite-loader.

kisenka avatar kisenka commented on May 20, 2024

I've created the testcase https://github.com/kisenka/svg-sprite-loader-ssr-testcase for server-side rendering.

  1. Fork it.
  2. npm install
  3. npm run sprite-test

You will see that output from sprite loader which contains the whole sprite.
You can add your testcases in you forks and tell me.

from svg-sprite-loader.

kisenka avatar kisenka commented on May 20, 2024

@danilobuerger you're right. Sprite loader firstly created for in browser usage, so it works with browser environment out of the box. I think it will be good if sprite loader will use environment specific sprite implementation which depends on target webpack config option. Thoughts?

from svg-sprite-loader.

danilobuerger avatar danilobuerger commented on May 20, 2024

Hmm, so what we need to consider is client-only and server+client (render server side, pick up on client side) and server-only setups. Probably need to also consider outputing to a svg file (see #23).

Overall it might make more sense splitting this up in multiple loaders. One that returns symbol ids (or external ref + symbol ids) and builds the svg map. Another loader to include that svg map either as file or load it in dom or output it in some other way.

client-only

If inline, return symbol id on require. Include svg map in dom, updateable (?).
If file, return external ref + symbol id on require. Chunk svg map, maybe extractable with extract-text-webpack-plugin.

server-only

If inline, return symbol id on require. Output svg map so it can be rendered.
If file, return external ref + symbol id on require. Chunk svg map, maybe extractable with extract-text-webpack-plugin.

client+server

If inline, return symbol id on require. Output svg map so it can be rendered. Client should not include svg map in dom as its already present. Maybe it can updated it instead like react-helmet does for example.
If file, return external ref + symbol id on require. Chunk svg map, maybe extractable with extract-text-webpack-plugin. Client should not include svg map in dom.

from svg-sprite-loader.

qur2 avatar qur2 commented on May 20, 2024

Just as a heads-up, for my project, I switched to making a webpack bundle for the server as well (as per this article: http://jlongster.com/Backend-Apps-with-Webpack--Part-I) to avoid needing duplicate logic for every loader that node should know about.

from svg-sprite-loader.

wmertens avatar wmertens commented on May 20, 2024

I can confirm that the approach provided by @kisenka in #19 (comment) works for me.

I had to make the webpack config for the ?spriteModule=server-side-rendering-sprite-module conditional on the prerender build, and then in my app I just needed to import the server-side-rendering-sprite-module module and put the result of sprite.render() in the outgoing HTML.

However, I think that the approach outlined in #45 will be more efficient and easier to set up.

from svg-sprite-loader.

elado avatar elado commented on May 20, 2024

Confirming @hyatt03's solution works well! Thanks for sharing.

from svg-sprite-loader.

lrojas94 avatar lrojas94 commented on May 20, 2024

Hello!!

Are there any updates on this? (as I see this to be a feature for 2.0).
Also, could you, given you have the chance, point me in the right direction to use with React? Though I did check the example, I can't really see how to implement it with React.

Thanks in advance!

from svg-sprite-loader.

kisenka avatar kisenka commented on May 20, 2024

@lrojas94 work in progress, I planning to release alpha version on the next week.

Also, could you, given you have the chance, point me in the right direction to use with React?

Do you have concrete question about loader with React?

from svg-sprite-loader.

kisenka avatar kisenka commented on May 20, 2024

@oliverox
@olegakbarov
@qur2
@danilobuerger
@hyatt03
@wmertens
@elado
@lrojas94

Hey guys [email protected] with server side rendering is on the way, please read about it here #91 and take part in discussion/voting. Thanks!

from svg-sprite-loader.

kisenka avatar kisenka commented on May 20, 2024

Check 2.0.1 release

from 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.