Skip to content

Commit

Permalink
server: fix randomly throwing empty entry error
Browse files Browse the repository at this point in the history
  • Loading branch information
ije committed Jun 17, 2024
1 parent edca187 commit f323f03
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 116 deletions.
111 changes: 26 additions & 85 deletions server/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"sync"
"time"

"github.com/esm-dev/esm.sh/server/storage"
"github.com/evanw/esbuild/pkg/api"
"github.com/ije/gox/utils"
)
Expand Down Expand Up @@ -111,8 +112,8 @@ func (ctx *BuildContext) Query() (BuildResult, bool) {
} else {
_, err = fs.Stat(normalizeSavePath(ctx.zoneId, path.Join("types", b.Dts)))
}
// ensure the build files exist
if err == nil || os.IsExist(err) {
// ensure the build file exists
if err == nil || err != storage.ErrNotFound {
return b, true
}
}
Expand Down Expand Up @@ -175,9 +176,14 @@ func (ctx *BuildContext) Build() (ret BuildResult, err error) {
}

func (ctx *BuildContext) install() (err error) {
if ctx.wd == "" {
if ctx.wd == "" || ctx.pkgJson.Name == "" {
ctx.wd = path.Join(ctx.npmrc.Dir(), ctx.pkg.Fullname())
ctx.pkgDir = path.Join(ctx.wd, "node_modules", ctx.pkg.Name)
if rp, e := os.Readlink(ctx.pkgDir); e == nil {
ctx.pnpmPkgDir = path.Join(path.Dir(ctx.pkgDir), rp)
} else {
ctx.pnpmPkgDir = ctx.pkgDir
}
err = ctx.npmrc.installPackage(ctx.pkg)
if err != nil {
return
Expand All @@ -188,11 +194,6 @@ func (ctx *BuildContext) install() (err error) {
return
}
ctx.pkgJson = ctx.normalizePackageJSON(pkgJson)
if rp, e := os.Readlink(ctx.pkgDir); e == nil {
ctx.pnpmPkgDir = path.Join(path.Dir(ctx.pkgDir), rp)
} else {
ctx.pnpmPkgDir = ctx.pkgDir
}
}
return
}
Expand Down Expand Up @@ -222,19 +223,25 @@ func (ctx *BuildContext) buildModule() (result BuildResult, err error) {
}

entry := ctx.resolveEntry(ctx.pkg)
log.Debugf("build(%s): Entry%+v", ctx.pkg, entry)

result, reexport, err := ctx.lexer(&entry, false)
if err != nil && !strings.HasPrefix(err.Error(), "cjsLexer: Can't resolve") {
if entry.isEmpty() {
err = fmt.Errorf("could not resolve entry")
return
}
log.Debugf("build(%s): Entry%+v", ctx.pkg, entry)

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

result, reexport, err := ctx.lexer(&entry, false)
if err != nil && !strings.HasPrefix(err.Error(), "cjsLexer: Can't resolve") {
return
}

// cjs reexport
if reexport != "" {
pkg, _, _, e := ctx.lookupDep(reexport)
Expand Down Expand Up @@ -265,7 +272,7 @@ func (ctx *BuildContext) buildModule() (result BuildResult, err error) {
if err != nil {
return
}
result.Dts = ctx.lookupTypes(entry)
result.Dts, err = ctx.resloveDTS(entry)
return
}

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

if entry.esm == "" {
if entry.cjs == "" {
err = fmt.Errorf("could not resolve \"%s\"", entryModuleSpecifier)
return
}
buf := bytes.NewBuffer(nil)
fmt.Fprintf(buf, `import * as __module from "%s";`, entryModuleSpecifier)
if len(result.NamedExports) > 0 {
Expand Down Expand Up @@ -862,6 +865,7 @@ func (ctx *BuildContext) buildModule() (result BuildResult, err error) {
if ctx.isDenoTarget() {
conditions = append(conditions, "deno")
}
minify := config.Minify == nil || !bytes.Equal(config.Minify, []byte("false"))
options := api.BuildOptions{
Outdir: "/esbuild",
Write: false,
Expand All @@ -870,9 +874,9 @@ func (ctx *BuildContext) buildModule() (result BuildResult, err error) {
Format: api.FormatESModule,
Target: targets[ctx.target],
Platform: api.PlatformBrowser,
MinifyWhitespace: !ctx.dev,
MinifyIdentifiers: !ctx.dev,
MinifySyntax: !ctx.dev,
MinifyWhitespace: minify,
MinifyIdentifiers: minify,
MinifySyntax: minify,
KeepNames: ctx.args.keepNames, // prevent class/function names erasing
IgnoreAnnotations: ctx.args.ignoreAnnotations, // some libs maybe use wrong side-effect annotations
Conditions: conditions,
Expand Down Expand Up @@ -1207,20 +1211,7 @@ rebuild:
deps.Sort()

result.Deps = deps
result.Dts = ctx.lookupTypes(entry)
return
}

func (ctx *BuildContext) LookupTypes() (dts string, err error) {
// install the package
ctx.stage = "install"
err = ctx.install()
if err != nil {
return
}

entry := ctx.resolveEntry(ctx.pkg)
dts = ctx.lookupTypes(entry)
result.Dts, err = ctx.resloveDTS(entry)
return
}

Expand Down Expand Up @@ -1252,56 +1243,6 @@ func (ctx *BuildContext) buildTypes() (ret BuildResult, err error) {
return
}

func (ctx *BuildContext) lookupTypes(entry BuildEntry) string {
if entry.dts != "" {
if !ctx.existsPkgFile(entry.dts) {
return ""
}
return fmt.Sprintf(
"/%s%s/%s%s",
ctx.pkg.ghPrefix(),
ctx.pkg.Fullname(),
ctx.getBuildArgsPrefix(ctx.pkg, true),
strings.TrimPrefix(entry.dts, "./"),
)
}

// use types from package "@types/[task.npm.Name]" if it exists
if ctx.pkgJson.Types == "" && !strings.HasPrefix(ctx.pkgJson.Name, "@types/") && regexpFullVersion.MatchString(ctx.pkgJson.Version) {
versionParts := strings.Split(ctx.pkgJson.Version, ".")
versions := []string{
versionParts[0] + "." + versionParts[1], // major.minor
versionParts[0], // major
}
typesPkgName := toTypesPkgName(ctx.pkgJson.Name)
pkgVersion, ok := ctx.args.deps[typesPkgName]
if ok {
// use the version of the `?deps` query if it exists
versions = append([]string{pkgVersion}, versions...)
}
for _, version := range versions {
p, err := ctx.npmrc.getPackageInfo(typesPkgName, version)
if err == nil {
typesPkg := Pkg{
Name: typesPkgName,
Version: p.Version,
SubPath: ctx.pkg.SubPath,
SubModule: ctx.pkg.SubModule,
}
b := NewBuildContext(ctx.zoneId, ctx.npmrc, typesPkg, ctx.args, "types", BundleFalse, false, false)
dts, _ := b.LookupTypes()
if dts != "" {
// use tilde semver range instead of the exact version
return strings.ReplaceAll(dts, fmt.Sprintf("%s@%s", typesPkgName, p.Version), fmt.Sprintf("%s@~%s", typesPkgName, p.Version))
}
break
}
}
}

return ""
}

func (ctx *BuildContext) transformDTS(types string) (err error) {
start := time.Now()
buildArgsPrefix := ctx.getBuildArgsPrefix(ctx.pkg, true)
Expand Down
77 changes: 65 additions & 12 deletions server/build_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ type BuildEntry struct {
dts string
}

// isEmpty checks if the entry is empty
func (entry *BuildEntry) isEmpty() bool {
return entry.esm == "" && entry.cjs == "" && entry.dts == ""
}

// hasEntry checks if the entrypoint of the given type exists
func (entry *BuildEntry) hasEntry(entryType string) bool {
switch entryType {
Expand Down Expand Up @@ -576,18 +581,18 @@ func (ctx *BuildContext) resolveEntry(pkg Pkg) (entry BuildEntry) {
normalizeBuildEntry(ctx, &entry)
if entry.esm != "" {
m, ok := ctx.pkgJson.Browser[entry.esm]
if ok && m != "" {
if ok && isRelativeSpecifier(m) {
entry.esm = m
}
}
if entry.cjs != "" {
m, ok := ctx.pkgJson.Browser[entry.cjs]
if ok && m != "" {
if ok && isRelativeSpecifier(m) {
entry.cjs = m
}
}
if pkg.SubModule == "" {
if m, ok := ctx.pkgJson.Browser["."]; ok && m != "" {
if m, ok := ctx.pkgJson.Browser["."]; ok && isRelativeSpecifier(m) {
if ctx.pkgJson.Type == "module" || strings.HasSuffix(m, ".mjs") {
entry.esm = m
} else {
Expand Down Expand Up @@ -922,6 +927,62 @@ func (ctx *BuildContext) resolveExternalModule(specifier string, kind api.Resolv
return
}

func (ctx *BuildContext) resloveDTS(entry BuildEntry) (string, error) {
if entry.dts != "" {
if !ctx.existsPkgFile(entry.dts) {
return "", nil
}
return fmt.Sprintf(
"/%s%s/%s%s",
ctx.pkg.ghPrefix(),
ctx.pkg.Fullname(),
ctx.getBuildArgsPrefix(ctx.pkg, true),
strings.TrimPrefix(entry.dts, "./"),
), nil
}

// use types from package "@types/[task.npm.Name]" if it exists
if ctx.pkgJson.Types == "" && !strings.HasPrefix(ctx.pkgJson.Name, "@types/") && regexpFullVersion.MatchString(ctx.pkgJson.Version) {
versionParts := strings.Split(ctx.pkgJson.Version, ".")
versions := []string{
versionParts[0] + "." + versionParts[1], // major.minor
versionParts[0], // major
}
typesPkgName := toTypesPkgName(ctx.pkgJson.Name)
pkgVersion, ok := ctx.args.deps[typesPkgName]
if ok {
// use the version of the `?deps` query if it exists
versions = append([]string{pkgVersion}, versions...)
}
for _, version := range versions {
p, err := ctx.npmrc.getPackageInfo(typesPkgName, version)
if err == nil {
typesPkg := Pkg{
Name: typesPkgName,
Version: p.Version,
SubPath: ctx.pkg.SubPath,
SubModule: ctx.pkg.SubModule,
}
b := NewBuildContext(ctx.zoneId, ctx.npmrc, typesPkg, ctx.args, "types", BundleFalse, false, false)
err := b.install()
if err != nil {
return "", err
}
dts, err := b.resloveDTS(b.resolveEntry(typesPkg))
if err != nil {
return "", err
}
if dts != "" {
// use tilde semver range instead of the exact version
return strings.ReplaceAll(dts, fmt.Sprintf("%s@%s", typesPkgName, p.Version), fmt.Sprintf("%s@~%s", typesPkgName, p.Version)), nil
}
}
}
}

return "", nil
}

func (ctx *BuildContext) normalizePackageJSON(p PackageJSON) PackageJSON {
if ctx.pkg.FromGithub {
// if the name in package.json is not the same as the repository name
Expand Down Expand Up @@ -992,14 +1053,6 @@ func (ctx *BuildContext) normalizePackageJSON(p PackageJSON) PackageJSON {
}

func (ctx *BuildContext) lexer(entry *BuildEntry, forceCjsOnly bool) (ret BuildResult, reexport string, err error) {
pkgJson := ctx.pkgJson
typesOnly := strings.HasPrefix(pkgJson.Name, "@types/") || (entry.esm == "" && entry.cjs == "" && entry.dts != "")

if typesOnly {
ret.TypesOnly = true
return
}

if entry.esm != "" && !forceCjsOnly {
isESM, namedExports, erro := ctx.esmLexer(entry.esm)
if erro != nil {
Expand All @@ -1025,7 +1078,7 @@ func (ctx *BuildContext) lexer(entry *BuildEntry, forceCjsOnly bool) (ret BuildR
entry.cjs = entry.esm
entry.esm = ""
reexport = r.ReExport
log.Warnf("fake ES module '%s' of '%s'", entry.cjs, pkgJson.Name)
log.Warnf("fake ES module '%s' of '%s'", entry.cjs, ctx.pkgJson.Name)
return
}

Expand Down
8 changes: 6 additions & 2 deletions server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Config struct {
BanList BanList `json:"banList"`
BuildConcurrency uint16 `json:"buildConcurrency"`
BuildTimeout uint16 `json:"buildTimeout"`
Minify json.RawMessage `json:"minify"`
DisableSourceMap bool `json:"disableSourceMap"`
DisableCompression bool `json:"disableCompression"`
Cache string `json:"cache"`
Expand Down Expand Up @@ -99,10 +100,13 @@ func fixConfig(c *Config) *Config {
c.AuthSecret = os.Getenv("AUTH_SECRET")
}
if !c.DisableCompression {
c.DisableCompression = os.Getenv("DISABLE_COMPRESSION") != ""
c.DisableCompression = os.Getenv("DISABLE_COMPRESSION") == "true"
}
if !c.DisableSourceMap {
c.DisableSourceMap = os.Getenv("DISABLE_SOURCEMAP") != ""
c.DisableSourceMap = os.Getenv("DISABLE_SOURCEMAP") == "true"
}
if c.Minify == nil && os.Getenv("MINIFY") == "false" {
c.Minify = []byte("false")
}
if c.BuildConcurrency == 0 {
c.BuildConcurrency = uint16(runtime.NumCPU())
Expand Down
6 changes: 5 additions & 1 deletion server/dts_transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,11 @@ func transformDTS(ctx *BuildContext, dts string, buildArgsPrefix string, marker
exports: NewStringSet(),
}
b := NewBuildContext(ctx.zoneId, ctx.npmrc, depPkg, args, "types", BundleFalse, false, false)
dts, err := b.LookupTypes()
err = b.install()
if err != nil {
return "", err
}
dts, err = b.resloveDTS(b.resolveEntry(depPkg))
if err != nil {
return "", err
}
Expand Down
7 changes: 3 additions & 4 deletions server/dts_walker.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"io"
"regexp"
"strings"
)

var (
Expand Down Expand Up @@ -74,9 +73,9 @@ func walkDts(r io.Reader, buf *bytes.Buffer, resolve func(specifier string, kind
if err != nil {
return
}
if format == "types" && strings.HasPrefix(res, "{ESM_CDN_ORIGIN}") {
format = "path"
}
// if format == "types" && strings.HasPrefix(res, "{ESM_CDN_ORIGIN}") {
// format = "path"
// }
fmt.Fprintf(buf, `/// <reference %s="%s" />`, format, res)
} else {
buf.Write(line)
Expand Down
Loading

0 comments on commit f323f03

Please sign in to comment.