From e0967666ab9be578c71217d634d9bb00c971eab6 Mon Sep 17 00:00:00 2001 From: Je Xia Date: Wed, 20 Nov 2024 04:27:15 +0800 Subject: [PATCH 1/2] Use mjs extenstion for sub-module build --- server/build_resolver.go | 27 +++++++++++++++------------ server/embed/tsx.ts | 2 +- server/esm_router.go | 16 +++++++++------- test/build-args/bundle.test.ts | 6 +++--- test/build-args/deps.test.ts | 4 ++-- test/build-args/external.test.ts | 4 ++-- test/common/jotail.test.ts | 2 +- test/common/rc-util.test.ts | 2 +- test/fix-url/test.ts | 6 +++--- test/issue-581/test.ts | 2 +- test/issue-671/test.ts | 4 ++-- test/issue-711/test.ts | 2 +- test/issue-728/test.ts | 2 +- test/issue-761/test.ts | 2 +- test/vue/transfrom-sfc-on-fly.test.ts | 2 +- test/worker/test.ts | 6 +++--- 16 files changed, 47 insertions(+), 42 deletions(-) diff --git a/server/build_resolver.go b/server/build_resolver.go index 7e7bb48dc..0da4d69a2 100644 --- a/server/build_resolver.go +++ b/server/build_resolver.go @@ -97,11 +97,13 @@ func (ctx *BuildContext) Path() string { } name := strings.TrimSuffix(path.Base(esmPath.PkgName), ".js") - extname := ".mjs" - if esmPath.SubBareName != "" { - name = esmPath.SubBareName - extname = ".js" + if esmPath.SubBareName == name { + // if the sub-module name is same as the package name + name = "__" + esmPath.SubBareName + } else { + name = esmPath.SubBareName + } // workaround for es5-ext "../#/.." path if esmPath.PkgName == "es5-ext" { name = strings.ReplaceAll(name, "/#/", "/%23/") @@ -117,22 +119,24 @@ func (ctx *BuildContext) Path() string { name += ".nobundle" } ctx.path = fmt.Sprintf( - "/%s/%s%s/%s%s", + "/%s/%s%s/%s.mjs", esmPath.PackageName(), ctx.getBuildArgsPrefix(ctx.target == "types"), ctx.target, name, - extname, ) return ctx.path } func (ctx *BuildContext) getImportPath(esmPath ESMPath, buildArgsPrefix string) string { name := strings.TrimSuffix(path.Base(esmPath.PkgName), ".js") - extname := ".mjs" if esmPath.SubBareName != "" { - name = esmPath.SubBareName - extname = ".js" + if esmPath.SubBareName == name { + // if the sub-module name is same as the package name + name = "__" + esmPath.SubBareName + } else { + name = esmPath.SubBareName + } // workaround for es5-ext "../#/.." path if esmPath.PkgName == "es5-ext" { name = strings.ReplaceAll(name, "/#/", "/%23/") @@ -142,12 +146,11 @@ func (ctx *BuildContext) getImportPath(esmPath ESMPath, buildArgsPrefix string) name += ".development" } return fmt.Sprintf( - "/%s/%s%s/%s%s", + "/%s/%s%s/%s.mjs", esmPath.PackageName(), buildArgsPrefix, ctx.target, name, - extname, ) } @@ -653,7 +656,7 @@ func (ctx *BuildContext) resolveConditionExportEntry(conditions *OrderedMap, mTy } } else if ctx.isDenoTarget() { var condition interface{} - for _, conditionName := range []string{"deno", "workerd", "worker", "node"} { + for _, conditionName := range []string{"deno", "node"} { condition = conditions.Get(conditionName) if condition != nil { // entry.ibc = conditionName != "browser" diff --git a/server/embed/tsx.ts b/server/embed/tsx.ts index f62dd5b3e..c24a5fba6 100644 --- a/server/embed/tsx.ts +++ b/server/embed/tsx.ts @@ -95,7 +95,7 @@ function tsx() { async function initTsx() { const pkg = "/@esm.sh/tsx@1.0.4"; const [m, w] = await Promise.all([ - import(pkg + "/$TARGET/@esm.sh/tsx.mjs"), + import(pkg + "/$TARGET/tsx.mjs"), fetch(urlFromCurrentModule(pkg + "/pkg/tsx_bg.wasm")), ]); await m.default(w); diff --git a/server/esm_router.go b/server/esm_router.go index 4229aebc1..393abc2f5 100644 --- a/server/esm_router.go +++ b/server/esm_router.go @@ -1263,7 +1263,7 @@ func esmRouter(debug bool) rex.Handle { } // match path `PKG@VERSION/X-${args}/esnext/SUBPATH` - argsX := false + xArgs := false if resType == ESMBuild || resType == ESMDts { a := strings.Split(esm.SubBareName, "/") if len(a) > 1 && strings.HasPrefix(a[0], "X-") { @@ -1274,12 +1274,12 @@ func esmRouter(debug bool) rex.Handle { esm.SubPath = strings.Join(strings.Split(esm.SubPath, "/")[1:], "/") esm.SubBareName = toModuleBareName(esm.SubPath, true) buildArgs = args - argsX = true + xArgs = true } } // fix the build args that are from the query - if !argsX { + if !xArgs { err := normalizeBuildArgs(npmrc, path.Join(npmrc.StoreDir(), esm.PackageName()), &buildArgs, esm) if err != nil { return rex.Status(500, err.Error()) @@ -1338,7 +1338,7 @@ func esmRouter(debug bool) rex.Handle { return bytes.ReplaceAll(buffer, []byte("{ESM_CDN_ORIGIN}"), []byte(cdnOrigin)) } - if !argsX { + if !xArgs { externalRequire := query.Has("external-require") // workaround: force "unocss/preset-icons" to external `require` calls if !externalRequire && esm.PkgName == "@unocss/preset-icons" { @@ -1384,7 +1384,7 @@ func esmRouter(debug bool) rex.Handle { isDev = true } basename := strings.TrimSuffix(path.Base(esm.PkgName), ".js") - if strings.HasSuffix(submodule, ".css") && !strings.HasSuffix(esm.SubPath, ".js") { + if strings.HasSuffix(submodule, ".css") && !strings.HasSuffix(esm.SubPath, ".mjs") { if submodule == basename+".css" { esm.SubBareName = "" target = maybeTarget @@ -1393,9 +1393,11 @@ func esmRouter(debug bool) rex.Handle { return rex.Redirect(url, http.StatusFound) } } else { - isMjs := strings.HasSuffix(esm.SubPath, ".mjs") - if isMjs && submodule == basename { + if submodule == basename { submodule = "" + } else if submodule == "__"+basename { + // the sub-module name is same as the package name + submodule = basename } esm.SubBareName = submodule target = maybeTarget diff --git a/test/build-args/bundle.test.ts b/test/build-args/bundle.test.ts index 1188ec1ff..803fe7327 100644 --- a/test/build-args/bundle.test.ts +++ b/test/build-args/bundle.test.ts @@ -20,9 +20,9 @@ Deno.test("?bundle with ?external", async () => { Deno.test("?bundle=false", async () => { const res = await fetch("http://localhost:8080/@pyscript/core@0.3.4/dist/py-terminal-XWbSa71s?bundle=false&target=es2022"); res.body?.cancel(); - assertEquals(res.headers.get("x-esm-path")!, "/@pyscript/core@0.3.4/es2022/dist/py-terminal-XWbSa71s.nobundle.js"); + assertEquals(res.headers.get("x-esm-path")!, "/@pyscript/core@0.3.4/es2022/dist/py-terminal-XWbSa71s.nobundle.mjs"); const res2 = await fetch(new URL(res.headers.get("x-esm-path")!, "http://localhost:8080")); const code = await res2.text(); - assertStringIncludes(code, "./core.nobundle.js"); - assertStringIncludes(code, "./error-96hMSEw8.nobundle.js"); + assertStringIncludes(code, "./core.nobundle.mjs"); + assertStringIncludes(code, "./error-96hMSEw8.nobundle.mjs"); }); diff --git a/test/build-args/deps.test.ts b/test/build-args/deps.test.ts index 1d448cd50..2c7a7ca55 100644 --- a/test/build-args/deps.test.ts +++ b/test/build-args/deps.test.ts @@ -5,7 +5,7 @@ Deno.test("?deps", async () => { const res = await fetch("http://localhost:8080/@mui/material@5.16.7?deps=react@18.2.0,react-dom@18.2.0,foo@0.0.0&target=es2022"); const code = await res.text(); assertStringIncludes(code, 'import "/react-dom@18.2.0/es2022/react-dom.mjs"'); - assertStringIncludes(code, 'import "/react@18.2.0/es2022/jsx-runtime.js"'); + assertStringIncludes(code, 'import "/react@18.2.0/es2022/jsx-runtime.mjs"'); assertStringIncludes(code, 'import "/react@18.2.0/es2022/react.mjs"'); assertStringIncludes(code, 'import "/react-transition-group@^4.4.5?deps=react-dom@18.2.0,react@18.2.0&target=es2022"'); assertStringIncludes(code, 'export * from "/@mui/material@5.16.7/X-ZHJlYWN0LWRvbUAxOC4yLjAscmVhY3RAMTguMi4w/es2022/material.mjs"'); @@ -16,7 +16,7 @@ Deno.test("?deps", async () => { const res = await fetch("http://localhost:8080/@mui/material@5.16.7/X-ZHJlYWN0LWRvbUAxOC4yLjAscmVhY3RAMTguMi4w/es2022/material.mjs"); const code = await res.text(); assertStringIncludes(code, 'from"/react-dom@18.2.0/es2022/react-dom.mjs"'); - assertStringIncludes(code, 'from"/react@18.2.0/es2022/jsx-runtime.js"'); + assertStringIncludes(code, 'from"/react@18.2.0/es2022/jsx-runtime.mjs"'); assertStringIncludes(code, 'from"/react@18.2.0/es2022/react.mjs"'); assertStringIncludes(code, 'from"/react-transition-group@^4.4.5?deps=react-dom@18.2.0,react@18.2.0&target=es2022"'); assertStringIncludes(code, 'from"/@mui/system@^5.16.7/createTheme?deps=react@18.2.0&target=es2022"'); diff --git a/test/build-args/external.test.ts b/test/build-args/external.test.ts index 108c171c7..622618fc6 100644 --- a/test/build-args/external.test.ts +++ b/test/build-args/external.test.ts @@ -7,11 +7,11 @@ Deno.test("`?external` query", async () => { const res2 = await fetch("http://localhost:8080/*preact@10.23.2/jsx-runtime"); const code2 = await res2.text(); - assertStringIncludes(code2, '"/preact@10.23.2/X-Kg/denonext/jsx-runtime.js"'); + assertStringIncludes(code2, '"/preact@10.23.2/X-Kg/denonext/jsx-runtime.mjs"'); const res3 = await fetch("http://localhost:8080/preact@10.23.2/hooks?external=preact"); const code3 = await res3.text(); - assertStringIncludes(code3, '"/preact@10.23.2/X-ZXByZWFjdA/denonext/hooks.js"'); + assertStringIncludes(code3, '"/preact@10.23.2/X-ZXByZWFjdA/denonext/hooks.mjs"'); }); Deno.test("drop invalid `?external`", async () => { diff --git a/test/common/jotail.test.ts b/test/common/jotail.test.ts index 4469b3622..f874d9a6b 100644 --- a/test/common/jotail.test.ts +++ b/test/common/jotail.test.ts @@ -1,6 +1,6 @@ import { assertExists } from "jsr:@std/assert"; Deno.test("jotail", async () => { - const utils = await import("http://localhost:8080/jotai@2.0.3/es2022/vanilla/utils.js"); + const utils = await import("http://localhost:8080/jotai@2.0.3/es2022/vanilla/utils.mjs"); assertExists(utils.splitAtom); }); diff --git a/test/common/rc-util.test.ts b/test/common/rc-util.test.ts index 244772aec..051e5b1b6 100644 --- a/test/common/rc-util.test.ts +++ b/test/common/rc-util.test.ts @@ -1,6 +1,6 @@ import { assertExists } from "jsr:@std/assert"; -import * as dynamicCSS from "http://localhost:8080/rc-util@5.27.2/es/Dom/dynamicCSS.js"; +import * as dynamicCSS from "http://localhost:8080/rc-util@5.27.2/es/Dom/dynamicCSS.mjs"; Deno.test("Export all members when the package is not a standard ES module", async () => { assertExists(dynamicCSS.updateCSS); diff --git a/test/fix-url/test.ts b/test/fix-url/test.ts index 5650dde22..800b47e5d 100644 --- a/test/fix-url/test.ts +++ b/test/fix-url/test.ts @@ -7,7 +7,7 @@ Deno.test("query as version suffix", async () => { assertEquals(res.headers.get("cache-control"), "public, max-age=31536000, immutable"); assertEquals(res.headers.get("content-type"), "application/javascript; charset=utf-8"); assert(!res.headers.get("vary")!.includes("User-Agent")); - assertStringIncludes(code, "/react-dom@18.3.1/es2022/client.development.js"); + assertStringIncludes(code, "/react-dom@18.3.1/es2022/client.development.mjs"); }); Deno.test("`/jsx-runtime` in query", async () => { @@ -17,7 +17,7 @@ Deno.test("`/jsx-runtime` in query", async () => { assertEquals(res.headers.get("cache-control"), "public, max-age=31536000, immutable"); assertEquals(res.headers.get("content-type"), "application/javascript; charset=utf-8"); assert(!res.headers.get("vary")!.includes("User-Agent")); - assertStringIncludes(code, "/react@18.3.1/es2022/jsx-runtime.development.js"); + assertStringIncludes(code, "/react@18.3.1/es2022/jsx-runtime.development.mjs"); }); Deno.test("redirect semver versioning module for deno target", async () => { @@ -112,7 +112,7 @@ Deno.test("support `/#/` in path", async () => { assertEquals(res.status, 200); assertEquals(res.headers.get("content-type"), "application/javascript; charset=utf-8"); assertEquals(res.headers.get("cache-control"), "public, max-age=31536000, immutable"); - assertStringIncludes(await res.text(), "/denonext/string/%23/contains.js"); + assertStringIncludes(await res.text(), "/denonext/string/%23/contains.mjs"); }); Deno.test("dts-transformer: support `.d` extension", async () => { diff --git a/test/issue-581/test.ts b/test/issue-581/test.ts index 17cb6cff0..10d85aa89 100644 --- a/test/issue-581/test.ts +++ b/test/issue-581/test.ts @@ -1,7 +1,7 @@ import { assertEquals } from "jsr:@std/assert"; import dayjs from "http://localhost:8080/dayjs@1.11.7"; -import relativeTime from "http://localhost:8080/dayjs@1.11.7/plugin/relativeTime.js"; +import relativeTime from "http://localhost:8080/dayjs@1.11.7/plugin/relativeTime.mjs"; dayjs.extend(relativeTime); diff --git a/test/issue-671/test.ts b/test/issue-671/test.ts index 566feb76b..59c2341c1 100644 --- a/test/issue-671/test.ts +++ b/test/issue-671/test.ts @@ -17,7 +17,7 @@ Deno.test("issue #671", async () => { await res2.body?.cancel(); const esmPath2 = res2.headers.get("x-esm-path"); const code2 = await fetch("http://localhost:8080" + esmPath2).then((res) => res.text()); - assertStringIncludes(code2, 'from"/preact@10.0.0/es2020/compat/jsx-runtime.js"'); - assertStringIncludes(code2, 'from"/preact@10.0.0/es2020/compat.js"'); + assertStringIncludes(code2, 'from"/preact@10.0.0/es2020/compat/jsx-runtime.mjs"'); + assertStringIncludes(code2, 'from"/preact@10.0.0/es2020/compat.mjs"'); assertStringIncludes(code2, 'hi?alias=react:preact/compat&deps=preact@10.0.0&target=es2020"'); }); diff --git a/test/issue-711/test.ts b/test/issue-711/test.ts index 07e5193c8..9eeb736e0 100644 --- a/test/issue-711/test.ts +++ b/test/issue-711/test.ts @@ -1,7 +1,7 @@ import { assert, assertEquals, assertStringIncludes } from "jsr:@std/assert"; Deno.test("issue #711", async () => { - const res = await fetch("http://localhost:8080/@pyscript/core@0.1.5/core.js", { + const res = await fetch("http://localhost:8080/@pyscript/core@0.1.5/core.mjs", { headers: { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15", }, diff --git a/test/issue-728/test.ts b/test/issue-728/test.ts index 314a7e97d..ddc5f40fa 100644 --- a/test/issue-728/test.ts +++ b/test/issue-728/test.ts @@ -2,7 +2,7 @@ import { assertEquals } from "jsr:@std/assert"; Deno.test("issue #728", async () => { const res2 = await fetch( - `http://localhost:8080/@wooorm/starry-night@3.0.0/es2022/source.css.js`, + `http://localhost:8080/@wooorm/starry-night@3.0.0/es2022/source.css.mjs`, ); res2.body?.cancel(); assertEquals( diff --git a/test/issue-761/test.ts b/test/issue-761/test.ts index 381643688..4042c7965 100644 --- a/test/issue-761/test.ts +++ b/test/issue-761/test.ts @@ -1,6 +1,6 @@ import { assertEquals } from "jsr:@std/assert"; -import { streamParse } from "http://localhost:8080/gh/bablr-lang/bablr@279a549d0bf730e7d8ed008386ff157fc5b0fecd/lib/enhanceable.js"; +import { streamParse } from "http://localhost:8080/gh/bablr-lang/bablr@279a549d0bf730e7d8ed008386ff157fc5b0fecd/lib/enhanceable.mjs"; Deno.test("issue #761", () => { assertEquals(typeof streamParse, "function"); diff --git a/test/vue/transfrom-sfc-on-fly.test.ts b/test/vue/transfrom-sfc-on-fly.test.ts index 95e5a8b31..885562192 100644 --- a/test/vue/transfrom-sfc-on-fly.test.ts +++ b/test/vue/transfrom-sfc-on-fly.test.ts @@ -9,6 +9,6 @@ Deno.test("Transfrom SFC on fly", async () => { assertEquals(res.headers.get("content-type"), "application/javascript; charset=utf-8"); const code = await res.text(); assertStringIncludes(code, "/vue@3.5.8/"); - assertStringIncludes(code, "/PhAirplay.vue.js"); + assertStringIncludes(code, "/PhAirplay.vue.mjs"); } }); diff --git a/test/worker/test.ts b/test/worker/test.ts index 665f851fe..055cf7539 100644 --- a/test/worker/test.ts +++ b/test/worker/test.ts @@ -302,7 +302,7 @@ Deno.test("esm-worker", { sanitizeOps: false, sanitizeResources: false }, async assertEquals(res10.status, 200); assertEquals(res10.headers.get("Cache-Control"), "public, max-age=31536000, immutable"); assertStringIncludes(js, `__Process$`); - assert(!js.includes("/node/process.js")); + assert(!js.includes("/node/process.mjs")); const res11 = await fetch(`${workerOrigin}/typescript@5.5.4/es2022/typescript.mjs.map`); assertEquals(res11.status, 200); @@ -315,7 +315,7 @@ Deno.test("esm-worker", { sanitizeOps: false, sanitizeResources: false }, async headers: { "User-Agent": "ES/2022" }, }); const modUrl = new URL(res.headers.get("x-esm-path")!, workerOrigin); - assert(modUrl.pathname.endsWith("/es2022/server.js")); + assert(modUrl.pathname.endsWith("/es2022/server.mjs")); assertEquals(res.status, 200); assertEquals(res.headers.get("Content-Type"), "application/javascript; charset=utf-8"); assertEquals(res.headers.get("Cache-Control"), "public, max-age=3600"); @@ -401,7 +401,7 @@ Deno.test("esm-worker", { sanitizeOps: false, sanitizeResources: false }, async await t.step("jsr", async () => { const res = await fetch(`${workerOrigin}/jsr/@std/encoding/base64`, { headers: { "User-Agent": "ES/2022" } }); const modUrl = new URL(res.headers.get("x-esm-path")!, workerOrigin); - assert(modUrl.pathname.endsWith("/es2022/base64.js")); + assert(modUrl.pathname.endsWith("/es2022/base64.mjs")); assertEquals(res.status, 200); assertEquals(res.headers.get("Content-Type"), "application/javascript; charset=utf-8"); assertEquals(res.headers.get("Cache-Control"), "public, max-age=3600"); From ef9acfc94d495bef2995d01bc254142090bb2e13 Mon Sep 17 00:00:00 2001 From: Je Xia Date: Wed, 20 Nov 2024 04:35:26 +0800 Subject: [PATCH 2/2] Update issue template --- .../failing-import-in-browser.md | 3 +- .../ISSUE_TEMPLATE/failing-import-in-deno.md | 1 - .../failing-import-with-reejs.md | 28 ------------------- 3 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/failing-import-with-reejs.md diff --git a/.github/ISSUE_TEMPLATE/failing-import-in-browser.md b/.github/ISSUE_TEMPLATE/failing-import-in-browser.md index af44359a8..8166e6145 100644 --- a/.github/ISSUE_TEMPLATE/failing-import-in-browser.md +++ b/.github/ISSUE_TEMPLATE/failing-import-in-browser.md @@ -24,5 +24,4 @@ After `onload` I got this: ## Additional info -- **esm.sh version**: -- **Browser version**: +- **Browser info**: diff --git a/.github/ISSUE_TEMPLATE/failing-import-in-deno.md b/.github/ISSUE_TEMPLATE/failing-import-in-deno.md index b20c34063..1642857b8 100644 --- a/.github/ISSUE_TEMPLATE/failing-import-in-deno.md +++ b/.github/ISSUE_TEMPLATE/failing-import-in-deno.md @@ -24,5 +24,4 @@ After running `deno run` I got this: ## Additional info -- **esm.sh version**: - **Deno version**: diff --git a/.github/ISSUE_TEMPLATE/failing-import-with-reejs.md b/.github/ISSUE_TEMPLATE/failing-import-with-reejs.md deleted file mode 100644 index b55539a34..000000000 --- a/.github/ISSUE_TEMPLATE/failing-import-with-reejs.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -name: A failing module import in Nodejs/Bun/Deno (via Reejs) -about: Submit a report if a module fails to import in Any Supported Runtime with Reejs' URL Imports. -title: 'Failed to import -' -labels: reejs ---- - -## Failing module - -- **GitHub**: https://github.com/my/repo -- **npm**: https://npmjs.com/package/my_package - -```js -let package = await URLImport("https://esm.sh/my_module"); -``` - -## Error message - -After running the code in `reejs repl` I got this: - -``` -/* your error log here */ -``` - -## Additional info - -- **esm.sh version**: -- **Paste the `reejs doctor` report: