Skip to content

Frontend code style

Code style tools

Frontend code style is enforced by these tools:

  • oxlint: JavaScript and TypeScript linting, including the <script> block of .vue files.
  • ESLint: Vue template linting (.vue files only).
  • oxfmt: Code formatting of .js, .ts and .vue files. It replaced Prettier.
  • Stylelint: CSS and SCSS linting.
  • vue-tsc: TypeScript type checking in Vue.js projects.

Linting

  • .oxlintrc.json: oxlint rules for .js, .ts and .vue <script>: the @eslint/js and typescript-eslint recommended rules, the project limits (complexity, max-depth, max-params, max-lines, no-console, ...) and the project rules from easy_eslint/oxlint-plugin.mjs.
  • eslint.config.js: ESLint rules for .vue files: eslint-plugin-vue rules and @typescript-eslint/no-unused-vars (oxlint cannot see variables used only in the template).

The same configuration is used by CI and by the IDE. The dev server (bundle exec vite dev) also runs oxlint on app/frontend/src at start and on each hot update.

Run the linters with:

yarn lint      # oxlint, then ESLint on .vue files
yarn lint:fix  # the same with autofix

Errors fail the CI yarn lint job; warnings do not.

Which tool reports which rule

No rule is reported by both tools.

Rules Files Tool
Core and @typescript-eslint/* rules, project limits .js, .ts, .vue <script> oxlint
easy-rules/* .js, .ts, .vue <script> oxlint
vue/* .vue ESLint
@typescript-eslint/no-unused-vars .vue ESLint
no-unused-vars .js, .ts oxlint

Project rules (easy-rules/<rule>):

  • easy-rules/camelcase: ESLint camelcase with properties: "never", so Rails snake_case keys are allowed.
  • easy-rules/naming-convention: @typescript-eslint/naming-convention. Variables are camelCase, const may be UPPER_CASE; *.stories.ts also allows PascalCase; files in constants/ directories require UPPER_CASE const names (error).
  • easy-rules/no-gql-function-call: gql must be a tagged template (gql`...`), not a function call.
  • easy-rules/test-description-capitalization: it and describe descriptions in *.spec.{js,ts} start with a capital letter.

Disable comments

eslint-disable comments work in both tools:

// eslint-disable-next-line easy-rules/naming-convention
// eslint-disable-next-line complexity

Project rules are referenced as easy-rules/<rule>, not camelcase or @typescript-eslint/naming-convention. Unused disable comments in .vue files are not reported.

Formatting

  • .oxfmtrc.json: formatting rules (print width 120, double quotes, semicolons, one attribute per line, ...). Stylesheets are not formatted.

Run oxfmt with:

yarn fmt        # format files
yarn fmt:check  # list files that are not formatted

yarn lint ends with yarn fmt:check, so unformatted files fail the lint gate locally and in CI. yarn fmt or yarn lint:fix fixes them. yarn codegen:graphql formats generated files with oxfmt --write.

Stylelint configuration

  • .stylelintrc.js: linting rules for stylesheets.
  • .stylelintignore: excluded files. Temporary files in app/frontend/src/design_system/**/stylesheets/temp/ and the bundled jQuery UI CSS are ignored.

yarn stylelint checks only app/frontend/src/design_system/**/*.{css,scss}. Run it with:

yarn stylelint

vue-tsc configuration

  • tsconfig.json: global TypeScript settings.
  • tsconfig.pipeline.json: scope of the TypeScript check.
  • tsc.ignored_files.json: files with historical diagnostics that the check tolerates.

yarn tsc runs tsc.script.js, which runs vue-tsc against tsconfig.pipeline.json. A diagnostic is tolerated only when its primary file is listed in tsc.ignored_files.json. yarn tsc:pipeline is an alias.

Run the TypeScript check with:

yarn tsc

Do not add new entries to tsc.ignored_files.json.