Skip to content

Commit

Permalink
fix #2715: allow package subpaths with alias
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Dec 19, 2022
1 parent 1ec8085 commit 270a210
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 32 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -74,6 +74,10 @@

The change in the previous release to forbid duplicate function declarations in certain cases accidentally forbid some edge cases that should have been allowed. Specifically duplicate function declarations are forbidden in nested blocks in strict mode and at the top level of modules, but are allowed when they are declared at the top level of function bodies. This release fixes the regression by re-allowing the last case.

* Allow package subpaths with `alias` ([#2715](https://github.com/evanw/esbuild/issues/2715))

Previously the names passed to the `alias` feature had to be the name of a package (with or without a package scope). With this release, you can now also use the `alias` feature with package subpaths. So for example you can now create an alias that substitutes `@org/pkg/lib` with something else.

## 0.16.9

* Update to Unicode 15.0.0
Expand Down
28 changes: 17 additions & 11 deletions internal/bundler_tests/bundler_default_test.go
Expand Up @@ -7182,18 +7182,22 @@ func TestPackageAlias(t *testing.T) {
import "@abs-path/pkg7/foo"
import "@scope-only/pkg8"
import "slash/"
import "prefix-foo"
import "@scope/prefix-foo"
`,
"/nested3/index.js": `import "pkg3"`,
"/nested3/node_modules/alias3/index.js": `test failure`,
"/node_modules/alias1/index.js": `console.log(1)`,
"/node_modules/alias2/foo.js": `console.log(2)`,
"/node_modules/alias3/index.js": `console.log(3)`,
"/node_modules/alias4/index.js": `console.log(4)`,
"/node_modules/alias5/foo.js": `console.log(5)`,
"/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)`,
"/nested3/index.js": `import "pkg3"`,
"/nested3/node_modules/alias3/index.js": `test failure`,
"/node_modules/alias1/index.js": `console.log(1)`,
"/node_modules/alias2/foo.js": `console.log(2)`,
"/node_modules/alias3/index.js": `console.log(3)`,
"/node_modules/alias4/index.js": `console.log(4)`,
"/node_modules/alias5/foo.js": `console.log(5)`,
"/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)`,
"/node_modules/prefix-foo/index.js": `console.log(10)`,
"/node_modules/@scope/prefix-foo/index.js": `console.log(11)`,
},
entryPaths: []string{"/entry.js"},
options: config.Options{
Expand All @@ -7209,6 +7213,8 @@ func TestPackageAlias(t *testing.T) {
"@abs-path/pkg7": `/alias7/dir`,
"@scope-only": "/alias8/dir",
"slash": "/alias9/some/file.js",
"prefix": "alias10",
"@scope/prefix": "alias11",
},
},
})
Expand Down
6 changes: 6 additions & 0 deletions internal/bundler_tests/snapshots/snapshots_default.txt
Expand Up @@ -4088,6 +4088,12 @@ console.log(8);
// alias9/some/file.js
console.log(9);

// node_modules/prefix-foo/index.js
console.log(10);

// node_modules/@scope/prefix-foo/index.js
console.log(11);

================================================================================
TestQuotedProperty
---------- /out/entry.js ----------
Expand Down
27 changes: 12 additions & 15 deletions pkg/api/api_impl.go
Expand Up @@ -6,6 +6,7 @@ import (
"math"
"math/rand"
"os"
"path"
"regexp"
"sort"
"strconv"
Expand Down Expand Up @@ -488,28 +489,24 @@ func validateAlias(log logger.Log, fs fs.FS, alias map[string]string) map[string

// Valid alias names:
// "foo"
// "foo/bar"
// "@foo"
// "@foo/bar"
// "@foo/bar/baz"
//
// Invalid alias names:
// "./foo"
// "foo/bar"
// "../foo"
// "/foo"
// "C:\\foo"
// ".foo"
// "foo/"
// "@foo/"
// "@foo/bar/baz"
// "foo/../bar"
//
if !strings.HasPrefix(old, ".") && !strings.HasPrefix(old, "/") && !fs.IsAbs(old) {
slash := strings.IndexByte(old, '/')
isScope := strings.HasPrefix(old, "@")
if slash != -1 && isScope {
pkgAfterScope := old[slash+1:]
if slash2 := strings.IndexByte(pkgAfterScope, '/'); slash2 == -1 && pkgAfterScope != "" {
valid[old] = new
continue
}
} else if slash == -1 {
valid[old] = new
continue
}
if !strings.HasPrefix(old, ".") && !strings.HasPrefix(old, "/") && !fs.IsAbs(old) && path.Clean(strings.ReplaceAll(old, "\\", "/")) == old {
valid[old] = new
continue
}

log.AddError(nil, logger.Range{}, fmt.Sprintf("Invalid alias name: %q", old))
Expand Down
17 changes: 11 additions & 6 deletions scripts/js-api-tests.js
Expand Up @@ -157,14 +157,19 @@ let buildTests = {

await Promise.all([
valid('foo'),
valid('@scope'),
valid('@scope/foo'),
valid('foo/bar'),
valid('@foo'),
valid('@foo/bar'),
valid('@foo/bar/baz'),

invalid('foo/bar'),
invalid('/foo'),
invalid('./foo'),
invalid('@scope/'),
invalid('@scope/foo/bar'),
invalid('../foo'),
invalid('/foo'),
invalid('C:\\foo'),
invalid('.foo'),
invalid('foo/'),
invalid('@foo/'),
invalid('foo/../bar'),
])
},

Expand Down

0 comments on commit 270a210

Please sign in to comment.