filesize-analysisというGithub Actionを作った話
GW初日からもくもくと草を生やしている @apple-yagi です。
filesize-analysisというGithub Actionを作ったので紹介します。
filesize-analysis とは
各PRのリポジトリ内にある指定されたディレクトリ内の指定された拡張子のファイルのサイズを取得し、コメントをしてくれるGithub Actionです(こんな感じ↓)。
実際にコメントしているPR
4月29日から作り始めて、本日(4月30)リリースしたので、まだクオリティは低いですが、自分がやりたかった最低限の事はできてると思ってます(プッシュするたびに新しいコメントを作るのがちょっとうざいけど、ファイルサイズの遍歴が見れるからこれはこれでありかも?)。
作った背景
フロントエンド開発において、アプリケーションをビルドした後のファイルサイズは気になるところです。
例えば、Webpackにはwebpack-bundle-analyzerというライブラリがあり、出力されたバンドルファイルのサイズや、バンドルの中に入っているモジュールを確認することができます。
しかし、プルリクエストを出す度にいちいちそういったライブラリでファイルサイズを確認するのは少し面倒です。そして、少し面倒な事はいずれやらなくなります。(そして、バンドルサイズは気付かぬ内に肥大化していく...
そこでエンジニアは、各プルリクエストのコメントにバンドルサイズを表示すれば良いじゃんと思います(私はそう思いました)。
Webpackであれば、以下のようなGithub actionがあります。
このGithub actionは便利なのですが、Github Actionsのworkflowの記述量がとても多くなってしまいます。。。
見たい方はこちらを
name: Diff bundle stats
on: [pull_request]
jobs:
build-base:
name: Build base
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: ${{ github.base_ref }}
- name: Install dependencies
run: npm ci
env:
NODE_AUTH_TOKEN: ${{secrets.TOKEN_REPO}}
- name: Build
run: npm run build-demo
- name: Upload base stats.json
uses: actions/upload-artifact@v2
with:
name: base
path: ./demo/demo-dist/stats.json
retention-days: 1
build-pr:
name: Build PR
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install dependencies
run: npm ci
env:
NODE_AUTH_TOKEN: ${{secrets.TOKEN_REPO}}
- name: Build
run: npm run build-demo
- name: Upload base stats.json
uses: actions/upload-artifact@v2
with:
name: pr
path: ./demo/demo-dist/stats.json
retention-days: 1
report:
name: Generate report
runs-on: ubuntu-latest
needs: [build-base, build-pr]
steps:
- name: Checkout PR
uses: actions/checkout@v2
- name: Download base stats
uses: actions/download-artifact@v2
with:
name: base
path: base
- name: Download PR stats
uses: actions/download-artifact@v2
with:
name: pr
path: pr
- name: Get diff
id: get-diff
uses: NejcZdovc/bundle-size-diff@v1
with:
base_path: './base/stats.json'
pr_path: './pr/stats.json'
- name: Comment
uses: NejcZdovc/comment-pr@v1.1.1
with:
file: 'comment.md'
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
OLD: ${{steps.get-diff.outputs.base_file_string}}
NEW: ${{steps.get-diff.outputs.pr_file_string}}
DIFF: ${{steps.get-diff.outputs.diff_file_string}}
DIFF_PERCENT: ${{steps.get-diff.outputs.percent}}
個人的にはCI(typecheck, Unit Test, etc...)用のworkflowの中に軽い気持ちで差し込みたいなと思っていたので、これは。。。となりました。
また、webpack-bundle-analyzer
で出力されるstats.json
からバンドルサイズなどを引っ張ってきているため、esbuildやviteを使用したときは使えないのでは?と思っています。
なので、今回filesize-analysisを作成しました。
filesize-analysis のコンセプト
filesize-analysis
は前述した背景から以下のようなコンセプトで作成しました。
Github Actionsの記述量を少なくする
filesize-analysis
を使用するためのworkflowの記述量はこれだけです。
on:
pull_request:
permissions:
pull-requests: write # PRにコメントするために必要
jobs:
analysis:
runs-on: ubuntu-latest
steps:
- name: Checkout PR
uses: actions/checkout@v2
- name: Install & Build
run: yarn --frozen-lock && yarn build:production
- name: Analysis
uses: apple-yagi/filesize-analysis@v1
with:
out_dir: "./dist" # ファイルサイズを表示したいファイルが入っているディレクトリ
ext: "bundle.js|chunk.js" # ファイルサイズを確認したい拡張子(単数の場合 -> "bundle.js")
github_token: ${{secrets.GITHUB_TOKEN}}
filesize-analysis
を使用するstep以外にも無駄なものを書いてますが、実質最後の6行だけで以下のようなコメントを出力してくれます(便利✨)。
個人的にpermissions
でpull-requests: write
を与えないといけないところが気に食わないですが、CIの最後とかにスッと入れても良いと思えるくらいの記述量でファイルサイズを教えてくれます🎉
特定のフロントエンドツールに依存しない
ある特定のツール(webpack-bundle-analyzer
など)の出力結果からバンドルサイズを取得してしまうと、別のツール(esbuild
、vite
など)に乗り換えた時に使用できなくなってしまうので、そういったものに依存しないようにしました。
これを実現するためにユーザーが指定したout_dir
やext
から対象のファイルを抽出し、対象のファイルのサイズを見にいくようにしています。
最後に
この記事を書きながら、もしかしてこんなツールもう作っている人いるかな?と思って少し調べたら、こんなものを見つけてしまい、これで良いじゃん、と自分自身思ってしまってます。。。filesize-analysis
はpackage.json
がなくても動く(特定のプログラム言語にも依存していない)ので、別のところで使えるかな(CやGoをビルドした後のファイルサイズとか?)と思ったりしています(diffを出すには特定の言語に縛る必要がある気がしていますが)。
Discussion