はじめに
皆さんはマジカルミライ
をご存知でしょうか。
初音ミクのライブなわけですが、このチケットを応募する際に面倒な点がありました。
個人情報を応募するたびに入力しなければいけない点です!!!
マジカルミライ2023は大阪、東京合わせて12公演あるので、
もし、すべてに応募する場合、12回入力する必要が出てきます。
ということで、今回はこの個人情報を入力する部分をChrome拡張機能
を利用して、
自動入力してもらおうと思います。
ただChrome拡張機能作っても面白くないので、Typescriptで作成し、Github Actionsで自動Build&Releaseまで目指します。
今回作成した成果物
念のため
自動入力を目的に作り始めますが、実際のソースの解説は今回しません。
フォームの内容をlocalstorage に記録し、次回以降localstorage から呼び出せるようにする感じです。
どこかで別の記事にはするかもしれませんが…
また、botと同じ扱いとなる可能性があります。
今回作成した拡張機能の使用は自己責任でお願いします。
Typescript でChrome 拡張機能の雛形作成
まずプロジェクトフォルダを作成して、npmの初期設定をしていきます。
コマンドラインでpackage.jsonを作成することができます。
package.json の作成
npm init
package.jsonの中身はよしなに必要事項を書いてください。
この後buildコマンドをここに記載していきます。
Typescript の導入
今回はTypescriptで作成するので、Typescriptを導入していきます。
Chromeの型定義も一緒に導入します。
npm install -D typescript @types/chrome
tsconfig.jsonを作成します。
下記コマンドで初期化できますが、ファイルを作成しても問題ありません。
npx tsc --init
ビルドツールを使用する予定なので、tscによるトランスパイルは行わない設定にしていきます。
ただ、型チェックは引き続き行いたいので、"outDir"は入れず、"noEmit"をオプションに追加します。
{
"compilerOptions": {
"target": "ESNext",
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"useDefineForClassFields": true,
"module": "ESNext",
"rootDir": "./src",
"moduleResolution": "node",
"baseUrl": "src",
"resolveJsonModule": true,
"allowJs": true,
"checkJs": true,
"removeComments": true,
"esModuleInterop": true,
"strict": true,
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"skipLibCheck": true,
"noEmit": true,
"isolatedModules": true
},
"include": ["src"],
"exclude": ["node_modules", "dist", "./tsconfig.json"]
}
Vite の導入
Typescriptなので、ビルドを行い、Javascriptにしていく必要があります。
webpackも検討しましたが、思ったより簡単にできなかったので見送りました。
実行時間もViteのほうが早いようなので、今回は様々あるビルドツールの中でViteを採用していきます。
npm i -D vite
導入が終わったら設定ファイルを書いていきます。
rootディレクトリやoutput先、inputするファイルなどを設定します。
import { resolve } from 'node:path'
import { defineConfig } from 'vite'
export default defineConfig((opt) => {
return {
root: 'src',
build: {
outDir: '../dist',
rollupOptions: {
input: {
index: resolve(__dirname, 'src/index.ts'),
},
output: {
entryFileNames: '[name].js',
},
},
},
}
})
manifest.jsonの作成
これで基本的な設定が整いました。
あとはChrome拡張に必要なmanifest.json とindex.ts を作成するだけです。
今回はva.pia.jp に適用できるよう設定していきます。
また、出力されるファイルはindex.js となるため、content_scripts にindex.jsを読み込むよう設定していきます。
manifest.json はsrc/public に作成していきます。
{
"manifest_version": 3,
"name": "Auto Form Input",
"description": "Base Level Extension",
"version": "1.0",
"content_scripts": [
{
"matches": ["http://va.pia.jp/*", "https://va.pia.jp/*"],
"js": ["index.js"],
"css": ["global.css"]
}
]
}
package.json の修正
最後にビルドを行うために、package.json のscript に以下を追加します。
tsc を行った後、vite のbuildを行います。
vite のbuild を行う際に、outdirが空でない場合、エラーが発生しますが、emptyOutDirオプションをつけてあげることで、エラーを発生させないようにできます。
今回は空でなくてもビルドできるよう、オプションをつけていきます。
"build": "tsc && vite build --emptyOutDir"
Typescript でChrome 拡張機能の雛形完成
これで、Typescript でChrome 拡張機能を作成するひな形が完成しました。
あとはsrc フォルダ内にindex.ts ファイルを作成し、書き始めるだけです!
Github リリースノートを自動作成する
皆さんご存じの通り、Github はGithub Actions が存在します。
このGithub Actions を利用して、Chrome 拡張機能をbuild して、Github のリリースノートにbuild した成果物を掲載したいと思います。
release.yml を作成する
.github/workflows フォルダにymlファイルを作成します。
今回はリリースノートには特に記載せず、build を行った日時のzipファイルが生成されるように設定しました。
また、発火するタイミングはmain ブランチにpush されたタイミングとしました。
yml ファイルの全体像は以下の通りです。
name: build and release
on:
push:
branches: [main]
jobs:
release:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.step_version.outputs.version }}
upload_url: ${{ steps.step_upload_url.outputs.upload_url }}
steps:
- name: Generate release tag
id: release_tag
env:
TZ: 'Asia/Tokyo'
run: echo "nowDATE=$(date +'%Y-%m-%d_%H:%M:%S')" >> $GITHUB_ENV
- uses: actions/checkout@v3
- name: ci
run: npm ci
- name: Build
run: npm run build
- name: Zip output
run: zip -r ${{ env.nowDATE }}.zip dist
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release
draft: false
prerelease: false
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./${{ env.nowDATE }}.zip
asset_name: ${{ env.nowDATE }}.zip
asset_content_type: application/zip
各yml ファイルの説明
少しだけですが、何を行っているか説明しようと思います。
- name: Generate release tag
id: release_tag
env:
TZ: 'Asia/Tokyo'
run: echo "nowDATE=$(date +'%Y-%m-%d_%H:%M:%S')" >> $GITHUB_ENV
リリースファイルのための日時を作成しています。
シンプルにdateをnowDate としてGITHUB_ENV に残しています。
- uses: actions/checkout@v3
- name: ci
run: npm ci
- name: Build
run: npm run build
- name: Zip output
run: zip -r ${{ env.nowDATE }}.zip dist
リリースノートを作成します。
各項目を記載しますが、今回はtag をブランチ名にし、そのほかは特に設定しないことにしました。
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release
draft: false
prerelease: false
build された成果物をリリースノートにアップロードします。
パスと名前は日付にしているため、追記した環境変数から取得するようにしています。
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./${{ env.nowDATE }}.zip
asset_name: ${{ env.nowDATE }}.zip
asset_content_type: application/zip
これで自動的にmain ブランチにpush されるとリリースされるようになりました!
感想
今回はChrome の拡張機能をTypescript で作成しましたが、実際ここまでする必要はなんだろうなぁという気持ちはあります。
ただ、React を今まで使ってこなかった&Next.js などはすでにTypescript のビルドが含まれていたりと、考慮することがなかったので良い経験になりました。
また、自動でリリースノートを作成するワークフローも作成してみたかったので、勉強になりました。
何かの参考になれば幸いです。
参考