utamaro’s blog

誰かの役に立つ情報を発信するブログ

vuejsもreactjsも使わないchrome拡張機能の作り方

chrome拡張機能の作り方

この記事では、一人でchrome拡張機能を開発して、ストアに上げるためのデータを作るまでをご紹介します。

また、有料のサンプルコードをBaseにて提供しています。
googleで検索したページのタイトルをジョジョの名言に置き換える拡張機能です。)
(購入はこちらから)

utamaro.base.shop

サンプル画像(左の検索結果が、右の画像のようになるサンプルです)

f:id:miyaji-y26:20180716182713p:plainf:id:miyaji-y26:20180716182717p:plain

※ html, css, javascript, npmで依存関係の管理ができることを前提条件としています。

まずは、拡張機能を作るにあたっての要件を決めます。

  • 要件
    • 規模が大きくなっても、効率的に開発できること
    • console.logデバッグをビルド段階で削除すること(ビルド後のソースに含まれない)
    • html内のdomを作成する際はテンプレートとして用意したものを使う
    • scssで開発する
    • font-awesomeを使う(アイコンを表示するための神ライブラリ)
    • ファイルを保存して、画面を更新すると変更が適用されていること(毎回手動でのビルドは不要)
    • 開発段階と、リリース段階の設定ファイルを分けること
    • htmlからのjs, cssの読み込みは最低限(多くてもそれぞれ2つまで)とする
    • ビルドで作成されたソースコードはminifyされていること
    • 追加で勉強することが少ない(少しググるだけ)

これらの要件に当てはまるように使用するライブラリを選定します。

chrome拡張機能を作るための構成

有料で用意したサンプルの構成を基に解説します。

サンプルでは「googleの検索結果のタイトルをジョジョの名言に置き換える拡張機能」を作りました。

こちらで解説するのは以下の項目についてです。 - ファイル構成 - package.jsonの設定 - コマンド使用例 - templateについて

その他についてはソースコード内にコメントで書いています。

ファイル構成

サンプルコードのファイル構成は以下のようになっています。

.
├── extension  ⇠ このファイルをzip化するとそのままストアに上げることができます。
│   ├── assets
│   │   ├── css  ⇠ scssのファイルがコンパイルされると更新されます。
│   │   └── js  ⇠ jsファイルがコンパイルされると更新されます。
│   ├── icons  ⇠ 拡張機能に必要なアイコンを入れます。
│   │   ├── icon128.png
│   │   ├── icon16.png
│   │   ├── icon256.png
│   │   └── icon48.png
│   ├── manifest.json
│   └── popup.html
├── js  ⇠ 開発用のjsファイルです。コンパイルが必須です。
│   ├── content.js
│   └── script.js
├── node_modules
│   └── ...
├── package-lock.json
├── package.json
├── scss  ⇠ 開発用のscssファイルです。コンパイルが必須です。
│   ├── contentStyle.scss
│   ├── popstyle.scss
│   └── reset.scss
├── templates
│   └── helloMessage.handlebars
├── web-fonts-with-css  ⇠ font-awesomeで使用します。
│   └── scss
├── webpack.base.config.js  ⇠ dev,productionのベースとなるwebpackコンフィグです。
├── webpack.dev.config.js  ⇠ 開発用のwebpackコンフィグです。
└── webpack.production.config.js  ⇠ リリース用のwebpackコンフィグです。

package.jsonの設定

{
  "name": "starter01",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "scss-dev-w": "node-sass -r ./scss -o ./extension/assets/css/ -w --output-style expanded",
    "scss-dev": "node-sass -r ./scss -o ./extension/assets/css/ --output-style expanded --indent-type tab --indent-width 1",
    "scss-product": "node-sass -r ./scss -o ./extension/assets/css/ --output-style compressed",
    "webpack-dev": "webpack --config webpack.dev.config.js --mode development --progress --display-error-details",
    "webpack-dev-w": "webpack --config webpack.dev.config.js --mode development --progress --display-error-details --watch",
    "webpack-production": "webpack --config webpack.production.config.js --mode production --progress --display-error-details"
  },
  "author": "y-miyajima",
  "license": "ISC",
  "dependencies": {
    ...
  },
  "devDependencies": {},
  "directories": {
    "lib": "lib"
  },
  "description": ""
}

package.jsonのscriptsによく使うコマンドを用意しています。

例えば、scss-devですが、これはnode-sassというnpmモジュールを使ってscssをcssに変換するコマンドです。

また、-wがついているものは、ファイルが更新されると自動的に変換されます。

ただし、更新を監視するフォルダを指定しているので、環境が変わった際は修正が必要です。

それぞれのコマンドについての説明は以下のとおりです。

  • scss-dev, scss-dev-w
    • node-sassを使ってscssをcssに変換する
    • -r オプションによって./scssに配置した.scssファイルを再帰的に監視する
    • -o オプションによって./extension/assets/css/に変換後のファイルを保存する
    • --output-style の次がexpandedなら通常表示、compressedならminifyされます。 直感的にわかるサイトを見つけたので、参考にしてください。 https://web-design-weekly.com/2014/06/15/different-sass-output-styles/
  • scss-product
    • scss-devとほとんど同じです
    • compressedをつけているので、cssがminifyされます。
  • webpack-dev, webpack-dev-w
    • webpackを使ってjsをコンパイルする
    • --config オプションを使用すると環境ごとに分けた設定ファイルを指定できる
    • --mode オプションを指定するとwebpack側で組み込みの設定を最適化してくれます。あまり恩恵は感じていませんが、追加しています。https://webpack.js.org/concepts/mode/
    • --progress コンパイル時のログを表示します。
    • --display-error-details 読んで時のごとく、エラーの詳細を出します。個人的には、このオプションを付けないと何でエラーになったのかわかりませんでした。
    • --watch ファイルの更新を監視します。更新されたときにコンパイルが実行されます。
  • webpack-production
    • リリース時に使用するコマンドです。
    • ほとんどwebpack-devと同じです。

以上のコマンドは以下のように使用できます。

npm run css-dev-w
npm run webpack-dev-w
npm run webpack-dev-w

リリース時は以下のコマンドを実行します。

npm run webpack-production

templateについて

templateについてですが、listのアイテムを複製する際に繰り返し使用するdomを指しています。

例えば、サンプル内ではhelloの文字列をtemplateとしています。

使い方によっては以下のようなulタグ内のliタグを追加したりできます。

<ul>
    <li>item</li>  ⇠ これをtemplate化して、複数itemをulタグ内に追加する
</ul>

サンプルではhandlebarsというライブラリを使ってtemplateを解決しています。 他の使い方については https://handlebarsjs.com/ こちらを参考にしてください。

tempalteと聞いてvuejsを使わないのはなぜかと疑問が浮かぶかもしれません。

私もvuejsを使った開発経験があるのですが、久しぶりに自分が書いたコードを見ると理解するまでに時間がかかりました。

久しぶりに読むコードが読めない場合、知識が足りないか、理解が足りないかのどちらかだと考えています。

理解するまでに時間がかかるということは、1ヶ月後にバグが見つかり修正することになったときに、すぐに取り掛かれないのでは?と考えました。

そのため、知識が必要なvuejsではなく、理解しやすいhandlebarsを使用することに決めました。

また、使い慣れたjspやjinja2(pythonのテンプレートエンジン)に似ていることも理由です。

font-awesomeを使う際の注意点

scssを使うのが良いと思います。

cssではhtmlで読み込む必要があり、linkタグが多くなってしまうためです。

scssで使うときは、以下のように設定します。

まずはfont-awesomeをダウンロードし、必要なファイルをコピーして配置します。 https://use.fontawesome.com/releases/v5.1.0/fontawesome-free-5.1.0-web.zip

必要なファイルは以下の2つです。 - fontawesome-free-5.0.13/web-fonts-with-css/scss - fontawesome-free-5.0.13/web-fonts-with-css/webfonts

scss/_variables.scssの中のwebfontsへのパスを修正します。

// scssをcssにすると以下のようになります。
// src: url("./webfonts/fa-regular-400.eot");
// 実際に使用するcssからのパスを設定すること
$fa-font-path:                "./webfonts" !default;
// ...

あとは、font-awesomeをscssファイルからimportするだけです。

// ↓ fontawesomeを使うためのimport
@import "../web-fonts-with-css/scss/fontawesome.scss";
@import "../web-fonts-with-css/scss/fa-regular.scss";
// ↑ solid, brandsがあるので使いたいものをimportすること