2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Deno公式マニュアルのWeb Worker APIからテキストファイルを読むとこでつまづいた

Last updated at Posted at 2021-07-18

Deno | Manual

ここ

DenoでWorkerを使うときはnew Workerの第二引数で{type: "module"}をつける。
Workerの中でDenoの機能を使いたいときはさらにdenoプロパティを追加する。
deno: true, deno: falseでもいいらしい。
で、実行時は--allow-read--unstableをつける。

main.js
const worker = new Worker(new URL("./worker.js", import.meta.url).href, {
  type: "module",
  deno: {
    namespace: true,
  },
});
worker.postMessage({ filename: "./log.txt" });
worker.js
self.onmessage = async (e) => {
  const { filename } = e.data;
  const text = await Deno.readTextFile(filename);
  console.log(text);
  self.close();
};
log.txt
hello world

だけどエラーが出た。
やってみてエラー出なかった人もいると思う。

% deno run --allow-read --unstable main.js
error: Uncaught (in promise) Error: Unhandled error event reached main worker.
    at Worker.#poll (deno:runtime/js/11_workers.js:243:23)

Workerのエラーは何も教えてくれないから困った。

エラーの理由

ソースと同じディレクトリにlog.txtを置いて読もうとしてたこと。
log.txtがカレントディレクトリにないと動かない。

./worker.js./log.txtという、二つの相対パスが書かれてる。
./worker.jsnew URL("./worker.js", import.meta.url).hrefで絶対パスに変換されてる。
ソースと同じディレクトリにあればいい。

だけど./log.txtは相対パス。
今いるフォルダの中にlog.txtがないとDeno.readTextFileで読めない。

じゃぁ絶対パスにすればいいかってnew URL("./log.txt", import.meta.url).hrefを渡しても動かない。
URL#hrefが返すパスはfile://から始まるので、取り除いておかないとDeno.readFileで読めない。
標準ライブラリのfromFileUrlを使う。正規表現で消してもいいけど。

つまりmain.jsをこうすればいけた。
カレントディレクトリのテキストファイルを読みたい人はそのままでいい。

main.js
import { fromFileUrl } from "https://deno.land/std@0.101.0/path/mod.ts";

const workerURL = new URL("./worker.js", import.meta.url).href;
const textURL = new URL("./log.txt", import.meta.url).href; // file:///path/to/log.txt
const filename = fromFileUrl(textURL); // /path/to/log.txt

const worker = new Worker(workerURL, {
  type: "module",
  deno: {
    namespace: true,
  },
});
worker.postMessage({ filename });

ちなみにmain.js側から引き継ぐパーミッションも個別に指定できるけど、そっちはソースディレクトリからの相対パスになる。

main.js
import { fromFileUrl } from "https://deno.land/std@0.101.0/path/mod.ts";

const workerURL = new URL("./worker.js", import.meta.url).href;
const textURL = new URL("./log.txt", import.meta.url).href;
const filename = fromFileUrl(textURL);

const worker = new Worker(workerURL, {
  type: "module",
  deno: {
    namespace: true,
    permissions: {
      read: [
        "./log.txt", // main.jsからの相対パス!
      ],
    },
  },
});
worker.postMessage({ filename });

分かってみれば、そりゃDeno.readTextFileはカレントディレクトリ読むよねって感じ

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?