LoginSignup
2
1

More than 1 year has passed since last update.

Chrome拡張(Content Script)をTypeScriptで作成した際の設定類【個人開発】

Last updated at Posted at 2021-09-17

Amazon.co.jpのウィッシュリストとランキングページで獲得ポイントの表示を追加するChrome拡張"Amazon Wishlist Point Visualization"を作りました。セールになっている商品を見つけやすくなります。

この記事の概要

元々は自分向けにjQueryを使用して作成していたChrome拡張を勉強の一環+脱jQueryとして、TypeScriptで作成しなおしました。私自身がChrome拡張を作成する際に作例が大いにヒントとなったため、重要そうな部分や躓いた点について書いていきます。

プログラムそのものは各自で実装したい内容が異なると思うのであまり触れず、設定ファイル類に絞って記載します。

Chrome拡張をTypeScriptで作成したい人」の助けになると嬉しいです。

Chrome拡張で作成できる機能はいくつか種類がありますが、今回作成したのはContent Scriptです。これは特定のURLでのみ実行されるスクリプトです。

特定のURLで動作するスクリプトで、表示されているDOM要素を読み込んだり、変更を加える事ができる。文字の大きさを変えたり、リンクを変更したりといった用途に使います。

https://oxynotes.com/?p=8836

使用した技術要素

  • 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向けの定義データ
package.json
  "scripts": {
    "build": "webpack --mode production"
  }

マニフェストの作成

manifest.json
{
  "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の設定

tsconfig.json
{
  "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を使用している場合modulecommonjs以外を指定すると、エラーが発生します。そのためts-nodeを使用して一旦commonjsとしてプログラムを読み込ますことでエラーを回避しています。

webpackの設定

webpack.config.ts
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.tsindexという名前で定義しています。Chrome拡張を作成する際にContent Script以外も作成する場合はindexcontentなどに書き換えたりすると出力結果が見分けやすくなると思います。

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にて公開しています。

参考にした記事

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1