Skip to content

Commit

Permalink
fix #2730: alias now strips a trailing slash
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Dec 14, 2022
1 parent b0a82d3 commit 7bf440d
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -26,6 +26,10 @@
}
```

* The alias feature now strips a trailing slash ([#2730](https://github.com/evanw/esbuild/issues/2730))

People sometimes add a trailing slash to the name of one of node's built-in modules to force node to import from the file system instead of importing the built-in module. For example, importing `util` imports node's built-in module called `util` but importing `util/` tries to find a package called `util` on the file system. Previously attempting to use esbuild's package alias feature to replace imports to `util` with a specific file would fail because the file path would also gain a trailing slash (e.g. mapping `util` to `./file.js` turned `util/` into `./file.js/`). With this release, esbuild will now omit the path suffix if it's a single trailing slash, which should now allow you to successfully apply aliases to these import paths.

## 0.16.6

* Do not mark subpath imports as external with `--packages=external` ([#2741](https://github.com/evanw/esbuild/issues/2741))
Expand Down
2 changes: 1 addition & 1 deletion internal/bundler/bundler.go
Expand Up @@ -548,7 +548,7 @@ func ResolveFailureErrorTextSuggestionNotes(
}
hint := ""

if resolver.IsPackagePath(path) {
if resolver.IsPackagePath(path) && !fs.IsAbs(path) {
hint = fmt.Sprintf("You can mark the path %q as external to exclude it from the bundle, which will remove this error.", path)
if kind == ast.ImportRequire {
hint += " You can also surround this \"require\" call with a try/catch block to handle this failure at run-time instead of bundle-time."
Expand Down
3 changes: 3 additions & 0 deletions internal/bundler/bundler_default_test.go
Expand Up @@ -6924,6 +6924,7 @@ func TestPackageAlias(t *testing.T) {
import "@abs-path/pkg6"
import "@abs-path/pkg7/foo"
import "@scope-only/pkg8"
import "slash/"
`,
"/nested3/index.js": `import "pkg3"`,
"/nested3/node_modules/alias3/index.js": `test failure`,
Expand All @@ -6935,6 +6936,7 @@ func TestPackageAlias(t *testing.T) {
"/alias6/dir/index.js": `console.log(6)`,
"/alias7/dir/foo/index.js": `console.log(7)`,
"/alias8/dir/pkg8/index.js": `console.log(8)`,
"/alias9/some/file.js": `console.log(9)`,
},
entryPaths: []string{"/entry.js"},
options: config.Options{
Expand All @@ -6949,6 +6951,7 @@ func TestPackageAlias(t *testing.T) {
"@abs-path/pkg6": `/alias6/dir`,
"@abs-path/pkg7": `/alias7/dir`,
"@scope-only": "/alias8/dir",
"slash": "/alias9/some/file.js",
},
},
})
Expand Down
3 changes: 3 additions & 0 deletions internal/bundler/snapshots/snapshots_loader.txt
Expand Up @@ -1528,6 +1528,9 @@ console.log(7);
// alias8/dir/pkg8/index.js
console.log(8);

// alias9/some/file.js
console.log(9);

================================================================================
TestRequireCustomExtensionBase64
---------- /out.js ----------
Expand Down
16 changes: 15 additions & 1 deletion internal/resolver/resolver.go
Expand Up @@ -313,7 +313,21 @@ func (rr *resolver) Resolve(sourceDir string, importPath string, kind ast.Import
// when using Yarn PnP because Yarn PnP doesn't allow nested packages
// to "reach outside" of their normal dependency lists.
sourceDir = r.fs.Cwd()
debugMeta.ModifiedImportPath = value + importPath[len(key):]
if tail := importPath[len(key):]; tail != "/" {
// Don't include the trailing characters if they are equal to a
// single slash. This comes up because you can abuse this quirk of
// node's path resolution to force node to load the package from the
// file system instead of as a built-in module. For example, "util"
// is node's built-in module while "util/" is one on the file system.
// Leaving the trailing slash in place causes problems for people:
// https://github.com/evanw/esbuild/issues/2730. It should be ok to
// always strip the trailing slash even when using the alias feature
// to swap one package for another (except when you swap a reference
// to one built-in node module with another but really why would you
// do that).
value += tail
}
debugMeta.ModifiedImportPath = value
if r.debugLogs != nil {
r.debugLogs.addNote(fmt.Sprintf(" Matched with alias from %q to %q", key, value))
r.debugLogs.addNote(fmt.Sprintf(" Modified import path from %q to %q", importPath, debugMeta.ModifiedImportPath))
Expand Down

0 comments on commit 7bf440d

Please sign in to comment.