Closed11
Eslintの独自ルールをリポジトリに追加したい
ゴール
大層にeslint pluginを作るとかではなく今のリポジトリに追加でeslintのルールを作りたい
そしてできればルールはtypescriptで書きたい
公式のドキュメント読んでく
Runtime Rulesなるものがあるのでこれでいけそうな気はしてる
- Place all of your runtime rules in the same directory (e.g., eslint_rules).
- Create a configuration file and specify your rule ID error level under the rules key. Your rule will not run unless it has a value of "warn" or "error" in the configuration file.
- Run the command line interface using the --rulesdir option to specify the location of your runtime rules.
astエクスプローラー
@typescript-eslint/experimental-utils
を使って定義したruleが動いたのは確認できたけども--rulesdir
で実行されない
tsファイルで書いたruleだから一度ビルドしないといけないんかなぁ・・
typescriptで書いてjsにコンパイルしたら動いたのでざっくりまとめ
- @typescript-eslint/experimental-utilsいれる
- 任意のディレクトリにruleをかく
- astにどんな値や種類があるかはAST explorerでみる
- ruleのテストかく(@typescript-eslint/experimental-utils使って)
- ts→jsにコンパイルする
- eslint-plugin-rulesdirいれる(hack: なんかメンテされてなさそうなので自作のが良さそう)
- eslint-plugin-rulesdirでpluginとしてeslintのruleに追加する
実装例
import { TSESLint } from '@typescript-eslint/experimental-utils'
const cleanArch: TSESLint.RuleModule<'test', []> = {
meta: {
type: 'suggestion',
messages: {
test: 'test',
},
schema: [],
},
create: (context) => {
return {
ImportDeclaration(node) {
if (node.source.value === 'core/domains/models/business-group') {
// eslint-disable-next-line
console.log(context.getFilename())
context.report({
node,
messageId: 'test',
})
}
},
}
},
}
module.exports = cleanArch
.eslintrc.js
// TODO: eslint-plugin-rulesdirはメンテされてないっぽいので自作したい
const rulesDirPlugin = require('eslint-plugin-rulesdir')
rulesDirPlugin.RULES_DIR = 'eslint-rules/dist'
module.exports = {
parser: '@typescript-eslint/parser',
settings: {
},
parserOptions: {
},
plugins: [
'rulesdir',
],
extends: [
],
env: {
},
rules: {
'rulesdir/clean-arch': 'error',
},
}
--debug
オプションでlint実行時のデバッグ情報が見れる
ruleの内容を吐き出したいときはmessageにいれるとデバッグできる
meta
のmessages
とcreate
のdata
のとこ
import { TSESLint } from '@typescript-eslint/experimental-utils'
const cleanArch: TSESLint.RuleModule<'test', []> = {
meta: {
type: 'suggestion',
messages: {
test: '{{ foo }}',
},
schema: [],
},
create: (context) => {
return {
ImportDeclaration(node) {
if (node.source.value === 'core/domains/models/business-group') {
context.report({
node,
messageId: 'test',
data: {
foo: context.getFilename(),
},
})
}
},
}
},
}
module.exports = cleanArch
context.getFilename()は絶対パスを出力してくれる
/Users/foo/dev/project-name/src/core/adapters/adapter-name/index.ts
このスクラップは2021/05/14にクローズされました