Skip to content

Commit

Permalink
fix "exports" path resolution for scoped packages
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Mar 16, 2021
1 parent 8fcc937 commit fc77075
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

* Fix path resolution with the `exports` field for scoped packages

This release fixes a bug where the `exports` field in `package.json` files was not being detected for scoped packages (i.e. packages of the form `@scope/pkg-name` instead of just `pkg-name`). The `exports` field should now be respected for these kinds of packages.

* Improved error message in `exports` failure case

Node's new [conditional exports feature](https://nodejs.org/docs/latest/api/packages.html#packages_conditional_exports) can be non-intuitive and hard to use. Now that esbuild supports this feature (as of version 0.9.0), you can get into a situation where it's impossible to import a package if the package's `exports` field in its `package.json` file isn't configured correctly.
Expand Down
2 changes: 1 addition & 1 deletion internal/resolver/package_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ func esmParsePackageName(packageSpecifier string) (packageName string, packageSu
if slash2 == -1 {
slash2 = len(packageSpecifier[slash+1:])
}
packageName = packageSpecifier[:slash]
packageName = packageSpecifier[:slash+1+slash2]
}

if strings.HasPrefix(packageName, ".") || strings.ContainsAny(packageName, "\\%") {
Expand Down
83 changes: 83 additions & 0 deletions scripts/end-to-end-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2954,6 +2954,89 @@
}
}`,
}),
test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {
'in.js': `import abc from '@scope/pkg'; if (abc !== 123) throw 'fail'`,
'package.json': `{ "type": "module" }`,
'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,
'node_modules/@scope/pkg/package.json': `{
"type": "module",
"exports": {
".": "./subdir/foo.js"
}
}`,
}),
test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {
'in.js': `import abc from '@scope/pkg'; if (abc !== 123) throw 'fail'`,
'package.json': `{ "type": "module" }`,
'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,
'node_modules/@scope/pkg/package.json': `{
"type": "module",
"exports": {
".": {
"default": "./subdir/foo.js"
}
}
}`,
}),
test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {
'in.js': `import abc from '@scope/pkg'; if (abc !== 123) throw 'fail'`,
'package.json': `{ "type": "module" }`,
'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,
'node_modules/@scope/pkg/package.json': `{
"type": "module",
"exports": {
"default": "./subdir/foo.js"
}
}`,
}),
test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {
'in.js': `import abc from '@scope/pkg/foo.js'; if (abc !== 123) throw 'fail'`,
'package.json': `{ "type": "module" }`,
'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,
'node_modules/@scope/pkg/package.json': `{
"type": "module",
"exports": {
"./": "./subdir/"
}
}`,
}),
test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {
'in.js': `import abc from '@scope/pkg/foo.js'; if (abc !== 123) throw 'fail'`,
'package.json': `{ "type": "module" }`,
'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,
'node_modules/@scope/pkg/package.json': `{
"type": "module",
"exports": {
"./": {
"default": "./subdir/"
}
}
}`,
}),
test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {
'in.js': `import abc from '@scope/pkg/dir/foo.js'; if (abc !== 123) throw 'fail'`,
'package.json': `{ "type": "module" }`,
'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,
'node_modules/@scope/pkg/package.json': `{
"type": "module",
"exports": {
"./dir/": "./subdir/"
}
}`,
}),
test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {
'in.js': `import abc from '@scope/pkg/dir/foo.js'; if (abc !== 123) throw 'fail'`,
'package.json': `{ "type": "module" }`,
'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,
'node_modules/@scope/pkg/package.json': `{
"type": "module",
"exports": {
"./dir/": {
"default": "./subdir/"
}
}
}`,
}),
test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {
'in.js': `import abc from 'pkg/dirwhat'; if (abc !== 123) throw 'fail'`,
'package.json': `{ "type": "module" }`,
Expand Down

0 comments on commit fc77075

Please sign in to comment.