Firefoxのアドオン開発環境の導入(Add-on SDK編)その2

前回の続きです

Add-on SDKの開発環境を更に便利にする設定

jpm run を使うと一時的に新しいプロファイルが作られて綺麗な状態で動作確認できるのはいいんだけど、そのプロファイル上で起きた変更はウィンドウを閉じるとすべてなかったことになるのでブックマークも何もすべての設定が消えてしまう
これでは毎回特定のページ開いて動作確認したり他のアドオンとの相性を確認したりするのに不便だ
調べてみるといくつかのTipsが見つかったので記録しておく

指定したプロファイル・Firefoxのバージョンで実行する

jpm run にオプションを足して起動するやり方

jpm - Mozilla | MDN

jpm run -p <プロファイル名>

とりあえずこれではじめから好きな設定で使えるようになる
ただしjpmから起動した場合はプロファイルを一時的に別の場所にコピーしているらしいのでやはりこの状態での設定変更は保存されないので終了とともに起動前の状態に戻ってしまう
必要な設定はあらかじめ(jpmをつかわない)通常の起動時に済ませておけばいい
ちなみにプロファイルをコピーしないでそのまま使うオプションもあるようだがリスキーなので使わないほうがいいと思う

さらにDeveloper Edition でテストしたいとかNightlyでテストしたいとかもっと古いバージョンでテストしたいとかの場合は

jpm run -b <Firefox本体のフルパス>

もちろん両方同時にも使える

jpm run -p <プロファイル名> -b <Firefox本体のフルパス>

これでバッチファイルを作っとくといいかも

これを使ってもいいんだけど

これでも毎回再起動しないとプログラムの変更を確認できないしまだちょっと不便

再起動無しでファイルの更新を自動的に反映する

もっと便利なやり方を見つけたので結局上のやり方は使わずこっちにした

初めてでも理解できるようになる「Firefox機能拡張の開発」 | OXY NOTES

watchpostを使うとフォルダ内を監視してファイルに更新があると自動的にxpiを作りなおして再起動無しで変更が反映されるらしい
こりゃすごい

jpm

テスト環境のFirefox(プロファイル)には Extension Auto-Installer アドオンをインストールしておく

Extension Auto-Installer :: Add-ons for Firefox

あとは

jpm watchpost --post-url http://localhost:8888/

とするだけでテスト環境のFirefoxに自動的に最新の状態のアドオンが入る
これも同じくバッチファイルにしておくと楽
watchpostを立ち上げるのとExtension Auto-Installerアドオンが入ったFirefoxを立ち上げるのはどちらが先でも大丈夫みたい

ただしこの方法はjpmのコンソール上にエラーやデバッグ情報が一切表示されなくなるのでブラウザコンソールしか使用できなくなる

これでGreasemonkeyスクリプトの開発とほぼ同じくらいの快適さになった

Add-on SDKのconsole.logをWebコンソールにも表示する

上記の方法をいろいろ試しているうちにブラウザコンソール上にAdd-on SDKからconsole.log()のログが表示されない場合があることに気づいた
オプションなしで立ち上げた時のまっさらなプロファイルじゃないとブラウザコンソールにエラーログしか出ない
もちろんWebコンソールにも出ない
これはおかしい
不便すぎる
それでいろいろ試したり調べたりしてやっと見つけたのがこれ

Changes to console.log behaviour in SDK 1.14 | Mozilla Add-ons Blog

about:configにログレベルの設定があるそうな

about:configから新規作成→文字列で

extensions.sdk.console.logLevel

値は

all

これをすると任意のプロファイルでブラウザコンソールにも出るようになった
しかもWebコンソールにも出るようになった!
なにこれ素敵
ブラウザコンソールはドッキングできないから若干不満があったんだよね

これを見つけるまでが大変だった……
なんでこんな大事な設定を隠しておくのかね

Firefoxのアドオン開発環境の導入(Add-on SDK編)

少し前のトライアンドエラーの記録です

先に言っておくとcfxはもう古いのでjpm使ったよという内容なのでほんとに必要な人はcfxの代わりにjpmを導入するから読んでください

Firefoxアドオン開発の現状

まずは概要を調べてみる

Firefox 拡張の作り方 (2013 年版) - ひだまりソケットは壊れない

なんとなくしか知らなかったけどこの記事によるとFirefoxのアドオンの作り方は

  • Add-on SDK (または Add-on Builder) を使う方法
  • 従来からある XUL オーバーレイを用いる方法 (ブートストラップ型ではない XUL ベースの拡張機能)
  • Add-on SDK を用いずにブートストラップ型拡張機能を作る方法 (ブートストラップ型の XUL ベースの拡張機能)

現状上記の3通り

Add-on SDK というのは昔Jetpackと呼ばれていたやつだ
確かJetpackが出た当初はJetpackで作られたアドオンはまだ実験的な位置づけでリリース版のFirefoxのデフォルト状態では動かなかったのでGreasemonkeyのようにJetpackのランタイムのような公式アドオンを入れる必要があってそれで試した記憶がある

そういえばFirefoxで「拡張機能」を「アドオン」と呼ぶように変わったのはいつ頃だったかな

今回はGreasemonkeyのユーザースクリプトを移植する目的なので迷わず Add-on SDK を選択した
XULとかめどいです

Add-on SDK にはcfxというコマンドラインベースのツールが提供されているのでまずはそれをインストールする


cfxの導入

チュートリアル - Add-on SDK Documentation

  • ここを参考にインストール

インストール - Add-on SDK Documentation

  • cfx initでアドオンの雛形を作った

cfx 入門 - Add-on SDK Documentation

  • main.jsにサンプルコードをコピペした

ツールバーへのボタンの追加 - Add-on SDK Documentation

const widgets = require("widget");
const tabs = require("tabs");

var widget = widgets.Widget({
  id: "mozilla-link",
  label: "Mozilla website",
  contentURL: "http://www.mozilla.org/favicon.ico",
  onClick: function() {
    tabs.open("http://www.mozilla.org/");
  }
});
  • cfx runで起動

まっさらなFirefoxが立ち上がる
しかしチュートリアルにあるアイコンは表示されない
コンソールにはエラーログが出ている

Warning: Use of deprecated require path:
  In D:\My Documents\firefox\addon-sdk\<アドオン名>\lib\main.js:2:
    require('tabs').
  New path should be:
    require('sdk/tabs')
Warning: Use of deprecated require path:
  In D:\My Documents\firefox\addon-sdk\<アドオン名>\lib\main.js:1:
    require('widget').
  New path should be:
    require('sdk/widget')
Using binary at 'C:\Program Files (x86)\Mozilla Firefox\firefox.exe'.
Using profile at 'c:\users\<ユーザー名>\appdata\local\temp\tmpty8q7g.mozrunner'.
console.error: <アドオン名>:
  Message: Module `sdk/widget` is not found at resource://gre/modules/commonjs/sdk/widget.js
  Stack:
    CuddlefishLoader/options<.load@resource://gre/modules/commonjs/sdk/loader/cuddlefish.js:79:18
@resource://jid1-783qkrvmmwuzbg-at-jetpack/<アドオン名>/lib/main.js:1:17
CuddlefishLoader/options<.load@resource://gre/modules/commonjs/sdk/loader/cuddlefish.js:79:18
run@resource://gre/modules/commonjs/sdk/addon/runner.js:145:19
startup/</<@resource://gre/modules/commonjs/sdk/addon/runner.js:86:7
Handler.prototype.process@resource://gre/modules/Promise-backend.js:867:23
this.PromiseWalker.walkerLoop@resource://gre/modules/Promise-backend.js:746:7
this.PromiseWalker.scheduleWalkerLoop/<@resource://gre/modules/Promise-backend.js:688:37

console.error: <アドオン名>:
  Message: Module `sdk/widget` is not found at resource://gre/modules/commonjs/sdk/widget.js
  Stack:
    CuddlefishLoader/options<.load@resource://gre/modules/commonjs/sdk/loader/cuddlefish.js:79:18
@resource://jid1-783qkrvmmwuzbg-at-jetpack/<アドオン名>/lib/main.js:1:17
CuddlefishLoader/options<.load@resource://gre/modules/commonjs/sdk/loader/cuddlefish.js:79:18
run@resource://gre/modules/commonjs/sdk/addon/runner.js:145:19
startup/</<@resource://gre/modules/commonjs/sdk/addon/runner.js:86:7
Handler.prototype.process@resource://gre/modules/Promise-backend.js:867:23
this.PromiseWalker.walkerLoop@resource://gre/modules/Promise-backend.js:746:7
this.PromiseWalker.scheduleWalkerLoop/<@resource://gre/modules/Promise-backend.js:688:37

エラーログは名前が古いと言ってるっぽいので
require('tabs'). を require('sdk/tabs') に
require('widget'). を require('sdk/widget') に
変えてみたけどやっぱりダメっぽい

Using binary at 'C:\Program Files (x86)\Mozilla Firefox\firefox.exe'.
Using profile at 'c:\users\<ユーザー名>\appdata\local\temp\tmpdh1unj.mozrunner'.
console.error: <アドオン名>:
  Message: Module `sdk/widget` is not found at resource://gre/modules/commonjs/sdk/widget.js
  Stack:
    CuddlefishLoader/options<.load@resource://gre/modules/commonjs/sdk/loader/cuddlefish.js:79:18
@resource://~~-at-jetpack/<アドオン名>/lib/main.js:1:17
CuddlefishLoader/options<.load@resource://gre/modules/commonjs/sdk/loader/cuddlefish.js:79:18
run@resource://gre/modules/commonjs/sdk/addon/runner.js:145:19
startup/</<@resource://gre/modules/commonjs/sdk/addon/runner.js:86:7
Handler.prototype.process@resource://gre/modules/Promise-backend.js:867:23
this.PromiseWalker.walkerLoop@resource://gre/modules/Promise-backend.js:746:7
this.PromiseWalker.scheduleWalkerLoop/<@resource://gre/modules/Promise-backend.js:688:37

console.error: <アドオン名>:
  Message: Module `sdk/widget` is not found at resource://gre/modules/commonjs/sdk/widget.js
  Stack:
    CuddlefishLoader/options<.load@resource://gre/modules/commonjs/sdk/loader/cuddlefish.js:79:18
@resource://~~-at-jetpack/<アドオン名>/lib/main.js:1:17
CuddlefishLoader/options<.load@resource://gre/modules/commonjs/sdk/loader/cuddlefish.js:79:18
run@resource://gre/modules/commonjs/sdk/addon/runner.js:145:19
startup/</<@resource://gre/modules/commonjs/sdk/addon/runner.js:86:7
Handler.prototype.process@resource://gre/modules/Promise-backend.js:867:23
this.PromiseWalker.walkerLoop@resource://gre/modules/Promise-backend.js:746:7
this.PromiseWalker.scheduleWalkerLoop/<@resource://gre/modules/Promise-backend.js:688:37

ライブラリが見つからないらしい

  • ここまでやってみてなんかおかしい気がしてもう一度調べなおしてみる

jpm - Mozilla | MDN

You can use jpm for Firefox 38 and onwards. This article is the reference for jpm.

なんかFx38以降はjpmとかいうのを使えってことらしい
今試したcfxはpythonベースだったがnode.jsベースのものに変わったらしい

cfx has been deprecated, jpm should now be used instead. For more information see JPM replaces CFX for Firefox 38.

cfxはFx38でjpmに置き換わった模様

クソァ!時間返せ!
まあ旧Jetpackだからもう随分出てから経ってるしわからんでもない

それにしてもjpm関係のページがことごとく翻訳されてないので紛らわしい


cfxの代わりにjpmを導入する

jpm - Mozilla | MDN

  • Node.jsをインストールする

Node.js

からインストーラを落としてインストール。インストール時の設定はデフォルト。

  • jpmをインストールする

jpmをインストールするにはNode.jsのパッケージマネージャであるnpmを使用する。
Node.jsにはnpmが含まれているのでNode.jsを入れるとコマンドプロンプトからnpmコマンドが使える状態になっている。

npm install jpm --global

ごちゃごちゃとメッセージが表示されてjpmがインストールされる。

  • 新規アドオンのイニシャライズをする
mkdir my-addon
cd my-addon
jpm init

要は適当にフォルダ作って

jpm init

アドオンに関する情報の入力を求めてくるので適当に入力する。
nameはIDに使用されるものらしいのでちゃんとした名前にしたほうが良さげ。デフォルトはフォルダ名になる。
未入力でエンター押すとデフォルト値になる

cfxでは"main.js"だったがjpmではデフォルトでは"index.js"。

  • 実行
jpm run

で実行

  • XPI作成
jpm xpi

でパッケージ作成。 特に難しくなかった。 ていうかjpmの方がずっと楽。


とりあえず環境構築までで終わり
実際のAdd-on SDKでの開発はcfxもjpmも大して変わらない
一応書いておくとグリモンのユーザースクリプトからの移植はかなり簡単だった
それについては気が向いたらまた書きます

続き

Firefoxのアドオン開発環境の導入(Add-on SDK編)その2 - keep-alive