Astro の import 整理で少し詰まったのでメモ。
やりたかったことは、import 文をただアルファベット順にするだけではなく、意味のある単位で分けること。
特にこういう import を、
import Button from '@components/Button.astro';
import SectionHeading from '@components/SectionHeading.astro';
import { featureItems } from '@data/featureItems';
import ArrowIcon from '@images/icons/arrow-right.svg';
こうしたかった。
import Button from '@components/Button.astro';
import SectionHeading from '@components/SectionHeading.astro';
import { featureItems } from '@data/featureItems';
import ArrowIcon from '@images/icons/arrow-right.svg';
components、data、images は個人的に読み方が違うので、空行で分かれている方が見やすい。
使ったもの
今回の設定では、以下を使う。
npm install -D eslint-config-prettier eslint-plugin-astro eslint-plugin-import eslint-plugin-simple-import-sort
設定
// eslint.config.mjs
import eslintConfigPrettier from 'eslint-config-prettier';
import eslintPluginAstro from 'eslint-plugin-astro';
import importPlugin from 'eslint-plugin-import';
import simpleImportSort from 'eslint-plugin-simple-import-sort';
export default [
...eslintPluginAstro.configs.recommended,
{
plugins: {
'simple-import-sort': simpleImportSort,
import: importPlugin,
},
rules: {
'simple-import-sort/imports': [
'error',
{
groups: [
['^\\u0000'],
['^astro(?:$|/)', '^@astrojs/'],
['^@?\\w'],
['^@components/'],
['^@data/'],
['^@(?!images/)[^/]+/'],
['^\\.'],
['^@images/'],
],
},
],
'simple-import-sort/exports': 'error',
'import/newline-after-import': 'error',
},
},
eslintConfigPrettier,
];
メモ
simple-import-sort の groups は、外側の配列ごとにグループが分かれる。
groups: [
['^@components/'],
['^@data/'],
['^@images/'],
],
この場合、@components、@data、@images の間に空行が入る。
逆に、空行を入れたくないものは同じ配列に入れる。
['^astro(?:$|/)', '^@astrojs/']
これで astro と @astrojs は同じグループになる。
^@?\\w は外部 package 用
['^@?\\w']
これは react、clsx、zod、dayjs みたいな npm package を拾うためのもの。
これがないと、普通の外部 package が意図しない場所に並ぶことがある。
images は一番下にしたかった
画像 import は個人的に import ブロックの一番下にあった方が読みやすい。
なので @images/ は最後のグループにした。
['^@images/']
ただし、その他の alias を拾う fallback をこう書くと、
['^@[^/]+/']
@images/ もそこで拾われる可能性がある。
なので images だけ除外する。
['^@(?!images/)[^/]+/']
これで、@images/ は最後のグループまで流れる。
side effect import
CSS や font のような import は side effect import として扱われる。
import '../styles/global.css';
import '@fontsource/noto-sans-jp';
simple-import-sort では ^\\u0000 で拾える。
['^\\u0000']
CSS の読み込み順は表示に影響することがあるので、ここはあまり細かくいじらない方がよさそう。
役割分担
import の並び替えは simple-import-sort に任せる。
'simple-import-sort/imports': 'error'
export の並び替えも同じ plugin に任せる。
'simple-import-sort/exports': 'error'
import ブロックの後ろの空行だけ eslint-plugin-import に任せる。
'import/newline-after-import': 'error'
sort-imports や import/order は併用しない。
並び替え系のルールが複数あると、fix の結果が揺れそうなので。
最終的な並び
だいたいこの順番にする。
side effect import
Astro / @astrojs
npm package
@components
@data
その他 alias
相対 import
@images