Amazon.co.jpのウィッシュリストとランキングページで獲得ポイントの表示を追加__するChrome拡張"Amazon Wishlist Point Visualization"__を作りました。セールになっている商品を見つけやすくなります。
この記事の概要
元々は自分向けにjQueryを使用して作成していたChrome拡張を勉強の一環+脱jQueryとして、TypeScriptで作成しなおしました。私自身がChrome拡張を作成する際に作例が大いにヒントとなったため、重要そうな部分や躓いた点について書いていきます。
プログラムそのものは各自で実装したい内容が異なると思うのであまり触れず、設定ファイル類に絞って記載します。
「Chrome拡張をTypeScriptで作成したい人」の助けになると嬉しいです。
Chrome拡張で作成できる機能はいくつか種類がありますが、今回作成したのは__Content Script__です。これは特定のURLでのみ実行されるスクリプトです。
特定のURLで動作するスクリプトで、表示されているDOM要素を読み込んだり、変更を加える事ができる。文字の大きさを変えたり、リンクを変更したりといった用途に使います。
使用した技術要素
- TypeScript
- webpack
作成したもの
Amazonでウィッシュリストとランキングのページはデフォルトでは金額だけが表示されていて、獲得できるポイントが表示されていません。これでは獲得ポイントが増加するセール中なのか気付けません。
なので価格の横に獲得ポイントも表示させる機能を作りました。
ディレクトリ構造
├─dist 最終的な成果物を出力するディレクトリ
├─public 静的ファイルを格納するディレクトリ
│ ├─images
│ │ ├─icon16.png
│ │ ├─icon48.png
│ │ └─icon128.png
│ └─manifest.json
├─src プログラムを格納するディレクトリ
│ ├─index.ts
│ ├─ranking.ts
│ ├─util.ts
│ └─wishlist.ts
├─package.json
├─tsconfig.json
├─webpack.config.ts
└─yarn.lock
依存関係のインストール
使用するパッケージをインストールします。
yarn add -D typescript ts-loader ts-node webpack webpack-cli copy-webpack-plugin @types/webpack @types/copy-webpack-plugin
パッケージ名 | 用途 |
---|---|
typescript | TypeScript本体 |
ts-loader |
.ts ファイルを.js に変換 |
ts-node |
.ts を直接nodeで実行するために使用(後述する躓きのために必要) |
webpack | 複数のファイルを1つにまとめて出力 |
webpack-cli | webpackをコマンドで実行するために使用 |
copy-webpack-plugin | webpackでファイルをコピーするために使用 |
@types/webpack | TypeScript向けの定義データ |
@types/copy-webpack-plugin | TypeScript向けの定義データ |
"scripts": {
"build": "webpack --mode production"
}
マニフェストの作成
{
"manifest_version": 3,
"name": "Devola: Amazon Wishlist Point Visualization",
"short_name": "Devola",
"version": "1.3.0",
"description": "説明文",
"default_locale": "ja",
"icons": {
"16": "images/icon16.png",
"48": "images/icon48.png",
"128": "images/icon128.png"
},
"content_scripts": [
{
"matches": [
"https://www.amazon.co.jp/*/wishlist/*",
"https://www.amazon.co.jp/portal-migration/bestsellers/*",
"https://www.amazon.co.jp/gp/bestsellers/*",
"https://www.amazon.co.jp/gp/new-releases/*",
"https://www.amazon.co.jp/gp/movers-and-shakers/*"
],
"css": [],
"js": ["js/index.js"],
"run_at": "document_end"
}
]
}
matches
にて処理を実行したいURLパターンを定義します。今回はAmazonのウィッシュリストとランキングページを指定しています。
js
にて実行するスクリプトを指定します。/dist
が最終出力のディレクトリになるため、/dist/js/index.js
を実行するよう指定しています。
run_at
にてスクリプトを実行するタイミングを指定します。今回はDOMが読み込まれたタイミングで実行したいためdocument_end
を指定しています。その他のタイミングにしたい場合はドキュメントを参照してください。
TypeScriptの設定
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"strict": true,
"esModuleInterop": true,
"typeRoots": [ "node_modules/@types"]
},
"exclude": [
"node_modules"
],
"ts-node": {
"compilerOptions": {
"target": "es2020",
"module": "commonjs"
}
}
}
Chromeは新しいESにも対応しているため"target": "es2020"
を指定しています。
webpack.config.ts
を使用している場合module
にcommonjs
以外を指定すると、エラーが発生します。そのためts-node
を使用して一旦commonjs
としてプログラムを読み込ますことでエラーを回避しています。
webpackの設定
import webpack from "webpack";
import path from "path";
import CopyWebpackPlugin from "copy-webpack-plugin";
const config: webpack.Configuration = {
entry: {
index: path.join(__dirname, "src/index.ts"),
},
output: {
path: path.join(__dirname, "dist/js"),
filename: "[name].js",
clean: true,
},
module: {
rules: [
{
test: /.ts$/,
use: "ts-loader",
exclude: "/node_modules/",
},
],
},
resolve: {
extensions: [".ts", ".js"],
},
plugins: [
new CopyWebpackPlugin({
patterns: [{ from: "public", to: "../" }],
}),
],
};
export default config;
entry
にてバンドルする起点となるファイルを指定しています。index.ts
をindex
という名前で定義しています。Chrome拡張を作成する際にContent Script以外も作成する場合はindex
をcontent
などに書き換えたりすると出力結果が見分けやすくなると思います。
output
にてバンドルした結果をどこに出力するかを指定しています。今回は/dist/js/[name].js
として出力するように指定しています。[name]
にはindex
が入ります。
module
にてバンドルの対象となるファイルを指定しています。rule
にて一致した条件のファイルを何を用いて処理するのかを指定しています。今回は.ts
なファイルをts-loader
を使用して変換することを指定しています。node_modules
配下のファイルは変換したくないため除外しています。
resolve
にてプログラム内でimportする際に省略する可能性のある拡張子を指定しています。
plugins
内でCopyWebpackPlugin
をどのように使用するかを定義しています。/public
配下のファイルをoutput
で指定したディレクトリ(/dist
)にコピーするよう指定しています。
ビルドする
yarn build
実行してみると/dist
にファイルが出力されます。
dist
├─images
│ ├─icon16.png
│ ├─icon48.png
│ └─icon128.png
├─js
│ └─index.js
└─manifest.json
後は/dist
をzip化してChrome拡張の管理画面でアップロードすることで公開が行えます。
ここまで読んでいただきありがとうございました。実装コードはGitHubにて公開しています。