Solved

LucidChart with React

  • 20 February 2024
  • 10 replies
  • 158 views

Badge +2

Hello,

I am following the steps from the LucidChart Developer Docs “Using web frameworks | Using React: found here.

https://developer.lucid.co/guides/?_gl=1*mhld9f*_ga*MTA5NzkzMTU0NC4xNjk2NTE0NTk1*_ga_MPV5H3XMB5*MTcwODQ2MDk4My4xLjAuMTcwODQ2MDk4My42MC4wLjA.*_gcl_au*MTUzOTY2NTcwOS4xNzA4NDYwOTg1#using-react

I created an empty directory:  C:\ReactLucidTest

Following step 1, i created a package called “reacttest”

I also created an editor extension called “with-cool-ui’.

In step 2, I created the react app called rightpanel inside of with-cool-ui extension.  npm start successfully launched my browser and showed the CRA application.

In step 3, I opened up "C:\ReactLucidTest\reacttest\editorextensions\with-cool-ui\webpack.config.js" in notepad and replaced it with the code from the Developer Docs in step 3.

In step 4, I opened up "C:\ReactLucidTest\reacttest\editorextensions\with-cool-ui\src\extension.ts" and replaced the contents with the code found in step 4 on Developer Docs in step 4.

In step 5, I am getting an error when running the command “npx lucid-package test-editor-extension with-cool-ui”. The server from step 2 is still running.

 

Here is the exact error:

Executing onWatchRun build scripts

stderr error mkdir -p ../../public/rightpanel &&curl http://localhost:3000 | sed -E "s/(src|href)=\"/\\1=\"http:\/\/localhost:3000/gi" > ../../public/rightpanel/index.html: The syntax of the command is incorrect.

 

Listening at http://localhost:9900/extension.js

Listening at http://localhost:9901/shapeLibraries

Found npm start script in C:\ReactLucidTest\reacttest\editorextensions\with-cool-ui\rightpanel.

node:events:491

      throw er; // Unhandled 'error' event

      ^

 

Error: spawn npm ENOENT

    at ChildProcess._handle.onexit (node:internal/child_process:283:19)

    at onErrorNT (node:internal/child_process:476:16)

    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

Emitted 'error' event on ChildProcess instance at:

    at ChildProcess._handle.onexit (node:internal/child_process:289:12)

    at onErrorNT (node:internal/child_process:476:16)

    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {

  errno: -4058,

  code: 'ENOENT',

  syscall: 'spawn npm',

  path: 'npm',

  spawnargs: [ 'start' ]”

 

Anyone able to help?  Maybe in step 3 or 4, the code on the Developer Docs that I pasted into those 2 files is incorrect?  Can anyone maybe try to do the steps outlined in the Developer Docs and see if they can get it working?

Thanks, Dan

icon

Best answer by ablackburn 4 March 2024, 17:42

View original

Comments

Userlevel 3
Badge +3

Hey Dan! Apologies on the delayed response. There seems to be a bug with windows and our webpack script. We will be discussing tomorrow as a team. Will follow up shortly. Thanks!

Badge +2

Thanks for confirming!

Badge

Hey Dan,

Sorry again for the delay there. We're still working on making our script windows compatible. In the meantime, I've created a repo that can hopefully unblock you as a workaround.

https://github.com/lucidsoftware/sample-lucid-extensions/commit/32ef439f99d7189ef8acf1e40bb16207f1d68ea6

Here's the file that matters the most. You can create this one manually in your own `/public` folder and that should get your extension talking to your frontend.

https://github.com/lucidsoftware/sample-lucid-extensions/commit/32ef439f99d7189ef8acf1e40bb16207f1d68ea6#diff-9ef5a348eadc3a77e8bb80e863f1a768c8ec18b1bcd86f6210a2129c90e2b876

 

You’ll probably need to update this url to point to the right location (the url is relative to the root of `/public`): 

https://github.com/lucidsoftware/sample-lucid-extensions/commit/32ef439f99d7189ef8acf1e40bb16207f1d68ea6#diff-e44faa18ad076e8bde1bd79376967ee031fc04f3b8a714abe5f4149fee691fb5R11

 

 

This will come up again when you're wanting to generate your production bundle, so I’ll keep you in the loop on our fix.

Badge +2

Thanks! I will check this out shortly and I appreciate the fast response.

Badge +2

I unfortunately cannot get this to work still.  I even tried starting over from scratch several times.

You say “You can create {index.html} manually in your own `/public` folder and that should get your extension talking to your frontend.”

I downloaded the index.html file into this folder:

{mybasefolder}\reacttest\editorextensions\with-cool-ui\rightpanel\public

Is that the correct /public folder to put index.html in?

 

You say “You’ll probably need to update {extension.ts’s url } to point to the right location (the url is relative to the root of `/public`): 

my full path to “extension.ts” is:

"C:\ReactLucidTest\reacttest\editorextensions\with-cool-ui\src\extension.ts"

is that the correct “extension.ts” to edit?

 

my full path to “index.html” is:

"C:\ReactLucidTest\reacttest\editorextensions\with-cool-ui\rightpanel\public\index.html"


 

My current code for extension.ts is:

import {EditorClient, Panel, PanelLocation, Viewport} from 'lucid-extension-sdk';

const client = new EditorClient();

export class RightPanel extends Panel {

    private static icon = 'https://lucid.app/favicon.ico';

    constructor(client: EditorClient) {

        super(client, {

            title: 'From React',

            url: 'rightpanel/index.html',

            location: PanelLocation.RightDock,

            iconUrl: RightPanel.icon,

        });

    }

}

const rightPanel = new RightPanel(client);

 

you say “the url is relative to the root of `/public”, then should the url value simply be index.html?

Thanks,

Dan

Badge +2

I thought I would also share the results from “Step 3: Replace webpack.config.js for the editor extension” in the LucidChart guide.

I edited the following file:

C:\ReactLucidTest\reacttest\editorextensions\with-cool-ui\webpack.config.js

to contain the code below.  Is this the correct file and is this the correct contents?

 

onst path = require('path');

const WebpackShellPluginNext = require('webpack-shell-plugin-next');

const reactTargets = [{name: 'rightpanel', port: 3000}];

module.exports = {

    entry: './src/extension.ts',

    module: {

        rules: [

            {

                test: /\.tsx?$/,

                use: 'ts-loader',

                exclude: /node_modules/,

            },

            {

                test: /[\\\/]resources[\\\/]/,

                use: 'raw-loader',

                exclude: /\.json$/,

            },

        ],

    },

    resolve: {

        extensions: ['.ts', '.js'],

    },

    output: {

        filename: 'bin/extension.js',

        path: __dirname,

    },

    plugins: [

        new WebpackShellPluginNext({

            //When doing a watch build, run "npm start" and update the html file to prefix http://localhost:3000/ to all the resource URLs

            onWatchRun: {

                scripts: reactTargets.map(

                    (target) =>

                        `mkdir -p ../../public/${target.name} &&` +

                        `curl http://localhost:${target.port} | ` +

                        `sed -E "s/(src|href)=\\"/\\\\1=\\"http:\\/\\/localhost:${target.port}\/gi" > ` +

                        `../../public/${target.name}/index.html`,

                ),

                blocking: true,

            },

            // When doing a full build, run "npm run build" and then copy all the assets to the root level public folder

            onBeforeNormalRun: {

                scripts: reactTargets.map(

                    (target) =>

                        `mkdir -p ../../public/${target.name} &&` +

                        `cd ${target.name} && ` +

                        `npm run build && ` +

                        `sed -i -E "s/(src|href)=\\"\\//\\1=\\"\/gi" build/index.html &&` +

                        `cp -r build/* ../../../public/${target.name}`

                ),

                blocking: true,

            },

        }),

    ],

    mode: 'development',

};

Badge +2

I used chatgpt on the error I was getting and got the following response:
 

“The error message you're seeing suggests there's a syntax problem with your command. It appears you're trying to use Unix-style commands (`mkdir`, `curl`, `sed`) in a Windows environment, which might not work as expected because Windows command line (CMD) uses a different syntax. Moreover, the combination of commands and the way they are piped together could also be causing issues.

Let's break down your command and see how it can be adapted for Windows, or how you can use alternative tools:

1. `mkdir -p ../../public/rightpanel`: This command is trying to create a directory, including any necessary parent directories. The `-p` option, which allows the creation of nested directories, does not have a direct equivalent in Windows CMD, but PowerShell supports similar functionality.

2. `curl http://localhost:3000`: This command is used to fetch the content from the specified URL. Windows 10 and later include `curl`, so this part should work, but ensure `curl` is installed if you're on an older version.

3. `sed -E "s/(src|href)=\"/\\1=\"http:\/\/localhost:3000/gi"`: This part uses `sed`, a stream editor for filtering and transforming text, which is not natively available in Windows CMD. You might need to use a different tool for text processing, like PowerShell commands or download a Windows version of `sed`.

4. `> ../../public/rightpanel/index.html`: This part redirects the output to a file, which should work in Windows CMD as well.

For Windows, consider using PowerShell, which is more powerful and flexible than CMD, and supports more Unix-like commands. Here's how you might rewrite your command in PowerShell:

```powershell
# Ensure the directory exists
$dir = "../../public/rightpanel"
if (-Not (Test-Path $dir)) {
  New-Item -ItemType Directory -Force -Path $dir
}

# Fetch content and modify it
$content = Invoke-WebRequest -Uri "http://localhost:3000" | Select-Object -ExpandProperty Content
$modifiedContent = $content -replace '(src|href)="', '$1="http://localhost:3000/'

# Write to file
$modifiedContent | Set-Content "$dir/index.html"
```

This PowerShell script does the following:
- Checks if the directory exists and creates it if it doesn't.
- Fetches content from `http://localhost:3000`.
- Uses a regular expression to replace `src="` and `href="` with `src="http://localhost:3000/` and `href="http://localhost:3000/`.
- Writes the modified content to `../../public/rightpanel/index.html`.

Make sure to run this in a PowerShell environment. If you're integrating this into a build script or tool that doesn't run PowerShell by default, you might need to call it explicitly, e.g., by using `powershell -Command "<your command here>"` or saving the script to a `.ps1` file and running it with PowerShell.”

This leads me to think the issue is related to the webpack.config.js code.  Thoughts?

Badge

Hey Dan,

 

Sorry for not being clearer. There are in fact 2 places you’ll find index.html files.

 

The first one lives next to the react app (in my case in frontend-frameworks/editorextensions/react-example/react-example/public/index.html) which is what you're serving locally at `http://localhost:3000`. This one is managed by the react app and you shouldn't need to replace it.

The second one lives in a /public folder that sits right in the root of the package (in my case in /frontend-frameworks/public. I think in your case it should be /ReactLucidTest/reacttest/public, you can create it if it doesn't exist yet). This version of the HTML gets loaded in the iframe your extension creates when users open up the panel you're creating. The entire `/public` folder here will get hosted for you by Lucid; For development the file basically just links up to the resources getting hosted at your localhost address; For production, you can put the minified and bundled react app as well as any images/other static resources you’d like hosted into the folder, and they will be available for your extension to reference.

The version of the HTML that lives in the root level `/public` folder should be getting created automatically for you via that webpack script you pointed to. ChatGPT has the right of it, basically the script hits the locally hosted url, swaps some of the resource urls in it, and the pastes the resulting html/files into the root level `/public` folder (`/frontend-frameworks/public`). This is the one your extension panel should point at, and its URL will be relative to the public folder, so yes if you put your index.html file in `/ReactLucidTest/reacttest/public/index.html`, then your extension should just use `index.html` for the panel's URL. Looks like right now it's looking for `/rightpanel/index.html`.

 

The problem (as ChatGPT correctly identified) is that windows does not support this command: `sed -E "s/(src|href)=\"/\\1=\"http:\/\/localhost:3000/gi"`, so the webpack scrip is failing to replace the resource urls, and then erroring out before it trys to print the file you want into your root level `/public` folder. That powershell script looks like it will do what you want, but I’m not sure if you can execute that code from the webpack context cleanly. So you could either run it manually once (it only really needs to happen one time for development, and then any time you do a production deployment), or you can manually run the flow by putting the html file I linked where you need it by hand (so paste it somewhere in your /ReactLucidTest/reacttest/public folder, and then reference that location in your extension.ts file where you are specifying the panel's url.)

Badge +2

ablackburn,

I unfotunately cannot get this to work still.

Here is what I did:

  • Started over and created an empty folder:  C:\ReactLucidTest2
  • Followed the exact instructions as found in the official React Guide here.
  • Copied the index.html found that you linked here:  I placed the downloaded index.html in this folder: C:\ReactLucidTest2\reacttest\public
  • modified  C:\ReactLucidTest2\reacttest\editorextensions\with-cool-ui\src\extension.ts by setting url to one of these:
    • url: 'index.html',
    • url: 'right/index.html',

The react app is up and running in the browser at http://localhost:3000/ using npm start.

In a second command prompt, i cded to C:\ReactLucidTest2\reacttest and then run:

npx lucid-package test-editor-extension with-cool-ui

I get the following error message:

Listening at http://localhost:9900/extension.js
Listening at http://localhost:9901/shapeLibraries
Found npm start script in C:\ReactLucidTest2\reacttest\editorextensions\with-cool-ui\rightpanel.
node:events:496
      throw er; // Unhandled 'error' event
      ^

Error: spawn npm ENOENT
    at ChildProcess._handle.onexit (node:internal/child_process:286:19)
    at onErrorNT (node:internal/child_process:484:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
Emitted 'error' event on ChildProcess instance at:
    at ChildProcess._handle.onexit (node:internal/child_process:292:12)
    at onErrorNT (node:internal/child_process:484:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'spawn npm',
  path: 'npm',
  spawnargs: [ 'start' ]
}

Node.js v20.11.1

Thoughts?

I pulled down the full commit code but did not do anything with it since I still followed the official React Guide.

Would someone be willing to do a web meeting with me to get things up and running?

Thanks, Dan

Badge

Hey Dan,

 

We can absolutely meet with you to help get things unblocked. I’ll reach out via email  to schedule.

 

Alex

Reply