Repository: evanw/esbuild
File: internal/resolver/resolver.go (Go)

Code before:
	if ok {
		return absolute, true
	}

	// Is this a directory?
	dirInfo := r.dirInfoCached(path)
	if dirInfo == nil {
		return "", false
	}

	// Return the "main" field from "package.json"
	if dirInfo.packageJson != nil && dirInfo.packageJson.absPathMain != nil {
		return *dirInfo.packageJson.absPathMain, true
	}

	// Return the "index.js" file
	if dirInfo.absPathIndex != nil {
		return *dirInfo.absPathIndex, true
	}

	return "", false
}

func resolvePathWithoutStar(from, path string) (string, error) {
	replaced := strings.Replace(path, "/*", "", -1)
	return fp.Join(from, replaced), nil
}

func (r *resolver) loadNodeModules(path string, dirInfo *dirInfo) (string, bool) {
	for {
		// Handle TypeScript base URLs for TypeScript code
		if dirInfo.tsConfigJson != nil {

			if dirInfo.tsConfigJson.absPathBaseUrl != nil {
				if dirInfo.tsConfigJson.paths != nil {
					for key, originalPaths := range dirInfo.tsConfigJson.paths {
						for _, originalPath := range originalPaths {
							if matched, err := regexp.MatchString("^"+key, path); matched && err == nil {
								if absoluteOriginalPath, err := resolvePathWithoutStar(*dirInfo.tsConfigJson.absPathBaseUrl, originalPath); err == nil {
									elements := strings.Split(path, "/")

									elements = elements[1:]

									resolved := append(strings.Split(absoluteOriginalPath, string(os.PathSeparator)), elements...)
									basePath := strings.Join(resolved, "/")
									if absolute, ok := r.loadAsFileOrDirectory(basePath); ok {
										return absolute, true
									}
								}
							}
						}

Review comment (suggestion):
The code in this file is careful to always use the `fs` interface in the `resolver` instead of `path/filepath`. All platform-dependent things are supposed to happen inside the `fs` interface so that the resolver can be platform-independent. That interface uses the real `path/filepath` module for the esbuild command and the `path` module for tests. That way tests don't do different things on Windows.


Code after:

	// Is this a directory?
	dirInfo := r.dirInfoCached(path)
	if dirInfo == nil {
		return "", false
	}

	// Return the "main" field from "package.json"
	if dirInfo.packageJson != nil && dirInfo.packageJson.absPathMain != nil {
		return *dirInfo.packageJson.absPathMain, true
	}

	// Return the "index.js" file
	if dirInfo.absPathIndex != nil {
		return *dirInfo.absPathIndex, true
	}

	return "", false
}

func isTsConfigPathMatch(pattern string, path string) (string, bool) {
	starIndex := strings.IndexRune(pattern, '*')
	if starIndex == -1 {
		firstPath := strings.Split(path, "/")[0]
		return strings.Replace(path, pattern+"/", "", 1), firstPath == pattern
	}

	elements := strings.Split(pattern, "*")
	if starIndex == 0 {
		suffix := elements[1]
		return strings.Replace(path, suffix, "", 1), strings.HasSuffix(path, suffix)
	}
	prefix := elements[0]
	return strings.Replace(path, prefix, "", 1), strings.HasPrefix(path, prefix)
}

func (r *resolver) loadNodeModules(path string, dirInfo *dirInfo) (string, bool) {
	for {
		// Handle TypeScript base URLs for TypeScript code
		if dirInfo.tsConfigJson != nil {

			if dirInfo.tsConfigJson.absPathBaseUrl != nil {
				if dirInfo.tsConfigJson.paths != nil {
					for key, originalPaths := range dirInfo.tsConfigJson.paths {
						for _, originalPath := range originalPaths {
							if parts, ok := isTsConfigPathMatch(key, path); ok {
								absoluteOriginalPath := r.fs.Join(*dirInfo.tsConfigJson.absPathBaseUrl, originalPath)
								basePath := strings.Replace(absoluteOriginalPath, "*", parts, 1)
								if absolute, ok := r.loadAsFileOrDirectory(basePath); ok {
									return absolute, true
								}