SBI証券のUIに不満があったので久々にChrome拡張作った
開発TypeScript
何を作ったか
SBI証券 クイックメニュー というのを作った
SBI 証券の画面上部に「クイックメニュー」ボタンを追加し、ホバーするとメニューが出てくる。
よく使うページをユーザーが設定することもできる。
なぜ作ったか
SBI 証券のサイト構造が複雑すぎる。
SBI と楽天でよく比較がされるが、大体楽天のほうがUIやサイトの使いやすさは良いと言われることが多いが、自分は SBI が好きなのでどうにかしたいと思った
どう作ったか
Chrome 拡張を作るのは久々だった。最後に作ったのは数年前で、jQuery で DOM をゴリゴリいじる感じで作っていた。手続き的な書き方でカオスになりがちだったので、今回は React を使うことにした。
使ったライブラリ
ざっと書くとこんな感じ
- React
- @extend-chrome/storage
- typescript
- webpack
構造
大きく分けると2つ。
manifest.json はこんな感じ
{
"manifest_version": 3,
"name": "SBI証券 クイックメニュー",
"version": "1.6",
"description": "SBI証券にクイックメニューを追加し、目的のページにより簡単に飛べるようになります",
"icons": {
"128": "icon.png"
},
"options_page": "options.html",
"permissions": ["storage"],
"content_scripts": [
{
"matches": ["https://*.sbisec.co.jp/*"],
"css": ["assets/main.css"],
"js": ["bundle.js"],
"run_at": "document_idle"
}
]
}
メイン
クイックメニューを表示する Component
SBI の DOM を id で指定して、 React.createRoot
している
try {
const headerLi = document.createElement("li");
const headerContainer = document.getElementById("link02M");
if (!headerContainer) throw new Error("Root element not found");
const targetUl = headerContainer.querySelector("ul");
// targetUl の最初の要素として headerLi を追加する
if (!targetUl) throw new Error("Root element not found");
targetUl.insertBefore(headerLi, targetUl.firstChild);
const headerRoot = createRoot(headerLi);
headerRoot.render(<HeaderMenu />);
} catch (error) {
console.error(error);
}
SBI側の UI いじり
こんな感じの上書きをしている
#NAVIAREA02 {
height: auto !important;;
}
#HEADER01 #link02 {
width: 700px !important; /* デフォルトが590px */
right: 0px !important;
left: auto !important;
}
Chrome拡張では、cssファイルを読み込ませることができるが、style タグとして埋め込むとかではなく、 manifest.json
で指定することになる。
この css の指定がそれ。
"content_scripts": [
{
"matches": ["https://*.sbisec.co.jp/*"],
"css": ["assets/main.css"],
"js": ["bundle.js"],
"run_at": "document_idle"
}
]
オプション
メニュー項目をカスタマイズする画面
以下のファイルで構成
- options.html
- options.css
- options.ts
カスタムメニューの作り方
chrome.storage
を使って保存している
困ったこと
ts で書こうとしたが、 chrome
をどうやったら手軽に型付けできるか分からなかった。
@extend-chrome/storage
を使えば解決した。内部で頑張ってくれている。
エンジニアとしてはこのライブラリを読み解いて、 chrome
の扱いについて勉強するべき・・。
そうでなくても chrome.storage
のコードは煩雑になりがちなので、このライブラリは使った方がいい。
Webpack
上述の2種類に分かれるので、 entry は 2つ。
entry: {
bundle: "./src/index.tsx",
options: "./src/options.tsx",
},
output: {
path: `${__dirname}/dist`,
filename: "[name].js",
},
entry の key 名が、 output.filename
の [name]
になるって初めて知った
また、 option.html
のために options.js
を使うが、 bundle.js
は必要ないので以下のようにした
new HtmlWebpackPlugin({
filename: "options.html",
template: "src/options.html",
chunks: ["options"],
excludeChunks: ["bundle"],
}),
Chrome 拡張っていいよね
- いろんな事ができる
- 既存のサイトも魔改造できる
- 手軽に作れる
- 長いものに巻かれたプロダクトを作れる(今回は SBI に巻かれている)
- 審査が早い(数分。一度審査クリアすると0秒で終わる)
- 維持費が安い
おすすめ