feat: add Fresh lint plugin#3179
Conversation
| @@ -0,0 +1,13 @@ | |||
| { | |||
| "name": "@fresh/lint", | |||
There was a problem hiding this comment.
Perhaps a new package for linting is overkill, or could perhaps allow more drift (version mismatch between @fresh/lint and @fresh/core). The lint plugin could instead be a export on @fresh/core, e.g. @fresh/core/lint.
Given that it's unlikely for lint rules to require extra dependencies, it might be better to have the lint plugin just as a new export on @fresh/core. I feel like most projects will want the lint rules anyway, so maybe it's better to skip another dependency.
{
"lint": {
"plugins": ["jsr:@fresh/core/lint"]
}
}Note
It seems that it's not possible to use import maps with "lint.plugins" at the moment, so requires the jsr: prefix currently. I created denoland/deno#30297 to highlight this.
9a632d5 to
ef642ec
Compare
1d4962d to
e58c5f6
Compare
|
Nice plugin architecture — the 1. Test files will be published to JSR
"publish": {
"include": ["src/**/*.ts", ...],
"exclude": ["src/**/*.test.ts"]
}2. handler-export error message says "middlewares" but fires for all routes The message is 3.
4. Minor things
|
8d0f8b3 to
a0f56e2
Compare
|
I think I adressed all your feedback now @bartlomieju. Rebased to address conflicts, and addressed feedback in indiviual commits. I also made a couple of commits to fix formatting and accidental change in
Let me know if there's anything else you think I missed or is left to do 🙂 Edit: Nevermind, I see I must first fix my test errors! |
|
Ok, only one thing that fails currently, and that's All I can think of is to replace the current test assertion temporarily: // Re-enable this after `@fresh/lint` is published
// expect(check.code).toEqual(0);
expect(check.stderr).toBe('error: JSR package not found: @fresh/lint'); |
There was a problem hiding this comment.
This seems unrelated - can you remove it?
There was a problem hiding this comment.
Fixed. Sorry, I was trying out a new editor and this was committed by accident 😅
|
|
||
| // Keep these as is, as we replace these version in our release script | ||
| const FRESH_VERSION = "2.2.1"; | ||
| const FRESH_LINT_VERSION = "0.0.0"; |
There was a problem hiding this comment.
This should be bumped to something more sensible like 0.1.0
|
I'm not sure anymore how I feel about it... It seems useful, but there are more questions than answers. How will we update these rules using Fresh updater? What if a user changes the rule on their own? I wonder if the better mechanism would be to consume lint plugins from npm/jsr in |
I just imagined that // deno.json
{
"lint": {
"plugins": ["@fresh/lint"],
"rules": {
"exclude": ["fresh/excluded-rule"]
}
}
}
The intent with this PR is to publish Sorry if I was unclear in the PR. I just felt it odd that linting rules for Fresh was tied to Deno releases, and it was harder to add lint rules for Fresh in Rust IMO. 🙂 |
lunadogbot
left a comment
There was a problem hiding this comment.
CI is red on every test job because init - fmt, lint, and type check project (packages/init/src/init_test.ts:228) runs deno task check against the generated project, whose deno.json now contains lint.plugins: ["jsr:@fresh/lint"] and imports["@fresh/lint"] = "jsr:@fresh/lint@^0.1.0" — a package this PR creates but that doesn't exist on JSR yet. deno lint can't resolve the plugin and the task exits 1.
Two-step landing fixes the chicken-and-egg: ship the packages/lint/ package on its own, let it publish to JSR, then a follow-up PR wires the import + lint.plugins into packages/init/src/init.ts:572,582 and packages/update/src/update.ts:146. www/deno.json can keep the local path either way.
- nit:
handler-export.ts:21selector matchesexport const handlers = …andexport function handlers() {}but notexport { handlers }re-export syntax. Uncommon in routes, but worth either covering or noting as out-of-scope. The test file doesn't exercise it either. - nit:
new Set<[filename: string, code: string]>([...])in both*.test.tsfiles dedupes by array-reference (every literal is unique), so it behaves identically to a plain array but reads oddly.const okCases = [...]is clearer. - The TODOs still listed in the PR description (dup-rule prevention, island-imports rule) suggest this is still WIP — maintainer call whether to split those out or land them together.
Adapts the two existing Fresh lint rules in Deno into it's own Lint plugin.
Used as an example for #3174 for possible creating new Fresh lint rules too.
Note
Requires the AST regex selector fix that is included in Deno v2.4.5
TODO's
freshtag in Deno"fresh/island-imports"rule to disallow importingfreshfrom Islands**/islands/**or something, since it's not possible yet to configure the Island folder. I made Allow passing options to lint rules indeno.jsondenoland/deno#30295 to make this possible perhaps in the futurePotential future rules
fresh/route-exports: Lint module exports ofroutes/*configforRouteConfig)handlers,default export,config, etcfresh/island-props: Lint values that can be serialized correctly (may not work without type info)Closes #2950