monaco-jsx-highlighter
![npm downloads](https://img.shields.io/npm/dm/monaco-jsx-highlighter.svg?style=flat-square)
An extensible library to highlight (and comment) JSX syntax in the Monaco Editor
using Babel. It exposes its AST after it does its magic, so you can add your own
syntax-based or custom highlights.
![monaco-jsx-highlighter demo](https://github.com/luminaxster/syntax-highlighter/blob/demo_file/msh_demo.gif)
npm i @babel/parser @babel/traverse monaco-jsx-highlighter
yarn add @babel/parser @babel/traverse monaco-jsx-highlighter
TL;DR
import monaco from 'monaco-editor';
import {parse} from "@babel/parser";
import traverse from "@babel/traverse";
import MonacoJSXHighlighter, {makeBabelParse} from 'monaco-jsx-highlighter';
const babelParse = code => parse(code, {
sourceType: "module",
plugins: ["jsx"]
});
const monacoJSXHighlighter = new MonacoJSXHighlighter(
monaco, babelParse, traverse, getMonacoEditor()
);
monacoJSXHighlighter.highlightOnDidChangeModelContent(100);
monacoJSXHighlighter.addJSXCommentCommand();
function getMonacoEditor(){
return monaco.editor.create(
document.getElementById("editor"), {
value: 'const AB=<A x={d}><B>{"hello"}</B></A>;',
language: 'javascript'
});
}
NL;PR
New in v2
- Adds
makeBabelParse
: babel's parse configuration for JSX/TSX (thanks @HaimCandiTech) - TS codebase migration start.
- Reported defect fixes(dispose).
New in v1
- Babel is now used directly instead of via JsCodeShift.
- React fragment, spread child, spread attribute, and container expression
highlighting.
- highlightOnDidChangeModelContent(debounceTime) method debounces highlight
updates.
- Several defect repairs.
Breaking Changes
If you have used 0.x versions, you'll notice JsCodeShift has been replaced with
Babel:
- import j from 'jscodeshift';
+ import {parse} from "@babel/parser";
+ import traverse from "@babel/traverse";
This only affects the constructor signature:
+ const babelParse = code => parse(code, {sourceType: "module", plugins: ["jsx"]});
const monacoJSXHighlighter = new MonacoJSXHighlighter(
monaco,
- j,
+ babelParse, traverse,
monacoEditor
);
Also, monacoJSXHighlighter.highlightOnDidChangeModelContent
method now has an
optional debounce time as first parameter on its signature:
monacoJSXHighlighter.highlightOnDidChangeModelContent(
- afterHighlight: func,
+ debounceTime: number, afterHighlight: func,
...)
Dependencies
It requires monaco-editor
, @babel/parser
and @babel/traverse
, for
convenience, they are listed as peer dependencies and passed by reference (so
you can do lazy loading). Please install them before monaco-jsx-highlighter
;
Installation
Install the package in your project directory with:
NPM:
npm install @babel/parser
npm install @babel/traverse
npm install monaco-jsx-highlighter
YARN:
yarn add @babel/parser
yarn add @babel/traverse
yarn add monaco-jsx-highlighter
Replacing CSS classes with your own
import {JSXTypes} from 'monaco-jsx-highlighter';
JSXTypes.JSXText.options.inlineClassName = "myCustomCSS";
Overriding CSS classes
Take a look of
the src/JSXColoringProvider.css
file
and override the CSS classes you need. Make sure to import your customization
CSS files after you import monaco-jsx-highlighter
.
Advanced Usage
After your have a Monaco JSX Highlighter instance, monacoJSXHighlighter
:
const defaultOptions = {
parser: 'babel',
isHighlightGlyph: false,
iShowHover: false,
isUseSeparateElementStyles: false,
isThrowJSXParseErrors: false,
};
const monacoJSXHighlighter = new MonacoJSXHighlighter(
monaco, babelParse, traverse, monacoEditor, defaultOptions
);
The highlight activation method, monacoJSXHighlighter.highlightOnDidChangeModelContent(debounceTime: number, afterHighlight: func, ...)
, accepts a callback among other parameters. The callback afterHighlight
passes the AST used to highlight the code. Passing parameters and using the disposer function returned by the call are optional.
Note: The disposer is always called when the editor is disposed.
const highlighterDisposeFunc = monacoJSXHighlighter.
highlightOnDidChangeModelContent(
100,
ast=>{}
);
highlighterDisposeFunc();
let tid = null;
let debounceTime = 100;
monacoEditor.onDidChangeModelContent(() => {
clearTimeout(tid);
tid = setTimeout(() => {
monacoJSXHighlighter.highlightCode();
},
debounceTime,
);
});
monacoJSXHighlighter.highlightCode();
const afterHighlight = (
ast
) => {
monacoJSXHighlighter.JSXDecoratorIds.push(...yourdecoratorsIds);
};
monacoJSXHighlighter.highlightCode(
afterHighlight,
onError,
getAstPromise,
onParseErrors,
);
Additionally, you can add JSX commenting to your monaco editor with
monacoJSXHighlighter.addJSXCommentCommand()
:
comments in JSX children will result in {/*...*/}
instead of //...
. It mimics the commenting behavior of
the WebStorm IDE.
Follow this code to find out other perks:
const commentDisposeFunc = monacoJSXHighlighter.addJSXCommentCommand();
commentDisposeFunc();
Creating Monaco compatible ranges from Babel
import {configureLocToMonacoRange} from 'monaco-jsx-highlighter';
const locToMonacoRange = configureLocToMonacoRange(monaco);
const monacoRange = locToMonacoRange(babelAstNode.loc);