Repository navigation
Fix #2: strip debugger statements - #8
Conversation
Implement debugger statement removal for the strip plugin behind the `debugger` option so production builds can drop explicit debugger lines without affecting default behavior.
| transform(code: string, _id: string) { | ||
| return { code, map: null }; | ||
| if (!options.debugger) { | ||
| return { code, map: null }; |
There was a problem hiding this comment.
what is up with all of the map: null stuff? are we going to give actual values later? what does the map prop do?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
is the mapping update listed in the issues or should we add them now?
There was a problem hiding this comment.
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.
| name: "rolldown-plugin-strip", | ||
| apply: "build", | ||
| enforce: "pre", | ||
| transform(code: string, _id: string) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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).
Summary
debuggerstatement lines whenstrip({ debugger: true })is enabled.debuggerdisabled remains a no-op for this part).Issues
How to test
npm run checknpm run buildNotes
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.tsintransform()appliesstripDebuggerStatements()only whenoptions.debuggeris enabled.Why it was the right call here
The alternative is leaving
debuggerstatements 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".