19
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Chrome拡張のpopupをReactで作るサンプル

Last updated at Posted at 2021-12-17

はじめに

この記事は「【マイスター・ギルド】本物のAdvent Calendar 2021」13日目の記事です。
何かと頻繁に利用するGoogle Chrome。
今後も長いお付き合いになるので、使いやすくしたいってことで拡張機能の開発に興味を持ちました。
Extensions - Chrome Developers
本記事ではReactを使用してGoogle拡張のpopupを作るところまでにしたいと思います。(ほんとに入門です)
Create-React-Appで簡単に環境を作れるのが便利ですが、今回は使用せずシンプルにいきます。

本編

1.Reactのインストールからビルドまで

プロジェクトのルートフォルダに移動し、yarn init -yで初期化します。(これでpackage.jsonが作られます)
src, publicフォルダも作ります。

$ yarn init -y
$ mkdir src public

publicmanifest.jsonを作ります
このファイルは、Chrome拡張の色々な設定などを記述するものです。
参考:Manifest file format - Chrome Developers

manifest.json
{
  "name": "Getting Started Example",     // Extensionの名前
  "description": "Build an Extension!",  // Extensionの説明
  "version": "1.0",                      // Extensionのバージョン
  "manifest_version": 3,                 // manifestのバージョン
  "action": {
    "default_popup": "popup.html"        // popupに表示するhtmlファイル
  }
}

srcpopup.htmlを作成します。

popup.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="react-target"></div>
  </body>
</html>

Reactをインストールする

$ yarn add react react-dom

srcpopup.jsxを作成します。

popup.jsx
import React from "react";
import { render } from "react-dom";
const Popup = () => {
  return (
    <div>
      <h1>Hello, world!</h1>
      <p>This is a simple popup.</p>
    </div>
  );
}
render(<Popup/>, document.getElementById("react-target"));

webpackをインストールする

参考:Installation | webpack

$ yarn add --dev webpack webpack-cli

プロジェクトのルートにwebpack.config.jsを作成します。

webpack.config.js
const path = require("path");
module.exports = {
  entry: {
    // ここに読み込ませるファイルを記述する
    popup: "./src/popup.jsx",
  },
  output: {
    // 出力先とファイル名を指定する
    path: path.resolve(__dirname, "dist"),
    filename: "[name].js",
  }
};

package.jsonに追記します。

package.json
{
  "scripts": {
    "build": "webpack --config webpack.config.js"
  }
}

--config: 設定ファイルを指定します
これで、yarn buildと打つことでwebpack.config.jsをもとにwebpackが動いてくれるようになりました。
参考:Command Line Interface | webpack

babelをインストールする

このままではブラウザがjsxファイルに対応できないので、jsファイルにコンパイルする必要があります。
babel-loader@babel/core@babel/preset-env@babel/preset-reactをインストールし、webpack.config.jsに追記します。

$ yarn add --dev babel-loader @babel/core @babel/preset-env @babel/preset-react
webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env", "@babel/preset-react"],
          }
        }
      },
    ],
  },
}

webpackプラグインをインストールする

これでビルドできるようになりましたが、ビルドフォルダdistpopup.htmlmanifest.jsonが含まれていません。

ビルドにhtmlファイルを含める

HtmlWebpackPluginをインストールして、webpack.config.jsに追記します。

$ yarn add --dev html-webpack-plugin
webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/popup.html",
      filename: "popup.html",
    })
  ],
};

これでビルドフォルダにpopup.htmlが含まれるようになります。

ビルドにその他ファイルを含める

CopyWebpackPluginをインストールして、webpack.config.jsに追記します。

$ yarn add --dev copy-webpack-plugin
webpack.config.js
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [{ from: "public" }],
    }),
  ],
};

2. 自作した拡張をChromeに読み込む

ウィンドウ右上の拡張機能から「拡張機能を管理」をクリックします。
image.png
「デベロッパーモード」をクリックし、「パッケージ化されていない拡張機能を読み込む」をクリックします。
image.png
manifest.jsonのあるフォルダを指定すると、読み込み完了です。
image.png
新しいタブを開き、chrome-extension:// {extensionのid} / {ファイル名}と打ち込むことでも確認できるようです。この場合はChrome DevToolsも使えます。
(例) chrome-extension://cgbcaliplbidocbnjgkgfmacnedolee/popup.html
image.png
(読み込んだ拡張機能にIDが記載されています)

3. 少しだけ開発しやすくする

最後に、webpackの設定をdevelopment, productionにそれぞれ分けます。
webpack-mergeをインストールします。

$ yarn add --dev webpack-merge

プロジェクトのルートにwebpack.dev.js, webpack.prod.jsを作成します。

webpack.dev.js
const { merge } = require("webpack-merge");
const config = require("./webpack.config.js");
module.exports = merge(config, {
  mode: "development",
  devtool: "inline-source-map"
});
webpack.prod.js
const { merge } = require("webpack-merge");
const config = require("./webpack.config.js");
module.exports = merge(config, {
  mode: "production",
});

package.jsonを書き換えます。

package.json
{
  "scripts": {
    "dev": "webpack --watch --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  }
}

これで、production用にはyarn build、development用にはyarn devというコマンドを用意できました。
--watch:ファイルの差分を感知したときにビルドする

おわりに

今回はpopupのみでしたが、とても簡単にChrome拡張を作ることが出来ました。
初めてwebpackに触れたので、この調子で触りながら知見を広げていきたいと思います。
良い感じのChrome拡張機能ができたらまた記事にしたいです。
12月も残りわずか、、
今年もやり切って、よいお年を迎えましょう!

参考

Create React Appで始めるChrome拡張 - Qiita
Build a Chrome Extension With React & Webpack - YouTube

19
9
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
19
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?