ESLint config and CLI command for validation
>>> [!note] Migrated issue <!-- Drupal.org comment --> <!-- Migrated from issue #3559127. --> Reported by: [balintbrews](https://www.drupal.org/user/613760) Related to !375 !373 !353 >>> <h3 id="overview">Overview</h3> <p>Code Components are mostly idiomatic React, but there are certain guidelines they need to follow in order to work in Canvas. For example, the components always have to provide a default export &mdash;as opposed to named exports&mdash;, and they currently can't import <em>any</em> third-party package, only a <a href="https://project.pages.drupalcode.org/canvas/code-components/packages/#built-in-custom-packages">few supported ones</a>.</p> <p>Now that we just landed <span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3558752" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3558752</a></span>, the next step would be to create our own ESLint config which can be used by the starter template, as well as in a new <code>validate</code> command in the CLI tool to make sure the guidelines are followed.</p> <h3 id="proposed-resolution">Proposed resolution</h3> <ol> <li> Add a new package under <code>packages/eslint-config</code>, which we'll publish as<strong> <code>@drupal-canvas/eslint-config</code></strong>. </li> <li> <p> Provide three differents set of configs: <code>required</code>, <code>recommended</code>, and <code>all</code>.<br> Users should be able to use them in the following way in their ESLint config: </p> <pre><pre>import { defineConfig } from "eslint/config";<br>import { recommended as drupalCanvasRecommended } from "@drupal-canvas/eslint-config";<br>const eslintConfig = defineConfig([<br>&nbsp;&nbsp; ...drupalCanvasRecommended,<br>&nbsp;&nbsp; // ...<br>]);<br>export default eslintConfig;</pre></pre><ol> <li> <strong><code>required</code></strong> should cover the followings: <ol> <li>Bare minimum from <code>eslint-plugin-react</code> to avoid parser errors.</li> <li> <p>Our own config and custom rules where we need them.</p> <ol> <li>Components must provide a default export.</li> <li>Imports specifiers can only be <code>@/components/[component-name]</code>, <code>@/lib/[provided-lib-name]</code>, a bundled package (see import map in <code>src/features/code-editor/Preview.tsx</code>), or a full URL.</li> <li>Enforce that components are placed inside a single directory with no hierarchy, and that each component has a single folder with an <code>index.jsx</code>, <code>index.css</code> (optional), and <code>component.yml</code> file, and no other files in those directories (they would get overridden when the <code>download</code> CLI command is used). <strong>Note:</strong> This may not be a good fit for ESLint, in which case we should implement it in our <code>validate</code> CLI command.</li> <li>Prop machine names in component.yml must be camel cased version of the prop titles. See: <a href="https://github.com/balintbrews/canvas-cc-starter/blob/main/docs/important-notes.md#1-prop-machine-names-must-be-the-camel-cased-version-of-the-prop-titles">https://github.com/balintbrews/canvas-cc-starter/blob/main/docs/important-notes.md#1-prop-machine-names-must-be-the-camel-cased-version-of-the-prop-titles</a>. <strong>Note:</strong> This is probably not a good fit for ESLint, in which case we should implement it in our <code>validate</code> CLI command.</li> <li>Match the name from component.yml with the name of the component's folder. <strong>Note:</strong> This may not be a good fit for ESLint, in which case we should implement it in our <code>validate</code> CLI command.</li> </ol> </li> </ol> </li> <li><strong><code>recommended</code></strong> should cover <code>required</code> + <code>recommended</code> from <code>eslint-plugin-react</code>, <code>eslint-plugin-react-hooks</code>, and <code>eslint-plugin-jsx-a11y</code>.</li> <li><strong><code>all</code></strong> should cover <code>recommended</code> + all that makes sense from <code>eslint-plugin-react</code>, <code>eslint-plugin-react-hooks</code>, and <code>eslint-plugin-jsx-a11y</code>.</li> </ol> <p>See example config here: <a href="https://github.com/balintbrews/canvas-cc-starter/blob/main/eslint.config.js">https://github.com/balintbrews/canvas-cc-starter/blob/main/eslint.config.js</a>.</p> </li> <li>Implement a <code>validate</code> command in the CLI tool which runs ESLint checks using our required config. Make sure <code>validate</code> runs whenever the <code>build</code> command runs.</li> </ol> <h3 id="ui-changes">User interface changes</h3> <p>The CLI tool has a unified output for the <code>build</code> and <code>upload</code> commands. When the <code>upload</code> command is used, it runs the <code>build</code> command, and the errors are bubbled up to its output. Implement a standalone <code>validate</code> command with a similar output. Automatically run validate when the build command is run, and bubble the errors to its output similarly. Make sure the errors are displayed when the upload</p>
issue