deno_lint
deno_lint copied to clipboard
Interoperate with Existing ESLint Rules and Configs
@axetroy If you say there are too many options, why build out a deno lint
at all? That's only adding more options. We already have a linting tool for linting JavaScript and TypeScript and it is called eslint
. I don't see a value in duplicating all that work again.
Unless a developer only writes backend code, they will still need to touch eslint
.
If a parallel lint tool must be built (are there really not better ways to improve deno?) then it MUST be able to consume existing eslint rules. Otherwise people will waste their time reinventing the wheel, writing duplicate rules for deno and frontend code rather than application code.
Instead deno lint
would be more useful as something like golangci-lint where it aggregates and calls other already written lint rules and linters. It provides a "default lint config" (via url import) with sane default but still extendable.
Originally posted by @brandonkal in https://github.com/denoland/deno/issues/1880#issuecomment-601616251
Emphasis added.
What if deno lint
worked for frontend code?
My opinion is that linter should be fewer configurations (even 0)
The most popular eslint rules should be adopted, but no options are provided.
In the short term, this is very bad, because everyone's writing habits are different
But in the long term, it unifies the code style
As I think about deno fmt
We should not add some flags to set the code style, eg. whether use trailing commas, whether to use spaces or tabs. I think this is very bad.
People don’t have to discuss which one is the best style
Code style is only limited by your project and your personal writing style as you said. But having no option to thinker with that options only removes value to an otherwise highly (though opinionated by default) customizable environment
As has been discussed before, Deno doesn't do magic, doesn't pick default files and prefers to allow customization even though its defaults will be highly influenced by products such as ESLint and Prettier
I would suggest having the linting setup include only common problems only; perhaps extending eslint:recommended
(which is common problems only), something like:
{
"parserOptions": {
"ecmaVersion": X
},
"extends": [
"eslint:recommended"
]
}
Discussed offline with @magurotuna, we agree this is highly desirable and will look into what are the prerequisites.
Deno's linter doesn't provide alternatives for all the Eslint rules we've historically used, which is a deal-breaker for us switching to Deno.
We tried adding workarounds to Eslint to let it run in Deno files (see https://github.com/typescript-eslint/typescript-eslint/issues/5921), but it's overly complicated and kind-of outside the scope of Eslint. IMO it would really behoove Deno Lint to natively support Eslint rules, rather than Deno Lint trying to come up with its own replacements for Eslint rules.
AFAIK there are a few things that prevent Eslint from working with Deno:
Eslint can't resolve .ts
extensions
That's easy to work around:
// ts-resolver.js
const ts = require(`typescript`);
const tsExtension = /\.ts$/;
module.exports = {
resolveModuleNames: (
moduleNames,
containingFile,
reusedNames,
redirectedReference,
options
) => moduleNames.map((moduleName) =>
ts.resolveModuleName(
moduleName.replace(tsExtension, ``),
containingFile,
options,
ts.sys
).resolvedModule
),
};
// .eslintrc.js
module.exports = {
env: {
node: true,
},
overrides: [
{
files: [`*.ts`],
parser: `@typescript-eslint/parser`,
parserOptions: {
moduleResolver: __dirname + `/ts-resolver.js`,
},
},
],
};
Eslint can't resolve Deno's remote dependencies
For example:
import { serve } from 'https://deno.land/[email protected]/http/server.ts';
The eslint-import-resolver-deno
shows how to work around this, and it's not complicated. The package can also just be used wholesale:
const ts = require(`typescript`);
const denoResolver = require(`eslint-import-resolver-deno`);
const tsExtension = /\.ts$/;
module.exports = {
resolveModuleNames: (
moduleNames,
containingFile,
reusedNames,
redirectedReference,
options
) => moduleNames.map((moduleName) => {
if (moduleName.startsWith(`http`)) {
const { found, path } = denoResolver.resolve(
moduleName,
containingFile,
{
importMap: __dirname + `/import-map.json`,
}
);
if (found) {
moduleName = path;
}
}
return ts.resolveModuleName(
moduleName.replace(tsExtension, ``),
containingFile,
options,
ts.sys
).resolvedModule;
}),
};
Eslint doesn't "know" about Deno's global types
Despite the above workarounds to the module resolution issues, Eslint interprets anything reliant on a global Deno type as any
.
If Eslint can be configured to know about Deno's global types, then it seems like Eslint could support Deno pretty easily. Maybe this in turn means that Deno Lint could support Eslint pretty easily?
Update: Well, I'm getting there. I have ESlint itself apparently working. But I can't make the VSCode ESlint extension play nice with Deno imports.