Code style and linting 📝
⚠️

Some sections are still drafts and marked with a 📝 symbol. Feel free to contribute 🎉.

  • - add Prettier rules explanation
  • - check intro paragraph if the order of context makes sense

Code style and linting

For enforcing code style and utilizing static code analyzing we use ESLint along with a bunch of rulesets. The most noteworthy ruleset is the Airbnb JavaScript Style Guide (opens in a new tab).

We chose this approach because it provides strict but conventional rules. You can always execute the commands pnpm format to apply the Prettier formatting settings for all project files inside the src-directory, or pnpm lint to lint all projects files inside the src-directory based on the ESLint configuration.

We modified some rules to fit our code style. By default, ESLint will display an error if any rule is not satisfied. We don't work with warnings.

Our Prettier and ESLint configurations are located in own packages that get published to npm. This way we can easily share the configuration between projects and keep them up to date.

"react/react-in-jsx-scope": "off"

This rule automatically imports the react package in our file when we use JSX.

"react/jsx-props-no-spreading": "off"

Allow spreading props into components.

"react/require-default-props": "off"

Disable the requirement of default props for components.

"react/jsx-no-bind"

["error", { "allowFunctions": true, "allowArrowFunctions": true }]

Allow passing function references (expressions and declarations) as callbacks to component props.

"simple-import-sort/imports": "error"

To keep our import order consistent we chose to let it auto-sort by this ESLint plugin.

"simple-import-sort/exports": "error"

To keep our export order consistent we chose to let it auto-sort by this ESLint plugin.

"prettier/prettier": "error"

If any rule from the .prettierrc.json is not met, throw an error.

"import/extensions"

[
  2,
  "ignorePackages",
  {
    "": "never",
    "js": "never",
    "jsx": "never",
    "ts": "never",
    "tsx": "never"
  }
]

Allow omitting file extensions when importing either a .js, .jsx, .ts or .tsx file.

"import/no-extraneous-dependencies"

[
  "error",
  {
    "devDependencies": [
      "**/*.test.ts",
      "**/*.test.tsx",
      "**/*.config.js",
      "**/*.config.ts",
      "./scripts/sync-versions.ts",
      "./scripts/seed-db.ts"
    ]
  }
]

Forbid the import of external modules that are not declared in the package.json's dependencies, devDependencies, optionalDependencies, peerDependencies, or bundledDependencies.

"import/prefer-default-export": "off"

Do not prefer default export.

"@nrwl/nx/enforce-module-boundaries"

[
  "error",
  {
    "allow": [],
    "depConstraints": [
      {
        "sourceTag": "scope:app",
        "onlyDependOnLibsWithTags": ["scope:app", "scope:lib", "scope:types"]
      },
      {
        "sourceTag": "scope:lib",
        "onlyDependOnLibsWithTags": ["scope:lib", "scope:types"]
      },
      {
        "sourceTag": "scope:types",
        "onlyDependOnLibsWithTags": ["scope:types"]
      }
    ]
  }
]

Here we set contraints which package can import other packages inside the packages folder. For example, it does not make sense to import anything from app in lib but vice versa.

"@typescript-eslint/explicit-function-return-type"

[
  "error",
  {
    "allowExpressions": true
  }
]

Always pass the return type of a function declaration. As we follow the rule to prefer function declarations over expressions for 'standalone' functions (not as callback) it makes sense to enforce the rule only for function declarations.

"consistent-return": "off"

We disabled the rule due to the fact that we don't want to return undefined in every function explicitly.