TeselaGen / openVectorEditor

DEPRECATED - Teselagen's Open Source Vector/Plasmid Editor Component
https://teselagen.github.io/tg-oss/ove/#/Editor
MIT License
200 stars 72 forks source link

Server-side rendering (SSR) #870

Open nicolazilio opened 1 year ago

nicolazilio commented 1 year ago

Hi @tnrich,

I am interested in adding the circular plasmid view that OVE creates to a 'static' html or pdf file. From what I have read around, this is theoretically possible using server-side rendering of the OVE app to create the relevant svg (?) element, which can then be used wherever. Have you tried to do this at all? And, if so, have you been successful? I have been playing around a bit, and I keep getting errors that seems to be, unsurprisingly, related to not running the app in an actual browser. Or maybe you have a better solution for my problem?

Thank you very much in advance!

Nicola

tnrich commented 1 year ago

@nicolazilio I have not tried to do this yet (from the server at least) although it seems like a worthy goal!

I think you'll need to post the specific issues you're seeing and we can try working through them. It might help to publish an example repo here on github that we can use to troubleshoot.

nicolazilio commented 1 year ago

Sure, I've created a repository to get the ball rolling. Disclaimer: I am def not an expert in anything related to React, https://github.com/nicolazilio/ove-ssr-test.

I've taken the basic set up for SSR from https://github.com/satansdeer/ssr-example, which does indeed work in my hands. When I try, blindly, to put your code for the OVE demo from here https://github.com/tnrich/ove-react-demo-repo in App, the first error that I get is

/home/ssr-example/node_modules/teselagen-react-components/lib/autoTooltip.js:13
  document.addEventListener("mouseover", function (event) {
  ^

ReferenceError: document is not defined

which could maybe be solved as described here https://stackoverflow.com/a/54263025/4222260.

If I comment out the code that references document, the next error that I get is

/home/ssr-example/node_modules/teselagen-react-components/lib/FormComponents/Uploader.js:141
      return _regenerator["default"].wrap(function _callee3$(_context3) {
      ^

Error [ERR_REQUIRE_ESM]: require() of ES Module /home/ssr-example/node_modules/teselagen-react-components/node_modules/nanoid/index.js from /home/ssr-example/node_modules/teselagen-react-components/lib/FormComponents/Uploader.js not supported.
Instead change the require of index.js in /home/ssr-example/node_modules/teselagen-react-components/lib/FormComponents/Uploader.js to a dynamic import() which is available in all CommonJS modules.

I found a couple of possible solutions for this problem on StackOverflow but I don't know enough about the topic and I'd be changing stuff without understanding what I'm doing.

Does this help at all?

tnrich commented 1 year ago

@nicolazilio I think you'll need to find a way to compile (using webpack or another bundler) the code from OVE into a server-safe version.

You'll definitely run into a ton more issues unless there is some sort of compilation step. I was able to get past the error you posted above by editing the affected file in node_modules. I probably went through fixing ~20 errors (see details below for some of them) related to trying to run client code on the server before giving up trying to fix them manually.

Not sure what options exist for doing that. You'll need to do some research it sounds like.

/Users/tnrich/Sites/ove-ssr-test/node_modules/@blueprintjs/core/lib/cjs/components/toast/toaster.js:67 container.appendChild(containerElement); ^ TypeError: container.appendChild is not a function at Function.Toaster.create (/Users/tnrich/Sites/ove-ssr-test/node_modules/@blueprintjs/core/src/components/toast/toaster.tsx:131:19) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/toastr.js:5:32) at Module._compile (node:internal/modules/cjs/loader:1101:14) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Module.require (node:internal/modules/cjs/loader:1005:19) at require (node:internal/modules/cjs/helpers:102:18) error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. tnrich@Thomass-MBP ove-ssr-test % yarn ssr yarn run v1.22.19 $ node server/index.js /Users/tnrich/Sites/ove-ssr-test/node_modules/@blueprintjs/core/lib/cjs/components/toast/toaster.js:67 container.appendChild(containerElement); ^ TypeError: container.appendChild is not a function at Function.Toaster.create (/Users/tnrich/Sites/ove-ssr-test/node_modules/@blueprintjs/core/src/components/toast/toaster.tsx:131:19) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/toastr.js:5:32) at Module._compile (node:internal/modules/cjs/loader:1101:14) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Module.require (node:internal/modules/cjs/loader:1005:19) at require (node:internal/modules/cjs/helpers:102:18) error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. tnrich@Thomass-MBP ove-ssr-test % yarn ssr yarn run v1.22.19 $ node server/index.js /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/toastr.js:15 window.__tgClearAllToasts = function () { ^ ReferenceError: window is not defined at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/toastr.js:15:1) at Module._compile (node:internal/modules/cjs/loader:1101:14) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Module.require (node:internal/modules/cjs/loader:1005:19) at require (node:internal/modules/cjs/helpers:102:18) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/DataTable/FilterAndSortMenu.js:28:1) error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. tnrich@Thomass-MBP ove-ssr-test % yarn ssr yarn run v1.22.19 $ node server/index.js /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/toastr.js:15 typeof window !== 'undefined' && window.__tgClearAllToasts = function () { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SyntaxError: Invalid left-hand side in assignment at compileFunction () at Object.compileFunction (node:vm:352:18) at wrapSafe (node:internal/modules/cjs/loader:1031:15) at Module._compile (node:internal/modules/cjs/loader:1065:27) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Module.require (node:internal/modules/cjs/loader:1005:19) error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. tnrich@Thomass-MBP ove-ssr-test % yarn ssr yarn run v1.22.19 $ node server/index.js /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/toastr.js:83 if (!window.toastr) window.toastr = {}; ^ ReferenceError: window is not defined at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/toastr.js:83:1) at Module._compile (node:internal/modules/cjs/loader:1101:14) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Module.require (node:internal/modules/cjs/loader:1005:19) at require (node:internal/modules/cjs/helpers:102:18) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/DataTable/FilterAndSortMenu.js:28:1) error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. tnrich@Thomass-MBP ove-ssr-test % yarn ssr yarn run v1.22.19 $ node server/index.js /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/toastr.js:83 if (!window.toastr) window.toastr = {}; ^ ReferenceError: window is not defined at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/toastr.js:83:1) at Module._compile (node:internal/modules/cjs/loader:1101:14) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Module.require (node:internal/modules/cjs/loader:1005:19) at require (node:internal/modules/cjs/helpers:102:18) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/DataTable/FilterAndSortMenu.js:28:1) error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. tnrich@Thomass-MBP ove-ssr-test % yarn ssr yarn run v1.22.19 $ node server/index.js /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/DataTable/index.js:141 setTimeout(function () { ^ Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/node_modules/nanoid/index.js from /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/DataTable/index.js not supported. Instead change the require of /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/node_modules/nanoid/index.js in /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/DataTable/index.js to a dynamic import() which is available in all CommonJS modules. at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/DataTable/index.js:82:15) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/UploadCsvWizard.js:32:41) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/FormComponents/Uploader.js:24:48) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/index.js:75:40) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/open-vector-editor/lib/addOnGlobals.js:11:33) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/open-vector-editor/lib/index.js:8:1) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/src/App.js:8:25) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/server/server.js:8:35) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/server/index.js:8:1) { code: 'ERR_REQUIRE_ESM' } error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. tnrich@Thomass-MBP ove-ssr-test % yarn ssr yarn run v1.22.19 $ node server/index.js /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/FormComponents/tryToMatchSchemas.js:141 return editableFields.some(function (columnSchema) { ^ Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/node_modules/nanoid/index.js from /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/FormComponents/tryToMatchSchemas.js not supported. Instead change the require of index.js in /Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/FormComponents/tryToMatchSchemas.js to a dynamic import() which is available in all CommonJS modules. at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/FormComponents/tryToMatchSchemas.js:8:15) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/FormComponents/Uploader.js:30:50) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/teselagen-react-components/lib/index.js:75:40) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24) at Object.newLoader [as .js] (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:141:7) at Object. (/Users/tnrich/Sites/ove-ssr-test/node_modules/open-vector-editor/lib/addOnGlobals.js:11:33) at Module._compile (/Users/tnrich/Sites/ove-ssr-test/node_modules/pirates/lib/index.js:136:24)
nicolazilio commented 1 year ago

I thought that could be the case indeed.

I've tried to do what you suggested, i.e. compile the OVE code with webpack, but I still run into tons of errors, which I don't really understand, unsurprisingly because I'm really not an expert in anything related to React. I suspect that trying to do SSR with OVE is probably a lot more complicated than we think :). That said, maybe somebody with more experience in this topic could do it.

My next question then is: would/could it maybe be easier to extract the part of OVE that renders the SVG for the circular view and turn it into, for example, a self-standing node package? I suppose I'm looking at the problem in a very selfish manner, as my interest is to save programmatically the circular view as a file.

nicolazilio commented 1 year ago

I thought that could be the case indeed.

I've tried to do what you suggested, i.e. compile the OVE code with webpack, but I still run into tons of errors, which I don't really understand, unsurprisingly because I'm really not an expert in anything related to React. I suspect that trying to do SSR with OVE is probably a lot more complicated than we think :).

My next question then is: would/could it maybe be easier to extract the part of OVE that renders the SVG for the circular view and turn it into a self-standing node package? I suppose I'm looking at the problem in a very selfish manner, as my interest is to be able to save the circular view SVG programmatically.

tnrich commented 1 year ago

Hey @nicolazilio ya, your instinct is correct that it would indeed be easier to "to extract the part of OVE that renders the SVG for the circular view and turn it into a self-standing node package".

I've started that work for you on the example repo you set up for me. I think it would be cool if you took that work and turned it into its own little package - maybe something like ove-simple or ove-node or something like that.

Lemme know if you're able to run my PR (you can merge it into yours) and if it solves your issue - https://github.com/nicolazilio/ove-ssr-test/pull/1#issue-1548303079

nicolazilio commented 1 year ago

@tnrich, awesome, thanks a bunch! This looks like something I can, hopefully, tackle on my own. I've merged your PR into the main branch and will keep you updated on the progress.