Open11
Astroの環境構築について

まずは
npm create astro@latest
質問には全て Yes

とりあえずESLint、Stylelint、Prettier、Markuplintは入れておきたい。
やりたい・できたら嬉しいこと
- 保存時の自動lint,format,インポート
- importの補完
- importの自動整列
- React用のESLint設定追加
- import時のディレクトリのエイリアス指定
- CSS変数の補完
- CSSプロパティの並べ替え
- アクセシビリティの静的チェック
- TypeScriptのルール調整
めっちゃ余裕があればhusky,lint-stagedでコミット前のチェックまで対応したい

公式
かなり参考になりそうなスクラップ
こちらも

開発サーバーの設定
astro.config.mjs
export default defineConfig({
+ server: {
+ host: true, // 外部からのアクセスを可能にする
+ open: true // サーバー起動時にブラウザを開く
+ },
});

Reactインテグレーションの追加
npx astro add react
サンプルコンポーネントを追加してみる
import { useState } from "react";
function Counter() {
// useStateを使用して状態変数を宣言。初期値は0。
const [count, setCount] = useState(0);
// ボタンがクリックされたときにカウントを増やす関数
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>Increase Count</button>
</div>
);
}
export default Counter;
clientディレクティブをつけると動く。
---
import SampleReactComponent from '../components/SampleReactComponent';
---
<SampleReactComponent client:load/>

MDXインテグレーションの追加
npx astro add mdx
.mdxのサンプルページを追加してみる
src/pages/mdx-sample.mdx
import SampleReactComponent from "../../components/SampleReactComponent"
# Hello, MDX! This is a paragraph in your MDX file. You can write regular
Markdown here and also use JSX components.
## Here's a React component
---
<SampleReactComponent client:load />
---

ESLintと各種ESLintプラグインの追加
npm i -D eslint @eslint/js eslint-plugin-astro eslint-plugin-jsx-a11y typescript-eslint eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-import eslint-plugin-unused-imports eslint-config-prettier globals
eslint.config.mjs
import jsEslint from '@eslint/js';
import eslintConfigPrettier from 'eslint-config-prettier';
import astroEslint from 'eslint-plugin-astro';
import importPlugin from 'eslint-plugin-import';
import reactEslint from 'eslint-plugin-react';
import reactHooksEslint from 'eslint-plugin-react-hooks';
import unusedImports from 'eslint-plugin-unused-imports';
import globals from 'globals';
import tsEslint from 'typescript-eslint';
export default [
jsEslint.configs.recommended,
...tsEslint.configs.recommended,
...astroEslint.configs['flat/recommended'],
...astroEslint.configs['flat/jsx-a11y-recommended'],
reactEslint.configs.flat['jsx-runtime'],
{
languageOptions: {
globals: {
...globals.browser, // ブラウザのグローバル変数を追加
},
},
plugins: {
'react-hooks': reactHooksEslint,
'unused-imports': unusedImports,
import: importPlugin,
},
rules: {
...reactHooksEslint.configs.recommended.rules, // React Hooks のルールを追加
'unused-imports/no-unused-imports': 'error', // 未使用の import をエラーにする
// _ で始まる変数は未使用でもエラーにしない (https://typescript-eslint.io/rules/no-unused-vars/#benefits-over-typescript)
'@typescript-eslint/no-unused-vars': [
'error',
{
args: 'all',
argsIgnorePattern: '^_',
caughtErrors: 'all',
caughtErrorsIgnorePattern: '^_',
destructuredArrayIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true,
},
],
'react/jsx-sort-props': 'error', // props の順番をソートする
// import の順序を設定する
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', ['parent', 'sibling', 'index'], 'object', 'type'],
'newlines-between': 'always',
pathGroupsExcludedImportTypes: ['builtin'],
pathGroups: [
{
pattern: '@/components/**',
group: 'internal',
position: 'before',
},
],
alphabetize: {
order: 'asc',
},
},
],
},
},
{
ignores: ['.astro/', 'dist/'],
},
eslintConfigPrettier,
];
これ良いかもと思ったけど、ちょっとtoo muchなので今回はスルー。でも嫌いじゃない

prettier追加
npm i -D prettier prettier-plugin-astro
.prettierrc.mjs
/** @type {import("prettier").Config} */
export default {
printWidth: 100,
tabWidth: 2,
semi: true,
trailingComma: 'all',
singleQuote: true,
arrowParens: 'always',
useTabs: true,
plugins: ['prettier-plugin-astro'],
overrides: [
{
files: '*.astro',
options: {
parser: 'astro',
},
},
],
};
.prettierignore
node_modules/
.astro/
dist/
package-lock.json

.vscode/extensions.json
{
"recommendations": [
"astro-build.astro-vscode", // Astro
"dbaeumer.vscode-eslint", // ESLint
"esbenp.prettier-vscode", // Prettier
"yusukehirao.vscode-markuplint" // Markuplint
]
}
.vscode/settings.json
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.addMissingImports": "explicit"
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"files.insertFinalNewline": true,
"files.trimTrailingWhitespace": true,
"[markdown]": {
"files.trimTrailingWhitespace": false
},
"prettier.documentSelectors": ["**/*.astro"],
"eslint.validate": ["javascript", "javascriptreact", "astro", "typescript", "typescriptreact", "markdown", "mdx"],
"eslint.options": {
"overrideConfigFile": "eslint.config.mjs"
},
"javascript.preferences.importModuleSpecifier": "non-relative",
"typescript.preferences.importModuleSpecifier": "non-relative",
"mdx.server.enable": true,
"markuplint.enable": true
}

Markuplintを追加
対話コマンドの中でAstroとReactを選択
npx markuplint --init
✔ Which do you use template engines? · React (JSX), Astro
✔ May I install them automatically? (y/N) · true
✔ Do you customize rules? (y/N) · false
✔ Does it import the recommended config? (y/N) · true
.markuplintrc
{
"specs": {
"\\.tsx?$": "@markuplint/react-spec"
},
"parser": {
"\\.tsx?$": "@markuplint/jsx-parser",
"\\.astro$": "@markuplint/astro-parser"
},
"extends": [
"markuplint:recommended"
]
}

Stylelint追加
npm init stylelint stylelint-config-standard stylelint-config-html stylelint-config-recess-order postcss-html autoprefixer
.stylelintrc.mjs
export default {
extends: [
'stylelint-config-standard',
'stylelint-config-html/astro',
'stylelint-config-recess-order',
],
};
postcss.config.mjs
import autoprefixer from 'autoprefixer';
export default {
plugins: [autoprefixer],
};