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

Can't make Cytoscape.use() work with Gatsby #28

Open
mattorp opened this issue Jun 19, 2019 · 9 comments
Open

Can't make Cytoscape.use() work with Gatsby #28

mattorp opened this issue Jun 19, 2019 · 9 comments

Comments

@mattorp
Copy link

mattorp commented Jun 19, 2019

Where would you put the Cytoscape.use(), when using this library with Gatsby? The registration of extensions work fine for the standard cytoscape, but using this library I get the following error:
Uncaught TypeError: _cy.cxtmenu is not a function

import React from "react"
import CytoscapeComponent from "react-cytoscapejs"
import Cytoscape from "cytoscape"
import cxtmenu from "cytoscape-cxtmenu"
Cytoscape.use(cxtmenu)
const Cyto = () => {
  return (
    <CytoscapeComponent
      cy={cy => {
        cy.cxtmenu({
          selector: "core",
          commands: [
            {
              content: "Add",
              select: () => {
                console.log("add")
              },
              fillColor: "#0F0",
            },
          ],
        })
      }}
    />
  )
}
export default Cyto
@maxkfranz
Copy link
Collaborator

It looks like Gatsby doesn't handle import correctly.

@mattorp
Copy link
Author

mattorp commented Jun 19, 2019

The following example works as expected (with js cytoscape and Gatsby).

// /pages/Cyto.js
import React, { useRef, useEffect } from "react"
import Cytoscape from "cytoscape"
import cxtmenu from "cytoscape-cxtmenu"
Cytoscape.use(cxtmenu)

const Cyto = () => {
  const cyRef = useRef(null)

  useEffect(() => {
    const container = document.getElementById("cyto")
    cyRef.current = Cytoscape({ container })
    cyRef.current.cxtmenu({
      selector: "core",
      commands: [
        {
          content: "Add",
          select: () => {
            console.log("Add")
          },
          fillColor: "rgba(0,150,0,0.75)",
        },
      ],
    })
  })

  return (
    <div
      id="cyto"
      style={{
        height: "100vh",
        width: "100vh",
        backgroundColor: "rgb(30,30,30)",
      }}
    />
  )
}
export default Cyto

I've created a pull request that registers extensions passed as props in the constructor, which seems to solve the issue. I have yet to write tests for it, but opened it, in case you want to have a look.

@maxkfranz
Copy link
Collaborator

You can't register extensions in the constructor. An extension may be registered only once for the lifecycle of the app. The constructor can be called many times.

@mattorp
Copy link
Author

mattorp commented Jun 27, 2019

True. Is there another place within the library that would be a proper placement, or should the handling of extensions remain outside this library?

@maxkfranz
Copy link
Collaborator

maxkfranz commented Jul 3, 2019

The only place it would make sense within the library is in a static function. See cytosnap for an example: https://github.com/cytoscape/cytosnap#cytosnapuse

Cytosnap uses Cytosnap.use() for this with string literals like use([ 'cytoscape-cxtmenu' ]) rather than use([ require('cytoscape-cxtmenu') ]). This is necessary in cytosnap, because the cytoscape instance runs within a separate process -- the puppeteer process rather than the node one. I don't know what is causing gatsby to not import correctly, but using the same approach as cytosnap should resolve it.

A caveat is that you would have to call CytoscapeComponent.use() before any instance of CytoscapeComponent is instantiated. So it would be very similar to using Cytoscape.use(), except the passed values are extension package ID strings instead of extension classes.

@mattorp
Copy link
Author

mattorp commented Jul 19, 2019

Thanks Max!

I have dropped Gatsby, so the issue is not pressing to me at the moment.

I had some problems getting my fork to work correctly as a dependency, but I will look into this again later.

@akx
Copy link
Contributor

akx commented Sep 30, 2019

Depending on your bundling configuration, the issue (as alluded to in #17) might be that you have multiple Cytoscapes in your bundle.

@jdnudel
Copy link

jdnudel commented Jan 30, 2020

perhaps this should be a new issue, but I'm having a more general problem getting cystoscape to work with gatsby. it works fine in development, but as soon as i try to build and deploy to netlify, it throws a WebpackError: ReferenceError: window is not defined error. Does anyone have experience troubleshooting this? thank you.

@benrobertsonio
Copy link

@jdnudel a work around for modules that don't support SSR in Gatsby is documented here:

https://www.gatsbyjs.org/docs/debugging-html-builds/#fixing-third-party-modules

in gatsby-node.js:

exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
  if (stage === "build-html") {
    actions.setWebpackConfig({
      module: {
        rules: [
          {
            test: /react-cytoscapejs/,
            use: loaders.null(),
          },
        ],
      },
    })
  }
}

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

No branches or pull requests

5 participants