mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -05:00
fix(cli/js/web/worker): Disable relative module specifiers (#5266)
This commit is contained in:
parent
81a6f673ad
commit
44251ce8ea
7 changed files with 80 additions and 55 deletions
5
cli/js/lib.deno.shared_globals.d.ts
vendored
5
cli/js/lib.deno.shared_globals.d.ts
vendored
|
@ -1300,7 +1300,10 @@ declare class Worker extends EventTarget {
|
||||||
*
|
*
|
||||||
* ```ts
|
* ```ts
|
||||||
* // mod.ts
|
* // mod.ts
|
||||||
* const worker = new Worker("./deno_worker.ts", { type: "module", deno: true });
|
* const worker = new Worker(
|
||||||
|
* new URL("deno_worker.ts", import.meta.url).href,
|
||||||
|
* { type: "module", deno: true }
|
||||||
|
* );
|
||||||
* worker.postMessage({ cmd: "readFile", fileName: "./log.txt" });
|
* worker.postMessage({ cmd: "readFile", fileName: "./log.txt" });
|
||||||
*
|
*
|
||||||
* // deno_worker.ts
|
* // deno_worker.ts
|
||||||
|
|
|
@ -193,13 +193,11 @@ fn op_create_worker(
|
||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
let global_state = state.global_state.clone();
|
let global_state = state.global_state.clone();
|
||||||
let permissions = state.permissions.clone();
|
let permissions = state.permissions.clone();
|
||||||
let referrer = state.main_module.to_string();
|
|
||||||
let worker_id = state.next_worker_id;
|
let worker_id = state.next_worker_id;
|
||||||
state.next_worker_id += 1;
|
state.next_worker_id += 1;
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
let module_specifier =
|
let module_specifier = ModuleSpecifier::resolve_url(&specifier)?;
|
||||||
ModuleSpecifier::resolve_import(&specifier, &referrer)?;
|
|
||||||
let worker_name = args_name.unwrap_or_else(|| "".to_string());
|
let worker_name = args_name.unwrap_or_else(|| "".to_string());
|
||||||
|
|
||||||
let (join_handle, worker_handle) = run_worker_thread(
|
let (join_handle, worker_handle) = run_worker_thread(
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// Specifier should be resolved relative to current file
|
// Specifier should be resolved relative to current file
|
||||||
const jsWorker = new Worker("./sibling_worker.js", {
|
const jsWorker = new Worker(
|
||||||
type: "module",
|
new URL("sibling_worker.js", import.meta.url).href,
|
||||||
name: "sibling",
|
{ type: "module", name: "sibling" }
|
||||||
});
|
);
|
||||||
|
|
||||||
jsWorker.onerror = (_e) => {
|
jsWorker.onerror = (_e) => {
|
||||||
postMessage({ type: "error" });
|
postMessage({ type: "error" });
|
||||||
|
|
|
@ -37,7 +37,10 @@ function handleAsyncMsgFromWorker(
|
||||||
async function main(): Promise<void> {
|
async function main(): Promise<void> {
|
||||||
const workers: Array<[Map<number, Resolvable<string>>, Worker]> = [];
|
const workers: Array<[Map<number, Resolvable<string>>, Worker]> = [];
|
||||||
for (let i = 1; i <= workerCount; ++i) {
|
for (let i = 1; i <= workerCount; ++i) {
|
||||||
const worker = new Worker("./subdir/bench_worker.ts", { type: "module" });
|
const worker = new Worker(
|
||||||
|
new URL("subdir/bench_worker.ts", import.meta.url).href,
|
||||||
|
{ type: "module" }
|
||||||
|
);
|
||||||
const promise = createResolvable<void>();
|
const promise = createResolvable<void>();
|
||||||
worker.onmessage = (e): void => {
|
worker.onmessage = (e): void => {
|
||||||
if (e.data.cmdId === 0) promise.resolve();
|
if (e.data.cmdId === 0) promise.resolve();
|
||||||
|
|
|
@ -4,7 +4,10 @@ const workerCount = 50;
|
||||||
async function bench(): Promise<void> {
|
async function bench(): Promise<void> {
|
||||||
const workers: Worker[] = [];
|
const workers: Worker[] = [];
|
||||||
for (let i = 1; i <= workerCount; ++i) {
|
for (let i = 1; i <= workerCount; ++i) {
|
||||||
const worker = new Worker("./subdir/bench_worker.ts", { type: "module" });
|
const worker = new Worker(
|
||||||
|
new URL("subdir/bench_worker.ts", import.meta.url).href,
|
||||||
|
{ type: "module" }
|
||||||
|
);
|
||||||
const promise = new Promise((resolve): void => {
|
const promise = new Promise((resolve): void => {
|
||||||
worker.onmessage = (e): void => {
|
worker.onmessage = (e): void => {
|
||||||
if (e.data.cmdId === 0) resolve();
|
if (e.data.cmdId === 0) resolve();
|
||||||
|
|
|
@ -32,13 +32,14 @@ Deno.test({
|
||||||
fn: async function (): Promise<void> {
|
fn: async function (): Promise<void> {
|
||||||
const promise = createResolvable();
|
const promise = createResolvable();
|
||||||
|
|
||||||
const jsWorker = new Worker("../tests/subdir/test_worker.js", {
|
const jsWorker = new Worker(
|
||||||
type: "module",
|
new URL("subdir/test_worker.js", import.meta.url).href,
|
||||||
});
|
{ type: "module" }
|
||||||
const tsWorker = new Worker("../tests/subdir/test_worker.ts", {
|
);
|
||||||
type: "module",
|
const tsWorker = new Worker(
|
||||||
name: "tsWorker",
|
new URL("subdir/test_worker.ts", import.meta.url).href,
|
||||||
});
|
{ type: "module", name: "tsWorker" }
|
||||||
|
);
|
||||||
|
|
||||||
tsWorker.onmessage = (e): void => {
|
tsWorker.onmessage = (e): void => {
|
||||||
assertEquals(e.data, "Hello World");
|
assertEquals(e.data, "Hello World");
|
||||||
|
@ -67,10 +68,10 @@ Deno.test({
|
||||||
fn: async function (): Promise<void> {
|
fn: async function (): Promise<void> {
|
||||||
const promise = createResolvable();
|
const promise = createResolvable();
|
||||||
|
|
||||||
const nestedWorker = new Worker("../tests/subdir/nested_worker.js", {
|
const nestedWorker = new Worker(
|
||||||
type: "module",
|
new URL("subdir/nested_worker.js", import.meta.url).href,
|
||||||
name: "nested",
|
{ type: "module", name: "nested" }
|
||||||
});
|
);
|
||||||
|
|
||||||
nestedWorker.onmessage = (e): void => {
|
nestedWorker.onmessage = (e): void => {
|
||||||
assert(e.data.type !== "error");
|
assert(e.data.type !== "error");
|
||||||
|
@ -87,9 +88,10 @@ Deno.test({
|
||||||
name: "worker throws when executing",
|
name: "worker throws when executing",
|
||||||
fn: async function (): Promise<void> {
|
fn: async function (): Promise<void> {
|
||||||
const promise = createResolvable();
|
const promise = createResolvable();
|
||||||
const throwingWorker = new Worker("../tests/subdir/throwing_worker.js", {
|
const throwingWorker = new Worker(
|
||||||
type: "module",
|
new URL("subdir/throwing_worker.js", import.meta.url).href,
|
||||||
});
|
{ type: "module" }
|
||||||
|
);
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
throwingWorker.onerror = (e: any): void => {
|
throwingWorker.onerror = (e: any): void => {
|
||||||
|
@ -108,9 +110,10 @@ Deno.test({
|
||||||
fn: async function (): Promise<void> {
|
fn: async function (): Promise<void> {
|
||||||
const promise = createResolvable();
|
const promise = createResolvable();
|
||||||
|
|
||||||
const fetchingWorker = new Worker("../tests/subdir/fetching_worker.js", {
|
const fetchingWorker = new Worker(
|
||||||
type: "module",
|
new URL("subdir/fetching_worker.js", import.meta.url).href,
|
||||||
});
|
{ type: "module" }
|
||||||
|
);
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
fetchingWorker.onerror = (e: any): void => {
|
fetchingWorker.onerror = (e: any): void => {
|
||||||
|
@ -134,9 +137,10 @@ Deno.test({
|
||||||
fn: async function (): Promise<void> {
|
fn: async function (): Promise<void> {
|
||||||
const promise = createResolvable();
|
const promise = createResolvable();
|
||||||
|
|
||||||
const busyWorker = new Worker("../tests/subdir/busy_worker.js", {
|
const busyWorker = new Worker(
|
||||||
type: "module",
|
new URL("subdir/busy_worker.js", import.meta.url).href,
|
||||||
});
|
{ type: "module" }
|
||||||
|
);
|
||||||
|
|
||||||
let testResult = 0;
|
let testResult = 0;
|
||||||
|
|
||||||
|
@ -166,9 +170,10 @@ Deno.test({
|
||||||
// https://github.com/denoland/deno/issues/4080
|
// https://github.com/denoland/deno/issues/4080
|
||||||
const promise = createResolvable();
|
const promise = createResolvable();
|
||||||
|
|
||||||
const racyWorker = new Worker("../tests/subdir/racy_worker.js", {
|
const racyWorker = new Worker(
|
||||||
type: "module",
|
new URL("subdir/racy_worker.js", import.meta.url).href,
|
||||||
});
|
{ type: "module" }
|
||||||
|
);
|
||||||
|
|
||||||
racyWorker.onmessage = (e): void => {
|
racyWorker.onmessage = (e): void => {
|
||||||
assertEquals(e.data.buf.length, 999999);
|
assertEquals(e.data.buf.length, 999999);
|
||||||
|
@ -193,9 +198,10 @@ Deno.test({
|
||||||
const promise1 = createResolvable();
|
const promise1 = createResolvable();
|
||||||
const promise2 = createResolvable();
|
const promise2 = createResolvable();
|
||||||
|
|
||||||
const worker = new Worker("../tests/subdir/event_worker.js", {
|
const worker = new Worker(
|
||||||
type: "module",
|
new URL("subdir/event_worker.js", import.meta.url).href,
|
||||||
});
|
{ type: "module" }
|
||||||
|
);
|
||||||
|
|
||||||
worker.onmessage = (_e: Event): void => {
|
worker.onmessage = (_e: Event): void => {
|
||||||
messageHandlersCalled++;
|
messageHandlersCalled++;
|
||||||
|
@ -236,9 +242,10 @@ Deno.test({
|
||||||
fn: async function (): Promise<void> {
|
fn: async function (): Promise<void> {
|
||||||
const promise1 = createResolvable();
|
const promise1 = createResolvable();
|
||||||
|
|
||||||
const worker = new Worker("../tests/subdir/event_worker_scope.js", {
|
const worker = new Worker(
|
||||||
type: "module",
|
new URL("subdir/event_worker_scope.js", import.meta.url).href,
|
||||||
});
|
{ type: "module" }
|
||||||
|
);
|
||||||
|
|
||||||
worker.onmessage = (e: MessageEvent): void => {
|
worker.onmessage = (e: MessageEvent): void => {
|
||||||
const { messageHandlersCalled, errorHandlersCalled } = e.data;
|
const { messageHandlersCalled, errorHandlersCalled } = e.data;
|
||||||
|
@ -264,13 +271,14 @@ Deno.test({
|
||||||
const promise = createResolvable();
|
const promise = createResolvable();
|
||||||
const promise2 = createResolvable();
|
const promise2 = createResolvable();
|
||||||
|
|
||||||
const regularWorker = new Worker("../tests/subdir/non_deno_worker.js", {
|
const regularWorker = new Worker(
|
||||||
type: "module",
|
new URL("subdir/non_deno_worker.js", import.meta.url).href,
|
||||||
});
|
{ type: "module" }
|
||||||
const denoWorker = new Worker("../tests/subdir/deno_worker.ts", {
|
);
|
||||||
type: "module",
|
const denoWorker = new Worker(
|
||||||
deno: true,
|
new URL("subdir/deno_worker.ts", import.meta.url).href,
|
||||||
});
|
{ type: "module", deno: true }
|
||||||
|
);
|
||||||
|
|
||||||
regularWorker.onmessage = (e): void => {
|
regularWorker.onmessage = (e): void => {
|
||||||
assertEquals(e.data, "Hello World");
|
assertEquals(e.data, "Hello World");
|
||||||
|
@ -295,9 +303,10 @@ Deno.test({
|
||||||
name: "worker with crypto in scope",
|
name: "worker with crypto in scope",
|
||||||
fn: async function (): Promise<void> {
|
fn: async function (): Promise<void> {
|
||||||
const promise = createResolvable();
|
const promise = createResolvable();
|
||||||
const w = new Worker("../tests/subdir/worker_crypto.js", {
|
const w = new Worker(
|
||||||
type: "module",
|
new URL("subdir/worker_crypto.js", import.meta.url).href,
|
||||||
});
|
{ type: "module" }
|
||||||
|
);
|
||||||
w.onmessage = (e): void => {
|
w.onmessage = (e): void => {
|
||||||
assertEquals(e.data, true);
|
assertEquals(e.data, true);
|
||||||
promise.resolve();
|
promise.resolve();
|
||||||
|
|
|
@ -7,15 +7,21 @@ Workers can be used to run code on multiple threads. Each instance of `Worker`
|
||||||
is run on a separate thread, dedicated only to that worker.
|
is run on a separate thread, dedicated only to that worker.
|
||||||
|
|
||||||
Currently Deno supports only `module` type workers; thus it's essential to pass
|
Currently Deno supports only `module` type workers; thus it's essential to pass
|
||||||
`type: "module"` option when creating a new worker:
|
the `type: "module"` option when creating a new worker.
|
||||||
|
|
||||||
|
Relative module specifiers are
|
||||||
|
[not supported](https://github.com/denoland/deno/issues/5216) at the moment. You
|
||||||
|
can instead use the `URL` contructor and `import.meta.url` to easily create a
|
||||||
|
specifier for some nearby script.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// Good
|
// Good
|
||||||
new Worker("./worker.js", { type: "module" });
|
new Worker(new URL("worker.js", import.meta.url).href, { type: "module" });
|
||||||
|
|
||||||
// Bad
|
// Bad
|
||||||
new Worker("./worker.js");
|
new Worker(new URL("worker.js", import.meta.url).href);
|
||||||
new Worker("./worker.js", { type: "classic" });
|
new Worker(new URL("worker.js", import.meta.url).href, { type: "classic" });
|
||||||
|
new Worker("./worker.js", { type: "module" });
|
||||||
```
|
```
|
||||||
|
|
||||||
### Permissions
|
### Permissions
|
||||||
|
@ -28,7 +34,7 @@ For workers using local modules; `--allow-read` permission is required:
|
||||||
**main.ts**
|
**main.ts**
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
new Worker("./worker.ts", { type: "module" });
|
new Worker(new URL("worker.ts", import.meta.url).href, { type: "module" });
|
||||||
```
|
```
|
||||||
|
|
||||||
**worker.ts**
|
**worker.ts**
|
||||||
|
@ -81,7 +87,10 @@ To add the `Deno` namespace pass `deno: true` option when creating new worker:
|
||||||
**main.js**
|
**main.js**
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const worker = new Worker("./worker.js", { type: "module", deno: true });
|
const worker = new Worker(new URL("worker.js", import.meta.url).href, {
|
||||||
|
type: "module",
|
||||||
|
deno: true,
|
||||||
|
});
|
||||||
worker.postMessage({ filename: "./log.txt" });
|
worker.postMessage({ filename: "./log.txt" });
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue