This project is a proof of concept Angular application that uses Monaco editor to edit a "custom" defined language. It loads Monaco editor into a div with custom Monarch syntax highlighting, launches the MonacoEditor web worker and Aql web worker for syntax validation.
Inspired by amazzalel-habib's work in React. Github.
This project mostly overcomes the configuration hurldes of getting Monaco Editor running and talking to a language worker that uses an ANTLR4 defined language.
- Monaco Editor (VsCode)
- This repo uses Monaco Editor Core mostly because that's what the tutorial did, but also because the goal is to have an editor for one specific language embedded in a page, not a multi-purpose editor. Using the full monaco-editor would be fine too.
- Monarch Language highlighting
- Antlr4
- Antlr4ts
- Atlr4 VsCode Extension Used for generating TypeScript because I took too long figuring out how to get Antlr4ts cli working.
- @angular-builders/custom-webpack Used for customizing how Monaco Editor gets bundled.
- Web Workers
- Angular Generation
- Worker Plugin for Webpack Plugin used by angular to split worker bundles.
- MDN
These steps assume you generated an angular app using
ng new
.
Goals:
- Get monaco styles to be bundled and loaded correctly.
- Get Web Workers configured
- Get Antlr VsCode extension configured
Reason: Monaco require()
s its styles directly from css which the default angular builder does not handle well. By just import
ing monaco with typescript and using the default angular build, monaco will load, but won't have any styling and will be quite messed up.
Steps
-
Monaco bundling
-
Install Packages
-
npm install monaco-editor-core
-
npm install -D @angular-builders/custom-webpack@^10
IMPORTANT At the time of writing, the commit upgrading
@angular-builders/custom-webpack
to Angular 11 has been reverted and custom-webpack does not work with Angular 11. -
npm install -D style-loader css-loader
-
-
Configure angular to use custom-webpack
- Configur primary build:
"projects": { ... "[project]": { ... "build": { "builder": "@angular-builders/custom-webpack:browser", "options": { "customWebpackConfig": { "path": "./custom-webpack.config.ts", "mergeStrategies": { "externals": "replace" } },
- Configre other targets to use primary build: find-replace
@angular-devkit/build-angular
for@angular-builders/custom-webpack
- Create
custom-webpack.config.ts
in repository root with contents in this one.
-
-
Configure Web Workers
- Get Angular to configure web workers for us:
ng generate web-worker app
- Creates
tsconfig.worker.json
- Adds
"webWorkerTsConfig": "tsconfig.worker.json"
toangular.json
- Generates sample code that can be deleted but is useful when debugging things.
- Creates
src/app/app.worker.ts
(or something like it). - Adds a snippet instantiating the web worker from
src/app/app.component.ts
- Creates
- Creates
- Get Angular to configure web workers for us:
-
Configure Antlr Extension
- Install Atlr4 VsCode Extension.
- Install ts runtime dependency:
npm install antlr4ts
- Configure code generation
- In
.vscode/settings.json
"antlr4.generation": { "mode": "external", "outputDir": ".antlr", "language": "Typescript", "visitors": true },
- Or figure out
antlr4ts-cli
.
- In
- With whatever version of Typescript I have been using, the code that is generated isn't completely valid. So I add
// @ts-nocheck generated
to the top of the generated.ts
files.