Skip to content

Commit f323f03

Browse files
committed
server: fix randomly throwing empty entry error
1 parent edca187 commit f323f03

File tree

8 files changed

+121
-116
lines changed

8 files changed

+121
-116
lines changed

server/build.go

Lines changed: 26 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"sync"
1515
"time"
1616

17+
"github.com/esm-dev/esm.sh/server/storage"
1718
"github.com/evanw/esbuild/pkg/api"
1819
"github.com/ije/gox/utils"
1920
)
@@ -111,8 +112,8 @@ func (ctx *BuildContext) Query() (BuildResult, bool) {
111112
} else {
112113
_, err = fs.Stat(normalizeSavePath(ctx.zoneId, path.Join("types", b.Dts)))
113114
}
114-
// ensure the build files exist
115-
if err == nil || os.IsExist(err) {
115+
// ensure the build file exists
116+
if err == nil || err != storage.ErrNotFound {
116117
return b, true
117118
}
118119
}
@@ -175,9 +176,14 @@ func (ctx *BuildContext) Build() (ret BuildResult, err error) {
175176
}
176177

177178
func (ctx *BuildContext) install() (err error) {
178-
if ctx.wd == "" {
179+
if ctx.wd == "" || ctx.pkgJson.Name == "" {
179180
ctx.wd = path.Join(ctx.npmrc.Dir(), ctx.pkg.Fullname())
180181
ctx.pkgDir = path.Join(ctx.wd, "node_modules", ctx.pkg.Name)
182+
if rp, e := os.Readlink(ctx.pkgDir); e == nil {
183+
ctx.pnpmPkgDir = path.Join(path.Dir(ctx.pkgDir), rp)
184+
} else {
185+
ctx.pnpmPkgDir = ctx.pkgDir
186+
}
181187
err = ctx.npmrc.installPackage(ctx.pkg)
182188
if err != nil {
183189
return
@@ -188,11 +194,6 @@ func (ctx *BuildContext) install() (err error) {
188194
return
189195
}
190196
ctx.pkgJson = ctx.normalizePackageJSON(pkgJson)
191-
if rp, e := os.Readlink(ctx.pkgDir); e == nil {
192-
ctx.pnpmPkgDir = path.Join(path.Dir(ctx.pkgDir), rp)
193-
} else {
194-
ctx.pnpmPkgDir = ctx.pkgDir
195-
}
196197
}
197198
return
198199
}
@@ -222,19 +223,25 @@ func (ctx *BuildContext) buildModule() (result BuildResult, err error) {
222223
}
223224

224225
entry := ctx.resolveEntry(ctx.pkg)
225-
log.Debugf("build(%s): Entry%+v", ctx.pkg, entry)
226-
227-
result, reexport, err := ctx.lexer(&entry, false)
228-
if err != nil && !strings.HasPrefix(err.Error(), "cjsLexer: Can't resolve") {
226+
if entry.isEmpty() {
227+
err = fmt.Errorf("could not resolve entry")
229228
return
230229
}
230+
log.Debugf("build(%s): Entry%+v", ctx.pkg, entry)
231231

232-
if result.TypesOnly {
232+
typesOnly := strings.HasPrefix(ctx.pkgJson.Name, "@types/") || (entry.esm == "" && entry.cjs == "" && entry.dts != "")
233+
if typesOnly {
234+
result.TypesOnly = true
233235
result.Dts = "/" + ctx.pkg.ghPrefix() + ctx.pkg.Fullname() + entry.dts[1:]
234236
ctx.transformDTS(entry.dts)
235237
return
236238
}
237239

240+
result, reexport, err := ctx.lexer(&entry, false)
241+
if err != nil && !strings.HasPrefix(err.Error(), "cjsLexer: Can't resolve") {
242+
return
243+
}
244+
238245
// cjs reexport
239246
if reexport != "" {
240247
pkg, _, _, e := ctx.lookupDep(reexport)
@@ -265,7 +272,7 @@ func (ctx *BuildContext) buildModule() (result BuildResult, err error) {
265272
if err != nil {
266273
return
267274
}
268-
result.Dts = ctx.lookupTypes(entry)
275+
result.Dts, err = ctx.resloveDTS(entry)
269276
return
270277
}
271278

@@ -278,10 +285,6 @@ func (ctx *BuildContext) buildModule() (result BuildResult, err error) {
278285
}
279286

280287
if entry.esm == "" {
281-
if entry.cjs == "" {
282-
err = fmt.Errorf("could not resolve \"%s\"", entryModuleSpecifier)
283-
return
284-
}
285288
buf := bytes.NewBuffer(nil)
286289
fmt.Fprintf(buf, `import * as __module from "%s";`, entryModuleSpecifier)
287290
if len(result.NamedExports) > 0 {
@@ -862,6 +865,7 @@ func (ctx *BuildContext) buildModule() (result BuildResult, err error) {
862865
if ctx.isDenoTarget() {
863866
conditions = append(conditions, "deno")
864867
}
868+
minify := config.Minify == nil || !bytes.Equal(config.Minify, []byte("false"))
865869
options := api.BuildOptions{
866870
Outdir: "/esbuild",
867871
Write: false,
@@ -870,9 +874,9 @@ func (ctx *BuildContext) buildModule() (result BuildResult, err error) {
870874
Format: api.FormatESModule,
871875
Target: targets[ctx.target],
872876
Platform: api.PlatformBrowser,
873-
MinifyWhitespace: !ctx.dev,
874-
MinifyIdentifiers: !ctx.dev,
875-
MinifySyntax: !ctx.dev,
877+
MinifyWhitespace: minify,
878+
MinifyIdentifiers: minify,
879+
MinifySyntax: minify,
876880
KeepNames: ctx.args.keepNames, // prevent class/function names erasing
877881
IgnoreAnnotations: ctx.args.ignoreAnnotations, // some libs maybe use wrong side-effect annotations
878882
Conditions: conditions,
@@ -1207,20 +1211,7 @@ rebuild:
12071211
deps.Sort()
12081212

12091213
result.Deps = deps
1210-
result.Dts = ctx.lookupTypes(entry)
1211-
return
1212-
}
1213-
1214-
func (ctx *BuildContext) LookupTypes() (dts string, err error) {
1215-
// install the package
1216-
ctx.stage = "install"
1217-
err = ctx.install()
1218-
if err != nil {
1219-
return
1220-
}
1221-
1222-
entry := ctx.resolveEntry(ctx.pkg)
1223-
dts = ctx.lookupTypes(entry)
1214+
result.Dts, err = ctx.resloveDTS(entry)
12241215
return
12251216
}
12261217

@@ -1252,56 +1243,6 @@ func (ctx *BuildContext) buildTypes() (ret BuildResult, err error) {
12521243
return
12531244
}
12541245

1255-
func (ctx *BuildContext) lookupTypes(entry BuildEntry) string {
1256-
if entry.dts != "" {
1257-
if !ctx.existsPkgFile(entry.dts) {
1258-
return ""
1259-
}
1260-
return fmt.Sprintf(
1261-
"/%s%s/%s%s",
1262-
ctx.pkg.ghPrefix(),
1263-
ctx.pkg.Fullname(),
1264-
ctx.getBuildArgsPrefix(ctx.pkg, true),
1265-
strings.TrimPrefix(entry.dts, "./"),
1266-
)
1267-
}
1268-
1269-
// use types from package "@types/[task.npm.Name]" if it exists
1270-
if ctx.pkgJson.Types == "" && !strings.HasPrefix(ctx.pkgJson.Name, "@types/") && regexpFullVersion.MatchString(ctx.pkgJson.Version) {
1271-
versionParts := strings.Split(ctx.pkgJson.Version, ".")
1272-
versions := []string{
1273-
versionParts[0] + "." + versionParts[1], // major.minor
1274-
versionParts[0], // major
1275-
}
1276-
typesPkgName := toTypesPkgName(ctx.pkgJson.Name)
1277-
pkgVersion, ok := ctx.args.deps[typesPkgName]
1278-
if ok {
1279-
// use the version of the `?deps` query if it exists
1280-
versions = append([]string{pkgVersion}, versions...)
1281-
}
1282-
for _, version := range versions {
1283-
p, err := ctx.npmrc.getPackageInfo(typesPkgName, version)
1284-
if err == nil {
1285-
typesPkg := Pkg{
1286-
Name: typesPkgName,
1287-
Version: p.Version,
1288-
SubPath: ctx.pkg.SubPath,
1289-
SubModule: ctx.pkg.SubModule,
1290-
}
1291-
b := NewBuildContext(ctx.zoneId, ctx.npmrc, typesPkg, ctx.args, "types", BundleFalse, false, false)
1292-
dts, _ := b.LookupTypes()
1293-
if dts != "" {
1294-
// use tilde semver range instead of the exact version
1295-
return strings.ReplaceAll(dts, fmt.Sprintf("%s@%s", typesPkgName, p.Version), fmt.Sprintf("%s@~%s", typesPkgName, p.Version))
1296-
}
1297-
break
1298-
}
1299-
}
1300-
}
1301-
1302-
return ""
1303-
}
1304-
13051246
func (ctx *BuildContext) transformDTS(types string) (err error) {
13061247
start := time.Now()
13071248
buildArgsPrefix := ctx.getBuildArgsPrefix(ctx.pkg, true)

server/build_resolver.go

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ type BuildEntry struct {
2121
dts string
2222
}
2323

24+
// isEmpty checks if the entry is empty
25+
func (entry *BuildEntry) isEmpty() bool {
26+
return entry.esm == "" && entry.cjs == "" && entry.dts == ""
27+
}
28+
2429
// hasEntry checks if the entrypoint of the given type exists
2530
func (entry *BuildEntry) hasEntry(entryType string) bool {
2631
switch entryType {
@@ -576,18 +581,18 @@ func (ctx *BuildContext) resolveEntry(pkg Pkg) (entry BuildEntry) {
576581
normalizeBuildEntry(ctx, &entry)
577582
if entry.esm != "" {
578583
m, ok := ctx.pkgJson.Browser[entry.esm]
579-
if ok && m != "" {
584+
if ok && isRelativeSpecifier(m) {
580585
entry.esm = m
581586
}
582587
}
583588
if entry.cjs != "" {
584589
m, ok := ctx.pkgJson.Browser[entry.cjs]
585-
if ok && m != "" {
590+
if ok && isRelativeSpecifier(m) {
586591
entry.cjs = m
587592
}
588593
}
589594
if pkg.SubModule == "" {
590-
if m, ok := ctx.pkgJson.Browser["."]; ok && m != "" {
595+
if m, ok := ctx.pkgJson.Browser["."]; ok && isRelativeSpecifier(m) {
591596
if ctx.pkgJson.Type == "module" || strings.HasSuffix(m, ".mjs") {
592597
entry.esm = m
593598
} else {
@@ -922,6 +927,62 @@ func (ctx *BuildContext) resolveExternalModule(specifier string, kind api.Resolv
922927
return
923928
}
924929

930+
func (ctx *BuildContext) resloveDTS(entry BuildEntry) (string, error) {
931+
if entry.dts != "" {
932+
if !ctx.existsPkgFile(entry.dts) {
933+
return "", nil
934+
}
935+
return fmt.Sprintf(
936+
"/%s%s/%s%s",
937+
ctx.pkg.ghPrefix(),
938+
ctx.pkg.Fullname(),
939+
ctx.getBuildArgsPrefix(ctx.pkg, true),
940+
strings.TrimPrefix(entry.dts, "./"),
941+
), nil
942+
}
943+
944+
// use types from package "@types/[task.npm.Name]" if it exists
945+
if ctx.pkgJson.Types == "" && !strings.HasPrefix(ctx.pkgJson.Name, "@types/") && regexpFullVersion.MatchString(ctx.pkgJson.Version) {
946+
versionParts := strings.Split(ctx.pkgJson.Version, ".")
947+
versions := []string{
948+
versionParts[0] + "." + versionParts[1], // major.minor
949+
versionParts[0], // major
950+
}
951+
typesPkgName := toTypesPkgName(ctx.pkgJson.Name)
952+
pkgVersion, ok := ctx.args.deps[typesPkgName]
953+
if ok {
954+
// use the version of the `?deps` query if it exists
955+
versions = append([]string{pkgVersion}, versions...)
956+
}
957+
for _, version := range versions {
958+
p, err := ctx.npmrc.getPackageInfo(typesPkgName, version)
959+
if err == nil {
960+
typesPkg := Pkg{
961+
Name: typesPkgName,
962+
Version: p.Version,
963+
SubPath: ctx.pkg.SubPath,
964+
SubModule: ctx.pkg.SubModule,
965+
}
966+
b := NewBuildContext(ctx.zoneId, ctx.npmrc, typesPkg, ctx.args, "types", BundleFalse, false, false)
967+
err := b.install()
968+
if err != nil {
969+
return "", err
970+
}
971+
dts, err := b.resloveDTS(b.resolveEntry(typesPkg))
972+
if err != nil {
973+
return "", err
974+
}
975+
if dts != "" {
976+
// use tilde semver range instead of the exact version
977+
return strings.ReplaceAll(dts, fmt.Sprintf("%s@%s", typesPkgName, p.Version), fmt.Sprintf("%s@~%s", typesPkgName, p.Version)), nil
978+
}
979+
}
980+
}
981+
}
982+
983+
return "", nil
984+
}
985+
925986
func (ctx *BuildContext) normalizePackageJSON(p PackageJSON) PackageJSON {
926987
if ctx.pkg.FromGithub {
927988
// if the name in package.json is not the same as the repository name
@@ -992,14 +1053,6 @@ func (ctx *BuildContext) normalizePackageJSON(p PackageJSON) PackageJSON {
9921053
}
9931054

9941055
func (ctx *BuildContext) lexer(entry *BuildEntry, forceCjsOnly bool) (ret BuildResult, reexport string, err error) {
995-
pkgJson := ctx.pkgJson
996-
typesOnly := strings.HasPrefix(pkgJson.Name, "@types/") || (entry.esm == "" && entry.cjs == "" && entry.dts != "")
997-
998-
if typesOnly {
999-
ret.TypesOnly = true
1000-
return
1001-
}
1002-
10031056
if entry.esm != "" && !forceCjsOnly {
10041057
isESM, namedExports, erro := ctx.esmLexer(entry.esm)
10051058
if erro != nil {
@@ -1025,7 +1078,7 @@ func (ctx *BuildContext) lexer(entry *BuildEntry, forceCjsOnly bool) (ret BuildR
10251078
entry.cjs = entry.esm
10261079
entry.esm = ""
10271080
reexport = r.ReExport
1028-
log.Warnf("fake ES module '%s' of '%s'", entry.cjs, pkgJson.Name)
1081+
log.Warnf("fake ES module '%s' of '%s'", entry.cjs, ctx.pkgJson.Name)
10291082
return
10301083
}
10311084

server/config.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type Config struct {
1919
BanList BanList `json:"banList"`
2020
BuildConcurrency uint16 `json:"buildConcurrency"`
2121
BuildTimeout uint16 `json:"buildTimeout"`
22+
Minify json.RawMessage `json:"minify"`
2223
DisableSourceMap bool `json:"disableSourceMap"`
2324
DisableCompression bool `json:"disableCompression"`
2425
Cache string `json:"cache"`
@@ -99,10 +100,13 @@ func fixConfig(c *Config) *Config {
99100
c.AuthSecret = os.Getenv("AUTH_SECRET")
100101
}
101102
if !c.DisableCompression {
102-
c.DisableCompression = os.Getenv("DISABLE_COMPRESSION") != ""
103+
c.DisableCompression = os.Getenv("DISABLE_COMPRESSION") == "true"
103104
}
104105
if !c.DisableSourceMap {
105-
c.DisableSourceMap = os.Getenv("DISABLE_SOURCEMAP") != ""
106+
c.DisableSourceMap = os.Getenv("DISABLE_SOURCEMAP") == "true"
107+
}
108+
if c.Minify == nil && os.Getenv("MINIFY") == "false" {
109+
c.Minify = []byte("false")
106110
}
107111
if c.BuildConcurrency == 0 {
108112
c.BuildConcurrency = uint16(runtime.NumCPU())

server/dts_transform.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,11 @@ func transformDTS(ctx *BuildContext, dts string, buildArgsPrefix string, marker
197197
exports: NewStringSet(),
198198
}
199199
b := NewBuildContext(ctx.zoneId, ctx.npmrc, depPkg, args, "types", BundleFalse, false, false)
200-
dts, err := b.LookupTypes()
200+
err = b.install()
201+
if err != nil {
202+
return "", err
203+
}
204+
dts, err = b.resloveDTS(b.resolveEntry(depPkg))
201205
if err != nil {
202206
return "", err
203207
}

server/dts_walker.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"fmt"
77
"io"
88
"regexp"
9-
"strings"
109
)
1110

1211
var (
@@ -74,9 +73,9 @@ func walkDts(r io.Reader, buf *bytes.Buffer, resolve func(specifier string, kind
7473
if err != nil {
7574
return
7675
}
77-
if format == "types" && strings.HasPrefix(res, "{ESM_CDN_ORIGIN}") {
78-
format = "path"
79-
}
76+
// if format == "types" && strings.HasPrefix(res, "{ESM_CDN_ORIGIN}") {
77+
// format = "path"
78+
// }
8079
fmt.Fprintf(buf, `/// <reference %s="%s" />`, format, res)
8180
} else {
8281
buf.Write(line)

0 commit comments

Comments
 (0)