AstroとSvelteでStaticサイトを作って、GitHub Actions で定期的に情報を取得更新するようにした
はじめに
Astro が ver2.2 に達した投稿を見かけたので、React 製の oriverk.dev を Astro 製にリプレースしました。
- reference
Astroとは
Astro is the all-in-one web framework designed for speed. Pull your content from anywhere and deploy everywhere, all powered by your favorite UI components and libraries.
速度重視で、他の UI フレームワークも使えるオールインワンの Web フレームワークです。実際に Astro では SSG と SSR の両方を作ることが出来、React や Vue、Svelte なども混ぜて使うことができます。
コード先頭に frontmatter の様なものがあることを除けば、基本は Svelte や Vue の様で、if 文や繰り返し箇所は React の様な感じです。
index.astro
1---2import Layout from '../layouts/Layout.astro';3import Card from '../components/Card.astro';4---5
6<Layout title="Welcome to Astro.">7 <main>8 <h1>Welcome to <span class="text-gradient">Astro</span></h1>9 <ul role="list" class="link-card-grid">10 {[...Array(2)].map((_, i) => (11 <Card12 href={`https://astro.build/docs/${i === 0 ? '' : i}`}13 title={`Documentation ${i === 0 ? '' : i}`}14 />15 ))}16 </ul>17 </main>18</Layout>19
20<style>21 main {22 margin: auto;23 padding: 1.5rem;24 max-width: 60ch;25 }26 h1 {27 font-size: 3rem;28 font-weight: 800;29 margin: 0;30 }31</style>
AstroとSvelteを使った感想
よかったこと
- Astro 自体が非常に単純で理解しやすい(Next.js 比)
- astro.Config で md ファイルの取り扱いが設定でき、あれやこれやと until function を書かずとも frontmatter を取得したり、html にコンパイルできる
- よいこととは実感してないけどリポジトリサイズが非常に小さい
- 3.34MB: oriverk/oriverk.dev
- 593KB: oriverk/astro-site
- 3.34MB: oriverk/oriverk.dev
よくはなかったこと・ふつごうだったこと
.astro
での event handling にはdocument.querySelector
などと書く必要がある- Scripts and Event Handling 🚀 Astro Documentation
- Svelte などの UI フレームワークを使う必要がある主因だと思う
- Scripts and Event Handling 🚀 Astro Documentation
- Astro の構文が React と Vue/Svelte の中間みたいで、if 文や each 文を書くときに困惑する
- 経験により解消されるとは思う
.astro
上で UI フレームワークコンポネントを呼び出す際に、両者との微妙な違いにより困ることがある- GitHub 上で script や style 領域がハイライトされない
- Svelte も Vue もされない
サイトについて
主に次のような機能をもったサイトにしたいと考えました。
- Static Site である
- GitHub の Pinned Repos と Contribution Calendar(GitHub 草)を表示できる
- blog.oriverk.dev のコンテンツを取得表示できる
- Cloudflare Pages にデプロイし、サイトデータを自動で更新できる
また、以前に oriverk.dev を React で作ったときの感じを踏襲したいとも考えていました。
主に使用したもの
Astro だけでもサイトは作れますが、Astro と他 UI フレームワークを使った場合の感じを知りたかったので、軽量さに共通点を持つ Svelte を UI フレーム枠に採用しました。全体的な view?の/pages は astro ファイルで作り、components は svelte という風に使い分けました。
- Astro
- Svelte • Cybernetically enhanced web apps
- fetcher
- linter
Init astro app
1npm create astro@latest -- --template basics
Astro と Astronaut を掛けているのか、Houston という名前の顔文字が可愛いかったです。
![npm create astro@latest](https://user-images.githubusercontent.com/44029144/231638707-5afcf66c-2e6d-4bda-a69b-235e74507376.png)
![basics](https://user-images.githubusercontent.com/4677417/186188965-73453154-fdec-4d6b-9c34-cb35c248ae5b.png)
1npm i -D npm-run-all2npm i -D @commitlint/{config-conventional,cli}3# echo '{"extends": ["@commitlint/config-conventional"]}' > .commitlintrc.json4
5npm install -D eslint @typescript-eslint/parser eslint-plugin-{astro,jsx-a11y,import} eslint-import-resolver-typescript6npm install -D prettier prettier-plugin-astro eslint-config-prettier7# echo {} > .prettierrc.json8
9npx husky-init && npm install10npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'11
12npx astro add svelte13
14npm i sass cssnano autoprefixer
code linterの設定
Astro と Svelte を混ぜるので当然なのですが、両者用の設定が必要でした。なので、init svelte app の箇所に加えて
1npm i -D eslint-plugin-svelte3 prettier-plugin-svelte
ESLint Config
他レポジトリで使っていた svelte 用の Config と混ぜる形で作りました。Svelte は今年に入って触ったばかりなので、設定が正しい状態にあるかはわかりませんが、動いてます。
.eslintrc.yml
1extends:2 - plugin:astro/recommended3 - plugin:jsx-a11y/recommended4 - plugin:import/recommended5 - plugin:import/typescript6 - prettier7overrides:8 - files:9 - '*.astro'10 parser: astro-eslint-parser11 parserOptions:12 parser: '@typescript-eslint/parser'13 extraFileExtensions:14 - .astro15 rules: {}16 - files:17 - '*.svelte'18 processor: svelte3/svelte319 parserOptions:20 parser: '@typescript-eslint/parser'21 extraFileExtensions:22 - .svelte23 rules: {}24 settings:25 svelte3/typescript: true26parser: '@typescript-eslint/parser'27parserOptions:28 ecmaVersion: latest29 sourceType: module30plugins:31 - svelte332 - '@typescript-eslint'33ignorePatterns:34 - './dist/**/*'35settings: {}
Prettier Config
1trailingComma: es52tabWidth: 23semi: false4singleQuote: true5plugins:6 - prettier-plugin-astro7 - prettier-plugin-svelte8pluginSearchDirs: false
ChatGPTとGitHub GraphQL API
GitHub GraphQL API クエリ作成には ChatGPT を利用しました。ChatGPT のバージョンは 3.5 でデータは 2021 年 9 月までのものらしく、例えば 21 年 10 月以降に変わった内容については正確には答えることができません。なので、ChatGPT が出力したクエリを GitHub GraphQl API Explorer で試して正常に動くかを確認し、クエリを調整することにしました。
1GitHub GraphQL API を用いて、ユーザ名oriverkのpinned repository と contribution calendar のデータを取得せよ
ChatGPT-3.5 出力結果
1query {2 user(login: "oriverk") {3 pinnedItems(first: 6) {4 nodes {5 ... on Repository {6 name7 description8 url9 stargazers {10 totalCount11 }12 forkCount13 }14 }15 }16 contributionsCollection {17 contributionCalendar {18 totalContributions19 weeks {20 contributionDays {21 contributionCount22 date23 }24 }25 }26 }27 }28}
Explorer で検証した後、公式ドキュメントを片手に適宜クエリを修正して利用しました。
Contribution Calendar(GitHub草)
Svelte 製ライブラリの多くが更新を止めていたので、自作しました。
RSS fetcher
基本的に CatNose 氏の下記「RSS 集約サイト」に倣いました。なので割愛します。
- チーム個々人のテックブログをRSSで集約するサイトを作った(Next.js)
- catnose99/team-blog-hub: RSS based blog starter kit for teams
- catnose99/timeline: catnose’s timeline
GitHub ActionsによるCloudflare Pagesへの定期的デプロイ
1{2 "scripts": {3 "dev": "astro dev --project tsconfig.json",4 "start": "astro dev",5 "prebuild": "run-s prebuild:*",6 "build": "astro build",7 "preview": "astro preview",8 }9}
GitHub Actions でもこれを利用するようにしました。
workflows/deploy.yml
1name: continuous-deployment2on:3 push:4 branches:5 - main6 - dev7 schedule:8 - cron: "0 2 * * *"9 workflow_dispatch:10
11jobs:12 publish:13 runs-on: ubuntu-latest14 permissions:15 contents: read16 deployments: write17 name: build and deploy to Cloudflare Pages18 steps:19 - name: checkout20 uses: actions/checkout@v321
22 # Run a build step here if your project requires23 - name: setup node24 uses: actions/setup-node@v325 with:26 node-version: 1827
28 - name: install packages and build29 run: |30 npm install31 npm run build32 env:33 MODE: production34 SECRET_GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.SECRET_GITHUB_PERSONAL_ACCESS_TOKEN }}35 PUBLIC_GA_MEASUREMENT_ID: ${{ secrets.PUBLIC_GA_MEASUREMENT_ID }}36
37 - name: deploy to Cloudflare Pages38 uses: cloudflare/pages-action@v139 with:40 apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}41 accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}42 projectName: astro-site43 directory: dist
- astro-site/deploy.yml at main · oriverk/astro-site · GitHub
- Cloudflare Pages GitHub Action · Actions · GitHub Marketplace
AstroでGoogle Analytics
エラー類
Astro と UI FW のどちらに起因するか見極める必要性があり、この点は大変だなあと感じました。
date-fns/locale
svelte と date-fns
1Directory import '/home/oriverk/Codes/oriverk/astro-site/node_modules/date-fns/locale/ja' is not supported resolving ES modules imported from /home/oriverk/Codes/oriverk/astro-site/dist/entry.mjs2Did you mean to import date-fns/locale/ja/index.js?
1import { ja } from 'date-fns/locale'2import ja from 'date-fns/locale/ja/index.js'
CSS Logical Media Query error
Media Queries Level 4 からの次の様な書き方は、Svelte においては次のバージョンから使える模様。
1@media (max-width: 30em) { ... }
- メディアクエリーの使用 - CSS: カスケーディングスタイルシート | MDN
- CSS Logical Media Query error · Issue #8324 · sveltejs/svelte