だれも聞いていないと思って歌え

dance as if no one’s watching, sing as if no one’s listening, and live everyday as if it were your last.

jsdom を 10.0.0 に上げた際のメモ

Node.js と jsdom は勉強中ですが、 10.0.0 リリース直後にアップデートを行って対応した際のメモです。

ちなみに現在の最新バージョンは、 11.0.0 です。
9.xx から 10.0.0 に上げた時のように大きな変更はないようで、アップデート後も今回記事にした内容から変更していません。

変更内容

  • API の変更(古い API も一部提供しているようですが、理由のない限り新しい API を使用することを推奨)
  • Node.js v6以降でサポートしている新しいJavaScript機能の使用を開始、 Node.js v4およびv5のサポートを削除
  • 空の文字列にinnerHTMLを設定しないように修正
  • 引数が足りない場合に表示される xhr.open() のエラーメッセージを改善

詳しい内容はこちらを確認してください。

github.com

jsdom.fromURL

URL を参照して dom を取得するように jsdom.env を使用していましたが、バージョンアップにより使用できなくなっていたため jsdom.fromURL を使用するように変更しました。

jsdom.fromURL とは

  • URL が有効で DOM の生成に成功した場合、非同期処理で JSDOM オブジェクトを返す
  • url と contentType をオプションで指定できない
  • userAgent オプションは、 HTTP User-Agent Request Header として使用する

サンプル

JSDOM.fromURL("https://example.com/", options).then(dom => {
  console.log(dom.serialize());
});

書き換えてみた

before

import jsdom from 'jsdom';

jsdom.env({
  url: url,
  userAgent: xxxxx,
  done: (error, window) => {
    if (!error && typeof window !== 'undefined') {
      // DOM 取得後の処理を実行する
    } else {
      // エラー処理を行う
    }
  }
});

after

import { JSDOM } from 'jsdom';

JSDOM.fromURL(url, {
  userAgent: xxxxx
}).then(dom => {
  if (typeof dom.window !== 'undefined') {
    // DOM 取得後処理を実行する
  } else {
    // DOM が正しく取得されなかった場合のエラー処理を行う
  }
}).catch(error => {
  // リクエストが通らなかった場合のエラー処理を行う
});

躓いたところなど

  • これまで window.document で参照していたが、 dom.window.document を参照するように変わった
  • import 文が import { JSDOM } from 'jsdom' と変更した(別の解決策があったかも知れませんが、 README を参考にこのように解決しました)
  • JSDOM.fromURL に catch が必要か分からなかった(念のために Promise の書き方に倣って追加しましたが、不要であれば削除しようと思っています)
  • then の中で setTimeout() を実行していましたが、これが原因で警告が表示されていたので削除した
    • jsdom.env で使用していた名残でしたが、今回の API の変更によりそもそも不要だった可能性もありそうです

setTimeout() に関してはもう少し理解を深めたいと思います。