1
0
Fork 0
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:
Nayeem Rahman 2020-06-09 13:33:52 +01:00 committed by GitHub
parent 81a6f673ad
commit 44251ce8ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 55 deletions

View file

@ -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

View file

@ -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(

View file

@ -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" });

View file

@ -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();

View file

@ -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();

View file

@ -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();

View file

@ -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" });
``` ```