Open vrugtehagel opened 1 month ago
While a bit more verbose, you can use deno run -A jsr:@std/http/file-server
to achieve the same I think
As lowlighter suggested, we have https://jsr.io/@std/http/doc/file-server for your use case. You can also install it to your path using the below commands:
> # install
> deno install --allow-net --allow-read --allow-sys --global jsr:@std/http/file-server
> # start server
> file-server
> # show help
> file-server --help
It's a bit of a bummer that you'd need an internet connection to go that route even if you have deno
installed, but I guess it does suit the use-case. Thanks, people!
@vrugtehagel, you don't need internet connection after the first run, or once file-server
is installed.
I think we should really consider adding deno serve --fs
, it's very convenient.
Not sure if this is helpful, but here's a snippet that I wrote to boot up a no-dependency server with Deno:
const root = './src'
const mimeTypes = {
css: 'text/css',
html: 'text/html',
js: 'text/javascript',
// …
txt: 'text/plain',
}
const handler = async request => {
const {pathname} = new URL(request.url)
const filepath = `${root}${pathname}`.replace(/\/$/, '/index.html')
const url = new URL(filepath, import.meta.url)
const response = await fetch(url).catch(() => null)
if(response == null) return new Response('Not found', {status: 404})
if(response.status != 200) return response
const [extension] = url.pathname.match(/(?<=\.)\w+$/) ?? []
const contentType = mimeTypes[extension] ?? mimeTypes.txt
const headers = new Headers(response.headers)
headers.set('Content-Type', contentType)
return new Response(response.body, {headers})
}
export default {fetch: handler}
One thing to keep in mind when building this into Deno is that it must be aware of extension-to-Content-Type
conversions. If this is going to be built-in, perhaps an API of sorts could be good? If Deno manages MIME types then it might as well expose that info 😉
Hypothetically, fetch()
should cover the general use-case because fetch()
in Deno handles file URLs, but (perhaps intentionally?) it throws an error when a file is not found rather than resolving with a 404 response, which is what browsers do. This is why the snippet above manually handles 404s.
Other than this, I don't reckon it's too difficult to implement - willing to give it a shot if the specifications are clear.
Also, as a sidenote, I think --fs
is a good name for the flag and we can even accept a root for serving, like deno serve --fs=./src
. Alternatively, we can keep the --fs
flag boolean and do deno serve --fs --fs-root=./src
, but this is nice-to-have functionality since it's equivalent to cd ./src && deno serve --fs
. Just some thoughts 😉
For local development I often need a simple server that just spits out the files on my system as they are. Some runtimes (for other languages) provide such functionality; usually I end up using
php -S localhost:8080
which does just that. Deno has aserve
command, which is exciting but doesn't quite reach the use-case I need, since it requires an entry point that defines how the server should behave. I think it'd be nice to have a default server that responds with the files on the system, inferring content type from the file extensions.This could look like a plain
deno serve
(without entry point) but to protect users from mistakes like accidentally forgetting the entry point, perhaps an additional flag would be good, e.g.deno serve --plain
(or--default
, or--passthrough
, etcetera).Is this something the Deno team would be interested in?