GeekFactory

int128.hatenablog.com

Create React AppでChrome Extensionを開発する

Reactのアプリを開発するにはFacebook謹製のcreate-react-appが便利です。しかし、create-react-appはWebアプリの開発に特化しているため、Chrome Extensionの開発には使えない問題があります。スクリプトを少し変えてwatch buildを行う方法を紹介します。

Chrome Extensionの開発に必要なフロー

Chrome Extensionを開発するには以下のようなフローが必要になります。

  1. アプリをビルドし、 build フォルダに出力する。
  2. Chrome拡張機能を開き、デベロッパーモードで build フォルダを読み込む。
  3. Chrome Extensionを実行する。
  4. ソースコードを修正する。
  5. アプリをビルドし、 build フォルダに出力する。
  6. 3に戻る。

create-react-appでnpm startを実行するとlocalhost:3000で開発サーバが実行されます。localhost:3000をそのまま開いても通常のWebアプリとして扱われるため、Bookmarks APIなどのChrome APIを実行できません。Chrome APIを実行するには上記の2が必要になります。

スクリプトのカスタマイズ

create-react-appは内部でWebpackの開発サーバを実行しています。これをwatchに変更します。

今回は以下の方針で修正します。

  • ejectして修正するとバージョンアップに追随するのが辛いのでやりたくない。
  • create-react-appが持っているWebpackの設定(webpack.config.dev.js)をなるべくそのまま利用したい。

まず、package.jsonを以下のように修正します。

  "scripts": {
    "start": "node scripts/start.js",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "zip": "zip -j - build/* > build/extension.zip",
    "clean": "rm -fr build"
  }

scripts/start.jsを作成します。

process.env.NODE_ENV = 'development';

var fs = require('fs-extra');
var paths = require('react-scripts/config/paths');
var webpack = require('webpack');
var config = require('react-scripts/config/webpack.config.dev.js');

// removes react-dev-utils/webpackHotDevClient.js at first in the array
config.entry.shift();

var compiler = webpack(config);
compiler.watch({}, function(err, stats) {
  if (err) {
    console.error(err);
  } else {
    copyPublicFolder();
  }
  console.error(stats.toString({
    chunks: false,
    colors: true
  }));
});

// as react-scripts/scripts/build.js
function copyPublicFolder() {
  fs.copySync(paths.appPublic, paths.appBuild, {
    dereference: true,
    filter: file => file !== paths.appHtml
  });
}

ちょっと雑ですが、create-react-appが持っているWebpackの設定を一部改変してwatchに渡すことで継続的にビルドを実行できます。

これでChrome Extensionの開発に必要な下表のタスクが実行できるようになりました。

コマンド やること
npm start ファイルが変更される度にdevelopmentでビルド
npm build productionでビルド
npm zip ビルドをZIPファイルに固める

ご参考まで。