追記 2018/10/29
chrome
モジュールが使えなくなる、という指摘は半分正しくて半分間違ってる(いくらでもやりようがある)のでもうちょっとちゃんとした記事を書きました。
medium.com
以下原文ママ。
背景
- JSのプロジェクトで、特に僕はChrome拡張を作ることが多いんですが、ES6 syntaxを使いたい
- だいたいのES6 syntaxは、Chrome(現在 65.0.x)で使える
- ただし、問題は
import
です
Background Script でimportを使う
medium.com
つまりHTML5準拠のブラウザでは<script type="module" src="..."></script>
とすれば、これをエントリポイントとして以下import
は解決されるんだけど、ということは逆にmanifest.json
のbackground.scripts
でBackgroundスクリプトを指定するとtype="module"
属性を与えられないので、わざわざbackground.page
を使ってそこから<script>
しましょうね、という話。
manifest.json
{
"background": {
"page": "src/html/background.html"
}
}
src/html/background.html
<script type="module" src="src/js/background.js"></script>
Use ES6 import in Background Script · otiai10/chrome-extension-es6-import@ecf1267 · GitHub
Content Script でも、importを使いたい、のだが
同様の理由で、manifest.json
のcontent_scripts[i].js
でいきなりimport
を使っても
Uncaught SyntaxError: Unexpected identifier
となる。 Uncaught SyntaxError: Unexpected identifier · otiai10/chrome-extension-es6-import@154b321 · GitHub
どうにかして、HTMLを起因としたjsのロードをしたい。
scriptタグのインジェクション
manifest.json
の表現力では、どうにもcontent_script
のjsをtype="module"
でロードさせることができないので、<script>
タグそのものをページのHTMLに挿入すればよかろう、という発想。
まず、manifest.json
ではinject.js
を読ませる
manifest.json
"content_scripts": [
{
"matches": ["<all_urls>"],
- "js": ["src/js/content.js"]
+ "js": ["src/js/inject.js"]
}
],
"permissions": [
inject.js
では、<script>
タグの動的挿入を行う。
src/js/inject.js
(() => {
const src = chrome.extension.getURL('src/js/content.js');
console.log(src);
const script = document.createElement('script');
script.setAttribute('src', src);
script.setAttribute('type', 'module');
document.body.appendChild(script);
})();
いい感じに動きそうだが、これでも以下のエラーが出る。
GET chrome-extension://invalid/ net::ERR_FAILED
どうやらネットワークっぽいエラーで、jsのpathが正しく指定されていないか、あるいはもっと別の原因が考えられる。なお、inject.js
にconsole.log
させたsrc
のURLをクリックすれば正しくcontent.js
の内容が見えるので、pathが正しく指定されていない、ということはなさそう。
web_accessible_resources を指定すればよい
manifest.json
のweb_accessible_resources
というフィールドでは、ウェブからのリダイレクトなどの参照を許すChrome拡張内のリソースのパスを指定することができる。まさに今回、Chrome拡張側から見れば第三者の立場であるHTMLから、Chrome拡張内のリソースを<script src="...">
でロードさせようとしているので、これに該当する。
このとき、content.js
だけではなく、content.js
を起因とするすべてのimport
で参照されるリソースをweb_accessible_resources
に指定する必要があるので、ワイルドカードを使った。
],
"permissions": [
"<all_urls>"
+ ],
+ "web_accessible_resources": [
+ "src/js/*"
]
}
いい感じに動いた。
ソースコードまとめ
github.com
懸念
node_modules
以下にあるパッケージをどうやってimpotするか
- full pathを書けばimportできるだろうけれど、Chrome拡張としてリリースビルドにどう含めるか
- そもそもリリースビルドにnode_modules以下のすべてを含めるわけにはいかない
結論
webpack使お...
DRY