Skip to content

fix(bundler-plugins): Preserve directive prologues during bundle injection - #24221

Open
Andarist wants to merge 10 commits into
getsentry:developfrom
Andarist:feat/strict-mode-injection-tests
Open

fix(bundler-plugins): Preserve directive prologues during bundle injection#24221
Andarist wants to merge 10 commits into
getsentry:developfrom
Andarist:feat/strict-mode-injection-tests

Conversation

@Andarist

@Andarist Andarist commented Sep 9, 2026

Copy link
Copy Markdown

Bundler plugins inject Sentry code into generated bundles. In some outputs the injection could be placed before directive prologues such as "use strict", causing JavaScript to stop recognizing them as directives.

I found this issue to affect some production cases - I don't have access to their sources so I can't fully say how the original code was authored and what exactly made it lose the strict mode, but the generated output looked like this:

try{!function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?
  globalThis:"undefined"!=typeof self?self:{},t=(new e.Error).stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="612bd636-5fcc-473a-bdd0-20460245872c",e._sentryDebugIdIdentifier="sentry-dbid-612bd636-5fcc-473a-bdd0-
  20460245872c")}()}catch(e){}"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[120],{67232:function(e,t,n){var r,l=n(41498),a=n(90413),o={usingClientEntryPoint:!1,Events:null,Dispatcher:{current:null}};function i(e){var
  t="https://react.dev/errors/"+e;if(1<arguments.length){t+="?args[]="+encodeURIComponent(arguments[1]);

Given the sentry code was injected before the strict mode directive, that changed the meaning of arguments[1] at this position in the app code:

function aW(e, t) {
  if (null !== (t = null !== (t = t.updateQueue) ? t.lastEffect : null)) {
    var n = (t = t.next);
    do {
      if ((n.tag & e) === e) {
        var r = n.create,
          l = n.inst;
        /* arguments[1] no longer refer to the original argument */
        r = r();

        l.destroy = r;
      }
      n = n.next;
    } while (n !== t);
  }
}

That's because in the sloppy mode the assignment to t before the arguments[1] reference changes the arguments content too 🫠 . You can test it out using this isolated sample:

function test(foo) {
  foo = 2;
  console.log(arguments[0]); // 2
}

test(1);

function testStrict(foo) {
  "use strict";
  foo = 2;
  console.log(arguments[0]); // 1
}

testStrict(1);

This PR:

  • adds a bunch of tests for edge cases and for source mapping behavior (the latter was already working OK but didn't quite have the coverage)
  • replaces simple regex with a more spec-compliant tiny scanner so the proper injection point can be found
  • in Webpack BannePlugin can only prepend/append text, as far as I know, it can't just inject into an arbitrary position. So it was replaced with a compilation hook and ReplaceSource plugin. That allows for a fine-grained control at the asset level
  • in the case of Rollup, this PR only slightly changes the insertion point calculation - but it doesn't replace the overall mechanism/hooks used
  • esbuild has not required any fixes because inject API handles this for us

AI disclosure: I have steered it a bunch myself and I understand each line of code added. I ensured (using my own judgement) that all of this matches the project's style and goal but ofc I have much less context on that than the maintainers here. That said, I can address any PR feedback thrown my way.

Andarist and others added 5 commits September 9, 2026 08:59
Co-Authored-By: OpenAI Codex <codex@openai.com>
…ction

Co-Authored-By: OpenAI Codex <codex@openai.com>
Co-Authored-By: OpenAI Codex <codex@openai.com>
Co-Authored-By: OpenAI Codex <codex@openai.com>
Co-Authored-By: OpenAI Codex <codex@openai.com>
@chargome
chargome requested review from chargome and timfish September 9, 2026 08:20

@timfish timfish left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Seems sensible to me!

Andarist and others added 2 commits September 9, 2026 15:34
Co-Authored-By: OpenAI Codex <codex@openai.com>
Co-Authored-By: OpenAI Codex <codex@openai.com>
@Andarist

Andarist commented Sep 9, 2026

Copy link
Copy Markdown
Author

@timfish could u re-approve the CI run? I fixed the test failures (hopefully the last ones). I'd test it out properly locally... but I'm facing a stupid issue of this project having such a big dep graph that I'm currently running out of disk space 🫠 I need to clean it up but didn't have time for that right now. FWIW, I was totally testing this... but through proxy isolated pnpm-based projects. So I, from the start, tested he behavioral changes of this PR - but then I faced some outdated snapshots here 😢

Andarist and others added 3 commits September 9, 2026 21:58
Co-Authored-By: OpenAI Codex <codex@openai.com>
Co-Authored-By: OpenAI Codex <codex@openai.com>
Co-Authored-By: OpenAI Codex <codex@openai.com>
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.

2 participants