esbuild icon indicating copy to clipboard operation
esbuild copied to clipboard

pnpm module resolution errors (on Windows)

Open callumevans opened this issue 1 year ago • 2 comments

I'm seeing some issues resolving pnpm packages, specifically on Windows, via the Go API.

I'm not entirely sure it's the same issue as mentioned in https://github.com/evanw/esbuild/issues/67, but I'm able to reproduce it from the example given there (https://github.com/timsuchanek/esbuild-pnpm).

Given the following Go code (where C:/Users/callu/Desktop/esbuild-pnpm/index.js is the cloned repo mentioned in #67):

	workingDirectory, _ := os.Getwd()

	result := api.Build(api.BuildOptions{
		EntryPoints: []string{"C:/Users/callu/Desktop/esbuild-pnpm/index.js"},
		Bundle:      true,
		Write:       true,
		Format:      api.FormatCommonJS,
		Platform:    api.PlatformNode,
		Target:      api.ES2015,
		Sourcemap:   api.SourceMapLinked,
		Metafile:    true,
		GlobalName:  "exports",
		Outdir:      filepath.Join(workingDirectory, ".output"),
		LogLevel:    api.LogLevelVerbose,
	})

With the verbose output, I'm getting the following:

♦ [VERBOSE] Resolving import "chalk" in directory "C:\\Users\\callu\\Desktop\\esbuild-pnpm" of type "require-call"

  Checking for package alias matches
    Failed to find any package alias matches
  Read 8 entries for directory "C:\\Users\\callu\\Desktop\\esbuild-pnpm"
  Searching for "chalk" in "node_modules" directories starting from "C:\\Users\\callu\\Desktop\\esbuild-pnpm"
    Parsed package name "chalk" and package subpath "."
    Checking for a package in the directory "C:\\Users\\callu\\Desktop\\esbuild-pnpm\\node_modules\\chalk"
    Read 8 entries for directory "C:\\Users\\callu\\Desktop\\esbuild-pnpm"
    Read 5 entries for directory "C:\\Users\\callu\\Desktop\\esbuild-pnpm\\node_modules"
    The file "C:\\Users\\callu\\Desktop\\esbuild-pnpm\\node_modules\\chalk\\package.json" exists
    Read 5 entries for directory "C:\\Users\\callu\\Desktop\\esbuild-pnpm\\node_modules\\chalk"
    Attempting to load "C:\\Users\\callu\\Desktop\\esbuild-pnpm\\node_modules\\chalk" as a file
      Checking for file "chalk"
      Found file "chalk"
  Read 5 entries for directory "C:\\Users\\callu\\Desktop\\esbuild-pnpm\\node_modules"
  Primary path is "C:\\Users\\callu\\Desktop\\esbuild-pnpm\\node_modules\\chalk" in namespace "file"

● [DEBUG] Failed to read file "C:\\Users\\callu\\Desktop\\esbuild-pnpm\\node_modules\\chalk": read C:\Users\callu\Desktop\esbuild-pnpm\node_modules\chalk: Incorrect function.

X [ERROR] Cannot read file "../../../Users/callu/Desktop/esbuild-pnpm/node_modules/chalk": Incorrect function.

    ../../../Users/callu/Desktop/esbuild-pnpm/index.js:1:22:
      1 │ const chalk = require('chalk')
        ╵                       ~~~~~~~

Something tells me this is a me-problem, although I've been able to replicate this in other contexts.

It works great if I just use an npm install - no issues whatsoever. With a pnpm install, I start seeing the above errors.

This also seems to be Windows-specific. Works fine on macOS.

I've tried various tweaks to the api.Build config, but haven't managed to get it working consistently.

callumevans avatar Oct 08 '24 17:10 callumevans

Base on your log above, it seems the problem is that esbuild did not try to resolve symlinks created by pnpm on Windows. The correct log should be like:

  Searching for "chalk" in "node_modules" directories starting from "D:\\a\\esbuild-3937\\esbuild-3937"
    Parsed package name "chalk" and package subpath "."
    Checking for a package in the directory "D:\\a\\esbuild-3937\\esbuild-3937\\node_modules\\chalk"
    Read 9 entries for directory "D:\\a\\esbuild-3937\\esbuild-3937"
    Read 5 entries for directory "D:\\a\\esbuild-3937\\esbuild-3937\\node_modules"
+   Resolved symlink "D:\\a\\esbuild-3937\\esbuild-3937\\node_modules\\chalk" to "D:\\a\\esbuild-3937\\esbuild-3937\\node_modules\\.pnpm\\[email protected]\\node_modules\\chalk"
    The file "D:\\a\\esbuild-3937\\esbuild-3937\\node_modules\\chalk\\package.json" exists
    Read 4 entries for directory "D:\\a\\esbuild-3937\\esbuild-3937\\node_modules\\chalk"
    Looking for "." in "exports" map in "D:\\a\\esbuild-3937\\esbuild-3937\\node_modules\\chalk\\package.json"
      Checking path "" against target "./source/index.js"
        Joined "" to "./source/index.js" to get "./source/index.js"
      ...

The above log was generated from a windows machine on github actions. Maybe you are just using old versions of esbuild and pnpm?

hyrious avatar Oct 09 '24 01:10 hyrious

The file system on Windows has multiple roots (volume labels) while the file system on Unix has a single root (just /). I'm aware that this is problematic with some of esbuild's Yarn support (Yarn actually allows ../ to traverse between different volumes on Windows while Windows doesn't, and esbuild doesn't support that yet).

It's possible that cross-volume paths are the problem here. If that's the case, the reproduction steps would require spreading your source code across multiple volumes, and a possible workaround could be to make sure your source code is all on the same volume. Or if that workaround doesn't work then that wasn't the problem.

I'm sorry that I can't test this myself but I don't have easy access to a Windows machine.

evanw avatar Oct 09 '24 14:10 evanw

Appreciate the response on this - apologies for not getting back in a timely manner.

I've written this off as Windows being a bit ... unique.

I've tried the same stuff on Linux and it works fine. Assuming it's something strange with how my specific Windows machine was behaving.

callumevans avatar Jan 15 '25 12:01 callumevans