Skip to content

Instantly share code, notes, and snippets.

@bahtou
Last active July 14, 2019 19:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bahtou/73abeae1a28d5759362d6f3ee8f59789 to your computer and use it in GitHub Desktop.
Save bahtou/73abeae1a28d5759362d6f3ee8f59789 to your computer and use it in GitHub Desktop.
eslint-prettier-summary

Prettier - An opinionated code formatter

Linters have two categories of rules:

Formatting rules: eg: max-len, no-mixed-spaces-and-tabs, keyword-spacing, comma-style... Prettier alleviates the need for this whole category of rules! Prettier is going to reprint the entire program from scratch in a consistent way, so it's not possible for the programmer to make a mistake there anymore :)

Code-quality rules: eg no-unused-vars, no-extra-bind, no-implicit-globals, prefer-promise-reject-errors... Prettier does nothing to help with those kind of rules. They are also the most important ones provided by linters as they are likely to catch real bugs with your code!

{
  "endOfLine": "lf"
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "none",
  "useTabs": false
}

Example: .prettierrc

{
  "arrowParens": "avoid",
  "bracketSpacing": false,
  "endOfLine": "lf",
  "jsxBracketSameLine": false,
  "jsxSingleQuote": false,
  "printWidth": 120,
  "quoteProps": "as-needed",
  "rangeStart": 0,
  "rangeEnd": "Infinity",
  "semi": false,
  "singleQuote": false,
  "tabWidth": 4,
  "trailingComma": "none",
  "useTabs": false
}

useful for CI

Prettier's printer is a fork of recast's printer with its algorithm replaced by the one described by Wadler in "A prettier printer". There still may be leftover code from recast that needs to be cleaned up.

The basic idea is that the printer takes an AST and returns an intermediate representation of the output, and the printer uses that to generate a string. The advantage is that the printer can "measure" the IR and see if the output is going to fit on a line, and break if not.

This means that most of the logic of printing an AST involves generating an abstract representation of the output involving certain commands. For example, concat(["(", line, arg, line ")"]) would represent a concatenation of opening parens, an argument, and closing parens. But if that doesn't fit on one line, the printer can break where line is specified.

More (rough) details can be found in commands.md.

Test

prettier --config ./.prettierrc --write

prettier --check

Eslint - The pluggable linting utility for JavaScript and JSX

ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs. In many ways, it is similar to JSLint and JSHint with a few exceptions:

  • ESLint uses Espree for JavaScript parsing.
  • ESLint uses an AST to evaluate patterns in code.
  • ESLint is completely pluggable, every single rule is a plugin and you can add more at runtime.

More:

Code linting is a type of static analysis that is frequently used to find problematic patterns or code that doesn’t adhere to certain style guidelines.

The primary reason ESLint was created was to allow developers to create their own linting rules.

While ESLint will ship with some built-in rules to make it useful from the start, you’ll be able to dynamically load rules at any point in time.

Everything is pluggable:

  • Rule API is used both by bundled and custom rules
  • Formatter API is used both by bundled and custom formatters
  • Additional rules and formatters can be specified at runtime
  • Rules and formatters don’t have to be bundled to be used

Every rule:

  • Is standalone
  • Can be turned off or on (nothing can be deemed “too important to turn off”)
  • Can be set to a warning or error individually

Additionally:

  • Rules are “agenda free” - ESLint does not promote any particular coding style
  • Any bundled rules are generalizable

The following are equivalent Prettier rules. Some rules will auto-format using eslint —fix, while other rules are left un-formatted or not formatted the way Prettier formats.

"rules": {
  "arrow-parens": [2, "as-needed"],
  "comma-dangle": [2, "never"],
  "indent": ["error", 2],
  "jsx-quotes": [0, "prefer-double"],
  "linebreak-style": ["error","unix"],
  "max-len": [2, { "code": 80 }],
  "no-tabs": 2,
  "object-curly-spacing": [2, "always"],
  "quotes": ["error", "single"],
  "quote-props": [2, "as-needed"],
  "semi": ["error", "always"]
}

Example: .eslintrc

{
  "env": {
    "browser": true,
    "commonjs": true,
    "es6": true
  },
  "extends": "eslint:recommended",
  "globals": {
    "Atomics": "readonly",
    "SharedArrayBuffer": "readonly"
  },
  "parserOptions": {
    "ecmaVersion": 2018
  },
  "rules": {
    "comma-dangle": [2, "never"],
    "indent": ["error", 2],
    "linebreak-style": ["error","unix"],
    "no-tabs": 2,
    "quotes": ["error", "single"],
    "semi": ["error", "always"]
  }
}
  • eslint --fix
  • eslint --fix-dry-run
  • eslint --fix-type

Test

eslint --config ./.eslintrc <path-to-file>

eslint --config ./.eslintrc <path-to-file> --fix

A sharable configuration is an npm package that exports a configuration object. Make sure the package has been installed to a directory where ESLint can require it. The extends property value can omit the eslint-config- prefix of the package name.

Example extends:

{
  "extends": [
    "eslint:recommended",
    "plugin:prettier/recommended",
    "eslint-config-prettier/react",
    "prettier/react"
  ]
}

Configuration.plugins

A plugin is an npm package that usually exports rules. Plugins can expose additional rules for use in ESLint.

Plugins can be bundled with configurations. This can be useful when you want to provide not just code style, but also some custom rules to support it.

Plugins can have processors that tell ESLint how to process files other than JavaScript.

Configuration will not enable any of the plugin’s rules by default, and instead should be treated as a standalone config

"extends": [ "eslint:recommended" ]

The above extended configuration represents a list of opinionated recommended rules by Eslint. Configurations can be created at will & shared in the extends property.

Eslint + Prettier

eslint-config-prettier

{
  "extends": [
    "eslint:recommended", 
    "prettier"
  ]
}

The above configuration turns off (overwrites) all rules that are unnecessary or might conflict with Prettier. As you write code, Eslint will no longer show 'squiggly' lines to highlight stylistic and/or formatting mistakes. Also, the above configuration will not show you mistakes in your code that do not conform to Prettier.

eslint-plugin-prettier

Use this plugin to highlight mistakes in your code that do violate Prettier rules. NB: Prettier must be installed.

{
  "extends": [
    "eslint:recommended", 
    "plugin:prettier/recommended"
  ]
}

The above is equivalent to:

{
  "extends": [
    "eslint:recommended"
  ],
  "plugins": [
    "prettier"
  ],
  "rules": {
    "prettier/prettier": "error"
  }
}

See this: https://eslint.org/docs/user-guide/configuring#using-the-configuration-from-a-plugin

When add the plugin your code should now highlight mistakes.

To target particular Prettier rules:

{
  "rules": {
    "prettier/prettier": [
      "error",
      {
        "tabWidth": 4,
        "printWidth": 120,
        "singleQuote": true
      }
    ]
  }
}

Eslint vs Prettier formatting

the idea here was to present forttming differences.

i stopped here because it's really opinionated. And Prettier is already opinionated.

Custom Eslint Rules

simple examples:

module.exports = {
  rules: {
    "camel_case": require('./camel_case'),
    "no-commented-out-code": require('./no-commented-out-code')
}
module.exports = function (context) {
  'use strict';

  var comments = context.getAllComments();

  comments.filter(function (comment) {
    return isValidCode(comment.value.trim());
  }).forEach(function (commentedCode) {
    var code = cut(commentedCode.value.trim());
    var lines = commentedCode.loc.end.line - commentedCode.loc.start.line + 1;
    var linesMsg = '(' + lines + ' line' + (lines === 1 ? '' : 's') + ')';
    context.report({
      loc: commentedCode.loc
    }, 'commented out code ' + quote(code) + ' ' + linesMsg);
  });

  return {};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment