プロフィール

髭山髭人(ひげひと)

自分の書いた記事が、一人でも誰かの役に立てば...
活動信条の一つとして「貴方のメモは、誰かのヒント」というのがあります。

このサイトについて

本家HP packetroom.net から切り離した いわゆる技術メモ用のブログで、無料レンタルサーバーにて運用しています。広告表示はその義務なのでご容赦。
XREA さんには長年お世話になっています

ES6?風味でjavascriptを書いたらOBS運用で躓いた話

経緯と概要

配信(例:ニコ生やTwitch等)を行う時に、ちょっとした自作ツールをOBSに入れて遊んだりしているのですが、自作ツールの作り直し中の検証で ブラウザ環境(Chrome)では通るのに、OBS上のブラウザ上で動かすとうまく行かなかった。

先に結論

class Hoge{
    constructor(){

    }
    MethodA(){

    }
    //↓ここ
    MethodB = () =>{

    }
}

class 構文を使おうとした時、MethodB の書き方がこれ(アロー関数)なのがいけなかった。

OBSで javascript を読ませるとき、classでアロー関数式を使うのは様子見した方が良さそう?

もう少し詳しく

https://obsproject.com/ja/
発生環境:OBS Studio (Win) 23.2.1 x64

OBSではブラウザ(旧:ブラウザソース)という機能があり、他ウェブサイトやローカル上で用意したhtmlのページを配信画面上に出すことが出来ます。

Twitchでよく見かけるstreamlabs 等が比較的有名?だと思います。

.html をローカルで用意し、複数の .js を <script> タグで読み込ませて、ちょっとしたツールを作成していました。

テストや開発環境としてChromeのブラウザを利用していたのですが、同じものをOBSで動作させるとどうにもコケる。

具体的には、const _hoge = new HogeClass(); といった感じで書いたクラスがインスタンス化できませんでした。

我らの console.log(); が使えなかったので、自作のエラーログ表示関数を用意しつつ辿ってみると ReferenceError: HogeClass is not defined が出てきました。 え?なんで用意した class が無いことになってるんすか Σ(´ `;)

インスタンス化させる処理と、HogeClass 自体の定義を別のスクリプトに切り分けていたり、メイン処理を windows.onload = に突っ込んでいたりしたので、何かしらの 読み込みの順番や、先に定義(≒宣言)させておく必要がある ものだと思って順番や記述先を変えたり試行錯誤してみたのですが、いずれも改善ならず。

以前作ったツール上の Class はちゃんと動いていたので、作り直した HogeClass の記述と見比べていると

MethodB = () =>{
 //云々
}

といった感じの アロー関数 でメソッドを記述していたのが目に留まりました。

正直、特に深い意味もなく書いていた だけだったので、ここを

MethodB(){
 //云々
}

と、ひねりのない書き方に戻したところ、ReferenceError: HogeClass is not defined が出なくなり、HogeClass として認識。
無事インスタンス化にも成功しましたとさ、めでたしめでたし

所感

昔の感覚(※個人による) に比べると、Javascriptの書き方のセオリーも結構変わっていますよね。

var だけだったのが letconst に置き換わったり (むしろ旧環境に足を引っ張られていない限りvarは非推奨だったりも) function とかいちいち書かなくても済む個所が出てきたり クロージャを意識する必要が無くなってきたり。

addEventListener とかは普通にやるので、this 周りはまだちょっと考えないと時々コケたりしますけど (。_。;

class let const といった類は ECMAScript6(通称:ES6) の規格とのことで、OBS自体がES6に対応していない..という事では無いのでしょう。
class 構文の中で アロー関数式(Arrow functions)がピンポイントでコケたってことを考えると、仕様のすくい漏らし..もといバグなのかなぁ?と思ったり思わなかったりしました。

後々気づいた事

OBSのエラーログを開けば、もう少し早く気付けたかもしれません...

OBSのメニューから ヘルプ → ログファイル の項目にて色々確認できます。
今回話に挙げた javascript のエラーも、こちらにきちんと発生個所(行番号)付きで乗っていました。

↓ こんな感じで。

07:47:33.817: obs-browser: Uncaught SyntaxError: Unexpected token = (source: http://absolute/C:/うんたらかんたら/hoge.js?:225)
08:15:12.949: obs-browser: Uncaught SyntaxError: Unexpected token = (source: http://absolute/C:/うんたらかんたら/hoge.js?:225)

また、twitterで以下のように教えていただきました

= だと stage 3 のclass field なので、現行仕様では : にしないと通らないです

https://github.com/tc39/proposal-class-fields

ES6 だからといって何でもかんでもぺちぺち新しい書き方が使えるという訳ではなく、それなりの段階があるのかな、と自己解釈しました。
constlet が使えるからと、class上でアロー関数式も使えると思い込んではいけない (戒め)

規格的にChromeが先を行き過ぎているので、そのペースに慣れすぎるのも時折不都合を生じさせる原因になったりするのかもしれませんね。

OBS上でJavaScriptのデバッグが出来るそうな

OBSのwebソースレイアウト上で動くコメジェネとか個人開発していたので、この機能は地味に助かる...

--remote-debugging-port=1234 をOBSのショトカに加えて起動

あとは普通にブラウザ側 から http://localhost:1234/ に接続するだけ。 ( 一応他ソフトとのポート競合などに注意? 80なんかはあからさますぎるので避けたほうが? )