Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Docusaurus ESLint plugin to enforce best Docusaurus practices #7206

Merged
merged 21 commits into from Apr 29, 2022

Conversation

elias-pap
Copy link
Contributor

@elias-pap elias-pap commented Apr 18, 2022

Motivation

Explained in the description of #6472

Have you read the Contributing Guidelines on pull requests?

Yes

Test Plan

Doc URL: https://deploy-preview-7206--docusaurus-2.netlify.app/docs/api/misc/@docusaurus/eslint-plugin/

Unit tests are included and integrated with existing jest setup.

Output of `yarn test eslint-plugin`
yarn run v1.22.17
$ jest eslint-plugin
 PASS  packages/eslint-plugin/__tests__/lib/rules/no-dynamic-i18n-messages.test.js
  no-dynamic-i18n-messages
    valid
      ✓ <Translate>text</Translate> (20 ms)
      ✓ <Translate> text </Translate> (1 ms)
      ✓ <Translate>"text"</Translate> (2 ms)
      ✓ <Translate>'text'</Translate> (1 ms)
      ✓ <Translate>`text`</Translate> (1 ms)
      ✓ <Translate>{"text"}</Translate> (2 ms)
      ✓ <Translate>{'text'}</Translate> (1 ms)
      ✓ <Translate>{`text`}</Translate> (1 ms)
      ✓ <Component>{text}</Component> (2 ms)
      ✓ <Component> {text} </Component> (1 ms)
      ✓ <Translate
                id="homepage.title"
                description="The homepage welcome message">
                  Welcome to my website
              </Translate> (2 ms)
      ✓ <Translate
                values={{firstName: 'Sébastien'}}>
                  {'Welcome, {firstName}! How are you?'}
              </Translate> (5 ms)
      ✓ translate({message: 'My page meta title'}) (1 ms)
      ✓ translate({message: 'The logo of site {siteName}'}, {siteName: 'Docusaurus'}) (1 ms)
      ✓ translate({otherProp: metaTitle}) (1 ms)
      ✓ translate({otherProp: `My page meta title`}) (1 ms)
    invalid
      ✓ <Translate>{text}</Translate> (2 ms)
      ✓ <Translate> {text} </Translate> (1 ms)
      ✓ <Translate>`{text}`</Translate> (2 ms)
      ✓ <Translate>{`${text}`}</Translate> (1 ms)
      ✓ translate({message: metaTitle}) (1 ms)
      ✓ translate({message: `My page meta title`}) (1 ms)

 PASS  packages/eslint-plugin/__tests__/lib/rules/no-untranslated-text.test.js
  no-untranslated-text
    valid
      ✓ <Translate>text</Translate> (9 ms)
      ✓ <Translate> text </Translate> (1 ms)
      ✓ <Translate>"text"</Translate> (1 ms)
      ✓ <Translate>'text'</Translate> (1 ms)
      ✓ <Translate>`text`</Translate> (1 ms)
      ✓ <Translate>{"text"}</Translate> (1 ms)
      ✓ <Translate>{'text'}</Translate> (1 ms)
      ✓ <Translate>{`text`}</Translate> (1 ms)
      ✓ <Component>{text}</Component> (1 ms)
      ✓ <Component> {text} </Component> (1 ms)
    invalid
      ✓ <Component>text</Component> (1 ms)
      ✓ <Component> text </Component> (2 ms)
      ✓ <Component>"text"</Component>
      ✓ <Component>'text'</Component>
      ✓ <Component>`text`</Component> (1 ms)
      ✓ <Component>{"text"}</Component> (1 ms)
      ✓ <Component>{'text'}</Component> (1 ms)
      ✓ <Component>{`text`}</Component> (1 ms)
      ✓ <>text</> (1 ms)

Test Suites: 2 passed, 2 total
Tests:       41 passed, 41 total
Snapshots:   0 total
Time:        0.512 s, estimated 1 s
Ran all test suites matching /eslint-plugin/i.
Done in 1.25s.

This is also dogfooded in our own monorepo.

@facebook-github-bot facebook-github-bot added the CLA Signed Signed Facebook CLA label Apr 18, 2022
@netlify
Copy link

netlify bot commented Apr 18, 2022

[V2]

Built without sensitive environment variables

Name Link
🔨 Latest commit 40cfd23
🔍 Latest deploy log https://app.netlify.com/sites/docusaurus-2/deploys/626c043637a15500083fb170
😎 Deploy Preview https://deploy-preview-7206--docusaurus-2.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@github-actions
Copy link

github-actions bot commented Apr 18, 2022

⚡️ Lighthouse report for the changes in this PR:

Category Score
🟠 Performance 67
🟢 Accessibility 100
🟠 Best practices 83
🟢 SEO 100
🟢 PWA 90

Lighthouse ran on https://deploy-preview-7206--docusaurus-2.netlify.app/

@Josh-Cena
Copy link
Collaborator

At a glance, it looks much, much better than I could've imagined 👍 Thanks a bunch! I'll play with it later.

node.children.every((child) => isTextLabelChild({child}));

return {
"JSXElement[openingElement.name.name='Translate']": (node) => {
Copy link
Collaborator

@Josh-Cena Josh-Cena Apr 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine for now, but in the long term, we may need to first check the imported name because it may not be imported as Translate (cf our translationExtractor implementation). I'm not aware if we can let ESLint do a two-round traverse in an efficient way—I think people usually use Program:exit?

Copy link
Collaborator

@Josh-Cena Josh-Cena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks really solid and it's already ready to be shipped IMO.

There are many useful extensions to make, but I think this will make a great initial kickstart.

const isMessageTypeValid = (type) => type === 'Literal';

const isNodeValid = (node) =>
node.children.every((child) => isTextLabelChild({child}));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be useful to add an option ignoreJSXAttributes. We may want to flag <div aria-label="untranslated" /> as well. Doesn't have to be in this PR though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't understand that, could you provide an example usage of ignoreJSXAttributes ? Also what is the purpose of <div aria-label="untranslated" /> ? Self-closing tags do not have children (excluding the children prop) therefore the current rules do not apply in this case, right ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry, wrong comment place. I was talking about no-untranslated-text. There should be an option that turns on warning for JSX attributes like aria-label as well, not just string literal children.

@Josh-Cena Josh-Cena added the pr: new feature This PR adds a new API or behavior. label Apr 19, 2022
@Josh-Cena Josh-Cena changed the title feat: add eslint plugin feat: Docusaurus eslint plugin to ensure best Docusaurus practices Apr 19, 2022
@Josh-Cena
Copy link
Collaborator

Seems to work pretty nicely 🎉

image

(Although 99% of them are false-positives, not something we can help, lol)

packages/eslint-plugin/package.json Outdated Show resolved Hide resolved
website/docs/api/plugins/eslint-plugin.md Outdated Show resolved Hide resolved
website/docs/api/plugins/eslint-plugin.md Outdated Show resolved Hide resolved
website/docs/api/plugins/eslint-plugin.md Outdated Show resolved Hide resolved
website/docs/api/plugins/overview.md Outdated Show resolved Hide resolved
Copy link
Collaborator

@Josh-Cena Josh-Cena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @elias-pap I'm sorry but this would probably take a bit longer than expected to be merged, because @slorber needs to review this as well, but he has limited availability. Luckily it doesn't touch existing code and should have very little merge conflict over time, so we'll probably go back to it in June, after 2.0 has been released. Thanks again!

website/docs/api/plugin-methods/_category_.yml Outdated Show resolved Hide resolved
website/docs/api/misc/eslint-plugin/README.md Outdated Show resolved Hide resolved
elias-pap and others added 2 commits April 22, 2022 11:21
- Reorder sidebar entries
- Fix title size
- Use Markdown file paths
- Simplify relative links
Copy link
Collaborator

@Josh-Cena Josh-Cena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fully ready. @elias-pap There's no more feedback from my side. If @slorber manages to review this, we can merge it.

@elias-pap
Copy link
Contributor Author

Great, thanks for the reviews @Josh-Cena.

Copy link
Collaborator

@slorber slorber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks nice

As this is an optional plugin, not enabled by default the risk to merge this is quite low so we can give it a try 👍

packages/eslint-plugin/.eslintrc.js Show resolved Hide resolved
website/docs/api/misc/eslint-plugin/README.md Outdated Show resolved Hide resolved
@Josh-Cena Josh-Cena changed the title feat: Docusaurus eslint plugin to ensure best Docusaurus practices feat: Docusaurus ESLint plugin to enforce best Docusaurus practices Apr 29, 2022
@Josh-Cena
Copy link
Collaborator

Hold on—there are some minor issues. I would first fix all internal warnings and merge it no later than tomorrow.

@Josh-Cena Josh-Cena requested a review from slorber April 29, 2022 15:29
@Josh-Cena
Copy link
Collaborator

Josh-Cena commented Apr 29, 2022

Will merge this soon. Thanks again @elias-pap much appreciated! It's caught a lot of issues in our own repo which I've just fixed.

@Josh-Cena Josh-Cena merged commit 3b1170e into facebook:main Apr 29, 2022
@elias-pap elias-pap deleted the add-eslint-plugin branch April 29, 2022 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed Signed Facebook CLA pr: new feature This PR adds a new API or behavior.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants