jacomyal / sigma.js

A JavaScript library aimed at visualizing graphs of thousands of nodes and edges
https://www.sigmajs.org
MIT License
11.16k stars 1.59k forks source link

V2@alpha issue in WebGLRenderer and React #1006

Closed lksnmnn closed 5 years ago

lksnmnn commented 5 years ago

Hey there.

I am currently evaluating a bunch of different graph drawing libraries and I wanted to add sigma.js v2 to my stack. I tried running the basic example but I am always greeted with this error:

Error: sigma/renderers/weblg/shaders/utils.loadShader: error while compiling the shader:
ERROR: 0:1: '/' : syntax error

weblg is a typo in your exception message btw

I run the example code within a React App using the following packages:

Does anyone have an idea how to fix this?

Cheers, Lukas

Ps: All examples use the WebGLRenderer, will you implement a Canvas Renderer for v2? Or is this the same (I saw it renders as canvas in the examples)?

Yomguithereal commented 5 years ago

Hello @lksnmnn. I can't reproduce your issue. Can you point me to your code somehow?

weblg is a typo in your exception message btw

Don't hesitate to open a PR.

Ps: All examples use the WebGLRenderer, will you implement a Canvas Renderer for v2? Or is this the same (I saw it renders as canvas in the examples)?

I will at one point implement a canvas renderer. But I am currently focusing on WebGL because sigma is mostly about performance and canvas is unable to provide said performance.

(I saw it renders as canvas in the examples)

The examples are all webgl.

lksnmnn commented 5 years ago

Thank you for the quick reply. I will create a minimal example for this error and upload it to a gist this evening.

My bad. I did not know that WebGL renders into a <canvas> element.

lksnmnn commented 5 years ago

PR for the typo: https://github.com/jacomyal/sigma.js/pull/1007

lksnmnn commented 5 years ago

Hex @Yomguithereal. Here is a minimal React App implementing the basic example from sigma.js v2: https://github.com/lksnmnn/react-sigma-example

I am new to React, so maybe I am doing something wrong, but all other libraries (like d3, vivagraph, vis.js, g6, ...) worked straight up.

Yomguithereal commented 5 years ago

There seems to be an issue with create-react-app's magic. It seems it attempts to transpile modules inside sigma dependencies for a reason I cannot fathom. Try without and it should work. I will try to find some time to pinpoint the exact issue (maybe my package.json is giving some erroneous hints regarding transpilation by third-parties).

lksnmnn commented 5 years ago

Hm I see.

This answer describes a way to add a custom config for a third-party module: https://stackoverflow.com/questions/44805482/transpiling-third-party-modules-with-create-react-app-build?rq=1

I will try to use this later today, but it would be cool if sigma.js would "just work" ;). Let me know if I can be of any help.

Cheers, Lukas

Yomguithereal commented 5 years ago

Sigma should already « just work ». There is no need to transpile it since packaged sources are already transpiled. Here create react app is doing some bad magic for a reason I don’t really get.

lksnmnn commented 5 years ago

I just compared the package.json of sigma.js and d3. So far the only differences I could spot were that d3 provides an entry point for ES6 Modules in Node by specifying the module key, but this should only provide backwards compatibility afaik. Also they do not provide Babel presets, but idk if this has any impact on Reacts bundling scripts.

The in main specified entry points differ too (content wise), but I am more of a backend developer and never made my own JS module, so I can't say why they export the code differently. I will have more time this weekend and will try to get it to work (and read some documentation on JavaScript modules I guess ;) )

Yomguithereal commented 5 years ago

My intuition is that create-react-app uses some magic related to webpack's loader to read the .glsl files embedded into the sources of sigma v2 and loads them erroneously as urls whereas they already are transpiled. I can try to find if there is an option of create-react-app to mitigate that. One of my co-workers also told me that using the eject command would help you figure out if there is such a loader issue.

lksnmnn commented 5 years ago

I will try to eject later, but it would be cool if I get it to work without having to care about the configuration too much. I guess I won't be the last person to set up sigma with create-react-app or similar. :)

Yomguithereal commented 5 years ago

Sure, but it's a bit sad that create-react-app dirty magic is messing things up :). Anyway, if you find the source of the issue, I'll be glad to fix it so this does not happen anymore.

lksnmnn commented 5 years ago

I found a very similar issue: https://github.com/facebook/create-react-app/issues/1517

Basically they confirm the issue with .glsl files and point to ejecting from react-scripts. But there is another comment, referring to a different solution which I am going to try this weekend.

The idea is to specify custom webpack loaders for file formats like glsl. See https://www.npmjs.com/package/glslify-loader for reference. :)

lksnmnn commented 5 years ago

Eject it is then. Closing this.

vrk7bp commented 4 years ago

Sorry to resurrect an old issue, but I've run into this same exact issue again using V2@alpha32. @lksnmnn, once you ran npm run eject was there anything else you had to do in order to get SigmaJS V2 to run in your react application?

vrk7bp commented 4 years ago

I'm in a similar situation as you... backend developer who isn't too familiar with React :). But my understanding of the glslify-loader solution is it is something that would have to be implemented as part of sigma with the webpack configuration, so not a solution if we were trying to just add sigma as a package within our package.json.

vrk7bp commented 4 years ago

For what it's worth, I tried npm run eject and re-running the React app caused the same error. I then tried modifying the webpack.config.js file that was generated as part of the eject command to use the glslify-loader...

{ test: /\.glsl$/, use: [ 'raw-loader', 'glslify-loader' ] }

That changed the error message I got to:

Error: sigma/renderers/webgl/shaders/utils.loadShader: error while compiling the shader: ERROR: 1:1: '' : syntax error

vrk7bp commented 4 years ago

@Yomguithereal if there's any information that I can provide that would help better pinpoint this error I'd be glad to provide it :).

vrk7bp commented 4 years ago

For anyone that runs into this problem in the future, I was able to figure out a solution that doesn't rely on npm run eject...

As @lksnmnn and @Yomguithereal mentioned above, the issue is Create-React-App attempting to transpile the .glsl files. The way to get around this is to get the "file" loader/catch-all loader towards the bottom of the webpack.config.js that is in Create-React-App to ignore .glsl files. So essentially we need to change this...

{
      loader: require.resolve('file-loader'),
      exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
      options: {
        name: 'static/media/[name].[hash:8].[ext]',
      },
}

To this:

{
      loader: require.resolve('file-loader'),
      exclude: [/\.(js|mjs|jsx|ts|tsx|glsl)$/, /\.html$/, /\.json$/],
      options: {
        name: 'static/media/[name].[hash:8].[ext]',
      }
}

One way to do this is to run npm run eject, though that is probably not idea. Instead, we can take advantage of Rescripts (https://github.com/harrysolovay/rescripts). So we can instead setup Rescripts and then setup a .rescriptsrc in the root like so:

const { edit, getPaths } = require("@rescripts/utilities");

const predicate = valueToTest => {
  return valueToTest.oneOf;
}

const transform = match => ({
  ...match,
  oneOf: [
    ...match.oneOf.slice(0, -1),
    // Rewriting the "file" loader to include .glsl files in the ignore
    {
      loader: require.resolve('file-loader'),
      exclude: [/\.(js|mjs|jsx|ts|tsx|glsl)$/, /\.html$/, /\.json$/],
      options: {
        name: 'static/media/[name].[hash:8].[ext]',
      },
    }
  ]
});

function rescriptIgnoreGLSL() {
  return config => {
    const matchingPaths = getPaths(predicate, config);
    return edit(transform, matchingPaths, config);
  };
}

module.exports = [
  [
    rescriptIgnoreGLSL,
  ],
]

Took a little while to figure out, and I learned a fair amount about webpacks and Create-React-App along the way :), but hopefully this saves some folks a little bit of time.

jakekara commented 4 years ago

Thanks @vrk7bp, I will have to try this.

I'm probably just missing something, but I was getting the same error when I imported using

import * as sigma from 'sigma';

but it worked fine when I changed it to:

import * as sigma from "sigma/build/sigma"

This also requires no ejecting.

I'm quite rusty on the implications of this in Webpack terms. Does this mean that the package.json entrypoint could just be pointed to that file?