Create React AppでChrome Extensionを開発する
Reactのアプリを開発するにはFacebook謹製のcreate-react-appが便利です。しかし、create-react-appはWebアプリの開発に特化しているため、Chrome Extensionの開発には使えない問題があります。スクリプトを少し変えてwatch buildを行う方法を紹介します。
Chrome Extensionの開発に必要なフロー
Chrome Extensionを開発するには以下のようなフローが必要になります。
- アプリをビルドし、
build
フォルダに出力する。 - Chromeの拡張機能を開き、デベロッパーモードで
build
フォルダを読み込む。 - Chrome Extensionを実行する。
- ソースコードを修正する。
- アプリをビルドし、
build
フォルダに出力する。 - 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ファイルに固める |
ご参考まで。