Vue.jsアプリケーションの開発において、コードの一貫性と可読性を高めるために、ESLintカスタムルールを導入して`components`オプション内のコンポーネント定義をアルファベット順に強制することができます。このルールは、コンポーネントの定義順序が誤っている場合に警告を発し、自動修正も提供します。
1. カスタムESLintルールの定義
まず、ESLintカスタムルールファイルを作成します。例えば、`your-rules/sort-vue-components.js`というファイル名で保存します。
module.exports = {
meta: {
type: 'suggestion',
docs: {
description: 'Vueコンポーネントの`components`オプション内のプロパティをアルファベット順にソートします。',
category: 'Stylistic Issues',
recommended: false,
},
fixable: 'code', // 自動修正可能
schema: [], // ルールにオプションはなし
},
create(context) {
return {
// デフォルトエクスポートを監視
ExportDefaultDeclaration(node) {
if (node.declaration.type !== 'ObjectExpression') {
return; // オブジェクトリテラルではない場合は処理しない
}
const componentProps = node.declaration.properties;
const componentsOptionNode = componentProps.find(
prop => prop.key.type === 'Identifier' && prop.key.name === 'components'
);
// 'components'プロパティが存在しないか、オブジェクトではない場合は処理しない
if (!componentsOptionNode || componentsOptionNode.value.type !== 'ObjectExpression') {
return;
}
const componentEntries = componentsOptionNode.value.properties;
if (componentEntries.length < 2) {
return; // 1つ以下のコンポーネント定義はソートの必要がない
}
// 現在の定義を名前でソート
const sortedEntries = [...componentEntries].sort((a, b) =>
a.key.name.localeCompare(b.key.name)
);
// 現在の順序とソートされた順序を比較
for (let i = 0; i < componentEntries.length; i++) {
if (componentEntries[i] !== sortedEntries[i]) {
const currentComponentName = componentEntries[i].key.name;
const expectedComponentName = sortedEntries[i].key.name;
context.report({
node: componentEntries[i],
message: `コンポーネントの定義はアルファベット順にソートされるべきです。'${currentComponentName}'は'${expectedComponentName}'の位置に来るべきです。`,
fix(fixer) {
const sourceCode = context.getSourceCode();
const sortedText = sortedEntries
.map(entry => sourceCode.getText(entry))
.join(',\n');
// 'components'オブジェクトの中身全体を置き換える
const startOffset = componentsOptionNode.value.range[0] + 1; // 開始ブレース '{' の直後
const endOffset = componentsOptionNode.value.range[1] - 1; // 終了ブレース '}' の直前
return fixer.replaceTextRange([startOffset, endOffset], sortedText);
},
});
// 最初の不順な項目を報告したら、残りの項目は同じ自動修正で対処されるため、ここで処理を終了
break;
}
}
},
};
},
};
このルールは以下の動作を実行します。
- ファイル内のデフォルトエクスポートの抽象構文木(AST)ノードである`ExportDefaultDeclaration`を監視します。
- デフォルトエクスポートがオブジェクトリテラルであることを確認します。
- そのオブジェクト内で`components`という名前のプロパティを検索します。
- `components`プロパティが存在し、それがオブジェクトリテラルである場合、その中のコンポーネント定義をアルファベット順にチェックします。
- もし定義順序が正しくない場合、ESLintは問題を報告し、自動修正機能を提供して正しい順序に並べ替えます。
2. .eslintrc.jsでのカスタムルールの利用
次に、プロジェクトの`.eslintrc.js`ファイルに上記のカスタムルールを参照する設定を追加します。これにより、ESLintがVueコンポーネントファイルでこのルールを適用するようになります。
module.exports = {
root: true,
env: {
node: true,
},
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
},
// 他のESLint設定 (例えば、extendsやpluginsなど)
// extends: [
// 'eslint:recommended',
// 'plugin:vue/vue3-recommended',
// // ...
// ],
// plugins: [
// 'vue',
// // ...
// ],
rules: {
// 他のプロジェクト固有のルール
// 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
// ...
},
overrides: [
{
// .vueファイルにのみこのルールを適用
files: ['*.vue'],
// Vueプラグインを利用している場合、プロセッサを指定することでスクリプトブロックをESLintが解析できるようになります。
// processor: require('eslint-plugin-vue').processors['.vue'],
rules: {
// カスタムルールを 'error' レベルで適用
'custom-rules/vue-component-sort': require('./your-rules/sort-vue-components.js'),
},
},
],
};
この設定では、`overrides`セクションを使用して、特定のファイル(ここでは`*.vue`ファイル)にのみカスタムルール`custom-rules/vue-component-sort`を適用しています。`require('./your-rules/sort-vue-components.js')`でカスタムルールファイルを指定し、ESLintがそれをロードできるようにします。