Skip to content

Commit d82e35f

Browse files
authored
Fix sub-modules end with .map (#1311)
1 parent 00591ba commit d82e35f

3 files changed

Lines changed: 59 additions & 16 deletions

File tree

server/build.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ func (ctx *BuildContext) Build() (meta *BuildMeta, err error) {
143143
return
144144
}
145145

146-
// analyze splitting modules
147-
if ctx.bundleMode == BundleDefault && ctx.pkgJson.Exports.Len() > 1 {
146+
// analyze splitting modules if bundling
147+
if ctx.pkgJson.Exports.Len() > 1 && !ctx.isNoBundle() {
148148
ctx.status = "analyze"
149149
err = ctx.analyzeSplitting()
150150
if err != nil {
@@ -369,14 +369,7 @@ func (ctx *BuildContext) buildModule(analyzeMode bool) (meta *BuildMeta, include
369369

370370
browserExclude := map[string]*set.Set[string]{}
371371
implicitExternal := set.New[string]()
372-
noBundle := ctx.bundleMode == BundleFalse || ctx.pkgJson.SideEffects.Len() > 0
373-
if ctx.pkgJson.Esmsh != nil {
374-
if v, ok := ctx.pkgJson.Esmsh["bundle"]; ok {
375-
if b, ok := v.(bool); ok && !b {
376-
noBundle = true
377-
}
378-
}
379-
}
372+
noBundle := ctx.isNoBundle()
380373
esmifyPlugin := esbuild.Plugin{
381374
Name: "esmify",
382375
Setup: func(build esbuild.PluginBuild) {
@@ -1553,3 +1546,15 @@ func (ctx *BuildContext) install() (err error) {
15531546
}
15541547
return
15551548
}
1549+
1550+
func (ctx *BuildContext) isNoBundle() bool {
1551+
noBundle := ctx.bundleMode == BundleFalse || ctx.pkgJson.SideEffects.Len() > 0
1552+
if ctx.pkgJson.Esmsh != nil {
1553+
if v, ok := ctx.pkgJson.Esmsh["bundle"]; ok {
1554+
if b, ok := v.(bool); ok && !b {
1555+
noBundle = true
1556+
}
1557+
}
1558+
}
1559+
return noBundle
1560+
}

server/router.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,10 +1007,34 @@ func esmRouter(esmStorage storage.Storage, logger *log.Logger) rex.Handle {
10071007
rawFlag := query.Has("raw") || strings.HasPrefix(ctx.R.Host, "raw.")
10081008
if rawFlag {
10091009
pathKind = RawFile
1010-
if esmPath.SubPath != "" {
1011-
extname := path.Ext(pathname)
1012-
if !strings.HasSuffix(esmPath.SubPath, extname) {
1013-
esmPath.SubPath += extname
1010+
}
1011+
1012+
// restore the original path extension
1013+
if pathKind == RawFile && esmPath.SubPath != "" {
1014+
extname := path.Ext(pathname)
1015+
if !strings.HasSuffix(esmPath.SubPath, extname) {
1016+
esmPath.SubPath += extname
1017+
}
1018+
}
1019+
1020+
if pathKind == RawFile && !rawFlag && esmPath.SubPath != "" && strings.HasSuffix(esmPath.SubPath, ".map") {
1021+
pkgJson, err := npmrc.installPackage(esmPath.Package())
1022+
if err != nil {
1023+
return rex.Status(500, err.Error())
1024+
}
1025+
filename := path.Join(npmrc.StoreDir(), esmPath.ID(), "node_modules", esmPath.PkgName, esmPath.SubPath)
1026+
stat, err := os.Lstat(filename)
1027+
if err != nil {
1028+
if os.IsNotExist(err) {
1029+
if _, ok := pkgJson.Exports.Get("./" + esmPath.SubPath); ok {
1030+
pathKind = EsmEntry
1031+
}
1032+
} else {
1033+
return rex.Status(500, err.Error())
1034+
}
1035+
} else if stat.IsDir() {
1036+
if _, ok := pkgJson.Exports.Get("./" + esmPath.SubPath); ok {
1037+
pathKind = EsmEntry
10141038
}
10151039
}
10161040
}
@@ -1176,8 +1200,10 @@ func esmRouter(esmStorage storage.Storage, logger *log.Logger) rex.Handle {
11761200
if rawQuery != "" {
11771201
query = "?" + rawQuery
11781202
}
1203+
// redirect to the 'main' JS file
11791204
return redirect(ctx, fmt.Sprintf("%s/%s%s%s", origin, esmPath.ID(), utils.NormalizePathname(entry.main), query), true)
11801205
}
1206+
11811207
filename := path.Join(npmrc.StoreDir(), esmPath.ID(), "node_modules", esmPath.PkgName, esmPath.SubPath)
11821208
stat, err := os.Lstat(filename)
11831209
if err != nil && os.IsNotExist(err) {
@@ -1201,11 +1227,11 @@ func esmRouter(esmStorage storage.Storage, logger *log.Logger) rex.Handle {
12011227
}
12021228
entry := b.resolveEntry(esmPath)
12031229
if entry.main != "" && entry.main != "./"+esmPath.SubPath {
1204-
// redirect to the resolved path
12051230
query := ""
12061231
if rawQuery != "" {
12071232
query = "?" + rawQuery
12081233
}
1234+
// redirect to the resolved path
12091235
return redirect(ctx, fmt.Sprintf("%s/%s%s%s", origin, esmPath.ID(), utils.NormalizePathname(entry.main), query), true)
12101236
}
12111237
ctx.SetHeader("Cache-Control", ccImmutable)
@@ -1834,7 +1860,7 @@ func esmRouter(esmStorage storage.Storage, logger *log.Logger) rex.Handle {
18341860
}
18351861
ctx.SetHeader("Last-Modified", fi.ModTime().UTC().Format(http.TimeFormat))
18361862
ctx.SetHeader("Cache-Control", ccImmutable)
1837-
if endsWith(savePath, ".css") {
1863+
if strings.HasSuffix(savePath, ".css") {
18381864
ctx.SetHeader("Content-Type", ctCSS)
18391865
} else if endsWith(savePath, ".map") {
18401866
ctx.SetHeader("Content-Type", ctJSON)

test/issue-1285/test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { assertEquals, assertStringIncludes } from "jsr:@std/assert";
2+
3+
Deno.test("issue #1285 - Export path ending with .map fails to resolve", async () => {
4+
const res = await fetch(
5+
"http://localhost:8080/es-iterator-helpers@1.2.2/Iterator.prototype.map",
6+
{ headers: { "User-Agent": "i'm a browser" } },
7+
);
8+
const js = await res.text();
9+
assertEquals(res.status, 200);
10+
assertEquals(res.headers.get("content-type"), "application/javascript; charset=utf-8");
11+
assertStringIncludes(js, 'export * from "/es-iterator-helpers@1.2.2/es2022/Iterator.prototype.map.mjs"');
12+
});

0 commit comments

Comments
 (0)