Skip to content
This repository has been archived by the owner on Mar 22, 2024. It is now read-only.

Lit Component #24

Closed
ballcoach12 opened this issue Jun 7, 2023 · 20 comments
Closed

Lit Component #24

ballcoach12 opened this issue Jun 7, 2023 · 20 comments

Comments

@ballcoach12
Copy link

My team would like to build a Lit component to wrap an editor for a language that we created using Langium. We have a Lit app almost working with a component that should be able to provide the editor for our language. However, we are running into problems with rollup when we try to build the app. It seems that the monaco-editor-wrapper does some things that rollup doesn't like.

I came across the recent announcement about the monaco-editor-wrapper Lit component being discontinued in the latest release.

image

My questions are:

  1. Is there a way to deliver the editor wrapper as a Lit component at all?
  2. Should we just try to wrap the React editor so that we can use it in a Lit app?
  3. Should my question be redirected to the Langium repo?

Thanks

@kaisalmen
Copy link
Collaborator

kaisalmen commented Jun 7, 2023

  1. Should my question be redirected to the Langium repo?

Hi @ballcoach12 this is exactly the correct spot to ask your questions. 👍

  1. Is there a way to deliver the editor wrapper as a Lit component at all?

We discontinued monaco-editor-comp because nobody seemed to really use it: according to download numbers it never increased popularity and we ourselves discontinued to use it.
Due to the way the whole underlying stack of monaco-editor, monaco-languageclient and monaco-vscode-api is now configured, using a web component now felt counter-intuitive, but it is still possible. You won't be able to pass the configuration as property, but putting a web component shell around monaco-editor-wrapper will work.

  1. Should we just try to wrap the React editor so that we can use it in a Lit app?

I would wrap monaco-editor-wrapper and not the react-component or just consider using pure JavaScript. The aim of the wrapper is to make it work in pure HMTL/JS context. No framework is required.

I guess you are aware of these Langium examples:
https://github.com/TypeFox/monaco-components/tree/main/packages/examples/src/langium
Two entry points are:
https://github.com/TypeFox/monaco-components/blob/main/packages/examples/wrapper_langium.html
and:
https://github.com/TypeFox/monaco-components/blob/main/packages/examples/react_langium.html

However, we are running into problems with rollup when we try to build the app. It seems that the monaco-editor-wrapper does some things that rollup doesn't like.

We build a bundle for verification with vite which uses rollup 3 under the hood for production bundling. Asset inclusions and commonjsOptions are likely a problem for you, see the vite config:
https://github.com/TypeFox/monaco-components/blob/main/packages/examples/vite.bundle-mew.ts

This bundle is used here:
https://github.com/TypeFox/monaco-components/blob/main/packages/examples/verify_wrapper.html

Hopefully this already helps you to move forward. If there are more questions. don't hesitate to ask. If our READMEs are unclear, please let us know, too. We may have forgotten some things when upting them for v2 🙂

@ballcoach12
Copy link
Author

Many thanks, @kaisalmen, for your helpful response. We are still studying how best to attack this problem, so I'm sure I'll have additional questions. We essentially want to accomplish what is described here, but using Lit instead of React.

@ballcoach12
Copy link
Author

It feels like I am really close to getting this working. I created a new Lit element project (I was working with a Lit app before) and Rollup is now out of the picture. Only WebDev server is involved. The only problem that I can see is that it cannot seem to find the vscode package. For some reason, I recall that it isn't as easy as adding vscode to the dependencies in my package.json file. So I'm not sure how to go about resolving this. The error I get is:

Error while transforming node_modules\monaco-editor-wrapper\dist\index.js: Could not resolve import "vscode".

  10 | import 'monaco-editor/esm/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.js';
  11 | import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
> 12 | import * as vscode from 'vscode';
     |            ^
  13 | import { getMonacoCss } from './generated/css.js';
  14 | import { MonacoLanguageClient, CloseAction, ErrorAction, MonacoServices } from 'monaco-languageclient';
  15 | import { toSocket, WebSocketMessageReader, WebSocketMessageWriter } from 'vscode-ws-jsonrpc';

Note that I am using the following versions in my package.json file:

"monaco-editor": "^0.39.0",
"monaco-editor-workers": "^0.34.2",
"monaco-editor-wrapper": "^1.3.1"

@kaisalmen
Copy link
Collaborator

kaisalmen commented Jun 8, 2023

Is there any specific reason you are using a fairly the old version of monaco-editor-wrapper? 2.0.0 was released last week and I recommend starting from there.

No matter which version you use, you have to use monaco-vscode-api as vscode dependency. monaco-editor-wrapper depends on monaco-languageclient and it depends on monaco-vscode-api:

"vscode": "npm:@codingame/monaco-vscode-api@~1.78.8",

You have to use compatible versions, see:
https://github.com/TypeFox/monaco-languageclient#using-monaco-languageclient

monaco-editor 0.39.0 is too new and not yet supported and additionally the worker support package should fit the monaco-editor version.

Idea: start to wrap one of the simple examples into a lit component. Throw out all unnecessary stuff (HTML buttons, restart handling):
https://github.com/TypeFox/monaco-components/blob/main/packages/examples/src/wrapperTs.ts
or
https://github.com/TypeFox/monaco-components/blob/main/packages/examples/src/wrapperWs.ts

@ballcoach12
Copy link
Author

ballcoach12 commented Jun 9, 2023

@kaisalmen , as you suggested, I am trying to wrap one of the simple examples. But the problem seems to be dependency resolution. I am not even at the point yet where I am using Lit, and I can't build a bundle due to dependency resolution.

I have created a minimal example here: https://github.com/ballcoach12/monaco-editor-ts.

We are using Parcel to build our module now instead of Rollup (maybe that's a mistake), and it fails when we attempt the build:

🚨 Build failed.

@parcel/core: Failed to resolve 'vscode/service-override/configuration' from './node_modules/monaco-editor-wrapper/dist/editorVscodeApi.js'

  G:\BITBUCKET\PROTOTYPE\monaco-editor-ts\packages\monaco-ts\node_modules\monaco-editor-wrapper\dist\editorVscodeApi.js:1:41
  > 1 | import { updateUserConfiguration } from 'vscode/service-override/configuration';
  >   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    2 | import { registerExtension } from 'vscode/extensions';
    3 | import 'vscode/default-extensions/theme-defaults';

@parcel/resolver-default: Cannot load file './service-override/configuration' from module 'vscode'

It does not seem to know how to resolve 'vscode/service-override/configuration' even though we reference "vscode": "npm:@codingame/monaco-vscode-api@~1.78.8",. My guess is that your Vite-based implementation gets around this problem by pre-bunding these modules.

@ballcoach12
Copy link
Author

Also, I noticed that the build:comp npm script is still in the main package.json file. This probably needs to be removed since the web components implementation has been removed.

@kaisalmen
Copy link
Collaborator

Hi @ballcoach12 we don't use parcel, so I can't really help there.
As you know we use vite/rollup for bundling, but it also works with webpack. We have a verification example in the monaco-languageclient repo that creates a working bundle from an client, see here: https://github.com/TypeFox/monaco-languageclient/blob/main/packages/verify/webpack/webpack.config.js

https://github.com/ballcoach12/monaco-editor-ts only contains a README. Did you forgot to push updates?

Thanks for the hint regarding the package.json. I already pushed an update.

@ballcoach12
Copy link
Author

Sorry about that! The files should be in the repo now (been a long week...:)

@ballcoach12
Copy link
Author

I got a basic example working where I wrap an editor in Lit. I'll post it to the repo next week. Thanks for the input!

@ballcoach12
Copy link
Author

ballcoach12 commented Sep 14, 2023

Picking this back up after a few months...

One of the reasons why we are using an earlier version of monaco-editor-wrapper is because that's what is generated by the generator-langium. I assume that the Langium implementation will eventually catch up to the newer version of monaco-editor-wrapper, but ~1.6.0 seems to be the version for now.

I recall seeing a comment somewhere along the way that one of the notable differences between wrapper versions is the ability to use UserConfig to set up the editor. IIRC, it was highly recommended to do that if we are trying to package our language editor inside a Lit component.

One thing that I am a bit confused on is the difference between 'classic' mode and 'VscodeApi' mode. Can you explain that to me and advise on how I should determine which one to choose?

@kaisalmen
Copy link
Collaborator

I assume that the Langium implementation will eventually catch up

@ballcoach12 there is eclipse-langium/langium#1163 Once #45 and #47 are done and a new release is available my plan is to update the template.

classic mode basically supplies the configuration/capabilities you know from monaco-editor.
vscodeApi mode allows you to use all the vscode services monaco-vscode-api exposes, e.g. textmate grammars, views support, debugger, etc.

Our documentation needs to be improved. It will come... 😅

@kaisalmen
Copy link
Collaborator

@ballcoach12 the Langium Grammar example (moved over here from monaco-languageclient a couple of weeks ago):
https://github.com/TypeFox/monaco-components/blob/main/packages/examples/src/langium/wrapperLangium.ts
now allows to start the editor in both modes. One uses monarch, the other one textmate.

@ballcoach12
Copy link
Author

@kaisalmen, thanks for the information. That likely explains why I was seeing multiple errors related to missing dependencies in my experimentation to get my implementation up and running. I was probably trying to run the editor in vscode mode and had not supplied the right dependencies.

At the moment, I am pursuing two approaches. The first is similar to how you guys test the mew.js bundle by inserting the TS code to configure the editor into the HTML file. I've been able to get a basic editor with Javascript support up and running this way.

The second approach is similar to the Statemachine example where the TS code is in a separate file that is referenced by a <script> tag in the HTML. I have not gotten this to work yet; the browser console shows an exception being thrown inside the Promise, stating that we cannot access createLangiumGlobalConfig before it is initialized. My guess is that this has something to do with the lifecycle of loading the page, and that's why the corresponding examples have the Start button on the page.

I plan to post an updated example to my repo later today. I'll add to the notes on this issue when that is done.

@ballcoach12
Copy link
Author

I have posted a new repository at https://github.com/ballcoach12/stab-at-lang-editor. If someone has time to take a look at it, I'd greatly appreciate it. The wrapper-js-html project works correctly, but the wrapper-js-code project does not. In the latter case, I get the following error when the editor loads in the browser:

Uncaught (in promise) Error: unsupported at FileService.unsupported2 (tools.js:2:11) at writeFile (monaco.js:128:48) at createModelReference (monaco.js:135:15) at EditorAppClassic.updateEditorModel (editorAppBase.ts:121:31) at EditorAppClassic.createEditor (editorAppBase.ts:74:20) at EditorAppClassic.createEditors (editorAppClassic.ts:73:24) at MonacoEditorLanguageClientWrapper.start (wrapper.ts:89:30) at async restartEditor (common.ts:43:5) at async startEditor (common.ts:15:5)

I don't get this error in the first case. Something tells me that it is related to module formats or else I don't have something configured correctly.

@kaisalmen
Copy link
Collaborator

Hi @ballcoach12 I will have the time to look at it tomorrow, I guess.

@ballcoach12
Copy link
Author

Thanks, @kaisalmen. I greatly appreciate it. I'll buy you a beer! :)

@ballcoach12
Copy link
Author

I have updated the example code in the repo I created. I have gotten past the error that I mentioned above, and now only have one error in the browser:

image

I suspect that either Vite is doing something in the bundling/chunking that is breaking things, or I have somehow missed a configuration option for the editor. In any case, things seem to fail when the editor tries to make the /tmp directory, from what I can see.

@kaisalmen
Copy link
Collaborator

kaisalmen commented Sep 20, 2023

@ballcoach12 found it. Don't use vite-plugin-node-polyfills in your vite configuration. It breaks the code with bad polyfills.
Also, because you anyhow use vite, you dont't need the libs folder, just use regular package references in the code. vite does the magic.

@ballcoach12
Copy link
Author

Fixed!! I just modified my project and got it to work! Thanks so much for your help! I'll push my updates in case anyone wants to see my implementation as an example in the future.

@kaisalmen
Copy link
Collaborator

I'll push my updates in case anyone wants to see my implementation as an example in the future.

Sounds good.

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

No branches or pull requests

2 participants