diff --git a/README.md b/README.md index 0f9249567..77f2f1413 100644 --- a/README.md +++ b/README.md @@ -179,13 +179,13 @@ import { NinetyRing, NinetyRingWithBg } from "https://esm.sh/react-svg-spinners@ esm.sh is a **Deno-friendly** CDN that resolves Node's built-in modules (such as **fs**, **os**, etc.), making it compatible with Deno. ```javascript -import postcss from "https://esm.sh/postcss" -import autoprefixer from "https://esm.sh/autoprefixer" +import express from "https://esm.sh/express"; -const { css } = await postcss([ autoprefixer ]).process(` - backdrop-filter: blur(5px); - user-select: none; -.async() +const app = express(); +app.get("/", (req, res) => { + res.send("Hello World"); +}); +app.listen(3000) ``` For users using deno `< 1.31`, esm.sh uses [deno.land/std@0.177.0/node](https://deno.land/std@0.177.0/node) as node compatibility layer. You can specify a different version by adding the `?deno-std=$VER` query: diff --git a/server/build.go b/server/build.go index b5cc4bcb5..f32f4ae2f 100644 --- a/server/build.go +++ b/server/build.go @@ -885,17 +885,9 @@ esbuild: } } + // most of npm packages check for window object to detect browser environment, but Deno also has the window object + // so we need to replace the check with document object if task.Target == "deno" || task.Target == "denonext" { - // inject xhr polyfill for axios - switch task.Pkg.Name { - case "axios", "cross-fetch", "whatwg-fetch": - outputContent = bytes.Join([][]byte{ - []byte(`import "https://deno.land/x/xhr@0.3.0/mod.ts";`), - outputContent, - }, []byte{}) - } - // most of npm packages check for window object to detect browser environment, but Deno also has the window object - // so we need to replace the check with document object if task.DevMode { outputContent = bytes.Replace(outputContent, []byte("typeof window !== \"undefined\""), []byte("typeof document !== \"undefined\""), -1) } else { @@ -903,7 +895,7 @@ esbuild: } } - _, err = buf.Write(outputContent) + _, err = buf.Write(rewriteJS(task, outputContent)) if err != nil { return } diff --git a/server/rewrite.go b/server/rewrite.go new file mode 100644 index 000000000..aef6860fd --- /dev/null +++ b/server/rewrite.go @@ -0,0 +1,26 @@ +package server + +import ( + "bytes" + + "github.com/Masterminds/semver/v3" +) + +func rewriteJS(task *BuildTask, js []byte) []byte { + denoTarget := task.Target == "deno" || task.Target == "denonext" + switch task.Pkg.Name { + case "axios", "cross-fetch", "whatwg-fetch": + if denoTarget { + xhr := []byte(`import "https://deno.land/x/xhr@0.3.0/mod.ts";`) + buf := make([]byte, len(js)+len(xhr)) + copy(buf, xhr) + copy(buf[len(xhr):], js) + js = buf + } + case "iconv-lite": + if denoTarget && semver.MustParse(task.Pkg.Version).LessThan(semver.MustParse("0.5.0")) { + js = bytes.Replace(js, []byte("__Process$.versions.node"), []byte("void 0"), 1) + } + } + return js +} diff --git a/test/express/express.test.ts b/test/express/express.test.ts new file mode 100644 index 000000000..f81fb3cb5 --- /dev/null +++ b/test/express/express.test.ts @@ -0,0 +1,33 @@ +import { assertEquals } from "https://deno.land/std@0.178.0/testing/asserts.ts"; + +import express, { + type Request, + type Response, +} from "http://localhost:8080/express@4"; + +Deno.test( + "express", + { sanitizeOps: false, sanitizeResources: false }, + async () => { + const app = express(); + app.get("/", (_req: Request, res: Response) => { + // @ts-ignore + res.send("Hello World"); + }); + + const ac = new AbortController(); + await new Promise((resolve, reject) => { + const server = app.listen({ port: 3333 }, (err?: Error) => { + if (err) reject(err); + resolve(); + }); + ac.signal.onabort = () => { + server.close(); + }; + }); + + const res = await fetch("http://localhost:3333"); + assertEquals(await res.text(), "Hello World"); + ac.abort(); + }, +);