mirror of
https://github.com/hanzoai/esbuild.git
synced 2026-09-24 16:58:50 +00:00
fix #4482: don't inline using declarations
This commit is contained in:
@@ -2,6 +2,24 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
* Avoid inlining `using` and `await using` declarations ([#4482](https://github.com/evanw/esbuild/issues/4482))
|
||||
|
||||
Previously esbuild's minifier sometimes incorrectly inlined `using` and `await using` declarations into subsequent uses of that declaration, which then fails to dispose of the resource correctly. This bug happened because inlining was done for `let` and `const` declarations by avoiding doing it for `var` declarations, which no longer worked when more declaration types were added. Here's an example:
|
||||
|
||||
```js
|
||||
// Original code
|
||||
{
|
||||
using x = new Resource()
|
||||
x.activate()
|
||||
}
|
||||
|
||||
// Old output (with --minify)
|
||||
new Resource().activate();
|
||||
|
||||
// New output (with --minify)
|
||||
{using e=new Resource;e.activate()}
|
||||
```
|
||||
|
||||
* Fix module evaluation when an error is thrown ([#4461](https://github.com/evanw/esbuild/issues/4461), [#4467](https://github.com/evanw/esbuild/pull/4467))
|
||||
|
||||
If an error is thrown during module evaluation, esbuild previously didn't preserve the state of the module for subsequent module references. This was observable if `import()` or `require()` is used to import a module multiple times. The thrown error is supposed to be thrown by every call to `import()` or `require()`, not just the first. With this release, esbuild will now throw the same error every time you call `import()` or `require()` on a module that throws during its evaluation.
|
||||
|
||||
@@ -9190,7 +9190,7 @@ func (p *parser) mangleStmts(stmts []js_ast.Stmt, kind stmtsKind) []js_ast.Stmt
|
||||
// should have visited all the uses of "let" and "const" declarations
|
||||
// by now since they are scoped to this block which we just finished
|
||||
// visiting.
|
||||
if prevS, ok := result[len(result)-1].Data.(*js_ast.SLocal); ok && prevS.Kind != js_ast.LocalVar {
|
||||
if prevS, ok := result[len(result)-1].Data.(*js_ast.SLocal); ok && (prevS.Kind == js_ast.LocalLet || prevS.Kind == js_ast.LocalConst) {
|
||||
last := prevS.Decls[len(prevS.Decls)-1]
|
||||
|
||||
// The binding must be an identifier that is only used once.
|
||||
|
||||
@@ -5265,6 +5265,8 @@ func TestMangleInlineLocals(t *testing.T) {
|
||||
check("var x = 1; return x", "var x = 1;\nreturn x;")
|
||||
check("let x = 1; return x", "return 1;")
|
||||
check("const x = 1; return x", "return 1;")
|
||||
check("using x = 1; return x", "using x = 1;\nreturn x;")
|
||||
check("return async () => { await using x = 1; return x }", "return async () => {\n await using x = 1;\n return x;\n};")
|
||||
|
||||
check("let x = 1; if (false) x++; return x", "return 1;")
|
||||
check("let x = 1; if (true) x++; return x", "let x = 1;\nreturn x++, x;")
|
||||
|
||||
Reference in New Issue
Block a user