Open15

Astro プロジェクト環境構築メモ

siakassiakas

以下の環境でプロジェクトを作成。

  • Node.js 20.10.0
  • Pnpm 8.14.0

インストール

まずは Astro プロジェクトをセットアップ。
https://docs.astro.build/ja/install/auto/

pnpm create astro@latest

対話式でインストールを進める。

Where should we create your new project?
-> プロジェクト名を入力して Enter

How would you like to start your new project?
-> Empty を選択

Install dependencies?
-> Yes を選択

Do you plan to write TypeScript?
-> Yes を選択

How strict should TypeScript be?
-> Strict (recommended) を選択

Initialize a new git repository?
-> すでにリポジトリ準備済なら No を選択
-> リポジトリの作成と合わせてプロジェクト作成するつもりなら Yes

動作確認

Astro のセットアップが完了したら起動して確認。

pnpm dev
siakassiakas

以下の設定ファイルを反映していく。

.node-version

利用中の Node のバージョンと合わせて .node-version ファイルを作成。

node -v
v20.10.0

nodenv local 20.10.0

.editorconfig

# http://editorconfig.org
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true

[*.{md,markdown}]
trim_trailing_whitespace = false

.gitignore

# build output
dist/

# generated types
.astro/

# dependencies
node_modules/

# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# environment variables
.env
.env.production

# macOS-specific files
.DS_Store
siakassiakas

Prettier

以下のコマンドで Prettier と関連プラグインをインストールする。

pnpm add -D prettier prettier-plugin-astro prettier-plugin-organize-imports

Pretter v3 で動かないことがあるので、しばらくは以下のバージョンでインストールする方がいいかもしれない。

yarn add -D prettier@^2.8.8 prettier-plugin-astro@^0.10.0

設定ファイル

.prettierrc をドキュメントルートに作成。

.prettierrc
{
  "trailingComma": "all",
  "tabWidth": 2,
  "useTabs": false,
  "semi": false,
  "singleQuote": true,
  "jsxSingleQuote": false,
  "arrowParens": "always",
  "printWidth": 80,
  "bracketSpacing": true,
  "plugins": ["prettier-plugin-astro", "prettier-plugin-organize-imports"],
  "overrides": [
    {
      "files": "*.html",
      "options": {
        "printWidth": 360
      }
    },
    {
      "files": ["*.css", "*.scss"],
      "options": {
        "singleQuote": false
      }
    },
    {
      "files": "*.astro",
      "options": {
        "parser": "astro"
      }
    }
  ]
}

.prettierignore

.prettierignore をドキュメントルートに作成。

.prettierignore
node_modules/
.next/
.nuxt/
.astro/
build/
dist/
out/
public/
package-lock.json
yarn.lock
pnpm-lock.yaml
next.config.js

VS Code 設定

以下の内容で .vscode/settings.json を作成。

.vscode/settings.json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.formatOnPaste": true,
  "editor.codeActionsOnSave": {
    "source.addMissingImports": "explicit",
    "source.fixAll.eslint": "explicit"
  },
  "prettier.documentSelectors": ["**/*.astro"],
  "javascript.preferences.importModuleSpecifier": "non-relative",
  "typescript.preferences.importModuleSpecifier": "non-relative",
  "eslint.validate": [
    "html",
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ]
}

pnpm を使用した場合は "prettier.documentSelectors": ["**/*.astro"], の追加設定をしないと、自動整形してくれない。
https://github.com/withastro/prettier-plugin-astro?tab=readme-ov-file#formatting-with-the-vs-code-prettier-extension-directly

siakassiakas

React インテグレーションを追加

https://docs.astro.build/en/guides/integrations-guide/react/

astro add コマンドを使って React のインテグレーションを追加。astro add は必要なパッケージのインストールと設定ファイルの変更をまとめて実行してくれる。

# npm
npx astro add react

# yarn
yarn astro add react

# pnpm
pnpm astro add react

React と関連パッケージがインストールされ、astro.config.mjstsconfig.json が更新される。

siakassiakas

VS Code による import 補完

tsconfig にパスエイリアスを追加

tsconfig.json
{
  "extends": "astro/tsconfigs/strict",
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "react"
+   "baseUrl": ".",
+   "paths": {
+     "@/*": ["./src/*"],
+     "@@/*": ["./*"]
    }
  }
}

VS Code 設定

.vscode/settings.json に以下を追加。

.vscode/settings.json
{
  // 標準のフォーマッターを Prettier に設定
  "editor.defaultFormatter": "esbenp.prettier-vscode",

  // 保存時およびペースト時に自動フォーマットを実行する
  "editor.formatOnSave": true,
  "editor.formatOnPaste": true,

+ // 保存時の実行アクション
+ "editor.codeActionsOnSave": {
+   // import されていないモジュールを自動補完
+   "source.addMissingImports": true
+ },
+
+ // VSCode で import を記述する際に tsconfig の設定に応じて絶対パスとする
+ "javascript.preferences.importModuleSpecifier": "non-relative",
+ "typescript.preferences.importModuleSpecifier": "non-relative"
}

siakassiakas

Sass と Stylelint の導入

Sass

Sass の導入が必要かどうかはプロジェクトによって異なるが、多くの場合は「入れておくと大体便利」。Tailwind CSS や他の UI フレームワークを使う場合は不要なことも多い。

yarn add -D sass

Stylelint

Sass / SCSS を使うなら Stylelint を入れておきたい。Stylelint に求めるものは以下の通り。

  • *.astro ファイル内の CSS フォーマット
  • Prettier を優先したフォーマット
  • 基本的な Sass の推奨ルール
  • CSS プロパティの自動ソート

それらを踏まえて以下のパッケージをインストールする。

なお、以前までは stylelint-config-prettier もインストールしていたが、Stylelint v15 以降はフォーマット関連のルールが非推奨となり、Prettier と干渉しなくなったため、stylelint-config-prettier は不要となった。

postcss-html は Stylelint 14 以降では CSS やそれに準ずるファイル以外を解析する場合は、別途シンタックスモジュールが必要になったため、*.astro ファイルで Stylelint を有効化するためにインストールする。

yarn add -D stylelint stylelint-config-standard-scss stylelint-config-recess-order postcss-html

Stylelint の設定ファイルは .cjs 拡張子で用意する。

.stylelintrc.cjs
module.exports = {
  extends: ['stylelint-config-standard-scss', 'stylelint-config-recess-order'],
  overrides: [
    {
      files: ['*.astro', '**/*.astro'],

      // `*.astro` では postcss-html を指定しないとシンタックスエラーになってしまう
      customSyntax: 'postcss-html',
    },
  ],
}

ignore も用意する。

.stylelintignore
node_modules/
.astro/
dist/
public/
*.cjs
*.mjs
*.json
*.txt

VS Code 設定更新

VS Code での保存時に Stylelint が実行されるよう、設定ファイルも以下のように追記する。

.vscode/settings.json
{
  // 標準のフォーマッターを Prettier に設定
  "editor.defaultFormatter": "esbenp.prettier-vscode",

  // 保存時およびペースト時に自動フォーマットを実行する
  "editor.formatOnSave": true,
  "editor.formatOnPaste": true,

  // 保存時の実行アクション
  "editor.codeActionsOnSave": {
    // import されていないモジュールを自動補完
    "source.addMissingImports": true,

+   // ファイル保存時に Stylelint による自動フォーマットを実行する
+   "source.fixAll.stylelint": true
  },

  // VSCode で import を記述する際に tsconfig の設定に応じて絶対パスとする
  "javascript.preferences.importModuleSpecifier": "non-relative",
  "typescript.preferences.importModuleSpecifier": "non-relative",

+ // Stylelint とのバッティング回避のため、VS Code 標準の自動整形を無効化(CSS, SCSS, LESS)
+ "css.validate": false,
+ "scss.validate": false,
+ "less.validate": false,
+
+ // Stylelint の実行対象を指定
+ "stylelint.validate": ["html", "css", "scss", "postcss", "astro"]
+ 
+ // Stylelint の実行パスを指定(Path 指定がないとローカル環境で Stylelint が動作しない場合がある)
+ "stylelint.stylelintPath": "node_modules/stylelint"
}

siakassiakas

Astro 向け Stylelint ルール追加

.stylelintrc.cjs
module.exports = {
  extends: ['stylelint-config-standard-scss', 'stylelint-config-recess-order'],
  overrides: [
    {
      files: ['*.astro', '**/*.astro'],

      // `*.astro` では postcss-html を指定しないとシンタックスエラーになってしまう
      customSyntax: 'postcss-html',

+     rules: {
+       // 次の擬似クラスの使用を許可
+       // :global()
+       'selector-pseudo-class-no-unknown': [
+         true,
+         {
+           ignorePseudoClasses: ['global'],
+         },
+       ],
+     },
    },
  ],
}
siakassiakas

ESLint 導入

Astro 向けの ESLint 設定を追加

まず Astro 用のプラグインと関連パッケージ、そして Prettier の設定を優先するパッケージをインストール。

https://github.com/ota-meshi/eslint-plugin-astro

yarn add -D eslint eslint-plugin-astro @typescript-eslint/parser eslint-plugin-jsx-a11y eslint-config-prettier

設定ファイルと ignore ファイルを以下の通り追加する。設定ファイルの拡張子は .csj とする。

.eslintrc.cjs
module.exports = {
  env: {
    browser: true,
    es2022: true,
    node: true,
  },
  extends: ['plugin:astro/recommended', 'prettier'],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    project: './tsconfig.json',
  },
  overrides: [
    {
      files: ['*.astro'],
      parser: 'astro-eslint-parser',
      parserOptions: {
        parser: '@typescript-eslint/parser',
        extraFileExtensions: ['.astro'],
      },
    },
  ],
}
.eslintignore
node_modules/
.astro/
dist/
public/
package-lock.json
yarn.lock
vite.config.ts
next.config.js
tsconfig.json
src/env.d.ts
*.cjs
*.mjs

React 向けの ESLint 設定を追加

React 向けの ESLint 設定には eslint-config-react-app を使用する。

https://www.npmjs.com/package/eslint-config-react-app

yarn add -D eslint-config-react-app

.eslintrc.cjsextendsreact-app を追加する。
なお、 eslint-config-react-app をインストールするだけで extendseslint:recommendedplugin:@typescript-eslint/recommended を指定できるらしいが、できるだけシンプルに運用したいため、それらの記述はおこなわないことにした。

また、import のソートや削除を自動化するために以下のプラグインも追加。

yarn add -D eslint-plugin-import eslint-plugin-unused-imports
.eslintrc.cjs
module.exports = {
  env: {
    browser: true,
    es2022: true,
    node: true,
  },
  extends: [
    'plugin:astro/recommended',
+   'react-app',
    'prettier'
  ],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    project: './tsconfig.json',
  },
+ plugins: ['import', 'unused-imports'],
  overrides: [
    {
      files: ['*.astro'],
      parser: 'astro-eslint-parser',
      parserOptions: {
        parser: '@typescript-eslint/parser',
        extraFileExtensions: ['.astro'],
      },
    },
  ],
}

VS Code 設定更新

VS Code での保存時に ESLint が実行されるよう、設定ファイルも以下のように追記する。

.vscode/settings.json
{
  // 標準のフォーマッターを Prettier に設定
  "editor.defaultFormatter": "esbenp.prettier-vscode",

  // 保存時およびペースト時に自動フォーマットを実行する
  "editor.formatOnSave": true,
  "editor.formatOnPaste": true,

  // 保存時の実行アクション
  "editor.codeActionsOnSave": {
    // import されていないモジュールを自動補完
    "source.addMissingImports": true,

+   // ファイル保存時に ESLint による自動フォーマットを実行する
+   "source.fixAll.eslint": true,

    // ファイル保存時に Stylelint による自動フォーマットを実行する
    "source.fixAll.stylelint": true
  },

  // VSCode で import を記述する際に tsconfig の設定に応じて絶対パスとする
  "javascript.preferences.importModuleSpecifier": "non-relative",
  "typescript.preferences.importModuleSpecifier": "non-relative",

+ // ESLint の実行対象を定義
+ "eslint.validate": [
+   "html",
+   "javascript",
+   "javascriptreact",
+   "typescript",
+   "typescriptreact",
+   "astro"
+ ],

  // Stylelint とのバッティング回避のため、VS Code 標準の自動整形を無効化(CSS, SCSS, LESS)
  "css.validate": false,
  "scss.validate": false,
  "less.validate": false,

  // Stylelint の実行対象を指定
  "stylelint.validate": ["html", "css", "scss", "postcss", "astro"],

  // Stylelint の実行パスを指定(Path 指定がないとローカル環境で Stylelint が動作しない場合がある)
  "stylelint.stylelintPath": "node_modules/stylelint"
}

siakassiakas

format コマンドを追加

Prettier / ESLint / Stylelint の設定ができたので、リントとフォーマットをまとめて実行する npm scripts を追加する。

詳細は以下のスクラップを参照。

https://zenn.dev/siakas/scraps/d590ee924648c7

  • npm-run-all をインストール
  • package.json にスクリプトを追加
  • フォーマットの対象ファイルは .eslintignore.prettierignore で管理し、スクリプト上には記載しない
  • fix は prettier → eslint の順に順次実行させる
yarn add -D npm-run-all
package.json
{
  ...
  "scripts": {
    "dev": "astro dev",
    "start": "astro dev",
    "build": "astro build",
    "preview": "astro preview",
    "astro": "astro"
+   "lint": "run-p -l -c --aggregate-output lint:*",
+   "lint:eslint": "eslint .",
+   "lint:prettier": "prettier --check .",
+   "fix": "run-s fix:prettier fix:eslint",
+   "fix:eslint": "npm run lint:eslint -- --fix",
+   "fix:prettier": "npm run lint:prettier -- --write"
  },
  ...
}

siakassiakas

Tailwind CSS 導入

https://docs.astro.build/ja/guides/integrations-guide/tailwind/

astro add で Tailwind インテグレーションを追加。

# npm
npx astro add tailwind

# yarn
yarn astro add tailwind

# pnpm
pnpm astro add tailwind

tailwind.config.cjs ファイルが生成され、 astro.config.mjs が更新される。

astro.config.mjs
import { defineConfig } from 'astro/config'
import react from '@astrojs/react'
import mdx from '@astrojs/mdx'
+ import tailwind from '@astrojs/tailwind'

// https://astro.build/config
export default defineConfig({
  integrations: [
    react(),
    mdx(),
+   tailwind()
  ],
})

Next.js などで手動インストールする場合は、PostCSS や Autoprefixer などを別途インストールして postcss.config.js を用意したり、 @tailwind base; 等を記述したグローバルスタイルの CSS ファイルを用意したりする必要があるが、Astro のインテグレーションではまとめて用意されているらしく、それらの設定は不要らしい。

astro add tailwind 経由でインストールした Tailwind は微妙にバージョンが古いので、最新版にしておく。

yarn add -D tailwindcss

Tailwind のクラス名を自動で並び替えたいので、Prettier の Tailwind 向けプラグインをインストールする。

yarn add -D prettier-plugin-tailwindcss

※上記プラグインは prettier-plugin-astro 同様、インストールするだけで機能するが、バージョンの違いなどで動作しない場合は .prettierrcplugins プロパティで設定する必要があるかもしれない。

siakassiakas

astro-compress 導入

HTML や CSS、JS、画像などを圧縮してくれる astro-compress を astro add で導入する。

# npm
npx astro add astro-compress

# yarn
yarn astro add astro-compress

# pnpm
pnpm astro add astro-compress
siakassiakas

ビルド設定

astro dev でサーバを自動オープン

astro.config.mjs
import { defineConfig } from 'astro/config'
import react from '@astrojs/react'
import mdx from '@astrojs/mdx'
import compress from 'astro-compress'

// https://astro.build/config
export default defineConfig({
+ server: {
+   open: true,
+ },
  integrations: [react(), mdx(), compress()],
})

siakassiakas

Tailwind Typography インストール

pnpm add -D @tailwindcss/typography

tailwind.config.mjs を以下の通り変更。

tailwind.config.mjs
/** @type {import('tailwindcss').Config} */
export default {
  content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
  theme: {
    extend: {},
  },
+ plugins: [require('@tailwindcss/typography')],
}