lexical icon indicating copy to clipboard operation
lexical copied to clipboard

Feature: MarkdownShortcuts: missing dependency for transformer. Ensure node dependency is included in editor initial config.

Open boluo-O opened this issue 2 years ago • 9 comments

When i try to use MarkdownShortcutPlugin with default transformers like that <MarkdownShortcutPlugin /> I encountered this problem. After debug for a while, i find i must add all this node in the editor config. const EDITOR_NODES = [ HorizontalRuleNode, CodeNode, HeadingNode, LinkNode, ListNode, ListItemNode, QuoteNode, ] Any missing node will result in an error.

Perhaps we need to give a hint in MarkdownShortcutPlugin doc or more detailed error message like Ensure HorizontalRuleNode is included in editor initial config. .

Lexical version: "lexical": "^0.9.1", "@lexical/markdown": "^0.9.1",

Steps To Reproduce

  1. use MarkdownShortcutPlugin like <MarkdownShortcutPlugin />
  2. Missing any node of [ HorizontalRuleNode, CodeNode, HeadingNode, LinkNode, ListNode, ListItemNode, QuoteNode, ]

Link to code example:

The current behavior

MarkdownShortcuts: missing dependency for transformer. Ensure node dependency is included in editor initial config.

The expected behavior

Better MarkdownShortcutPlugin doc or more detailed error message like Ensure HorizontalRuleNode is included in editor initial config.

boluo-O avatar Mar 28 '23 02:03 boluo-O

This looks like a feature, as it's not a bug because the behavior is expected.

milaabl avatar Mar 28 '23 10:03 milaabl

We can add a more specific error message and/or some docs though - good call. Probably more like a feature, but sorry you lost time on this.

acywatson avatar Mar 28 '23 19:03 acywatson

Just in case it's any useful: you can pass custom list of transformers into shortcuts plugin (https://github.com/facebook/lexical/blob/main/packages/lexical-react/src/LexicalMarkdownShortcutPlugin.tsx#L44) which can only include trasnformers for nodes your editor includes

fantactuka avatar Mar 28 '23 19:03 fantactuka

We can add a more specific error message and/or some docs though - good call. Probably more like a feature, but sorry you lost time on this.

Yes, this is a feature. it's my fault. I have change the title.

boluo-O avatar Mar 29 '23 02:03 boluo-O

Looks like HorizontalRuleNode isn't covered in the doc at all.

dizys avatar Jun 18 '23 08:06 dizys

I'm new to lexical, and finding out which imports to use was really non-intuitive.

My approach was to do grep in node_modules to find class declarations, and this is what I came up with, which seems to work:

import { CodeNode } from '@lexical/code';
import { LinkNode } from '@lexical/link';
import { ListNode, ListItemNode } from '@lexical/list';
import { HeadingNode, QuoteNode } from '@lexical/rich-text';
import { HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';

koliyo avatar Jul 07 '23 08:07 koliyo

+1 Markdown Shortcut plugin breaking with: Uncaught Error: MarkdownShortcuts: missing dependency heading for transformer. Ensure node dependency is included in editor initial config.

Threw this in my editor config:

 nodes: [
    HorizontalRuleNode,
    CodeNode,
    LinkNode,
    ListNode,
    ListItemNode,
    HeadingNode,
    QuoteNode,
  ],

cruzluna avatar Feb 08 '24 23:02 cruzluna

This looks like a feature, as it's not a bug because the behavior is expected.

If this is expected behaviour, why would they not just import it into the plugin by default?

SaintPepsi avatar Jul 10 '24 23:07 SaintPepsi

this covers almost all the nodes :)

versions

    "@lexical/react": "^0.17.0",
    "lexical": "^0.17.0",

imports

import { AutoLinkNode, LinkNode } from "@lexical/link";
import { ListNode, ListItemNode } from "@lexical/list";
import { TableNode, TableCellNode, TableRowNode } from "@lexical/table";
import { CodeNode } from "@lexical/code";
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
import { HorizontalRuleNode } from "@lexical/react/LexicalHorizontalRuleNode";

editor config object

  const editorConfig = {
      namespace: "Rich text editor in React",
      nodes: [
        LinkNode,
        AutoLinkNode,
        ListNode,
        ListItemNode,
        TableNode,
        TableCellNode,
        TableRowNode,
        HorizontalRuleNode,
        CodeNode,
        HeadingNode,
        LinkNode,
        ListNode,
        ListItemNode,
        QuoteNode,
      ],
      onError(error: Error) {
        throw error;
      },
      theme: theme,
    };

aaasisss avatar Aug 25 '24 04:08 aaasisss

This is very very unclear. Following the docs located here https://lexical.dev/docs/packages/lexical-markdown

We have this setup code if using react

import { TRANSFORMERS } from '@lexical/markdown';
import {MarkdownShortcutPlugin} from '@lexical/react/LexicalMarkdownShortcutPlugin';

<LexicalComposer>
  <MarkdownShortcutPlugin transformers={TRANSFORMERS} />
</LexicalComposer>

This by default causes the above error. The initial setup of the editor on this github readme. Doesn't have the nodes needed included or a nodes field in the editor config object. How is a new user to this library supposed to figure what to do with a plugin when there isn't clear instructions or a working code snippet to copy? No where is the nodes property mentioned in the documentation between setup and using the markdown plugin. Neither are the required list of nodes needed for transformers listed in the markdown plugin. Is there a guide or a getting started that covers these topics somewhere since I don't see this on the lexical docs site?

import {$getRoot, $getSelection} from 'lexical';
import {useEffect} from 'react';

import {LexicalComposer} from '@lexical/react/LexicalComposer';
import {PlainTextPlugin} from '@lexical/react/LexicalPlainTextPlugin';
import {ContentEditable} from '@lexical/react/LexicalContentEditable';
import {HistoryPlugin} from '@lexical/react/LexicalHistoryPlugin';
import {OnChangePlugin} from '@lexical/react/LexicalOnChangePlugin';
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
import {LexicalErrorBoundary} from '@lexical/react/LexicalErrorBoundary';

const theme = {
  // Theme styling goes here
  // ...
}

// When the editor changes, you can get notified via the
// LexicalOnChangePlugin!
function onChange(editorState) {
  editorState.read(() => {
    // Read the contents of the EditorState here.
    const root = $getRoot();
    const selection = $getSelection();

    console.log(root, selection);
  });
}

// Lexical React plugins are React components, which makes them
// highly composable. Furthermore, you can lazy load plugins if
// desired, so you don't pay the cost for plugins until you
// actually use them.
function MyCustomAutoFocusPlugin() {
  const [editor] = useLexicalComposerContext();

  useEffect(() => {
    // Focus the editor when the effect fires!
    editor.focus();
  }, [editor]);

  return null;
}

// Catch any errors that occur during Lexical updates and log them
// or throw them as needed. If you don't throw them, Lexical will
// try to recover gracefully without losing user data.
function onError(error) {
  console.error(error);
}

function Editor() {
  const initialConfig = {
    namespace: 'MyEditor',
    theme,
    onError,
  };

  return (
    <LexicalComposer initialConfig={initialConfig}>
      <PlainTextPlugin
        contentEditable={<ContentEditable />}
        placeholder={<div>Enter some text...</div>}
        ErrorBoundary={LexicalErrorBoundary}
      />
      <OnChangePlugin onChange={onChange} />
      <HistoryPlugin />
      <MyCustomAutoFocusPlugin />
    </LexicalComposer>
  );
}

ZelCloud avatar Nov 21 '24 05:11 ZelCloud

There's just simply no way for plugins, as currently defined, to carry initial configuration. The only way to improve this situation without changing anything fundamentally is to contribute documentation PRs to make this initial configuration easier to discover.

Lexical is a very low-level library as-is, it's a framework for building editors, not an off-the-shelf editor that can be customized. I have a side project that will probably improve this eventually, but my attention has been focused more on improving some lower-level issues. https://lexical-builder.pages.dev/

etrepum avatar Nov 21 '24 06:11 etrepum

Please make the doc more developer friendly.

YongzeYao avatar Jun 09 '25 06:06 YongzeYao

note I did not need CodeNode and LineNode, so I removed from DEFAULT_TRANSFORMERS.

export const MY_TRANSFORMERS: Transformer[] = DEFAULT_TRANSFORMERS.filter((t) => {
  if (t.type === 'multiline-element') {
    return !t.dependencies.includes(CodeNode);
  }
  if (t.type === 'text-match') {
    return !t.dependencies.includes(LinkNode);
  }
  return true;
});

matsuyama-k1 avatar Sep 28 '25 09:09 matsuyama-k1