この文書作成時のソフトウェアバージョンは以下です。
- Google Chrome 66.0.3359.139 (64bit)
- Firefox Quantum 59.0.3 (64 ビット)
結論から言うと、manifestをプラットフォームごとに分岐させ、js上はchrome.runtime.idの値で分岐させれば多重管理は防げる。
> ChromeExtensionとWebExtensionsには互換性がある、しかしChromeExtensionとWebExtensionsには互換性がある、しかし
ブラウザ拡張に用いるAPIはブラウザごとに違う。
OperaとChromeで採用されているのはextension API。
Firefoxで採用されているのはWebExtensions API。
MDNによれば、
WebExtension API で開発する拡張機能は、ブラウザー間で互換性が維持されるように設計されており、大半は Google Chrome や Opera でサポートされている extension API とコード互換性があります。これらのブラウザー向けに書かれた拡張機能はほとんどの場合、少しの変更を加えるだけで Firefox でも動くようになります。1
とのことなので、ひとつのコードベースでChromeもFirefoxもサポートしたいところ。
しかし、非互換API2があったり、互換とされるAPIであっても微妙に動きが異なったりする。
例えば、EventPageでコンテキストメニューに項目を追加するにはChromeExtensionでは以下のコードが推奨されている3
が、これをFirefoxで動かすとブラウザを閉じたときにコンテキストメニューはなくなり、再度インストールするまでコンテキストメニューに項目が追加されなくなる。(しかもパッケージ化していない拡張機能はブラウザが閉じるまでしか有効にならないのでテストできない! なんてこった)
> UserAgentからブラウザを判別して処理を分岐する方法UserAgentからブラウザを判別して処理を分岐する方法
とりあえず思いついたのがUserAgent文字列をパースしてブラウザを判別する方法。
パーサは勿論既存のものを使う。
今回はこちらを拝借https://github.com/faisalman/ua-parser-js
で、分岐したい部分を愚直に分岐する。
(今回はChromeとFirefoxのことしか考えていない)
> 他にいい方法があれば教えてください他にいい方法があれば教えてください
ください!!
ここから追記
教えていただきました! ありがとうございます!
WebExtensionsかどうかの判別なら、https://t.co/bktYhj4urBの値を見るといいと思います。
— Kazz (@asamuzakjp) 2018年5月11日
WebExtensionsの場合、manifest.jsonのhttps://t.co/RR8VgYa8vtの値が入ってます。
https://t.co/nUx4mfty4H
コンテキストメニューの生成を1本化したいということであれば、そもそもChromeでもonInstalled時ではなく、拡張のロード時でいいと思いますが。
— Kazz (@asamuzakjp) 2018年5月11日
心配だったら、contextMenus.removeAll()してから生成する https://t.co/nUx4mfty4H
> chrome.runtime.idchrome.runtime.id
Chromeではchrome.runtime.idの値は拡張機能一覧に表示されるIDと一致する。
Firefoxではmanifestに記載したIDと一致する
Chromeではmanifestにapplicationsキーが書かれていると
とエラーを吐かれてしまうので、なんとかする必要がある。
> ビルド時にmanifestを分岐するビルド時にmanifestを分岐する
結局分岐させた。
firefox用のmanifestを記載したjsonを作っておき、ビルド時にマージする。今回はGulpを使ってみた。
var gulp = require('gulp');
var mergeJson = require('gulp-merge-json');
var rimraf = require('rimraf')
gulp.task('clean', function(callback){
rimraf('release/firefox', callback)
});
gulp.task('releaseForFirefox', ['clean'], function(){
gulp.src(['manifest.json', 'manifest-firefox.json'])
.pipe(mergeJson({
fileName: 'manifest.json',
}))
.pipe(gulp.dest('release/firefox'));
// ソースのコピーとかアーカイブとか
...
});
gulp.task('releaseForChrome', ['clean'], function(){
gulp.src('manifest.json').pipe(gulp.dest('release/chrome'));
// ソースのコピーとかアーカイブとか
...
});
結局manifestは分岐することになったけど多重管理を防ぐことはできたので満足。
jsのソースも一本化できた。
0 件のコメント:
コメントを投稿