Closed8

TypeScript のリンター周りを包括している xojs/xo を調査する

ishiyamaishiyama

リンター、フォーマッターを使用するモチベーションとしては、
コーディングルールを統一することにあり、どのような記述方法が適切か議論することではないと思っている。
tslint の時代から思い返すと eslint prettier × typescript 周りを追いかけていつも疲弊している。
それならばxoを選択して、xoのバージョンだけを気にすることで、その分の時間を開発に回せるのではないかと。

Opinionated but configurable ESLint wrapper with lots of goodies included. Enforces strict and readable code. Never discuss code style on a pull request again! No decision-making. No .eslintrc to manage. It just works!

ishiyamaishiyama

xoは eslint prettier などを内包しており、
ルールも @sindresorhus 氏のものをベースに使用することになる。
それゆえどうしても、Airbnbの Style Guide を使用したい!という人には不向きかもしれない。
逆に、どんなルールでも「良い感じ」にコードが統一されていれば良い、という人にはマッチするツールになりそう。

ishiyamaishiyama

TypeScript, JSX はデフォルトでサポートされているが Vueコンポーネントはデフォルトではサポートされていない。(2022-12-02現在)

また、xo自体のメジャーバージョンはまだリリースされておらず、破壊的な変更が入る可能性は高い。
だが、リンター, フォーマッター周りのコストを削減できるツールとして今後も注目していきたい。

ishiyamaishiyama

実際のプラグラムにxoを導入してみたら、想像していたよりも制限が厳しすぎたり、エディターとの親和性などまだまだ課題が多い感じ。
引き続きwatchしていこうとは思うが、一旦は今まで通り下記で対応することにした。

npm init @eslint/config
npm i prettier eslint-config-prettier -D
# その後、.eslintrc.js と .prettierrc.js に必要な修正を加えていく
.vscode/settings.json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": ["source.organizeImports", "source.fixAll.eslint"],
  "typescript.preferences.importModuleSpecifier": "project-relative"
}
ishiyamaishiyama

node サンプル

package.json
  "scripts": {
    // ... 省略
    "lint": "tsc --noEmit && prettier --check src && eslint --ext .ts src",
    "fix": "prettier -w src && eslint --ext .ts src --fix"
  },
.eslintrc.js
module.exports = {
  env: {
    node: true,
    es2021: true
  },
  extends: ['standard-with-typescript', 'prettier'],
  overrides: [],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    project: 'tsconfig.json'
  },
  rules: {
    '@typescript-eslint/no-misused-promises': 'off'
  }
}
tsconfig.json
{
  "extends": "@tsconfig/node16/tsconfig.json",
  "compilerOptions": {
    "outDir": "./dist"
  },
}
ishiyamaishiyama

React サンプル

package.json
  "scripts": {
    // ... 省略
    "lint": "tsc --noEmit && prettier --check src && eslint --ext .ts,.tsx src",
    "fix": "prettier -w src && eslint --ext .ts src --fix"
  },
.eslintignore
*.d.ts
reportWebVitals.ts
.eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true
  },
  extends: [
    'plugin:react/recommended',
    'plugin:react/jsx-runtime',
    'standard-with-typescript',
    'prettier'
  ],
  overrides: [],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    project: 'tsconfig.json'
  },
  plugins: ['react'],
  settings: {
    react: {
      version: 'detect'
    }
  },
  rules: {
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/no-floating-promises': 'off'
  }
}
tsconfig.json
{
  "extends": "@tsconfig/create-react-app/tsconfig.json",
  "compilerOptions": {
    "outDir": "./dist"
  }
}
このスクラップは2022/12/02にクローズされました