Skip to content

Fix #2: strip debugger statements - #8

Merged
sam-parsons merged 1 commit into
mainfrom
feature/2-strip-debugger-statements
Apr 25, 2026
Merged

sam-parsons merged 1 commit into
mainfrom
feature/2-strip-debugger-statements

Conversation

@sam-parsons

@sam-parsons sam-parsons commented Apr 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Added debugger stripping logic that removes standalone debugger statement lines when strip({ debugger: true }) is enabled.
  • Kept default behavior unchanged (debugger disabled remains a no-op for this part).
  • Added focused tests for both disabled and enabled debugger behavior.

Issues

How to test

  • npm run check
  • npm run build

Notes


Learning notes

Build-time code elimination as a boundary decision

What it is
Build-time elimination removes code before runtime executes, rather than guarding that code with runtime conditions. The plugin becomes a boundary where we decide what behavior can never ship to production artifacts.

Where it appears in this PR
src/index.ts in transform() applies stripDebuggerStatements() only when options.debugger is enabled.

Why it was the right call here
The alternative is leaving debugger statements in source and relying on runtime discipline (or minifier side effects) to avoid shipping them. Centralizing this in the plugin gives deterministic output and a testable contract for production builds. The tradeoff is reduced flexibility because removal is global for matched patterns, but for debugger statements that is usually desirable and predictable.

If you want to go deeper
Search: "build-time vs runtime policy enforcement" and "compiler passes for dead/debug code elimination".

Implement debugger statement removal for the strip plugin behind the `debugger` option so production builds can drop explicit debugger lines without affecting default behavior.
Comment thread src/index.ts
transform(code: string, _id: string) {
return { code, map: null };
if (!options.debugger) {
return { code, map: null };

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

what is up with all of the map: null stuff? are we going to give actual values later? what does the map prop do?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Great question. is the source map payload for transformed code so downstream tooling (stack traces, devtools, further transforms) can map output positions back to original source. Right now this scaffold returns because we are doing simple string replacement without map generation yet; it is valid, but less debuggable. Yes, we should plan to return real maps once we switch to a proper source-editing approach (e.g., MagicString) in a follow-up issue so transform accuracy is preserved.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Correction to my previous reply: map means the source-map payload for transformed code, and map: null means this transform currently does not emit source maps. That is valid for now, but we should switch to emitting real maps in a follow-up when we adopt a source-editing utility like MagicString.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

is the mapping update listed in the issues or should we add them now?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Good call. It was not explicitly tracked in the original issue list, so I opened a dedicated follow-up: #9 (Emit source maps for transformed output). We can keep #2 scoped to debugger stripping behavior, and implement map emission in #9 with MagicString-based transforms so the contract is explicit and testable.

Comment thread src/index.ts
name: "rolldown-plugin-strip",
apply: "build",
enforce: "pre",
transform(code: string, _id: string) {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

how does this all work? the sample app will import the strip plugin, and when the rolldown build gets executed, is there a "transform" phase that every plugin registered with a transform method gets its code executed?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Yes, exactly. The sample app imports the plugin and registers it in Rolldown config. During build, Rolldown runs its plugin pipeline; for each loaded module, transform hooks are invoked in order (respecting enforce phase) and each hook can return modified code. In our plugin, transform receives module code and id, strips configured patterns, and returns updated code (plus source map when we add map generation).

@sam-parsons
sam-parsons merged commit 5cbce53 into main Apr 25, 2026
1 check passed
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.

Issue B: Strip debugger statements

1 participant