-
-
Notifications
You must be signed in to change notification settings - Fork 759
fix(napi/parser): reorder fields of ExportEntry on JS side
#16403
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(napi/parser): reorder fields of ExportEntry on JS side
#16403
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. |
CodSpeed Performance ReportMerging #16403 will not alter performanceComparing Summary
Footnotes
|
Merge activity
|
…16403) NAPI-RS 3.6.0 makes a change to the ordering of objects. It now puts optional fields last. This made tests in `napi/parser` for module record fail when we tried to update (#16383) because the `module_request` field of `ExportEntry` moves to last which breaks the snapshots. The change in NAPI-RS is unlikely to be reverted, because it's a sizeable perf optimization: napi-rs/napi-rs#2990 To work around this problem: 1. Move the field in the `ExportEntry` intermediate struct in `napi/parser` to last, so NAPI's output matches what you'd expect from the struct definition. 2. Alter the `#[estree]` attr on `ExportEntry` struct in `oxc_syntax` crate to match. Note: The `ExportEntry` struct in `napi/parser` is just an intermediate structure used for serialization. So I think it's fine to fiddle with its field order. The actual `ExportEntry` struct used in the module record is in `oxc_syntax` crate, and it remains unaltered.
18d85c2 to
12bd794
Compare
ExportEntry::module_request field to lastExportEntry on JS side
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adapts the ExportEntry serialization to accommodate NAPI-RS 3.6.0's performance optimization which places optional fields last in serialized objects. The change ensures test snapshots pass by aligning the field order across Rust, TypeScript, and generated code.
- Moved
module_requestoptional field to last position inStaticExportEntrystruct definition - Updated
#[estree]attribute with explicitfield_orderto control serialization - Regenerated all affected code including TypeScript definitions, ESTree serializers, and JavaScript deserializers
Reviewed changes
Copilot reviewed 3 out of 13 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| napi/parser/src/types.rs | Moved module_request field from line 185 to line 203 in StaticExportEntry struct |
| napi/parser/src-js/index.d.ts | Updated TypeScript definition to match Rust struct field ordering |
| crates/oxc_syntax/src/module_record.rs | Added field_order attribute to #[estree] macro to explicitly control serialization order |
| crates/oxc_syntax/src/generated/derive_estree.rs | Regenerated ESTree serializer with moduleRequest field serialized last |
| napi/parser/generated/deserialize/*.js | Updated all 8 deserializer variants to construct objects with moduleRequest property last |
| napi/parser/test/snapshots/esm.test.ts.snap | Updated snapshot expectations to reflect new field ordering in JSON output |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ll` (#16411) Follow-on after #16383 and #16403. While working on those I discovered an option NAPI-RS has to represent `Option::None` as `null`, instead of omitting the field entirely. Use that option on the structs used for transferring errors and module record over to JS. I think this is likely more performant because: 1. NAPI-RS can create all properties of the objects using only the faster `node_api_create_object_with_properties` API. 2. It produces consistent object shapes, so JS engine can better optimize code using these objects. It also brings the shape of the data perfectly into line between standard transfer and raw transfer, and is consistent with how empty fields in the AST are represented as `null`. I would have used this option before if I'd known it existed. ### Breaking change I've marked this as a breaking change because code consuming these objects would now need to check for empty fields with `value === null` instead of `value === undefined`. However in practice, most people probably use `!value` or `value ?? ...`, so it's unlikely to affect many users. This only affects module record and errors anyway, not the AST itself, as we transfer that as JSON, not via NAPI.
…ll` (oxc-project#16411) Follow-on after oxc-project#16383 and oxc-project#16403. While working on those I discovered an option NAPI-RS has to represent `Option::None` as `null`, instead of omitting the field entirely. Use that option on the structs used for transferring errors and module record over to JS. I think this is likely more performant because: 1. NAPI-RS can create all properties of the objects using only the faster `node_api_create_object_with_properties` API. 2. It produces consistent object shapes, so JS engine can better optimize code using these objects. It also brings the shape of the data perfectly into line between standard transfer and raw transfer, and is consistent with how empty fields in the AST are represented as `null`. I would have used this option before if I'd known it existed. ### Breaking change I've marked this as a breaking change because code consuming these objects would now need to check for empty fields with `value === null` instead of `value === undefined`. However in practice, most people probably use `!value` or `value ?? ...`, so it's unlikely to affect many users. This only affects module record and errors anyway, not the AST itself, as we transfer that as JSON, not via NAPI.
…xc-project#16412) Revert the change made in oxc-project#16403. It's no longer necessary after oxc-project#16411, because NAPI-RS no longer re-orders the fields.
### 💥 BREAKING CHANGES - 083fea9 napi/parser: [**BREAKING**] Represent empty optional fields on JS side as `null` (#16411) (overlookmotel) ### 🚀 Features - 7a2afee parser: Add TS1174 error for classes extending multiple base classes (#15993) (sapphi-red) - da87812 semantic: Add TS2309 error for export assignment with other exports (#15992) (sapphi-red) - d6d2bcd minifier: Remove unused function calls that are marked by `manual_pure_functions` (#16534) (sapphi-red) - c90f053 minifier: Support `.` separated values for `compress.treeshake.manualPureFunctions` (#16529) (sapphi-red) - a607cc4 codegen: Preserve comments between CatchClause's param and body (#16167) (copilot-swe-agent) - 8c10694 semantic: Expose get_comment_at method (#16439) (camc314) - 3981e7a ast: Add get_comment_at to lookup a comment by span (#16438) (camc314) ### 🐛 Bug Fixes - 699406a napi/parser: Move `ExportEntry::module_request` field to first (#16412) (overlookmotel) - 12bd794 napi/parser: Move `ExportEntry::module_request` field to last (#16403) (overlookmotel) ### ⚡ Performance - 790beeb napi/parser: Do not remove extraneous options on JS side (#16447) (overlookmotel) Co-authored-by: Boshen <[email protected]>
### 💥 BREAKING CHANGES - 083fea9 napi/parser: [**BREAKING**] Represent empty optional fields on JS side as `null` (#16411) (overlookmotel) ### 🚀 Features - 7a2afee parser: Add TS1174 error for classes extending multiple base classes (#15993) (sapphi-red) - da87812 semantic: Add TS2309 error for export assignment with other exports (#15992) (sapphi-red) - d6d2bcd minifier: Remove unused function calls that are marked by `manual_pure_functions` (#16534) (sapphi-red) - c90f053 minifier: Support `.` separated values for `compress.treeshake.manualPureFunctions` (#16529) (sapphi-red) - a607cc4 codegen: Preserve comments between CatchClause's param and body (#16167) (copilot-swe-agent) - 8c10694 semantic: Expose get_comment_at method (#16439) (camc314) - 3981e7a ast: Add get_comment_at to lookup a comment by span (#16438) (camc314) ### 🐛 Bug Fixes - 699406a napi/parser: Move `ExportEntry::module_request` field to first (#16412) (overlookmotel) - 12bd794 napi/parser: Move `ExportEntry::module_request` field to last (#16403) (overlookmotel) ### ⚡ Performance - 790beeb napi/parser: Do not remove extraneous options on JS side (#16447) (overlookmotel) Co-authored-by: Boshen <[email protected]>
…xc-project#16403) NAPI-RS 3.6.0 makes a change to the ordering of objects. It now puts optional fields last. This made tests in `napi/parser` for module record fail when we tried to update (oxc-project#16383) because the `module_request` field of `ExportEntry` moves to last which breaks the snapshots. The change in NAPI-RS is unlikely to be reverted, because it's a sizeable perf optimization: napi-rs/napi-rs#2990 To work around this problem: 1. Move the field in the `ExportEntry` intermediate struct in `napi/parser` to last, so NAPI's output matches what you'd expect from the struct definition. 2. Alter the `#[estree]` attr on `ExportEntry` struct in `oxc_syntax` crate to match. Note: The `ExportEntry` struct in `napi/parser` is just an intermediate structure used for serialization. So I think it's fine to fiddle with its field order. The actual `ExportEntry` struct used in the module record is in `oxc_syntax` crate, and it remains unaltered.
…ll` (oxc-project#16411) Follow-on after oxc-project#16383 and oxc-project#16403. While working on those I discovered an option NAPI-RS has to represent `Option::None` as `null`, instead of omitting the field entirely. Use that option on the structs used for transferring errors and module record over to JS. I think this is likely more performant because: 1. NAPI-RS can create all properties of the objects using only the faster `node_api_create_object_with_properties` API. 2. It produces consistent object shapes, so JS engine can better optimize code using these objects. It also brings the shape of the data perfectly into line between standard transfer and raw transfer, and is consistent with how empty fields in the AST are represented as `null`. I would have used this option before if I'd known it existed. ### Breaking change I've marked this as a breaking change because code consuming these objects would now need to check for empty fields with `value === null` instead of `value === undefined`. However in practice, most people probably use `!value` or `value ?? ...`, so it's unlikely to affect many users. This only affects module record and errors anyway, not the AST itself, as we transfer that as JSON, not via NAPI.
…xc-project#16412) Revert the change made in oxc-project#16403. It's no longer necessary after oxc-project#16411, because NAPI-RS no longer re-orders the fields.
### 💥 BREAKING CHANGES - 083fea9 napi/parser: [**BREAKING**] Represent empty optional fields on JS side as `null` (oxc-project#16411) (overlookmotel) ### 🚀 Features - 7a2afee parser: Add TS1174 error for classes extending multiple base classes (oxc-project#15993) (sapphi-red) - da87812 semantic: Add TS2309 error for export assignment with other exports (oxc-project#15992) (sapphi-red) - d6d2bcd minifier: Remove unused function calls that are marked by `manual_pure_functions` (oxc-project#16534) (sapphi-red) - c90f053 minifier: Support `.` separated values for `compress.treeshake.manualPureFunctions` (oxc-project#16529) (sapphi-red) - a607cc4 codegen: Preserve comments between CatchClause's param and body (oxc-project#16167) (copilot-swe-agent) - 8c10694 semantic: Expose get_comment_at method (oxc-project#16439) (camc314) - 3981e7a ast: Add get_comment_at to lookup a comment by span (oxc-project#16438) (camc314) ### 🐛 Bug Fixes - 699406a napi/parser: Move `ExportEntry::module_request` field to first (oxc-project#16412) (overlookmotel) - 12bd794 napi/parser: Move `ExportEntry::module_request` field to last (oxc-project#16403) (overlookmotel) ### ⚡ Performance - 790beeb napi/parser: Do not remove extraneous options on JS side (oxc-project#16447) (overlookmotel) Co-authored-by: Boshen <[email protected]>
NAPI-RS 3.6.0 makes a change to the ordering of objects. It now puts optional fields last.
This made tests in
napi/parserfor module record fail when we tried to update (#16383) because themodule_requestfield ofExportEntrymoves to last which breaks the snapshots.The change in NAPI-RS is unlikely to be reverted, because it's a sizeable perf optimization: napi-rs/napi-rs#2990
To work around this problem:
ExportEntryintermediate struct innapi/parserto last, so NAPI's output matches what you'd expect from the struct definition.#[estree]attr onExportEntrystruct inoxc_syntaxcrate to match.Note: The
ExportEntrystruct innapi/parseris just an intermediate structure used for serialization. So I think it's fine to fiddle with its field order. The actualExportEntrystruct used in the module record is inoxc_syntaxcrate, and it remains unaltered.