PyWebViewで複数のJavaScriptファイルを読み込む

# PyWebViewで複数のJavaScriptを使いたい

PyWebViewで、ウィンドウにJavaScriptを読み込ませたいときには、`window#evaluate_js()`というメソッドを利用します。

このメソッド、複数回呼び出したときは、それぞれのJavaScriptを別々のファイルと認識して処理します、このため次のようなメソッドを作っておくと、HTML5アプリケーション開発により近い感覚でPyWebViewのGUIを作れます。

```python
def webview_load_elems(window):
  """
  引数で指定した任意のウィンドウに、次のCSS、JSライブラリを読み込む
  ・bootstrap.css
  ・bootstrap.js/popper.js/jquery.js
  ・独自開発用の、index.css/index.js
  """
  css = ["index.css"]
  js = ["index.js", "classes.js"]
  nm = "node_modules"
  dist = nm / "bootstrap-honoka" / "dist"
  distjs = dist / "js"

  css.insert(0, dist / "css" / "bootstrap.css")
  js.insert(0, nm / "popper.js" / "dist" / "popper.js")
  js.insert(0, distjs / "bootstrap.js")
  js.insert(0, nm / "jquery" / "dist" / "jquery.js")

  for file in css:
    with open(file, mode="r", encoding="utf-8") as f:
      window.load_css(f.read())
  for file in js:
    with open(file, mode="r", encoding="utf-8") as f:
      window.evaluate_js(f.read())
```

```javascript:index.js
let test = TestClass()
/* ... */
```

```javascript:classes.js
class TestClass {
  /* ... */
}
```

## 上記コードの問題

上記のようにファイルを読み込むと、classes.jsで宣言したクラスをindex.jsで使うことはできません。ReferenceErrorが発生してしまいます。

最近のJavaScriptであれば`export`文などもありますが、PyWebView上で扱われるファイルは(初期設定では)ローカルファイルとして扱われること、そもそもファイルを読み込んでいるわけではなく、JavaScriptのコードを直接ブラウザエンジンに読み込んでることから、`export`文は使えません

### グローバルな変数のプロパティとして追加する

このようなときは、jQueryなどのファイルの先頭にヒントがあります。

```javascript:jquery.js
( function( global, factory ) {

	"use strict";

	if ( typeof module === "object" && typeof module.exports === "object" ) {

		// For CommonJS and CommonJS-like environments where a proper `window`
		// is present, execute the factory and get jQuery.
		// For environments that do not have a `window` with a `document`
		// (such as Node.js), expose a factory as module.exports.
		// This accentuates the need for the creation of a real `window`.
		// e.g. var jQuery = require("jquery")(window);
		// See ticket #14549 for more info.
		module.exports = global.document ?
			factory( global, true ) :
			function( w ) {
				if ( !w.document ) {
					throw new Error( "jQuery requires a window with a document" );
				}
				return factory( w );
			};
	} else {
		factory( global );
	}

// Pass this if window is not defined yet
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
```

jQueryはJavaScriptの実行環境毎に、グローバル変数やエクスポート領域に自分自身を登録することで、他のJavaScriptファイルからjQueryを呼び出すことを可能にしています。

PyWebViewの実行環境において、使えるグローバル変数は`window`です。ですので、`window`のプロパティとして、宣言したクラスを登録すればOK。


```javascript:classes.js
class TestClass {
  /* ... */
}

window.TestClass = TestClass;
```

これで`index.js`からでも`classes.js`のクラスが利用できるようになります。

## おまけ：PyWebViewウィンドウの開発者コンソールから、JavaScriptファイルを見たい

`webview.start()`メソッドの`gui`に開発者コンソールが利用できるブラウザエンジン(cefなど)、`debug`を`True`に設定すると、ブラウザウィンドウの右クリックメニューから開発者コンソールが開けるようになります。

この開発者コンソールから読み込んだJavaScriptファイルを見たい場合。読み込んだJavaScriptコードはファイルの形式ではないので、Sourceタブから中身を見ることができません。

そんなときは、JavaScriptファイルの先頭行に`console.log("ファイル名")`などと入れておくと良いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14499/624240f6-eb45-6078-9d0d-febe0bdbae0a.png)

画面右の「VMnn:行数」というリンクをクリックすると、読み込んだJavaScriptコードを閲覧することができます。