fix(browser): the published bundle parses on webpack 4 - #867
Conversation
`dist` shipped untranspiled optional chaining, nullish coalescing (ES2020) and logical assignment (ES2021). react-scripts 4 excludes node_modules from Babel, so webpack reads our output as-is with acorn and all three are parse errors — the app fails to compile at dist/index.js before a dev session could ever connect, with NO diagnostic, because it simply does not build. `init` already printed a transpilation recipe on `react-scripts@<5`. That was the weaker of the two fixes the report offered, and the report's own argument for the other one stands: an install path that requires editing your bundler config to run our dev-only SDK is one most people abandon. `target: ES2019` for this package only, deliberately below the repo's ES2022 base. This is the one package whose build output is parsed by somebody else's bundler, and ES2019 is the last target before all three operators. `lib` stays high: this downlevels SYNTAX, and the runtime is a modern browser either way. Costs 2.6% of bundle size, 5600 KB -> 5744 KB, measured clean on both sides — my first measurement said 48x smaller, which was a half-finished build, not a result. Three test files used BigInt LITERALS (`2n`), which ES2019 cannot express. `BigInt(2)` is the same value with no syntax requirement, so the tests keep testing BigInt and the package keeps building. The guard PARSES rather than greps, and that is the design. Its first version matched operators with regexes and produced two false failures on a dist that was already correct: the hits were in COMMENTS, one of them a comment quoting the very `form?.textContent` a previous fix had removed. A regex cannot tell code from prose about code. acorn is what webpack 4 uses, so the check fails exactly where a user's build would and nowhere else. It scans every emitted module, not the entry -- the entry is a 3 KB barrel and was clean while 52 siblings were not -- and carries a negative control, because a parser check that cannot fail proves nothing. Closes #680 Signed-off-by: Divyanshu Shekhar <imdshekhar@gmail.com>
|
Closing this as a duplicate of #745, which is better, and I should have found it before writing a line. #745 has been open since 3 September, fully green — including both install gates and the 28-minute Windows one — waiting on a review. I searched the issue for claims and went straight to building; its title says "webpack 4" and never mentions the issue number, so my grep missed it. That is my process failing, not theirs. It is also materially more correct than this branch. Three things it does that this one does not:
We independently converged on parsing at ES2019 as the real webpack-4 ceiling rather than grepping for operators, which is at least a good sign about the check. Nothing here is worth salvaging on top of theirs. |
Pull request was closed
Closes #680, on the option the report argued for.
What shipped before, and why it was the weaker half
initalready prints a transpilation recipe when it detectsreact-scripts@<5. That was option 2 of the report. Option 1 — publish a build their bundler can read — is the one it argued for, and I agree with the argument: "an install path that requires the user to edit their bundler config to run our dev-only SDK is an install path most people abandon."distshipped untranspiled optional chaining, nullish coalescing (ES2020) and logical assignment (ES2021). react-scripts 4 excludesnode_modulesfrom Babel, so webpack parses our output as-is with acorn and all three are parse errors. The app fails to compile atdist/index.jsbefore a dev session could ever connect, with no diagnostic, because it simply does not build.The change
target: ES2019inpackages/browser/tsconfig.jsononly — deliberately below the repo'sES2022base, because this is the one package whose build output another project's bundler parses. ES2019 is the last target before all three operators.libstays at ES2023: this downlevels syntax, and the runtime is a modern browser either way.Cost: 2.6% of bundle size, 5600 KB → 5744 KB, measured from a clean build on both sides. (My first measurement said 48x smaller, which was a half-finished build rather than a result — flagging it because the number was nonsense and I nearly reported it.)
Three test files used BigInt literals (
2n), which ES2019 cannot express.BigInt(2)is the same value with no syntax requirement, so those tests keep testing BigInt and the package keeps building.The guard parses rather than greps
Its first version matched operators with regexes and produced two false failures on a
distthat was already correct — both hits were inside comments, one of them a comment quoting the veryform?.textContentan earlier fix had removed. A regex cannot tell code from prose about code.dist-parses-on-webpack4.test.tsnow runs acorn atecmaVersion: 2019— the same parser webpack 4 uses — so it fails exactly where a user's build would and nowhere else. It also:dist/index.jsis a 3 KB barrel that was clean while 52 siblings were not;a?.b,a ?? banda ??= b, because a check that cannot fail proves nothing;dist.acornis added as a devDependency of this package. It was already in the tree transitively; this makes it resolvable rather than adding anything new.Gates
pnpm format:check,pnpm lint17/17,pnpm typecheck22/22,pnpm test:unit(140 browser files, 669 server)pnpm test:e2e— 36/36 + soakpnpm test:integration— 12/12 (the example apps consume this bundle, so this is the tier that matters here)