-
Notifications
You must be signed in to change notification settings - Fork 281
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
[POC][WIP] Hydrogen eslint plugin #726
Conversation
1dd05aa
to
c0c07ab
Compare
I am in favour of setting up eslint plugin. Thoughts on the new rules:
|
For context, there have been a couple of discussions I've had in discord about the I'm not sure it makes sense to enforce using the I think it's plenty valid for devs to use a normal
Do you have examples of the rules for each? In looking at the New Rules section, it seems like everything (for now?) would go into |
Oh! @frehner you have a good point about the image rule. It would become an annoyance to the developer they they just want to have an image with But I think the rule would be fine if it is just an enforcement of our own components like .. |
👍 I'm positive about having an eslint plugin and finding rules we can add to On publishing:
We can't remove or overwrite I would keep Let me know if there is a particular feedback you are looking for. On the rules, agree with the comments from @wizardlyhel and @frehner, maybe we could dogfood eslint rules within our repo, and slowly release as we find they are useful? |
Yeah, I too understand the frustration with this rule and would like to improve upon that. In this case, it looks to me like the better solution would be to make the Image component easier to work with in all cases? @wizardlyhel think the tracking pixel is a random exception, so they would probably disable the rule for that one.
Yeah that's right @frehner! Internally Internally we might break the remix-specific ones to a separate config, but for users this would all get bundled up into storefront. I don't see us writing custom rules for our development purposes too often. The CLI team does that for the CLI, however.
I just added a quick stab at this rule and it caught 5 violations in the demo-store. I think we can default to off or warn, but enable it in our templates. If a user finds it too strict they can disable it from there quite easily.
Good question. In this case I was going off the of the template reccomendations. As I think about it more, we could say that if there is a loader or action defined, then we enforce an error boundary. @wizardlyhel what do you think? |
@lordofthecactus your comment came in just as I was responding to the others.
:)
I am for the shorter option, but open to what others think. Do you have a pref?
I think the main things for reviewers is to read the proposal, but addtionally:
Optionally if you would like to help get this over the line, let me know (not mandatory). You can also run this POC to see the effects running eslint has across the packages/templates if that makes it easier to follow. |
I updated the list of rules to include a few provided by @juanpprieto IRL.
|
@frehner Yeah, I'm still working through this, but you can see the different configs (and how they relate/extend from one another) in the changed files area in the |
I am considering adding an
|
That's a great idea (and something we really need, as we aren't enforcing this in any other way otherwise). Should we probably call it This would include the use of |
Close due to inactivity |
Hydrogen ESLint Plugin Proposal
Overview
This RFC exists to propose a new ESLint setup for Hydrogen, both as a solution to our monorepo used in development and also for users building Hydrogen storefronts.
Background
In version 1 of hydrogen we had an
eslint-plugin
package that served to provide the following:1. Common Configurations
These level-set on common ESLint rules to enforce Shopify’s JavaScript best practices, and catch common issues when using Hydrogen. We maintain these so merchants don't need to worry about the undifferentiated setup common to every Hydrogen app. ESLint is a the standard tool for JavaScript and TypeScript, and providing either a base config or plugin is common among almost every other (meta-)framework.
We provide 3 possible configurations:
The Hydrogen configuration excludes suggested third-party plugins, but keeps the custom Hydrogen rules with their suggested defaults.
The TypeScript configuration is a partial set of overrides to augment the recommended or Hydrogen configurations.
2. Custom Rules
We also provided a set of custom rules that only made sense in projects using Hydrogen v1.
Proposal
This proposal recommends the configurations and custom rules will move into the new H2 repo as a new
eslint-plugin
package. The details of this migration are outlined below.New configurations
storefront
: This configuration will be exposed for Hydrogen storefronts and used across ourdemo-store
andhello-world
templates and any future scaffolding commands that relate to eslint (for example,h2 setup eslint
). It will contain a combined config of the internal configs forreact
,remix
andhydrogen
.workspace
: This configuration will be used in the mono-repo root and used across our packages.cli
: This configuration will be used in the hydrogen packagescli-hydrogen
andcreate-hydrogen
specifically. It will contain a the configurations and custom rules from the@shopify/eslint-plugin-cli
.library
: This configuration will be used in thehydrogen-react
package. It is more strict when it comes to typescript.New rules
We will remove all custom rules except
prefer-image-component
, as it's the one that makes sense in the H2 context.no-missing-error-boundary-in-route
: Have anErrorBoundary
in every route template.ErrorBoundary
is used when an Error is thrown in a “loader”, and is generally meant for unexpected errors, like 500, 503, etc. Any Storefront query or mutation error will be handled by theErrorBoundary
. Type the error as “unknown” since anything in JS can be thrown 🙂require-error-element-on-await
: Use the “errorElement” prop on every<Await>
component. When using “defer”, some promises may be rejected at a later time. The only way to handle this is to use the “errorElement” on the associated component, otherwise the error is swallowed.prefer-try-catch-in-route
Use try/catch – except in “loader”, “action”, and the Component. Those three “Route Module APIs” are handled automatically byErrorBoundary
and CatchBoundary, but the rest – such as “meta”, “links”, “handle”, etc. – will crash the server if an error is thrown.no-try-catch-in-loader
andno-try-catch-in-action
: For templates it’s easier to let the error be thrown and get handled by theErrorBoundary
than to handle it manually.route-module-export-order
: Remix-specific route API functions should be ordered and consistent in style, to help developers quickly scan and find what they're looking for. Order these APIs following a top-down order of concerns:shouldRevalidate
,headers
,meta
,links
)loader
,action
)Component
)ErrorBoundary
,CatchBoundary
)enforce-server-only
- checks if imported functions are only called inside loaders or actions, and if so recommend the module to be re-named with .server.prevent-returning-private-env-vars
- This could check that loaders don't return PRIVATE_ prefixed env variables, to avoid exposing secrets.Detailed design
Tech stack
The tech stack of the new plugin will be consistent with all hydrogen packages, written in typescript and tested with vitest.
How to write rules
Rules are structured as follows:
/README.md
: contains all documentation and usage instructions./<name-of-rule>.ts
: contains all code required to evaluate the rule./<name-of-rule>.test.ts
: contains a suite of tests to validate the rule's valid and invalid states./index.ts
: re-exports the rule to the outer world.Rules should auto-fix when possible and contain clear/ consistent messaging that directs users on where they can learn more.
Incremental adoption
Rather than publish this new package overtop of the old library on NPM, I suggest we release it as
eslint-plugin-h2
. Overtime we can deprecate, remove and overwriteeslint-plugin-hydrogen
when we are confident with the developer experience.Future proof
Rules are easy to write and maintain and we will be constantly evolving this library as Remix and other Hydrogen dependents change.
Alternate ideas
Do nothing
We've haven't received negetive feedback about ESLint, nor have we been burdened by the fact the old eslint-plugin is in the old Hydrogen v1 repo and not easily patchable. So why do anything and why do it now?