fix(codegen): keep exports[STR] = … key as plain string in minify#22402
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
Merging this PR will not alter performance
Comparing Footnotes
|
2b7165a to
05353f5
Compare
80a9235 to
6f06826
Compare
|
Same as #22400 (comment) said |
Merge activity
|
6f06826 to
decfc18
Compare
…22402) Stacked on #22400. Closes the second `cjs-module-lexer` gap. After #22400, `Object.defineProperty(exports, "name", ...)` is fine, but `exports["name"] = …` / `module.exports["name"] = …` were still being emitted with backtick keys in minify. The lexer recognises this form too — it just couldn't see them past the template literal. Valid-identifier keys (`exports["foo"]`) are already collapsed to dot access by the minifier earlier in the pipeline, so only non-identifier keys (`exports["has-dash"]`, `module.exports["__esModule"]`, …) survive to the codegen stage and were affected. In `AssignmentExpression::gen_expr`, detect when the LHS is a computed member expression on `exports` / `module.exports` whose key is a `StringLiteral`, and print the key via `print_string_literal(key, false)`. Other computed access (`otherObj["x"]`) is unaffected. ### Where each cjs-module-lexer named-export form lands | Pattern | Status | |---|---| | `exports.name = …` | identifier — never affected | | `module.exports.name = …` | identifier — never affected | | `module.exports = { "name": … }` | object property keys already use `allow_backtick: false` | | `Object.defineProperty(exports, "name", …)` | fixed in #22400 | | `exports["name"] = …` / `module.exports["name"] = …` | **fixed here** | ### Before / after ```js // input exports["has-dash"] = a; module.exports["__esModule"] = true; otherObj["not-exports"] = d; ``` ```js // before exports[`has-dash`]=a,module.exports[`__esModule`]=!0,otherObj[`not-exports`]=d; // after exports["has-dash"]=a,module.exports.__esModule=!0,otherObj[`not-exports`]=d; ``` (`module.exports.__esModule` collapses to dot via a separate minifier pass; `otherObj["x"]` correctly stays backtick.) Refs #22342 AI assisted.
decfc18 to
703557c
Compare

Stacked on #22400. Closes the second
cjs-module-lexergap.After #22400,
Object.defineProperty(exports, "name", ...)is fine, butexports["name"] = …/module.exports["name"] = …were still being emitted with backtick keys in minify. The lexer recognises this form too — it just couldn't see them past the template literal.Valid-identifier keys (
exports["foo"]) are already collapsed to dot access by the minifier earlier in the pipeline, so only non-identifier keys (exports["has-dash"],module.exports["__esModule"], …) survive to the codegen stage and were affected.In
AssignmentExpression::gen_expr, detect when the LHS is a computed member expression onexports/module.exportswhose key is aStringLiteral, and print the key viaprint_string_literal(key, false). Other computed access (otherObj["x"]) is unaffected.Where each cjs-module-lexer named-export form lands
exports.name = …module.exports.name = …module.exports = { "name": … }allow_backtick: falseObject.defineProperty(exports, "name", …)exports["name"] = …/module.exports["name"] = …Before / after
(
module.exports.__esModulecollapses to dot via a separate minifier pass;otherObj["x"]correctly stays backtick.)Refs #22342
AI assisted.