TypeScript + webpack でブラウザ拡張機能開発
TypeScript と webpack でブラウザ拡張機能/アドオンの開発するメリット
TypeScript は chrome API の型定義ファイル( @types/chrome ) があるので それを入れておくと型チェックと vscode で API の補完ができるようになる
webpack は jquery や axios など、npm でダウンロードしたライブラリも
出力されるファイル(bundle.js)に一緒に埋め込まれるので拡張機能開発向き
必要なものをダウンロード
$ npm i --save-dev webpack webpack-cli typescript ts-loader @types/chrome
フォルダ構成
. ├── manifest.json ├── package.json ├── index.html ├── tsconfig.json ├── webpack.config.js ├── icons │ ├── icon-128.png │ ├── icon-16.png │ ├── icon-19.png │ └── icon-48.png └── src ├── background.ts └── browserActrion.ts
manifest.json
EvalError: call to eval() blocked by CSP
エラーが出る場合は、manifest.json に以下を追記する
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
webpack でトランスパイルしたファイルにソースマップを埋め込むために eval が使われているのでこのエラーが出る。 webpack.config.js の devtool に false を設定してソースマップを無効にすることもできる。
ソースマップの設定については https://golang.hateblo.jp/entry/webpack-devtool-source-map に書いてます。
content_security_policy
については以下に載ってます。
https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy
tsconfig.json
{ "compilerOptions": { "target": "ES5", "module": "commonjs", "sourceMap": true, "removeComments": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true } }
webpack.config.js
webpack でバックグラウンドの jsファイルとその他の jsファイルを分けて出力するために entry で以下のようにする。
const path = require('path'); module.exports = { mode : 'development', devtool : 'inline-source-map', entry : { background : path.resolve(__dirname, 'src/background.ts'), browserAction : path.resolve(__dirname, 'src/browserActrion.ts') }, module : { rules : [ { test : /\.ts$/, use : 'ts-loader' } ] }, output : { // ファイルは jsフォルダ以下に background.bundle.js と browserAction.bundle.js で出力される filename : '[name].bundle.js', path : path.join(__dirname, 'js') } }
Webpackの実行
$ npx webpack
jsフォルダ以下に2つのファイルが出力される
. ├── manifest.json ├── package.json ├── index.html ├── tsconfig.json ├── webpack.config.js ├── icons │ ├── icon-128.png │ ├── icon-16.png │ ├── icon-19.png │ └── icon-48.png ├── js │ ├── background.bundle.js │ └── browserAction.bundle.js └── src ├── background.ts └── browserActrion.ts