Open etrepum opened 2 weeks ago
The latest updates on your projects. Learn more about Vercel for Git ↗︎
Name | Status | Preview | Comments | Updated (UTC) |
---|---|---|---|---|
lexical | ✅ Ready (Inspect) | Visit Preview | 💬 Add feedback | Apr 27, 2024 8:56pm |
lexical-playground | ✅ Ready (Inspect) | Visit Preview | 💬 Add feedback | Apr 27, 2024 8:56pm |
@lexical/eslint-plugin - an eslint plugin that helps with the rules of lexical ($functions) and provides an autofixer
Documentation preview: https://lexical-qke2cx8a9-fbopensource.vercel.app/docs/packages/lexical-eslint-plugin
Currently defines one rule: @lexical/rules-of-lexical
There's documentation per #5869 for adding a new package to npm already in the maintainers guide: https://lexical-qke2cx8a9-fbopensource.vercel.app/docs/maintainers-guide#creating-a-new-package
The thing about this package that's atypical relative to how most new packages would be created is that it's entirely written in cjs (not TypeScript or using modules), so that it can be used in the monorepo with our version of eslint without compilation. There are plenty of jsdoc comments for type checking though.
The design is basically that it will look for $function call expressions and see if they were made in an allowed context (e.g. from another $function). If they are not, then it will suggest a rename of fn to $fn.
Some complex situations that rules-of-lexical handles:
Avoid shadowing an existing variable
BEFORE ```typescript const createKeywordNode = useCallback((textNode: TextNode): KeywordNode => { return $createKeywordNode(textNode.getTextContent()); }, []); ``` AFTER ```typescript const $createKeywordNode_ = useCallback((textNode: TextNode): KeywordNode => { return $createKeywordNode(textNode.getTextContent()); }, []); ```Renaming an export
BEFORE ```typescript /** * Traverses up the tree and returns the first ListItemNode found. * @param node - Node to start the search. * @returns The first ListItemNode found, or null if none exist. */ export function findNearestListItemNode( node: LexicalNode, ): ListItemNode | null { const matchingParent = $findMatchingParent(node, (parent) => $isListItemNode(parent), ); return matchingParent as ListItemNode | null; } ``` AFTER ```typescript /** * Traverses up the tree and returns the first ListItemNode found. * @param node - Node to start the search. * @returns The first ListItemNode found, or null if none exist. */ export function $findNearestListItemNode( node: LexicalNode, ): ListItemNode | null { const matchingParent = $findMatchingParent(node, (parent) => $isListItemNode(parent), ); return matchingParent as ListItemNode | null; } /** @deprecated renamed to $findNearestListItemNode by @lexical/eslint-plugin rules-of-lexical */ export const findNearestListItemNode = $findNearestListItemNode; ```I've tested the output artifact (the npm pack that our integration tests build) with a project outside of the monorepo in this branch: https://github.com/etrepum/lexical-esm-nextjs/tree/lexical-eslint-plugin
I stripped this down to just the new code, it does not include fixes to any existing code.
I believe you should be able to try this out outside of the monorepo before it is released by installing it this way:
To see a concrete example of what this plugin would do in the monorepo, you can check out the last commit in #5979 https://github.com/facebook/lexical/pull/5979/commits/095502e543085b497fa18834c99e6d0eb9331997