Skip to content

Commit

Permalink
Merge pull request #132 from hatena/use-typescript-eslint-config
Browse files Browse the repository at this point in the history
typescript-eslint の config() ユーティリティをラップする形で提供する
  • Loading branch information
susisu authored Sep 4, 2024
2 parents fe9abf9 + b2d9b5d commit 37cdb8a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 36 deletions.
2 changes: 2 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ export default config({
### カスタム設定

ビルダー関数の第二引数には、カスタム設定の配列を与えることができます。プロジェクト固有の設定はここに追加するのがおすすめです。
[typescript-eslint のユーティリティ](https://typescript-eslint.io/packages/typescript-eslint#config)をラップしているため、`extends` が利用できます。

```javascript
import config from '@hatena/eslint-config-hatena/flat';
Expand All @@ -200,6 +201,7 @@ import globals from 'globals';
export default config({}, [
{
files: ['src/**/*.js'],
extends: [somePlugin.recommended],
languageOptions: {
globals: {
...globals.es2021,
Expand Down
69 changes: 33 additions & 36 deletions lib/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ const rules = require('../rules/index.js');
/**
* ESLint の設定を作る
* @param {ConfigOptions} [options] オプション
* @param {readonly import('eslint').Linter.Config[]} [configs] カスタム設定の配列
* @returns {import('eslint').Linter.Config[]} 設定の配列
* @param {readonly import('typescript-eslint').ConfigWithExtends[]} [configs] カスタム設定の配列
* @returns {import('typescript-eslint').Config} 設定の配列
*/
function config(options, configs) {
const tsProject = options?.tsProject ?? true;
Expand All @@ -41,11 +41,11 @@ function config(options, configs) {
const react = options?.react ?? false;
const prettier = options?.prettier ?? true;

return [
return tsEslint.config(
// # Linter 自体の設定
{
plugins: {
'@typescript-eslint': /** @type {import('eslint').ESLint.Plugin} */ (tsEslint.plugin),
'@typescript-eslint': tsEslint.plugin,
// eslint-plugin-import v2.29.1時点ではESLint v9に対応していないため、互換性ユーティリティを通す。
'import': compat.fixupPluginRules(importPlugin),
'react': reactPlugin,
Expand Down Expand Up @@ -82,7 +82,7 @@ function config(options, configs) {
files: ['**/*.{ts,tsx,cts,mts}'],
languageOptions: {
sourceType: 'module',
parser: /** @type {import('eslint').Linter.Parser} */ (tsEslint.parser),
parser: tsEslint.parser,
parserOptions: {
...(tsProjectService ? { projectService: tsProjectService } : tsProject ? { project: tsProject } : {}),
tsconfigRootDir,
Expand All @@ -93,41 +93,38 @@ function config(options, configs) {
},
},
// # ルール設定
...map({ files: ['**/*.{js,jsx,cjs,mjs}', '**/*.{ts,tsx,cts,mts}'] }, [
{ rules: jsPlugin.configs.recommended.rules },
{ rules: importPlugin.configs.recommended.rules },
{ rules: rules.javascript },
...(react
? [
{ rules: reactPlugin.configs.recommended.rules },
{ rules: reactPlugin.configs['jsx-runtime'].rules },
{ rules: reactHooksPlugin.configs.recommended.rules },
{ rules: rules.react },
]
: []),
]),
...map({ files: ['**/*.{ts,tsx,cts,mts}'] }, [
// languageOptions なども含まれるが上で設定しているものと重複するので, ここでは rules のみに絞る
...tsEslint.configs.recommendedTypeChecked.flatMap((config) =>
config.rules ? [{ rules: /** @type {import('eslint').Linter.RulesRecord} */ (config.rules) }] : [],
),
{ rules: importPlugin.configs.typescript.rules },
{ rules: rules.typescript },
]),
{
files: ['**/*.{js,jsx,cjs,mjs}', '**/*.{ts,tsx,cts,mts}'],
extends: [{ rules: jsPlugin.configs.recommended.rules }, { rules: importPlugin.configs.recommended.rules }],
rules: rules.javascript,
},
...(react
? [
{
files: ['**/*.{js,jsx,cjs,mjs}', '**/*.{ts,tsx,cts,mts}'],
extends: [
{ rules: reactPlugin.configs.recommended.rules },
{ rules: reactPlugin.configs['jsx-runtime'].rules },
{ rules: reactHooksPlugin.configs.recommended.rules },
],
rules: rules.react,
},
]
: []),
{
files: ['**/*.{ts,tsx,cts,mts}'],
extends: [
// recommendedTypeChecked には languageOptions なども含まれるが, 上で設定しているものと重複するのでここでは rules のみに絞る
...tsEslint.configs.recommendedTypeChecked.flatMap((config) => (config.rules ? [{ rules: config.rules }] : [])),
{ rules: importPlugin.configs.typescript.rules },
],
rules: rules.typescript,
},
// # カスタム設定
...(configs ?? []),
// # フォーマットに関するルールを無効化
...(prettier ? [{ rules: prettierConfig.rules }] : []),
];
}

/**
* @param {import('eslint').Linter.Config} base
* @param {readonly import('eslint').Linter.Config[]} configs
* @returns {import('eslint').Linter.Config[]}
*/
function map(base, configs) {
return configs.map((config) => ({ ...base, ...config }));
);
}

module.exports = config;

0 comments on commit 37cdb8a

Please sign in to comment.