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 —as opposed to named exports—, 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> ...drupalCanvasRecommended,<br> // ...<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