Open43

Astroでブログ置き換えの作業メモ

ヤマチューヤマチュー

作業スレ

ヤマチューヤマチュー

セットアップ

インストール
npm create astro@latest
選択肢のログ
Welcome to Astro! (create-astro v1.0.1)
Lets walk through setting up your new Astro project.

✔ Where would you like to create your new project? … ./yamachoo.com.v2
✔ Which template would you like to use? › Empty project
✔ Template copied!
✔ Would you like to install npm dependencies? (recommended)yes
✔ Packages installed!
✔ Would you like to initialize a new git repository? (optional)yes
✔ Git repository created!
✔ How would you like to setup TypeScript? › Strict (recommended)
✔ TypeScript settings applied!
✔ Setup complete.
✔ Ready for liftoff!

一週間前の調査時点から若干tsconfig.jsonなどに変更が加えられていそう

ヤマチューヤマチュー

eslint + prettier + npm-run-all

久しぶりに設定したので、自分の古いリポジトリ見たり、記事読んでいる👀
https://www.mizdra.net/entry/2022/03/24/093000

最終的にたどり着いたもの

npm init @eslint/config

✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · none
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser, node
✔ How would you like to define a style for your project? · guide
✔ Which style guide do you want to follow? · standard-with-typescript
✔ What format do you want your config file to be in? · JavaScript
npm install --save-dev eslint eslint-plugin-astro
npm install --save-dev @typescript-eslint/parser
npm i --save-dev prettier-plugin-astro prettier
npm install --save-dev eslint-config-prettier

npm i -D npm-run-all
.eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true
  },
  extends: ['plugin:astro/recommended', 'standard-with-typescript', 'prettier'],
  parserOptions: {
    project: './tsconfig.json',
    extraFileExtensions: ['.astro']
  },
  overrides: [
    {
      files: ['./src/env.d.ts'],
      rules: {
        '@typescript-eslint/triple-slash-reference': 'off'
      }
    }
  ]
}
.prettierrc.js
module.exports = {
  semi: false,
  singleQuote: true,
  tabWidth: 2,
  trailingComma: 'none'
}

JSやTSのeslintはconfig系のファイルを.jsで書く&将来のため入れているけど、もう少しシンプルにできるのかも

ヤマチューヤマチュー

standardを使いたいと思って色々と追加していたせいで、地味にeslintのエラーで詰まって2時間くらい溶かしてしまった
特に下のエラーの解決に時間がかかってしまった

エラー内容
  0:0  error  Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: src/pages/index.astro.
The file must be included in at least one of the projects provided

docsを眺めていて、extraFileExtensions: ['.astro']が必要そうだと気づいて追加したら上手くいった!

https://github.com/ota-meshi/astro-eslint-parser#parseroptionsparser

正直、eslint-plugin-astroの方で入っているからいらないのではと思っていたけど、standard-with-typescriptあたりに上書きされてしまっているんだろうなぁ

ヤマチューヤマチュー

daisyUIの導入

tailwindを使いつつも、基本的なものまで書くのは面倒なのでdaisyUIを入れる

https://daisyui.com/docs/install/?lang=en

npm run astro add tailwind
npm i -D daisyui

基本はインテグレーションが良しなにやってくれるので、以下の部分だけ修正

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
  plugins: [require('daisyui')]
}
ヤマチューヤマチュー

叩き用のレイアウトなどの作成

とりあえず、componentsに

  • Header
  • Main
  • Footer

あたりを簡単に作成して、Layoutを作成してみている

404も、とりあえず追加

ヤマチューヤマチュー

マークダウン周りの設定

過去に作っていたマークダウンの記述の記事が地味に役立った
ただ過去のGatsbyをちゃんとしていたせいか、設定しなきゃいけないことは結構ありそう👀

ヤマチューヤマチュー

和訳だと若干古いのか、このあたりの記述がなかったので英語で確認していった方が良さそう

astro.config.mjs
import { defineConfig } from 'astro/config';
import remarkToc from 'remark-toc';
import rehypeMinifyHtml from 'rehype-minify';

export default defineConfig({
  markdown: {
    remarkPlugins: [remarkToc],
    rehypePlugins: [rehypeMinifyHtml],
    // Preserve Astro's default plugins: GitHub-flavored Markdown and Smartypants
    // default: false
    extendDefaultPlugins: true,
  },
}

https://docs.astro.build/en/guides/markdown-content/#markdown-plugins

ヤマチューヤマチュー
npm i -D remark-code-titles
astro.config.mjs
// 略
import remarkCodeTitles from 'remark-code-titles'

export default defineConfig({
  // 略
  markdown: {
    remarkPlugins: [remarkCodeTitles],
    extendDefaultPlugins: true
  }
})

※rehype-code-titlesでは上手くいかなかった…
(そもそもremarkとrehypeの違いよく分かってないし、原因を知りたいなら勉強したほうが良さそう)

ヤマチューヤマチュー

マークダウンのCSS周りの設定

マークダウンはtailwindを使わないので、独自のCSSを書く

stylelintの設定

あまり要る気もすしないけど、正しく書ける気もしないので導入

npm install --save-dev stylelint stylelint-config-standard
npm install --save-dev stylelint-config-prettier
npm install --save-dev stylelint-config-rational-order
.stylelintrc.js
module.exports = {
  extends: [
    'stylelint-config-standard',
    'stylelint-config-recess-order',
    'stylelint-config-prettier'
  ]
}

https://stylelint.io/user-guide/get-started

ヤマチューヤマチュー

tailwindを使っているときにpostcssのnestingとか使いたいときは、ドキュメントを参考にpostcss.config.jsを作成して使いたいものを入れればOK

postcss.config.js
module.exports = {
  plugins: {
    'tailwindcss/nesting': {}
  }
}

またドキュメントに対して一見、tailwindcssautoprefixerが足りなさそうだが、インテグレーションでその部分は入っているみたいなので書かなくても動くよう

https://tailwindcss.com/docs/using-with-preprocessors

自作のCSSの中でTailwindのクラスの値を利用する

theme('screens.sm')のようにして自作のCSSでも同じ値が使える
→現在、自分の変数とかで置いている部分も置き換えれば完璧👍

ヤマチューヤマチュー

結局デザインを整えつつ、posts用のlayoutを作成した

TailwindやdaisyUIの仕組みに上手く乗れるようにCSSを修正したので、良い感じにダークモードやテーマの行き来ができるようになった
既存のブログの遺産を活かしつつ、改善ができたので良かった

あとはマークダウンのimageの部分を最適化できると良い

ヤマチューヤマチュー

外部リンクをタブで開くようにする

rehype-external-linksでいけそう
→上手くいかない。二度目だし、やっぱりrrehypePlugins上手く動いてなさそう?
→不本意ながらremarkの方で実装。あとで調査して置き換える方向で調整する

https://github.com/rehypejs/rehype-external-links

※remarkにも同じようなライブラリがあるが、rehype側を利用するように書かれていた

ヤマチューヤマチュー

SEO周りの最適化

これを使ってみる

https://github.com/jonasmerlin/astro-seo/tree/e7fdb7febd09ce77b32a5ee54e3b28bf4e6e79a9

あとはLighthouseを使いながら、少しだけ調整

  • descriptionタグの追加
  • 画像のaltタグ忘れの修正
  • CSSのminify対応
    • process.env.NODE_ENVが使えなかったので一部対応できず
    • import.meta.env.MODEを使わないといけなさそう。そのためにはconfigをmjstsにしないといけなさそう
      import.meta.env.MODEがconfig内では使えなさそう?.astro内では使えているので問題なさそうだけど…(そこまで重要ではないので、後で調べてみる)

https://tailwindcss.com/docs/optimizing-for-production

ヤマチューヤマチュー

CSS以外も圧縮してくれるインテグレーションあったの思い出したので導入
サードパーティだけど割と良さそう!

https://github.com/NikolaRHristov/astro-compress#readme

postcss側でcssnano入れて、astro-compressではcssoの圧縮されているけど、一応動いている&cssnanoの効果もありそうなので、このままでいくが、もしかしたらcssnanoを削除してもいいかも

ヤマチューヤマチュー

久しぶりに再開

ライブラリの更新

思いの外、Astroの更新が多かったので、まずはライブラリのアップデートを行った

npx npm-check-updates -u
npm i
ヤマチューヤマチュー

マークダウンのCSSの改善

パンダさんのブログを見ていたら@tailwindcss/typographyが良さそうとなり導入を決めた

https://panda-program.com/posts/from-gatsby-to-nextjs

daisyUIにも記載があった👀

https://daisyui.com/docs/layout-and-typography/

あと久しぶりに考えたらCSSを普通に書いていたがあまり良い手ではないので、@applyを使うのが良いと思ったので修正

https://tailwindcss.com/docs/reusing-styles#extracting-classes-with-apply

ヤマチューヤマチュー

考えたいこと&覚書スレ

ヤマチューヤマチュー

Blogの記事部分の構成について

前回のGatsbyのときは、src/posts配下に記事ごとにディレクトリを切り、そこにマークダウンと画像を置いていたことを思い出した
またリンクは/<blog-title>で特に/blog/<blog-title>とかにしていなかったので維持したい
→記事数も大したこと無いし、諦める方向で決定

一方、Astroはsrc/pages配下にマークダウンを置くとルーティングされる
似たような挙動にしたいなら、

  • src/pages/<blog-title>/index.md

とかでいける気はするが、記事が多くなったら(なる気もしないが)大変そう
それよりもちゃんとルーティングの設定をしても良い気もする

ヤマチューヤマチュー

他のBlogのテーマを見ていると、割とpublic配下にimagesディレクトリを切って、そこに全てのイメージを置いていそう
ただし、この場合は画像圧縮とかができなくなるので、採用するかは悩ましそう
→多分、問題なさそう

あとpages配下にblog or postディレクトリを切っているので、これが普通みたい
「郷に入っては郷に従え」でリンクは諦めても良さそう
(というかNext.js使っている人のブログもよくよく見たら同じ構成だったので、こういうものなのかもしれない)

ヤマチューヤマチュー

いったん、src/pages/posts/<blog-title>/index.mdを採用してみる
→とりあえずリンク的にはいけそう

(※画像は上手くいかなさそうなので、ちょっと考えるかも)

ヤマチューヤマチュー

マークダウン用のCSSをどうするか問題

tailwindでは制御しにくい部分なので、素直に独自のCSSで設定するのが丸そう
ついでにstylelintも設定しておきたい

(baseスタイルなどにテーマを当てると他の部分にも影響を与えてしまうため)

ただ、よくよく考えると、tailwindに上手く入れ込まないといけないかも??

ヤマチューヤマチュー

マークダウン内での画像の取り回し

せっかくディレクトリを記事ごとに分けているのにも関わらず、画像だけは記事のディレクトリを無視してルーティングが勝手にされてしまう
→そもそも画像がなさそう?

多分、設定がなにかあるはずなので、明日対処する
→publicに入れておくか、mdxを使って<Image>とか使うしかなさそうかも

思いつきだが、public/pages/<blog-title>/xxx.pngとかにすればパスが揃いそうかも?
→そもそも、src/pages/posts/<blog-title>/index.mdというマークダウン内で![サンプル](./sample.png)みたいに書くと、パスが/posts/sample.pngとなり、<blog-title>が無視されてしまう

ヤマチューヤマチュー

rehypeにも似たようなの見つけた

一応、どちらでも生成される結果は同じっぽいし大丈夫そうだけど、こっちの方が最近でもメンテナンスされていそうなので、こっちを採用する
→入れてみたが上手く動いてなさそうなので、remark側も試してみる
→remark側なら上手くいった。なぜ?

https://github.com/rockchalkwushock/rehype-code-titles

ヤマチューヤマチュー

📝remark → rehypeに置き換える

remark-code-titlesやremark-external-linksをrehype製のものに置き換えたい
現時点では、astroにissueは上がっていないが、どうもrehypePluginsが動いていなさそうな気がしているが…
実際にコードを読むのが良さそう👀

ヤマチューヤマチュー

マークダウン内での画像の最適化

画像の最適化は@astrojs/imageを使えば良さそうと思っていたが、Markdownのことも考えるとastro-imagetoolsの方が今回の使い方なら良いかもしれない。
→思った感じのことはできなかったので、@astrojs/image@astrojs/mdxを組み合わせる方向で考えてみる

https://astro-imagetools-docs.vercel.app/en/markdown-images

ただ少し気になるのは@astrojs/imageとastro-imagetoolsの関係性がよくわからない
正直、似た機能を提供しているので、今後もwatchしておいた方が良さそうかも👀

ヤマチューヤマチュー

@astrojs/image@astrojs/mdxの組み合わせもあまりうまく行かなさそう
→よくよく考えてみるとメジャーバージョン出ていないし、まだ早すぎるのかもしれない

やっぱり、やりたいことに対して上手な解決策が思いつかない…
→ただ、正直そこまでこだわることでもないので、いったん保留にしてみる

ヤマチューヤマチュー

@astrojs/image<Picture />で生成される画像、build結果が微妙かも
Gatsbyとかだとassetみたいなディレクトリにまとめて生成される感じだったが、Astroだとdistの直下に全部移ってしまうよう?(自分の設定が悪いだけかもしれないが)

ただ開発が活発&まだv0.5.0だし、そのうち設定できるようになるのかも?
いったんv1が出るまでは自分の用途的に必須でもないので保留で良いかも

ヤマチューヤマチュー

感想

  • astroテンプレートについて
    • 個人的にはvueに似ていて結構書きやすい
    • ただ、型安全なのか?と言われると微妙そう
  • いろいろなUIフレームワークが使える点
    • 今の所、astroテンプレートで十分感がある
    • そして何より、よくよく考えてみるとlintとかの設定をまともにしようと思うと、いろいろな記法で書ける環境を構築するの面倒くさそう(独自のテンプレートあるやつは特に)
    • 色々なUIコンポーネント使いたいなら、npm経由でnode_modulesから読み込んだ方が良さそうな気もする
  • astroでやれることについて
    • 思った以上にカスタマイズ性が高い
    • 個人的にはremarkでの拡張がめっちゃ便利
    • Gatsbyなどに比べても独自のプラグインではなく、それぞれのライブラリの拡張機能を上手く組み込んでいるように思われる
  • lint系のツールについて
    • ちょっと意外だったのが、lint系ツールの進化。1年前に比べても格段に記述しなくてはいけないことが減っている気がする。やっぱり時代はノーコンフィグの時代に移りつつあるのかな?
  • vscodeについて
    • 久しぶりに触っているが、やっぱりサクサク動く感じが良い
    • あと意外と前に入れていたプラグインの機能が標準で取り込まれていたりして、プラグイン周りをシンプルにできるのが良かった
    • ただ、最近はIntellijに慣れてきたせいかショートカットキーを間違えるので、やっぱりJetBrainに課金しても良い気がしてきた
ヤマチューヤマチュー

astroの惜しいところ

  • rehypePluginsが動いてなさそう?(調べきれていないので、自分が悪いかもだけど…)
  • 画像の取り回しが、まだまだGatsbyほど成熟されきっていない感
    • 多分、Next.jsのImageとか参考にしていそうだけど、まだまだ開発中という感じ
  • draft: true使った場合に、スキップされるのがマークダウンだけなので画像をpublicに置いていると微妙
ヤマチューヤマチュー

番外編

Tailwindについての疑問

MPAで作るBlogとかの場合、Tailwindの強みって活きてくるんだっけ?を感じている
ページごとに使っているCSSだけを読み込むようにしたいけど、生成されるCSSを見ている感じ分割されずに読み込んでいるので、これ巨大になった時に良いんだっけ?と感じる
ただ逆に言えば、初回に読み込まれてしまえば、その後はキャッシュされているから早いのかもしれないので、詳しいことが分からない…

あー、でも同じCSSは使い回されているわけだから普通に書くよりは圧縮できているかも?

Next.js、すごくね?

Astro見ていて感動したのだが、よくよく調べてみるとNext.jsが既に出している機能っぽいところに自分は感動していそうと思った
マークダウンのあたりでremarkとrehypeでカスタマイズできるあたりとか

https://nextjs.org/docs/advanced-features/using-mdx

割とReactしか書かない or 書きたくない、ならNext.jsの方が良さそうな気もする