Help us understand the problem. What is going on with this article?

Next.jsを使用してGoogle Chromeの拡張機能を作るとレイアウトとルーティングができるので結構楽に拡張の開発ができる。

はじめに

@yushimatenjinです。Next.jsアドベントカレンダー4日目ですね。
Next.jsを使うと簡単にGoogle Chromeの拡張機能が作れるんじゃないかなと思ったら簡単に作ることが出来たのでその紹介を今回しようかなと思います。

このときに得た知見をもとに書いています。

Chrome ExtensionをNext.jsで作ってみた

こちらが先日作成した、Next.jsで作ったChrome拡張を作るためのリポジトリです。
https://github.com/yushimatenjin/next-js-chrome-extension-starterkit

Next.jsのはじめ方

Next.jsを始めるには、Reactの使える環境がある方でしたら簡単に始められます。

1. 必要なパッケージをインストール

小さい構成で始めるにはこれだけで大丈夫です。

yarn init
yarn add react react-dom next

2.Pagesディレクトリを作る

mkdir pages

pages/index.jsを作成 & 書き換える

pages/index.js
const React from 'react'

export default () => <div>Hello, World!</div>

これだけ書くだけで/にアクセスしたときにHello, Worldを表示するページを作ることが出来ます。

.
├── package.json
├── pages
│   └── index.js
└── yarn.lock

起動をするためのスクリプトをpackage.jsonに追加する

package.json
  ...

   scripts{
      "dev": "next",
      "start": "next start",
      "build": "next build",
      "export": "next build && next export"
   }
  ...

起動する

index.jsの内容を表示するためには先程設定したyarn devのコマンドを打つことでlocalhost:3000にアクセスできるようになります。
ScreenShot 23.jpg

yarn dev

これがNext.jsで最小限に起動をする方法になります。開発環境で起動する場合にはyarn dev、ビルド&起動する場合にはyarn build && yarn startでサーバーが立ち上がります。

ChromeのExtensionを作る場合にはexportを使用して静的なページとして出力をします。

Chrome Extensionを作る

ChromeのExtensionを作るためにいくつのファイルを追加&変更します。

追加するフォルダ & 追加するファイル

  1. extensions // フォルダ
  2. extensions/manifest.json // 拡張機能の詳細を記述するファイル

manifest.jsonはこちらを参考にして記述をしていきます。

manifest.json
{
    "name": "extension",
    "description": "extension",
    "version": "1.0.0",
    "browser_action": {
      "default_popup": "./dist/index.html"
    },
    "permissions": [
      "bookmarks",
      "tabs",
      "activeTab"
    ],
    "manifest_version": 2
  }

変更するファイル

  1. package.json
変更前
package.json
   ....
  "scripts": {
    ...
    "export": "next build && next export"
  },
   ...
変更後

export-oオプションを付けて拡張機能の出力先を変更します。

package.json
   ....
  "scripts": {
    ...
    "export": "next build && next export -o extensions/dist"
  },
   ...

この3つの新しく変更を加えた状態の現在のディレクトリ構成はこのような状態となっております。

.
├── README.md
├── extensions
│   ├── dist
│   └── manifest.json
├── package.json
├── pages
│   └── index.js
└── yarn.lock

ちなみに上記の設定を行ったものがこのリポジトリとなりますので、このリポジトリをクローンをするとすぐに開発をし始めることが出来ます。

next-js-chrome-extension-starterkit

こちらのリポジトリはtsxファイルを追加したため少しファイルの構成が増えています。Next.jsではTypeScriptを扱おうとするとある程度必要なファイルを自動的にファイルを追加してくれます。

Chromeの拡張としてエクスポート

ScreenShot 23.jpg

この状態で起動をすると、白い背景にHello, World!と表示されていると思います。この状態のまま拡張にしてみましょう。

yarn export 

出力先をextension/distにpackage.jsonで設定しているので、静的なファイルが生成されます。

エクスポートされた拡張を読み込む

ScreenShot 26.jpg

  1. エクスポートされたChromeの拡張機能を読み込むためにはGoogle Chromeの設定 → その他ツール拡張機能を選択

ScreenShot 28.jpg

  1. パッケージ化されていない拡張を読み込む

ScreenShot 27.jpg

  1. プロジェクト → extensions ファイルを選択します

これで拡張機能を読み込むことが出来ます。

Chrome拡張を作ることが出来た(やったー!)

ScreenShot 30.jpg

ルーティングを追加する

Next.jsの特徴として静的サイトのルーティングを簡単に作れるので、新しいページを追加してみます。

Next.jsのLinkは可能ですが、URLの指定を.htmlまで記述する必要があります。開発環境では必要ないのでページのパスを取得するための関数を追加します。

constants/page.js
const Pages = () => {
    const suffix = process.env.NODE_ENV === "development" ? "" : ".html"
    const data = {
        index: `index${suffix}`,
        about: `about${suffix}`
    }
    return data
}

export default Pages

トップページから飛ぶ先のページ名aboutを追加します。

pages/about.js
import React from "react";
import Link from "next/link";
import Page from "../constants/page";

const About = () => {
  return (
    <div>
      このExtensionは@mxcn3が作成しました。
      <Link href={Page().index}>
        <a>トップページへ</a>
      </Link>
    </div>
  );
};

export default About;

トップページからページ名 aboutに飛べるようにします。

pages/index.js
import React from "react";
import Link from "next/link";
import Page from "../constants/page";

const Index = () => {
  return (
    <div>
      Hello World
      <Link href={Page().about}>
        <a>この拡張について</a>
      </Link>
    </div>
  );
};

export default Index;

yarn export

を再度実行することで拡張機能が更新されます。

output.gif

ページのサイズを変更する

ページのサイズをインラインで変更します。

あまり推奨されていないやり方みたいですが便利上インラインでスタイを変更します。
https://reactjs.org/docs/dom-elements.html#style

pages/index.js
import React from "react";
import Link from "next/link";
import Page from "../constants/page";

const Index = () => {
  return (
    //   ページの大きさを変更
    <div
      style={{
        width: 400,
        height: 400
      }}
    >
      Hello World
      <Link href={Page().about}>
        <a>この拡張について</a>
      </Link>
      {/* iframeを追加 */}
      <iframe
        style={{
          width: "100%",
          height: "100%",
          margin: 0,
          border: "none"
        }}
        src="https://playcanv.as/p/8NZ92jAY/"
      />
    </div>
  );
};

export default Index;

output2

このような形で表示されます。

まとめ

Next.jsはReactを使用して記述ができるので、Next.jsでGoogle Chromeの拡張機能を書くことができれば比較的作りやすいのではないでしょうか。Next.jsを使用したChrome拡張の記事などをあまり見なかったので記事にさせていただきました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away