Skip to content

Commit

Permalink
Fix subpath imports with Yarn PnP
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Sep 14, 2022
1 parent be4e272 commit 04a3f20
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 12 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -93,6 +93,10 @@

However, the compilation had a subtle bug where the automatically-generated function-level symbols for multible hoisted block-level function declarations in the same block a sloppy-mode context were generated in a random order if the output was in strict mode, which could be the case if TypeScript's `alwaysStrict` setting was set to true. This lead to non-determinism in the output as the minifier would randomly exchange the generated names for these symbols on different runs. This bug has been fixed by sorting the keys of the unordered map before iterating over them.

* Fix subpath imports with Yarn PnP ([#2545](https://github.com/evanw/esbuild/issues/2545))

Node has a little-used feature called [subpath imports](https://nodejs.org/api/packages.html#subpath-imports) which are package-internal imports that start with `#` and that go through the `imports` map in `package.json`. Previously esbuild had a bug that caused esbuild to not handle these correctly in packages installed via Yarn's "Plug'n'Play" installation strategy. The problem was that subpath imports were being checked after Yarn PnP instead of before. This release reorders these checks, which should allow subpath imports to work in this case.

## 0.15.7

* Add `--watch=forever` to allow esbuild to never terminate ([#1511](https://github.com/evanw/esbuild/issues/1511), [#1885](https://github.com/evanw/esbuild/issues/1885))
Expand Down
22 changes: 11 additions & 11 deletions internal/resolver/resolver.go
Expand Up @@ -1999,6 +1999,17 @@ func (r resolverQuery) loadNodeModules(importPath string, dirInfo *dirInfo, forb
}
}

// Find the parent directory with the "package.json" file
dirInfoPackageJSON := dirInfo
for dirInfoPackageJSON != nil && dirInfoPackageJSON.packageJSON == nil {
dirInfoPackageJSON = dirInfoPackageJSON.parent
}

// Check for subpath imports: https://nodejs.org/api/packages.html#subpath-imports
if dirInfoPackageJSON != nil && strings.HasPrefix(importPath, "#") && !forbidImports && dirInfoPackageJSON.packageJSON.importsMap != nil {
return r.loadPackageImports(importPath, dirInfoPackageJSON)
}

// If Yarn PnP is active, use it to find the package
if r.pnpManifest != nil {
if result := r.resolveToUnqualified(importPath, dirInfo.absPath, r.pnpManifest); result.status == pnpError {
Expand Down Expand Up @@ -2042,17 +2053,6 @@ func (r resolverQuery) loadNodeModules(importPath string, dirInfo *dirInfo, forb
}
}

// Find the parent directory with the "package.json" file
dirInfoPackageJSON := dirInfo
for dirInfoPackageJSON != nil && dirInfoPackageJSON.packageJSON == nil {
dirInfoPackageJSON = dirInfoPackageJSON.parent
}

// Check for subpath imports: https://nodejs.org/api/packages.html#subpath-imports
if dirInfoPackageJSON != nil && strings.HasPrefix(importPath, "#") && !forbidImports && dirInfoPackageJSON.packageJSON.importsMap != nil {
return r.loadPackageImports(importPath, dirInfoPackageJSON)
}

// Try to parse the package name using node's ESM-specific rules
esmPackageName, esmPackageSubpath, esmOK := esmParsePackageName(importPath)
if r.debugLogs != nil && esmOK {
Expand Down
3 changes: 3 additions & 0 deletions require/yarnpnp/in.mjs
Expand Up @@ -14,6 +14,9 @@ if (!d3.utcDay) throw '❌ d3-time'
import * as mm from 'mime'
if (mm.default.getType('txt') !== 'text/plain') throw '❌ mime'

import * as ajv from 'aws-jwt-verify'
if (!ajv.CognitoJwtVerifier) throw '❌ aws-jwt-verify'

import * as foo from 'foo'
if (foo.default !== 'foo') throw '❌ foo'

Expand Down
2 changes: 1 addition & 1 deletion scripts/test-yarnpnp.js
Expand Up @@ -38,7 +38,7 @@ function reinstallYarnIfNeeded() {
}

const rc = fs.readFileSync(path.join(rootDir, '.yarnrc.yml'), 'utf8')
fs.writeFileSync(path.join(rootDir, '.yarnrc.yml'), `pnpIgnorePatterns: ["./bar/**"]\n` + rc)
fs.writeFileSync(path.join(rootDir, '.yarnrc.yml'), `pnpEnableEsmLoader: true\npnpIgnorePatterns: ["./bar/**"]\n` + rc)

run('yarn install')
}
Expand Down

0 comments on commit 04a3f20

Please sign in to comment.