deno_lint icon indicating copy to clipboard operation
deno_lint copied to clipboard

Roadmap

Open bartlomieju opened this issue 4 years ago ā€¢ 33 comments

Opening this issue for tracking purposes as well as to better communicate what can be expected of deno_lint in the near future.

Here are the issues that current development focuses on (in the order it must be implemented):

  • [x] Scopes analysis #160 - requirement for any "more advanced" rule
  • [x] ESLint recommended rule set #48
  • [x] typescript-eslint recommended rule set #86

Next:

  • [x] better rule description and diagnostics #162 #159
  • [x] basic configuration - need ability to enable/disable rules for project (https://github.com/denoland/deno/pull/11776, https://github.com/denoland/deno/issues/11686)
  • [ ] plugin support #175 - mechanism for providing new rule sets

Future:

  • [x] documentation website
  • [x] use deno_lint from Node project #169
  • [ ] autofix

bartlomieju avatar Jun 18 '20 09:06 bartlomieju

Update: recommended set of rules from ESLint and typescript-eslint have been implemented.

We can now proceed to working towards better diagnostics and suggestions for lint rules as well as tentatively working on rudimentary configuration.

bartlomieju avatar Sep 15 '20 04:09 bartlomieju

I dont think the development team should use issues for tracking reasons, there is projects and readme or other markdown files or such that should be used instead in my opinion.

4ldas avatar Nov 21 '20 11:11 4ldas

I'm pretty ignorant on the topic, but would you be able to use deno linter in VSCode for nodejs/webpack projects? :) I tried to look up the answer and so far it looks like it would only work with this plugin and only for deno project.

JLarky avatar Jan 12 '21 05:01 JLarky

@JLarky As far as I know, there's no extension that makes it possible for deno_lint to be integrated into VSCode for Node projects. But I would say that technically it could be realized.

magurotuna avatar Jan 12 '21 10:01 magurotuna

Creator of @typescript-eslint here šŸ‘‹

I stumbled upon this project via a tweet.

Iā€™m just curious, were any experiments undertaken to try and ingest rules as they exist today (in TS) but execute them in rust?

ie replace the ESLint libraries but keep the existing low barrier to entry authoring experience (and 10000s of hours of already invested dev time in existing rules and plugins).

JamesHenry avatar Feb 11 '21 11:02 JamesHenry

Hey @JamesHenry, thanks for dropping by!

Iā€™m just curious, were any experiments undertaken to try and ingest rules as they exist today (in TS) but execute them in rust?

I'm not sure I understand the question, but let me try to answer anyway. Initially, before the inception of this project we explored the idea of using eslint directly by running it in Deno, however we were unsuccessful in producing something a'la browser build (nor did we find such build, let me know if it exists). From my understanding typescript-eslint is a plugin to eslint that additionally leverages TSC to be able to operate on TS's types (for rules such as no-floating-promises).

Providing similar functionality in Rust would require to have implementation of TSC in Rust, which currently does not exist (although I know @kdy1 is working on it).

We also explored idea of AST parsing in Rust using swc and converting it to a eslint compatible AST. This approach is feasible, however it circles back to the problem of not having browser build of eslint.

deno_lint hasn't received a lot of attention in the last couple months because of major works in deno repo, but we still want to develop it further and I'm more than happy to discuss pooling efforts.

bartlomieju avatar Feb 11 '21 12:02 bartlomieju

Yeah it was a genuinely open question - I haven't thought about it in any detail and I also don't know that much about rust or deno :)

I do know of interesting experiments involving mixing JS tooling with rust and was genuinely just curious if there are ways to achieve the best of both worlds for linting too.

So yeah nothing more from my side on this but I'll keep thinking about it - I have a good reason to dig into rust more at work now so hopefully that will inform my thinking as well.

JamesHenry avatar Feb 11 '21 13:02 JamesHenry

Ive juggled with the idea of reusing js rules for a project i am making too and i eventually reached a conclusion of "its too hard and limits things too much" for the following reasons:

  • Most users don't use "esoteric" rules from random plugins beyond popular ones like vue, react, import, and typescript, which i believe should be supported natively by the linter.
  • It limits performance optimizations way too much. Js is single threaded, having to spawn an entirely new vm and its friends for every file you want to lint on a separate thread incurs too much of a memory and performance loss to make it viable.
  • It's not good to rely on the stability of one project from a project in a completely different language with different opinions and an entirely different runtime altogether.
  • It limits further prospects for a different type checker.
  • It forces you to conform to an API you have no control over without being able to change it because of stability concerns in eslint.
  • Js' dynamic nature limits semantic understanding of rules, for example, you can provide a typed json schema for the config if you know what the rule expects for options. This is incredibly easy in rust using typetag + serde.

RDambrosio016 avatar Feb 11 '21 16:02 RDambrosio016

Also needed is the ability to define a global set of rules, not just per project. Per project rules should override (fully replace) the global rule set. Per file excludes (using // deno-lint-ignore-file ...) add to the the project excludes.

A possible nice enhancement would be to add // deno-lint-include-file to add to the project includes. And if done, // deno-lint-ignore-file should be deprecated for // deno-lint-exclude-file.

l-cornelius-dol avatar Jun 17 '21 21:06 l-cornelius-dol

Lots of great things happening around this project and it's great to see. I wanted to stop in here and very gently add some feedback into the pool. Since our entire team is coming to Deno from very deep Node experience, and years of experience with ESLint+Prettier, the bar the org is using for whether or not to adopt deno_lint is ESLint; the configurability and ability of ESLint. The closer deno_lint can get to that, I think the easier a switch to it will become for a lot of folks. (We like that deno_lint is opinionated, similar to how Go does things, but the ability to fine tune is something we're all accustomed to)

shellscape avatar Aug 22 '21 22:08 shellscape

Lots of great things happening around this project and it's great to see. I wanted to stop in here and very gently add some feedback into the pool. Since our entire team is coming to Deno from very deep Node experience, and years of experience with ESLint+Prettier, the bar the org is using for whether or not to adopt deno_lint is ESLint; the configurability and ability of ESLint. The closer deno_lint can get to that, I think the easier a switch to it will become for a lot of folks. (We like that deno_lint is opinionated, similar to how Go does things, but the ability to fine tune is something we're all accustomed to)

Thanks for feedback, could you give some more concrete examples of what you want to fine tune?

bartlomieju avatar Aug 23 '21 10:08 bartlomieju

there just doesn't seem to be enough optional rules (from what i can find) effectively replace eslint fully.

some example we're using and quite love, based on airbnb-base w/ eslint:

  • quotes
  • no-useless-concat
  • max-len

i'm trying to migrate [a lot] of code from node to deno (project w/ 30,000+ lines JS) and trying to make lines be node/eslint or deno agnostic with line-by-line comments like: /* eslint-disable-next-line no-empty */ // deno-lint-ignore no-empty

which works nicely. but i'm finding there are many rules we use/rely on w/ our team that dont seem to have deno complements (again, best i can tell). The above was just a few of them.

traceypooh avatar Sep 22 '21 22:09 traceypooh

@traceypooh thanks for the feedback. I'm interested in helping you out with the migration, could you please open a new issue listing which rules you use that are missing so we could evaluate and look into implementing them?

bartlomieju avatar Sep 22 '21 22:09 bartlomieju

thanks @bartlomieju

so keeping in mind these are just from one-off lines, where doing the trick like: /* eslint-disable-next-line no-empty */ // deno-lint-ignore no-empty

caused them to get flagged by deno lint as an unknown rule, etc. (So point being, there could be some other rules that, say, the airbnb-base has that deno lint doesnt have... yet! :) )

guard-for-in
import/no-extraneous-dependencies
import/no-named-as-default
import/no-named-as-default-member
import/no-unresolved
import/prefer-default-export
max-len
new-cap
no-alert
no-cond-assign
no-console
no-continue
no-multi-assign
no-nested-ternary
no-param-reassign
no-plusplus
no-return-assign
no-return-await
no-shadow
no-tabs
no-underscore-dangle
no-use-before-define
no-unused-expressions
no-useless-concat
no-useless-escape
prefer-destructuring
prefer-rest-params
quotes

traceypooh avatar Sep 22 '21 23:09 traceypooh

Is autofix near future or distant future?

chasm avatar Jan 15 '22 01:01 chasm

Is autofix near future or distant future?

At this point in time, there are no plans for when "autofix" feature could be delivered (or if it will be delivered at all).

bartlomieju avatar Jan 15 '22 13:01 bartlomieju

I'd encourage you all to at least begin planning, talking about it. If the recommendation is going to be to use the platform/builtins and not a litany of secondary community tooling, this is a must-have.

shellscape avatar Jan 15 '22 13:01 shellscape

Thanks for suggestion @shellscape but there's a lot of projects planned for Q1 and Q2 in Deno and we don't have bandwidth to squeeze autofix there, especially since we're planning to provide ESLint compatbility.

bartlomieju avatar Jan 15 '22 13:01 bartlomieju

Doesn't ESLint contain --fix support? Or is autofix talking about something else?

jespertheend avatar Jan 15 '22 13:01 jespertheend

Doesn't ESLint contain --fix support? Or is autofix talking about something else?

It does, but I'm talking about compatibility with existing ESLint plugins.

bartlomieju avatar Jan 15 '22 13:01 bartlomieju

@bartlomieju Thanks for the work on this project šŸš€ . We're looking at replacing ESLint/TypeScript ESLint with deno lint, mainly due to the first-party TypeScript support and performance benefits, along with less configuration to maintain.

Did you have an updated Roadmap for 2023? I know there was talk about ESLint compatibility. Just interested in the direction this project is taking.

teriu avatar Feb 16 '23 21:02 teriu

Hey @teriu. We are still discussing internally whether we should continue to work on improvements to deno_lint like custom plugin system (that wouldn't be compatible with ESLint's plugin system) or should we instead embed eslint (and probably typescript-eslint) and work on performance improvements to make it faster (we are in contact with ESLint maintainers and looking for ways how Deno team can help ESLint team, see https://github.com/bartlomieju/eslint_binary for some experimentation on that front).

That said, currently we have limited bandwidth to work on deno_lint and we plan to revisit this topic at a later date (think Q2/Q3).

It would be helpful if folks could leave feedback here with information what are your expectations for improvements and use cases.

bartlomieju avatar Feb 17 '23 12:02 bartlomieju

I believe I've already mentioned this before. But if the Deno team does decide to improve deno lint over embedding eslint, then support for JavaScript/TypeScript plugins would be a requirement for me to start using it. Otherwise I'd likely keep using ESLint, because I don't see myself writing ffi/rust plugins for small rules I want to add.

That said I'd prefer the ESLint embedding, I'm already using a lot of the built in rules as well as eslint-plugin-jsdoc for both linting and formatting. Because deno fmt is a bit too opinionated for my liking :)

jespertheend avatar Feb 17 '23 12:02 jespertheend

because I don't see myself writing ffi/rust plugins for small rules I want to add

The plugins would have a JavaScript/TypeScript API

bartlomieju avatar Feb 17 '23 12:02 bartlomieju

gentle reminder that deno still fails to run eslint: https://github.com/denoland/deno/issues/17448 :innocent:

toxeus avatar Feb 17 '23 13:02 toxeus

@bartlomieju Interesting. I've been reading through the proposed ESLint rewrite on the Github Issue. It's an interesting thread, although I'm not sure what the end result will look like for a codebase with predominantly TypeScript code. In our current codebase, we run the following ESLint configuration: airbnb-base + airbnb-typescript/base, along with typescript-eslint/recommended + type checking, unicorn/recommended and prettier/recommended (formatting related).

The state of play seems to be (and correct me if I'm wrong here šŸ˜€):

  • ESLint + TypeScript ESLint. ESLint doesn't support TypeScript parsing/rules out of the box, so in order to use Lint rules that require Type checking, you need to use a combination of ESLint & TypeScript ESLint. Quite a bit of complexity, and the current solution isn't necessarily performant, especially in a TypeScript monorepo (project references).
  • Rome. Written in Rust. Unfortunately, looks like funding is an issue, and development has slowed considerably (?). An "all-in-one" solution, rather than just purely handling linting/formatting. Native TypeScript support, impressive performance benchmarks.
  • deno lint. Written in Rust. Native TypeScript support, impressive performance benchmarks.

The main issue with Rome & deno lint seems to stem from limited compatibility with existing ESLint rule sets. Having a way to create certain rules using a JavaScript/TypeScript API might suffice, instead of trying to support all existing eslint- plugins. The performance advantages of using deno lint over other tools would make it worth the investment in plugins/rules. There is likely some rules which just don't need to exist anymore (ESLint is ~10 years old now), and TypeScript contains some checks (strict mode) that we use in place of Lint rules.

teriu avatar Feb 19 '23 21:02 teriu

I would happily switch to deno-lint if it supported a plugin system, preferably one that maintains the most performance while making plugins writable in TS/JS. Eslint plugin compatibility isn't a concern for me, and it seems like it would go in the opposite direction of performance (AST conversions required) and in general cause more headaches than it's worth. Ability to create auto-fix rules certainly seems like it should be a higher priority than Eslint compat. I suspect even if Eslint compat was available users would be unlikely to switch anyway if there was no support for auto fix.

robbiespeed avatar Feb 26 '23 18:02 robbiespeed

counterpoint: we dont particularly care about auto fix (though it's nice. much lower prio).

I switched my team over to npm compatibility mode.

I'm using velociraptor at top of huge project, with a scripts.yml that has these parts:

  lint:
    - vr eslint-setup
    - vr eslint
  eslint-setup:
    - deno cache --unstable --node-modules-dir npm:[email protected]         && echo>/dev/null
    - deno cache --unstable --node-modules-dir npm:eslint-plugin-compat@^3.3.0              && echo>/dev/null
    - deno cache --unstable --node-modules-dir npm:eslint-plugin-import@^2.22.1             && echo>/dev/null
    - deno cache --unstable --node-modules-dir npm:eslint-plugin-no-floating-promise@^1.0.2 && echo>/dev/null
  eslint:
    # We want to call either `eslint components tests` or `eslint [arg1] <arg2> ..`
    - echo components tests >| .testarg && echo >> .testarg
    # Next, two unusual things going on in..
    # Unfortunately right now running deno like this always exits 0, regardless.
    # Lint warnings/errors write to stdout -- so capture that to a file and check after if empty.
    # Wrap that with `script` command so the invoker will still see the useful colors in the output.
    - script -q .testout sh -c "deno run -A --unstable --node-modules-dir  npm:eslint@^7.32.0
        $(egrep . .testarg |tail -1) 2>/dev/null" &&  echo>/dev/null
    - rm .testarg; echo>/dev/null
    # .testout should be empty -- else a lint failure (remove any docker runtime start/stop logs)
    - egrep -v '^Script (started|done) on ' .testout |tr -d '\r' |egrep . |sort -o .testout && echo>/dev/null
    - test ! -s .testout  &&  echo>/dev/null
    - rm -f .testout && echo>/dev/null

There's obviously some limitations and workarounds. And you have to setup each plugin you are using w/ eslint. It's not ideal, but it was literally the last thing we needed before totally dropping node/npm otherwise for deno.

(Here's our .eslintrc.json in case helpf, too)

{
  // "used by `scripts.yml` for `vr lint`"

  "extends": "airbnb-base",
  "root": true,
  "parserOptions": {
    "sourceType": "module",
    // allow `??`
    "ecmaVersion": 2020
  },
  "plugins": [
    "no-floating-promise",
    "compat"
  ],
  "env": {
    "jest": true,
    "browser": true
  },
  "settings": {
    // Mark these as polyfilled - since we include on every page, @see Nav.inc and search for
    //   https://polyfill.archive.org/
    // We do this so lint testing won't squawk about Promise not being supported in IE 11.
    // Keep this list sync-ed with the URL mentioned in Nav.inc.
    "polyfills": [
      "Array.from",
      "Promise",
      "Object.assign",
      "Object.entries",
      "Object.keys",
      "Object.values",
      "window.customElements"
    ]
  },
  "rules": {
    // this just showed up as necessary w/ `vr lint` on Jun11, 2020
    "no-multiple-empty-lines": [2, {"max": 2}],
    "no-unused-vars": ["error", { "args": "none" }],

    // this just showed up w/ babel + eslint updates to latest versions Sep1,2019
    "operator-linebreak": "off",
    "import/no-cycle": "off", // it's ok to have cycles with ES Modules and import

    // "make sure all used JS compatible with 90%+ of currently used browsers a la caniuse.com"
    "compat/compat": "error",

    // "allow JSX in .js files"
    "react/jsx-filename-extension": "off",

    // "allow snakecase var names if dev desires"
    "camelcase": "off",

    // "allow: x  = 3 (for example lining up multiple lines by column)"
    "no-multi-spaces": "off",

    // "author discretion when using braces around one-liners or same-liners"
    "curly": "off",

    // "allow ++ or -- at the end fo a for() loop (all other uses are banned per airbnb!)"
    "no-plusplus": ["error", {"allowForLoopAfterthoughts": true}],

    // "allow JSON/map definitions to column-align values when multiline"
    "key-spacing": ["error", {"mode": "minimum"}],

    // "allow for (x of array)  and  for (key in obj)  and   for (val in array)"
    "no-restricted-syntax": ["error", "LabeledStatement", "WithStatement"],

    "no-restricted-globals": ["off", "location"],

    "nonblock-statement-body-position": "off",

    "indent": ["error", 2, {"CallExpression": {"arguments": "first"},
                            "ArrayExpression": "first",
                            "FunctionDeclaration": {"parameters": "first"},
                            "FunctionExpression": {"body": 1, "parameters": 2} }],

    "import/no-extraneous-dependencies": ["error", {
      "devDependencies": ["**/webpack.*.js", "**/*.js"]
    }],

    // "Turning these off since they throw errors for devDependencies"
    "import/no-unresolved": ["off"],
    "import/extensions": ["off"],

    "import/prefer-default-export": "off"
  },
  "ignorePatterns": [
    // stopgap until react is gone:
    "/components/ia-bookreader/iaux.min.js",
    // symlink to npm pkg:
    "/components/bookreader/",
    // 3rd party code:
    "/components/npm/",
    "/components/editxml/jquery.json-ui.js",
    "/components/uploader/jquery.sprintf.js",
    "/components/uploader/jquery.wysiwyg.js",
    "/components/uploader/wysiwyg.link.js"
  ]
}

traceypooh avatar Feb 26 '23 19:02 traceypooh

BTW, here's the few issues I've still got, distilled out to a clean/minimal git repo & setup:

https://github.com/traceypooh/eslint-deno

  • import/no-unresolved always unhappy
  • TypeError: cb is not a function (12 times here, more with more files)
  • always exits 0 status

I know at one point one of the main maintainers of eslint was interested in helping if it made sense, towards using with deno. I wonder if they could help with any of these seemingly last issues?

traceypooh avatar Mar 07 '23 08:03 traceypooh

@traceypooh this seems unrelated to deno lint itself since you're still using eslint. An issue in Deno's main repo is probably a better place for compatibility issues with npm packages like eslint.

robbiespeed avatar Mar 07 '23 12:03 robbiespeed