ポートフォリオサイトをAstro 5に移行

更新:2025-01-08
JavaScript

概要

このポートフォリオサイトはAstroで実装しており、バージョン4を使用していたが5が出ていたので移行する。いちおうnpx @astrojs/upgradeで簡単に移行できるらしいが、整理も兼ねてプロジェクトの作成からやってみる。

プロジェクトの作成

プロジェクトディレクトリを用意し、中に展開。

/project-dir
npm create astro@latest .

Node.jsのバージョンに関して警告が出た。

/project-dir
npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE package: 'create-astro@4.11.0',
npm warn EBADENGINE required: { node: '^18.17.1 || ^20.3.0 || >=22.0.0' },
npm warn EBADENGINE current: { node: 'v21.7.1', npm: '10.8.2' }
npm warn EBADENGINE }

Node.jsのリリース情報を確認し、条件を満たす最新のLTSをインストール。

/project-dir
volta install node@v23.5.0

npmのバージョンが古いと出た。

/project-dir
success: installed and set node@23.5.0 as default
note: this version of Node includes npm@10.9.2, which is higher than your default version (10.8.2).
To use the version included with Node, run `volta install npm@bundled`

書いてあるとおり実行してnpmのバージョンを更新。

/project-dir
volta install npm@bundled

再度プロジェクトの作成を実行。質問はすべて推奨項目を選択。

/project-dir
How would you like to start your new project?
A basic, minimal starter (recommended)
Install dependencies? (recommended)
Yes
# 最初から.gitはある状態でやったので以下は聞かれていない
# Initialize a new git repository?

開発サーバが起動できれば完了。

/project-dir
npm run dev
# http://localhost:4321/

開発環境の整備

パスエイリアス

ドキュメントにはcomponentsやassetsを個別で指定してあったが、その必要性が分からないのでsrc配下まとめて設定。

/project-dir/tsconfig.json
{
"extends": "astro/tsconfigs/strict",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
}
}
}

モジュールの追加

/project-dir
npm i @fontsource-variable/ysabeau astro-expressive-code date-fns
モジュール名簡易説明
@fontsource-variable/ysabeauロゴに使っているGoogle Fonts。
astro-expressive-codeMarkdownで書いたコードをコードブロックにする。
date-fns日付操作。たとえば記事を作成順にソートする。
/project-dir
npm i -D @expressive-code/plugin-line-numbers @markuplint/astro-parser autoprefixer destyle.css markuplint postcss-html prettier prettier-plugin-astro remark-breaks remark-directive remark-external-links sass stylelint stylelint-config-recess-order stylelint-config-recommended-scss
モジュール名簡易説明
@expressive-code/plugin-line-numbersコードブロックに行番号を表示。
@markuplint/astro-parserAstroの解析。
autoprefixerPostCSSでベンダープレフィックスを自動付与。
destyle.cssリセットCSS。
markuplintHTMLの静的解析。
postcss-htmlHTML内に書かれているCSSの処理。
prettierコードの自動フォーマット。
prettier-plugin-astroAstro ファイルのフォーマット。
remark-breaksMarkdownの改行反映。
remark-directiveMarkdownにカスタムディレクティブ導入。
remark-external-linksMarkdownのリンクを別タブで開く。
sassSassによるスタイリング。
stylelintスタイルシートの静的解析。
stylelint-config-recess-orderCSSプロパティの並び順。
stylelint-config-recommended-scssSassの解析ルール。

設定ファイルの用意

/project-dir/.env.development
PUBLIC_SITE_NAME=namakurajin
PUBLIC_SITE_URL=http://localhost:4321
/project-dir/.markuplintrc
{
"parser": {
".astro$": "@markuplint/astro-parser"
},
"extends": ["markuplint:recommended"]
}
/project-dir/.stylelintrc.json
{
"ignoreFiles": ["**/ec.*.css"],
"extends": ["stylelint-config-recommended-scss", "stylelint-config-recess-order"],
"rules": {
"font-family-no-duplicate-names": null,
"no-descending-specificity": null,
"no-duplicate-selectors": null
},
"overrides": [
{
"files": ["src/**/*.astro"],
"customSyntax": "postcss-html"
}
]
}
/project-dir/postcss.config.cjs
module.exports = {
plugins: [
require('autoprefixer'),
],
};
/project-dir/prettier.config.cjs
/** @type {import("prettier").Config} */
module.exports = {
arrowParens: "always",
bracketSpacing: true,
htmlWhitespaceSensitivity: "ignore",
printWidth: 100,
semi: true,
singleQuote: true,
trailingComma: "none",
useTabs: false,
plugins: ["prettier-plugin-astro"],
overrides: [
{
files: "*.astro",
options: {
parser: "astro",
},
},
],
};

コマンドの追加

/project-dir/package.json
{
// ...
"scripts": {
// ...
"format:astro": "prettier --write 'src/**/*.astro'",
"format:scss": "stylelint 'src/**/*.astro' --fix",
"lint:astro": "markuplint 'src/**/*.astro'",
"lint:scss": "stylelint 'src/**/*.astro'",
"format:html": "prettier --write 'dist/**/*.html'",
"format:css": "prettier --write 'dist/**/*.css' && stylelint 'dist/**/*.css' --fix",
"lint:html": "markuplint dist/**/*.html",
"lint:css": "stylelint 'dist/**/*.css'",
"generate": "npm run build && npm run format:html && npm run format:css && npm run lint:html"
},
// ...
}

ビルドの設定

静的な成果物になるよう意識した設定になっている。

/project-dir/astro.config.mjs
// @ts-check
import { defineConfig } from 'astro/config';
// コードブロック用
import expressiveCode from "astro-expressive-code";
import { pluginLineNumbers } from "@expressive-code/plugin-line-numbers";
import myRemarkPlugin from "./src/plugins/myRemarkPlugin";
// CSSのキャッシュを切る用
const cssVersion = '20240108';
// https://astro.build/config
export default defineConfig({
// HTMLを圧縮しない
compressHTML: false,
// Astroの拡張
integrations: [
// コードブロックの拡張
expressiveCode({
themes: ['dracula-soft'],
plugins: [
pluginLineNumbers()
]
})
],
markdown: {
remarkPlugins: ['remark-breaks', 'remark-external-links', 'remark-directive', myRemarkPlugin],
},
vite: {
build: {
rollupOptions: {
output: {
assetFileNames: (file) => {
const fileName = file.names[0];
// CSSは「css」ディレクトリに入れる
const cssRegex = /\.css$/i;
if (cssRegex.test(fileName)) {
return `assets/css/styles${cssVersion}.css`;
}
// フォントは「font」ディレクトリに入れる
const fontRegex = /\.(woff|woff2)$/i;
if (fontRegex.test(fileName)) {
return 'assets/font/[name].[ext]';
}
// 他にも必要ならここに設定を書く
// デフォルト
return 'assets/[name].[ext]';
},
// JavaScriptを任意の1ファイルにまとめる
entryFileNames: (_file) => {
return `assets/js/scripts.js`;
}
},
},
// CSS、JavaScriptを圧縮しない
minify: false,
// CSS、JavaScriptを必ず外部ファイルにまとめる
assetsInlineLimit: 0,
// ひとつのCSSにまとめる
cssCodeSplit: false,
}
}
});

コンテンツの作成

Astro 4で構築したものをそのまま流用。ここではディレクトリ構成のみメモしておく。

/project-dir/src
├── _articles
│   └── ここにMarkdown形式の記事を保存。
├── _statics
│   └── ここにMarkdown形式の固定ページ記事を保存。
├── components
│   ├── Article.astro
│   ├── Breadclumbs.astro
│   ├── Footer.astro
│   └── Header.astro
├── layouts
│   └── Layout.astro
├── libs
│   └── utils.ts
├── pages
│   ├── about.astro
│   ├── index.astro
│   └── note
│   ├── [slug].astro
│   └── index.astro
├── plugins
│   └── myRemarkPlugin.ts
└── styles
└── global.scss

デプロイ

このサイトはVercelを利用している。

ドメインのつけかえ

Astro 4のプロジェクトからドメインの設定を消して、今回のプロジェクトに再設定した。

[x] Add {wwwありURL} and redirect {wwwなしURL} to it (Recommended)
[ ] Add {wwwなしURL} and redirect {wwwありURL} to it
[ ] Add {wwwなしURL}

環境変数の追加

環境変数にPUBLIC_がついていると警告が出た。前からそうだったっけ?

PUBLIC_ exposes this value to the browser. Verify it is safe to share publicly.

このままだと環境変数が使えない(参照している箇所がundefinedになる)ので、警告アイコンをクリックして警告を受け入れて再度デプロイ。

続く...かもね