Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error loading Snap with webpack #341

Open
zuotian opened this issue Jan 6, 2015 · 45 comments
Open

Error loading Snap with webpack #341

zuotian opened this issue Jan 6, 2015 · 45 comments

Comments

@zuotian
Copy link

@zuotian zuotian commented Jan 6, 2015

When loading Snap (from the dev branch) with webpack.

var Snap = require('snapsvg');

browser throw error Uncaught TypeError: Cannot read property 'on' of undefined

from line 1625 in svg.js

...
// default
eve.on("snap.util.getattr", function () {
    var att = eve.nt();
...
@tykko87
Copy link

@tykko87 tykko87 commented Jan 13, 2015

Same problem for me.

@clm-a
Copy link

@clm-a clm-a commented Feb 23, 2015

Same problem here 😢

@ibrierley
Copy link
Collaborator

@ibrierley ibrierley commented Feb 23, 2015

Is this related to #338 maybe ?

@clm-a
Copy link

@clm-a clm-a commented Feb 23, 2015

@ibrierley I checked out back to commit No.#c0b0b5805ecb231 and just felt on the issue you've referenced !

@frank-weindel
Copy link

@frank-weindel frank-weindel commented Mar 6, 2015

Same here

@andrew-minted
Copy link

@andrew-minted andrew-minted commented Mar 11, 2015

Same!

@frank-weindel
Copy link

@frank-weindel frank-weindel commented Mar 14, 2015

I've found a fairly simple way of pull in Snap with webpack using legacy-loader. Unfortunately Snap uses eval() in certain places (transform() is one area I know for sure) and so Snap is REQUIRED to be on the window.

var Snap = require('legacy-loader?exports=Snap!Snap.svg');
window.Snap = Snap; // transform REQUIRES Snap on the window because it uses eval

If you want to also get access to other resources that Snap exports (like mina) you can do something like this instead:

var SnapLib = require('legacy-loader!Snap.svg');
var Snap = SnapLib.Snap;
var mina = SnapLib.mina;
window.Snap = Snap; // transform REQUIRES Snap on the window because it uses eval

A bit involved I know. ES6 destructuring could be used to make it a bit more pleasant. Hope this helps.

@DmitryBaranovskiy
Copy link
Contributor

@DmitryBaranovskiy DmitryBaranovskiy commented Mar 16, 2015

@frank-weindel Could you, please, point where “Snap uses eval() in certain places (transform() is one area I know for sure)”?

@frank-weindel
Copy link

@frank-weindel frank-weindel commented Apr 3, 2015

@DmitryBaranovskiy I think this may have been a webpack issue since I can't reproduce it anymore and we were using dev-tool: eval before. Apologies.

@frank-weindel
Copy link

@frank-weindel frank-weindel commented Apr 3, 2015

I retract my original comment as legacy-loader has some major issues in Firefox.

@kapooostin
Copy link

@kapooostin kapooostin commented Apr 15, 2015

But still do we have a way to load Snap with webpack, since it doesn't uses eval()?

@kapooostin
Copy link

@kapooostin kapooostin commented Apr 17, 2015

Here is another recipe

var Snap = require( "imports-loader?this=>window,fix=>module.exports=0!snapsvg/dist/snap.svg.js" );
@alfonsomunozpomer
Copy link

@alfonsomunozpomer alfonsomunozpomer commented Aug 20, 2015

I was also hitting some issues using Webpack.

I suggest everybody that for the time being they follow @kapooostin’s suggestion. Works like a charm. Thanks!

@hybrisCole
Copy link

@hybrisCole hybrisCole commented Aug 24, 2015

using this in react like

import Snap from 'imports-loader?this=>window,fix=>module.exports=0!snapsvg/dist/snap.svg.js';

I just added imports-loader to package.json and it works like a charm 👍

@NicholasTuck
Copy link

@NicholasTuck NicholasTuck commented Sep 25, 2015

Thanks everybody. I had some troubles moving this to the webpack config because I am still earning my webpack black belt. So I thought I would drop here what I did end up getting to work:

            {
                test: require.resolve('snapsvg'),
                loader: 'imports-loader?this=>window,fix=>module.exports=0'
            },
@dvdplm
Copy link

@dvdplm dvdplm commented Oct 7, 2015

@NicholasTuck awesome, totally worked. :)

@yazonnile
Copy link

@yazonnile yazonnile commented Oct 23, 2015

Sorry, but still all this things with legacy-loader or with imports-loader doesn`t work
Still have "Cannot read property 'on' of undefined" as in first message

In the "webpack" case of course

@harryworld
Copy link

@harryworld harryworld commented Oct 28, 2015

I'm using webpack to load Snap.svg for React.js application.
I'm trying with the several ways above on imports-loader, what I get in Snap are just the file name, any clue? (It says Snap is not a function`)

@harryworld
Copy link

@harryworld harryworld commented Oct 28, 2015

I found the answer not long afterward. It was because the mix plugins with file-loader
I end up modifying wepack.config.js, excluding .svg.js pattern from file-loader, and then use a combination of @hybrisCole and @NicholasTuck

@yazonnile
Copy link

@yazonnile yazonnile commented Oct 28, 2015

@harryworld thx. Will try!

@geelen
Copy link

@geelen geelen commented Jan 16, 2016

Would it be possible to publish a snap.svg-commonjs.js that left the require statements for eve intact that webpack works with out of the box? Is that all that's needed?

@0x80
Copy link

@0x80 0x80 commented Mar 5, 2016

Another solution

npm install snapsvg

And use this loader config:

      {
        test: require.resolve('snapsvg'),
        loader: 'imports-loader?this=>window,fix=>module.exports=0'
      }

Currently the npm version is still 0.4.0. Can it be bumped to 0.4.1 please? Seems it was published 11 months ago?

@bmcorser
Copy link

@bmcorser bmcorser commented Aug 21, 2016

Any plans on supporting webpack sans workaround?

@ova2
Copy link

@ova2 ova2 commented Sep 4, 2016

Should we build and publish the 0.4.1 version? I would like to use the latests one via NPM and WebPack.

@geelen
Copy link

@geelen geelen commented Sep 5, 2016

I published snapsvg-cjs so you can npm install snapsvg-cjs for use with webpack.

Once this project works out of the box with webpack I'll deprecate my snapsvg-cjs

@mjisican
Copy link

@mjisican mjisican commented Oct 18, 2016

Does anyone here have tried configuring Snap on a React Project?

@alfonsomunozpomer
Copy link

@alfonsomunozpomer alfonsomunozpomer commented Oct 18, 2016

@mjisican,

In Expression Atlas we use Snap and React. Have a look at a component that displays a SVG anatomogram here: https://github.com/gxa/anatomogram

@mjisican
Copy link

@mjisican mjisican commented Oct 19, 2016

Thanks @alfonsomunozpomer :D
been doing some experiments on react on my free time, this would help me... thank you very much :D

@vellinchou
Copy link

@vellinchou vellinchou commented Nov 3, 2016

@NicholasTuck it works for me ,thanks

fffej added a commit to fffej/manifestomanifesto that referenced this issue Dec 31, 2016
@hipkiss91
Copy link

@hipkiss91 hipkiss91 commented Jan 30, 2017

Any word on when this will be done? is the snapsvg-cjs still the best option?
Also, snapsvg-cjs doesn't work for me.

@sparr
Copy link

@sparr sparr commented Mar 12, 2017

I would really appreciate if anyone could post all the steps required to get this working in one place

@sfentress
Copy link

@sfentress sfentress commented Jun 7, 2017

I'm looking to write tests in Mocha for files that require("snapsvg"), and I'm trying to work out how to either get the require to work or how to stub it out entirely.

For my built application, I was able to get require to work using

npm install --save-dev babel-loader

webpack.config.js:
---
module.exports = {
  module: {
    ...
    loaders: [
      {
        test: require.resolve('snapsvg'),
        loader: 'imports-loader?this=>window,fix=>module.exports=0'
      }
    ]
  }
};

However, when you run tests with mocha the Webpack config is not used.

Is there a way to use the imports-loader with a .babelrc file? Or a way to get mocha to just return a stubbed Snap.svg?

@adamfratino
Copy link

@adamfratino adamfratino commented Aug 14, 2017

@geelen excellent of you to originally do this but is it now abandoned? Last commit Aug 2016, I'm seeing an open PR for the updated snap.svg 0.5.1 submitted in February.

@geelen
Copy link

@geelen geelen commented Aug 15, 2017

@88mpg wasn't abandoned just neglected! Just released v0.0.6 which has 0.5.1

@egorgrushin
Copy link

@egorgrushin egorgrushin commented Aug 17, 2017

Another solution, worked for me:
import * as Snap from 'snapsvg';
and remove the second group from regex:

before:

{
    test: /\.(eot|woff2?|svg|ttf)([\?]?.*)$/,
    use: 'file-loader'
}

after:

{
    test: /\.(eot|woff2?|svg|ttf)$/,
    use: 'file-loader'
}

and imports-loader:

{
   test: require.resolve('snapsvg'),
   use: 'imports-loader?this=>window,fix=>module.exports=0',
},

Big thx to @harryworld for thought about file-loader

@Sigfried
Copy link

@Sigfried Sigfried commented Aug 17, 2017

@alfonsomunozpomer, I saw that you're using react-svg in https://github.com/gxa/anatomogram, but I didn't see Snap.svg. Are you still using it?

I know it was an old post, but I'm trying to figure out how to integrate complex SVG manipulation (partly generated by mermaid.js) into an app based on create-react-app (which uses Webpack but doesn't expose its configuration options.)

I could just have a flow like:

  1. Generate SVG in mermaid.js
  2. Parse and manipulate it in Snap.svg
  3. Put it in my react component using react-svg.

But that seems bad because my SVGs are likely to get big and I'm going to want to be able to treat small parts of them like components themselves. I'm pondering a workflow (if I can figure out how to do it) more like:

  1. Generate SVG in mermaid.js
  2. Parse it in Snap.svg
  3. Send that to a react component hierarchy where different components render (and handle ui interactions with) different Snap elements.
  4. Try to keep updates limited to Snap and the react components and not regenerate from mermaid.js except for the biggest changes (like all new data or something).

Does that seem like an ok approach? There are a lot of parts of it I don't know how to make work yet.

@alfonsomunozpomer
Copy link

@alfonsomunozpomer alfonsomunozpomer commented Aug 17, 2017

@Sigfried Please have a look at ebi-gene-expression-group/anatomogram#3 for my reply.

@Sigfried
Copy link

@Sigfried Sigfried commented Aug 17, 2017

Thanks, @alfonsomunozpomer! I responded there. But getting something working was easier than I expected. In case anyone's interested, here's some code:

import Snap from 'snapsvg-cjs'

const doSnapStuff = (el, svgCode) => {
   let container = Snap(el)
   let s = Snap.parse(svgCode)
   let n = s.select('g.node')
   n.node.onclick = function(a,b,c,d){console.log({a,b,c,d}); n.select('div').node.style.backgroundColor='red'}
   container.add(s)
}
export default class Mermaid extends Component {
   svgRender() {
      let svgDiv = this.svgDiv
      getTheSvg(  // accepts props and callback, callback accepts svgCode
        this.props, 
        (svgCode) => {
          doSnapStuff(svgDiv, svgCode)
        }
      )
  }
  componentDidMount() {
    this.svgRender()
  }
  componentDidUpdate(prevProps, prevState) {
     if (!_.isEqual(prevProps,this.props)) {
       this.svgRender()
     }
  }
  render() {
    return  <div ref={d=>this.svgDiv=d}>
            </div>
  }
}
@8804645769
Copy link

@8804645769 8804645769 commented Sep 4, 2017

Thanks

@germansokolov13
Copy link

@germansokolov13 germansokolov13 commented Oct 23, 2017

I just can't get rid of the feeling that I am constantly developing software in the entirely wrong way. Every time I introduce a dependency I need to change Webpack's configuration and sometimes introduce another loader or plugin. I'm not sure if Webpack helps or just gets in the way. Why not just go back to copy/pasting .js files and writing <script> tags? This entire modules idea is just an venture.

@kimdah3
Copy link

@kimdah3 kimdah3 commented Jan 22, 2018

@NicholasTuck's solution worked for me after I put the rule first in rules array.

@DanielTate
Copy link

@DanielTate DanielTate commented Feb 7, 2018

@GrushinEgor's solution worked perfectly for me

@ivc369
Copy link

@ivc369 ivc369 commented Apr 27, 2018

@NicholasTuck 's solution worked perfectly for me 👍

@runninghead
Copy link

@runninghead runninghead commented Jan 14, 2019

When I try to download snap.svg from the Adobe Extensions site it says :"This Extension is retracted by the partner." It's pointed to all over the web as the best method to create animated SVGs. Please can someone tell me where are the instructions to download and install a working version of it for 2019 use?
A Guide would also be appreciated :)

@zhang14725804
Copy link

@zhang14725804 zhang14725804 commented Sep 30, 2019

add "<script src="/assets/jslibs/snap.svg-min.js"></script>" to index.html
add "declare var Snap;" in .ts file

it`s work for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.