npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

monaco-jsx-highlighter

v2.77.77

Published

An extensible library to highlight JSX syntax in the Monaco Editor using Babel.

Downloads

4,511

Readme

monaco-jsx-highlighter

npm version npm downloads

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.

LIVE DEMO

monaco-jsx-highlighter demo

# with npm (assuming you are already using monaco-editor)
  npm i @babel/parser @babel/traverse monaco-jsx-highlighter
# with yarn (assuming you are already using monaco-editor)
  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';

// Minimal Babel setup for React JSX parsing:
const babelParse = code => parse(code, {
   sourceType: "module",
   plugins: ["jsx"]
});

// Instantiate the highlighter
const monacoJSXHighlighter = new MonacoJSXHighlighter(
   monaco, babelParse, traverse, getMonacoEditor()
);
// Activate highlighting (debounceTime default: 100ms)
monacoJSXHighlighter.highlightOnDidChangeModelContent(100);
// Activate JSX commenting
monacoJSXHighlighter.addJSXCommentCommand();
// Done =)

function getMonacoEditor(){
  return monaco.editor.create(
          document.getElementById("editor"), {
            value: 'const AB=<A x={d}><B>{"hello"}</B></A>;',
            language: 'javascript'
          });
}

//use makeBabelParse if unsure of the config you need for TSX

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:

# with npm
 npm install @babel/parser
 npm install @babel/traverse
 npm install monaco-jsx-highlighter

YARN:

# with 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:JSX Syntax types and their CSS classnames.
// Customize the color font in JSX texts:  .myCustomCSS {color: red;}
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', // for reference only, only babel is supported right now
  isHighlightGlyph: false, // if JSX elements should decorate the line number gutter
  iShowHover: false, // if JSX types should  tooltip with their type info
  isUseSeparateElementStyles: false, // if opening elements and closing elements have different styling
  isThrowJSXParseErrors: false, // Only JSX Syntax Errors are not thrown by default when parsing, true will throw like any other parsign error
};

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.

// Optional: Disable highlighting when needed (e.g. toggling, unmounting, pausing)
const highlighterDisposeFunc = monacoJSXHighlighter.
   highlightOnDidChangeModelContent(
        100, 
        ast=>{}
   );
highlighterDisposeFunc(); // if you need to

// Internally the highlighter is triggering after each code change debounced
let tid = null;
let debounceTime = 100; // default
monacoEditor.onDidChangeModelContent(() => {
  clearTimeout(tid);
  tid = setTimeout(() => {
            monacoJSXHighlighter.highlightCode();
          },
          debounceTime,
  );
});

// You can do the higlighting directly at anytime
monacoJSXHighlighter.highlightCode();
// or customize its behavior by adding custom highlighting after the JSX highlighting
const afterHighlight = (
        ast // the ast generate by  Babel
) => {
  //... your customization code, check Babel for more info about AST types
  //optional: array with the decorators created by the highlighter, push your decorator ids to this array
  monacoJSXHighlighter.JSXDecoratorIds.push(...yourdecoratorsIds);
};

monacoJSXHighlighter.highlightCode(
        afterHighlight, //default: ast=>ast
        onError, // default: error=>console.error(error)
        getAstPromise, // default:  parse(monacoEditor.getValue())
        onParseErrors, // default: error=>error
);

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:

// Optional: Disable JSX commenting when needed (e.g. toggling, unmounting, pausing)
const commentDisposeFunc = monacoJSXHighlighter.addJSXCommentCommand();
commentDisposeFunc(); // if you need to

Creating Monaco compatible ranges from Babel

import {configureLocToMonacoRange} from 'monaco-jsx-highlighter';
// locToMonacoRange: converts Babel locations to Monaco Ranges
const locToMonacoRange = configureLocToMonacoRange(monaco);
const monacoRange = locToMonacoRange(babelAstNode.loc);