🦐
Nuxt.js + ky で Service WorkerからもAjaxできるようにする
nuxt/httpでも利用されている「ky」ですが、Nuxt.jsのインスタンス管理外から使ってみたい、しかもService Worker上から、という必要性があったものの、インストールと使い方で引っかかったので備忘録。
シンプルで良さそう!
インストール
普通にkyをインストールすると、Webpackな環境ではそのままではインポートできません。
import ky from 'ky'; // だめっぽい
import ky from '@/node_modules/ky/distribution'; // いけた
Node.js向けのpolyfillとしてky-universal
というものがあるようです。
ky本体とReadableStreamのpolyfillもインストールする必要があります。
$ npm i ky ky-universal web-streams-polyfill
# import ky from 'ky-universal'
$ npm run dev # Nuxt起動
..
..
This dependency was not found:
* ky in ./node_modules/ky-universal/browser.js
まだエラーが出るのでライブラリを修正する必要があります。
(プルリク案件なのか自分が間違っているのかわからない……)
~/node_modules/ky-universal/browser.js
//import ky from 'ky';
import ky from '@/node_modules/ky/distribution';
export default ky;
使い方
今回はAPIを叩くのではなく、サーバ側に置いてあるリソース(機械学習用の学習済みデータセット)を読み込むために使用しました。リソースは~/static
に置いてあるため、ルート直下にアクセスすることで取得できます。
(async () => {
const response = await ky.get(self.location.origin + '/dataset.txt'); // response.bodyがデータ本体
const reader = await response.body.getReader().read(); // reader.valueがUint8Array
const result = new TextDecoder('utf-8').decode(reader.value); // データの種類に応じて適宜変換
console.log(result); // いい感じ
})()
上記のコードだけで、メインスレッドからでも、Service Worker上からでも、データセットをテキスト形式で読み込むことができました。
Service Worker上からURL指定時の注意
console.log(self.location.href);
// メインスレッドのとき:http://localhost:3000/
// Worker上のとき:http://localhost:3000/_nuxt/ml.worker.js ※worker-loader利用
自サーバ上のリソースに対して相対URLを仕掛ける場合、Worker上で動いているかどうかでhrefが変わってくるため、self.location.origin
からの絶対位置URL指定にするのがよさそうです。
// 以下はService Worker上からやると404になる(メインスレッドからだと問題なし)
const response = await ky.get('./dataset.txt');
// これだとどっちからでもいける
const response = await ky.get('http://localhost:3000/dataset.txt'); // 開発時のみ
const response = await ky.get(self.location.origin + '/dataset.txt');
// self.locationはWorkerの場合はWorkerLocationオブジェクトとなる
なお、node-fetch
とabort-controller
は特に不要のようでした。
Discussion