Skip to content

Making standard easier to use #1356

@feross

Description

@feross

The vision of standard is to save you time in three ways:

  1. No configuration
  2. Automatically format code
  3. Catch style issues & programmer errors early

I think we do a really good job on (3), enforcing style and catching errors. We do a pretty good job on (2) as well, thanks to ESLint's --fix functionality.

But we can do way better at Number 1.

We're pretty far away from the vision of "just do this and you're done" for lots of real-world projects.

$ npm install standard
$ standard

In fact our readme promises "no configuration" and then goes on to do a bit too much explanation about packages to install and flags to pass to get standard to work for your particular codebase. And it's not working so well right now.

Here are some very rough ideas that that might improve the situation. Feedback very much welcome!


  • Include babel-eslint by default

    • One less package for Babel users to install
    • If the user is already using Babel, then their .babelrc is recognized and used automatically
    • No noticeable difference for non-Babel users (Note: need to verify if performance is same)
  • Remove --verbose flag and just always include the rule name in the error message

    • I think users almost always want to know the rule name they can google it to learn more

ESList exposes features that we decided to remove/hide for simplicity. But then users sometimes need these features, so we created additional packages to install as an escape hatch to get those features back. I'm not sure that this is actually simpler than just adding a command line flag for these features. So here's a few ideas:

  • Build in snazzy so users can add do standard --report=pretty and get pretty output
  • Build in standard-json so users can do standard --report=json to get JSON output
  • Build in standard-tap so users can do standard --report=tap to get TAP output

ESLint already supports these internally so it feels kind of strange to have to maintain these packages which just parse output and convert it back.

Note: these flags are not allowing arbitrary rules to be added or changed, so they're not the kind of "configuration" that we want to avoid. These are just command line flags that help users accomplish their goals. I can't see teammates bikeshedding about whether to use --pretty or not, and especially not for --json.


  • Allow all non-confusing browser globals Consider allowing use of browser globals #1330

    • Eliminate the need to use a window. prefix or a /* global Blah */ comment
    • Code that uses window. is not usable in a service worker or in Node.js
    • globalThis is not pretty and not widely available yet anyway.
    • Confusing browser variables like top and self will still be treated as undefined by default
  • Build in prettier Adopt prettier for consistent formatting #811

    • Users who want deterministic formatting on every save can just do standard --format.
    • Users who want minimal changes to their code, can continue using standard --fix.
    • Eliminates the need for additional wrapper packages and users to install multiple tools.
  • Lint JavaScript in Markdown files and HTML files by default Lint all JavaScript in markdown files by default #1355

    • All my code examples in README.md files and docs/ folders should be standard, but I never remember to install standard-markdown. We can build this in by default.

The TypeScript experience is completely broken right now. Typescript users need to install an ESLint plugin and configure some rules in order to get standard working. The problem is that you can't configure rules in standard. Indeed, that's the point. So they have to switch to standardx, another escape hatch that we built to handle cases that we don't handle correctly in standard itself.

Users also have to do this to get set up:

npm install @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev

Followed by

standard --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin *.ts

Ugh. This looks like configuration to me. Here's a possible solution:

  • Support Typescript out of the box TypeScript linting works only partially #1283
    • Detect .ts files and apply the necessary minimal rule changes so everything works.
    • Bundle the necessary parser and plugin so it just works.
    • Then typescript users can just do standard

If we support parsing Typescript and we default to the babel-eslint parser, then we can also:

  • Remove the --plugin and --parser flags.
    • No more need for users to understand this whole aspect of ESLint.
    • If you want to use plugins, different parsers, etc. then you should just use ESLint directly.

(An alternative is to just drop support for Typescript entirely if we can't do a good job of it)


Here's an idea that might be going too far, but if it worked would be really cool.

  • Support extensions Extensions proposal (not about making Standard "configurable") #703
    • Users can do e.g. standard --react or standard --vue and get additional rules for their specific framework. There can be a very small list of possible choices, maintained as shareable configs in the @standard org.
    • We can provide helpful warnings and bug catching rules to users of e.g. React, etc. that we currently can't do because these rules would apply to everyone.
    • There is already a concept of an env or an ESLint environment with the --env flag. Maybe this can piggyback on that concept?
    • So users could do e.g standard --env react --env mocha if they want additional rules for React and globals defined for Mocha tests, as one hypothetical example.

If we make all the changes I've proposed here, we'd go from this help page:

Flags:
        --fix       Automatically fix problems
    -v, --verbose   Show rule names for errors (to ignore specific rules)
        --version   Show current version
    -h, --help      Show usage information

Flags (advanced):
        --stdin     Read file text from stdin
        --global    Declare global variable
        --plugin    Use custom eslint plugin
        --env       Use custom eslint environment
        --parser    Use custom js parser (e.g. babel-eslint)

to this:

Flags:
        --fix       Automatically fix problems
        --format    Aggressively format code for consistency
        --version   Show current version
    -h, --help      Show usage information

Flags (advanced):
        --stdin     Read file text from stdin
        --report    Use custom reporter (choose from: pretty, json, tap)
        --global    Declare global variable
        --env       Use custom environment (choose from: react, vue, mocha, etc.)

If I had to summarize the main idea here I'd say it feels like we've let a lot of the complexity of ESLint leak through, and we can do better. Lots of the details of my proposed solutions might not be the best, but I hope this will re-energize us and get us thinking about solutions.

Eager for feedback!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions