Skip to content

refactor: switch to oxc-parser.#47

Merged
morganney merged 1 commit intomainfrom
develop
Feb 7, 2026
Merged

refactor: switch to oxc-parser.#47
morganney merged 1 commit intomainfrom
develop

Conversation

@morganney
Copy link
Owner

No description provided.

Copilot AI review requested due to automatic review settings February 7, 2026 21:23
@codecov
Copy link

codecov bot commented Feb 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (a71b9ad) to head (9876859).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main       #47    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            5         6     +1     
  Lines           77       301   +224     
  Branches        20        63    +43     
==========================================
+ Hits            77       301   +224     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@morganney morganney merged commit 9a891bd into main Feb 7, 2026
7 checks passed
@morganney morganney deleted the develop branch February 7, 2026 21:25
Copy link

Copilot AI left a 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 refactors the loader’s parser integration by replacing the Acorn-based parsing/walking stack with oxc-parser, and updates tests/tooling to validate behavior across bundlers (Webpack + Rspack).

Changes:

  • Replace Acorn + acorn-walk JSX setup with oxc-parser and a custom AST walk to find ImportExpression nodes and block comments.
  • Update Jest/spec setup (coverage provider, test matching) and add a Rspack-driven integration test run of the existing loader spec suite.
  • Update dependencies (remove Acorn stack, add oxc-parser, add @rspack/core) and bump package version to 3.0.0.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/parser.js Switch parsing to oxc-parser; add node normalization + custom walker; adjust returned AST shape.
package.json Remove Acorn deps; add oxc-parser; add @rspack/core; adjust scripts; version to 3.0.0.
package-lock.json Lockfile updates for removed/added deps.
jest.config.spec.js Switch coverage provider to v8; expand testMatch.
tests/parser.js Update tests to ESM-mock oxc-parser and add coverage for new parser behavior.
tests/loader.spec.js Allow running the suite against a configurable bundler (Webpack/Rspack).
tests/loader.rspack.spec.js Add Rspack wrapper that runs the loader spec suite under Rspack.
README.md Document Rspack compatibility and update parser link/reference.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +8 to +22
if (typeof node.start !== 'number') {
const span = node.span
if (span && typeof span.start === 'number') {
node.start = span.start
}
}

if (typeof node.end !== 'number') {
const span = node.span
if (span && typeof span.end === 'number') {
node.end = span.end
}
}

return node
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

normalizeNode mutates the AST nodes returned by oxc-parser by assigning start/end onto the original objects. This makes the parser output impure and can create surprising side effects if other code (or future changes) relies on the original shape or immutability of the AST. Prefer returning a shallow normalized copy (or storing normalized {start,end} separately) rather than modifying the parser’s objects in-place.

Suggested change
if (typeof node.start !== 'number') {
const span = node.span
if (span && typeof span.start === 'number') {
node.start = span.start
}
}
if (typeof node.end !== 'number') {
const span = node.span
if (span && typeof span.end === 'number') {
node.end = span.end
}
}
return node
let start = node.start
let end = node.end
let needsCopy = false
const span = node.span
if (typeof start !== 'number' && span && typeof span.start === 'number') {
start = span.start
needsCopy = true
}
if (typeof end !== 'number' && span && typeof span.end === 'number') {
end = span.end
needsCopy = true
}
if (!needsCopy) {
return node
}
return {
...node,
start,
end
}

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +51
visit(node)

for (const value of Object.values(node)) {
if (!value) {
continue
}

if (Array.isArray(value)) {
for (const entry of value) {
if (isNodeLike(entry)) {
walk(entry, visit)
}
}
continue
}

if (isNodeLike(value)) {
walk(value, visit)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom walk implementation allocates a new array for every node via Object.values(node) and recursively visits every enumerable property. This is significantly more expensive than a keyed AST walk and may become a bottleneck on large source files. Consider switching to an iterative walk (explicit stack) and avoiding Object.values allocations, or using an oxc-provided traversal utility if available.

Suggested change
visit(node)
for (const value of Object.values(node)) {
if (!value) {
continue
}
if (Array.isArray(value)) {
for (const entry of value) {
if (isNodeLike(entry)) {
walk(entry, visit)
}
}
continue
}
if (isNodeLike(value)) {
walk(value, visit)
const stack = [node]
while (stack.length > 0) {
const current = stack.pop()
if (!isNodeLike(current)) {
continue
}
visit(current)
for (const key in current) {
const value = current[key]
if (!value) {
continue
}
if (Array.isArray(value)) {
for (let i = value.length - 1; i >= 0; i--) {
const entry = value[i]
if (isNodeLike(entry)) {
stack.push(entry)
}
}
continue
}
if (isNodeLike(value)) {
stack.push(value)
}

Copilot uses AI. Check for mistakes.
*/
runner: 'jest-light-runner',
testMatch: ['**/__tests__/**/*.spec.js'],
testMatch: ['**/__tests__/**/*.spec.js', '**/__tests__/parser.js'],
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jest.config.spec.js now matches __tests__/parser.js, but that file is already included in the unit test suite (jest.config.js matches all non-*.spec.js tests). Since npm test runs both test:unit and test:spec, this causes the parser test suite to execute twice. Consider either renaming it to parser.spec.js (and excluding it from unit tests) or removing it from the spec testMatch.

Suggested change
testMatch: ['**/__tests__/**/*.spec.js', '**/__tests__/parser.js'],
testMatch: ['**/__tests__/**/*.spec.js'],

Copilot uses AI. Check for mistakes.

describe('parse', () => {
it('parses 2023 ecmascript and jsx while tracking block comments', () => {
it('parses 2023 ecmascript and jsx while tracking block comments', async () => {
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test name says it "parses 2023 ecmascript", but src/parser.js no longer pins an ECMA version (it relies on oxc-parser defaults). Consider updating the test description to avoid implying a fixed ECMA version, or explicitly configuring the parser to the intended target.

Suggested change
it('parses 2023 ecmascript and jsx while tracking block comments', async () => {
it('parses modern ecmascript and jsx while tracking block comments', async () => {

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant