diff options
author | Matt Mastracci <matthew@mastracci.com> | 2024-04-24 15:45:49 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-24 19:45:49 +0000 |
commit | 2f8825a935bfdf21ca592284556cd86c1552ac8d (patch) | |
tree | 68beddeb5547861212be188f126113e6b1afc1df /runtime | |
parent | c1bd9503dd0288a3c209ca2724d2a1de9d5d122b (diff) |
feat: Add `deno serve` subcommand (#23511)
By default, `deno serve` will assign port 8000 (like `Deno.serve`).
Users may choose a different port using `--port`.
`deno serve /tmp/file.ts`
`server.ts`:
```ts
export default {
fetch(req) {
return new Response("hello world!\n");
},
};
```
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/js/99_main.js | 58 | ||||
-rw-r--r-- | runtime/lib.rs | 1 | ||||
-rw-r--r-- | runtime/worker_bootstrap.rs | 42 |
3 files changed, 101 insertions, 0 deletions
diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 8164e0c9a..59d2a1434 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -35,6 +35,7 @@ const { ObjectAssign, ObjectDefineProperties, ObjectDefineProperty, + ObjectHasOwn, ObjectKeys, ObjectPrototypeIsPrototypeOf, ObjectSetPrototypeOf, @@ -52,6 +53,7 @@ const { const { isNativeError, } = core; +import { registerDeclarativeServer } from "ext:deno_http/00_serve.ts"; import * as event from "ext:deno_web/02_event.js"; import * as location from "ext:deno_web/12_location.js"; import * as version from "ext:runtime/01_version.ts"; @@ -679,6 +681,18 @@ const { target, } = op_snapshot_options(); +const executionModes = { + none: 0, + worker: 1, + run: 2, + repl: 3, + eval: 4, + test: 5, + bench: 6, + serve: 7, + jupyter: 8, +}; + function bootstrapMainRuntime(runtimeOptions, warmup = false) { if (!warmup) { if (hasBootstrapped) { @@ -695,8 +709,52 @@ function bootstrapMainRuntime(runtimeOptions, warmup = false) { 7: shouldDisableDeprecatedApiWarning, 8: shouldUseVerboseDeprecatedApiWarning, 9: future, + 10: mode, + 11: servePort, + 12: serveHost, } = runtimeOptions; + if (mode === executionModes.run || mode === executionModes.serve) { + let serve = undefined; + core.addMainModuleHandler((main) => { + if (ObjectHasOwn(main, "default")) { + try { + serve = registerDeclarativeServer(main.default); + } catch (e) { + if (mode === executionModes.serve) { + throw e; + } + } + } + + if (mode === executionModes.serve && !serve) { + console.error( + `%cerror: %cdeno serve requires %cexport default { fetch }%c in the main module, did you mean to run \"deno run\"?`, + "color: yellow;", + "color: inherit;", + "font-weight: bold;", + "font-weight: normal;", + ); + return; + } + + if (serve) { + if (mode === executionModes.run) { + console.error( + `%cwarning: %cDetected %cexport default { fetch }%c, did you mean to run \"deno serve\"?`, + "color: yellow;", + "color: inherit;", + "font-weight: bold;", + "font-weight: normal;", + ); + } + if (mode === executionModes.serve) { + serve({ servePort, serveHost }); + } + } + }); + } + // TODO(iuioiua): remove in Deno v2. This allows us to dynamically delete // class properties within constructors for classes that are not defined // within the Deno namespace. diff --git a/runtime/lib.rs b/runtime/lib.rs index f33e9b7e3..ec751f207 100644 --- a/runtime/lib.rs +++ b/runtime/lib.rs @@ -41,6 +41,7 @@ pub mod worker; mod worker_bootstrap; pub use worker_bootstrap::BootstrapOptions; +pub use worker_bootstrap::WorkerExecutionMode; pub use worker_bootstrap::WorkerLogLevel; mod shared; diff --git a/runtime/worker_bootstrap.rs b/runtime/worker_bootstrap.rs index c019dae1a..ee3b81c62 100644 --- a/runtime/worker_bootstrap.rs +++ b/runtime/worker_bootstrap.rs @@ -4,10 +4,36 @@ use deno_core::v8; use deno_core::ModuleSpecifier; use serde::Serialize; use std::cell::RefCell; +use std::num::NonZeroU16; use std::thread; use deno_terminal::colors; +/// The execution mode for this worker. Some modes may have implicit behaviour. +#[derive(Copy, Clone)] +#[repr(u8)] +pub enum WorkerExecutionMode { + /// No special behaviour. + None, + + /// Running in a worker. + Worker, + /// `deno run` + Run, + /// `deno repl` + Repl, + /// `deno eval` + Eval, + /// `deno test` + Test, + /// `deno bench` + Bench, + /// `deno serve` + Serve, + /// `deno jupyter` + Jupyter, +} + /// The log level to use when printing diagnostic log messages, warnings, /// or errors in the worker. /// @@ -63,6 +89,10 @@ pub struct BootstrapOptions { pub disable_deprecated_api_warning: bool, pub verbose_deprecated_api_warning: bool, pub future: bool, + pub mode: WorkerExecutionMode, + // Used by `deno serve` + pub serve_port: Option<NonZeroU16>, + pub serve_host: Option<String>, } impl Default for BootstrapOptions { @@ -94,6 +124,9 @@ impl Default for BootstrapOptions { disable_deprecated_api_warning: false, verbose_deprecated_api_warning: false, future: false, + mode: WorkerExecutionMode::None, + serve_port: Default::default(), + serve_host: Default::default(), } } } @@ -129,6 +162,12 @@ struct BootstrapV8<'a>( bool, // future bool, + // mode + i32, + // serve port + u16, + // serve host + Option<&'a str>, ); impl BootstrapOptions { @@ -151,6 +190,9 @@ impl BootstrapOptions { self.disable_deprecated_api_warning, self.verbose_deprecated_api_warning, self.future, + self.mode as u8 as _, + self.serve_port.map(|x| x.into()).unwrap_or_default(), + self.serve_host.as_deref(), ); bootstrap.serialize(ser).unwrap() |