Skip to content

Conversation

@hoxyq
Copy link
Contributor

@hoxyq hoxyq commented Nov 8, 2023

In order to make Haste work with React's artifacts, It is important to keep headers in this format:

/**
* ...
...
* ...
*/

For optimization purposes, Closure compiler will actually modify these headers by removing * prefixes, which is expected.
We should pass sources to the compiler without license headers, with these changes the current flow will be:

  1. Apply top-level definitions. For UMD-bundles, for example, or DEV-only bundles (e. g. if (__DEV__) { ...)
  2. Apply licence headers for artifacts with sourcemaps: oss-production and oss-profiling bundles, they don't need to preserve the header format to comply with Haste. We need to apply these headers before passing sources to Closure, so it can build correct mappings for sourcemaps.
  3. Pass these sources to closure compiler for minification and sourcemaps building.
  4. Apply licence headers for artifacts without sourcemaps: dev bundles, fb bundles. This way the header style will be preserved and not changed by Closure.

// We were passing sources without license headers to the Closure compiler.
// The reason for it is its optimization for multiline comment:
// it will change the format by removing * prefixes This doesn't work well with Haste.
const preMinifiedBundleSource = Wrappers.wrapWithLicenseHeader(
Copy link
Contributor

Choose a reason for hiding this comment

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

❓ Hmm. I am curious if the sourcemap transforms are still going to be accurate vs the output file contents if we don't include the license contents before the sourcemap gets generated.

This is an area where my own knowledge is very hazy. My coworker @hbenl might have more knowledge here.

My concern is that sending one version of the source file through Closure, and writing a modified file to disk, might cause line numbers to get mismatched when it's used in a debugger (such that it thinks you're paused on line 37 of a file, but that turns out to be a } character or something instead of the actual meaningful line of code).

I'd recommend doing some checks with the artifacts from this PR to see if setting breakpoints and stepping still seems to result in correct lines and variables being handled.

Copy link
Contributor Author

@hoxyq hoxyq Nov 9, 2023

Choose a reason for hiding this comment

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

You are right, mappings will also need to be updated. I will look for other approach here.

Copy link
Contributor Author

@hoxyq hoxyq Nov 9, 2023

Choose a reason for hiding this comment

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

I've ended up with manually updating the header to follow certain format. I couldn't find any annotations for Closure compiler that would allow us to preserve original header-comment format, unfortunately.

I've validated this in my template React-app, here is the demo, where I've replaced react-dom package with the one with sourcemaps:

Screen.Recording.2023-11-09.at.11.06.28.mov

Copy link
Contributor Author

@hoxyq hoxyq Nov 9, 2023

Choose a reason for hiding this comment

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

Alright, I think I found the best option for us:

  1. Artifacts with sourcemaps will get header attached before, so it will effect the sourcemaps and they will be generated correctly.
  2. Artifacts without sourcemaps (facebook-bundles are included in this category) will get header attached after Closure compiler, so they will preserve correct format of the header.

I've validated it the same way as above, sourcemaps work.

@hoxyq hoxyq force-pushed the refactor/preserve-header-format-in-artifacts branch from 9afb325 to b34fb8b Compare November 9, 2023 10:59
@facebook facebook deleted a comment from react-sizebot Nov 9, 2023
@facebook facebook deleted a comment from react-sizebot Nov 9, 2023
@hoxyq hoxyq force-pushed the refactor/preserve-header-format-in-artifacts branch from b34fb8b to 9708b15 Compare November 9, 2023 11:11
@facebook facebook deleted a comment from react-sizebot Nov 9, 2023
@hoxyq hoxyq force-pushed the refactor/preserve-header-format-in-artifacts branch from 9708b15 to a21c5af Compare November 9, 2023 11:51
@react-sizebot
Copy link

Comparing: 52d542a...a21c5af

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.min.js = 175.32 kB 175.32 kB = 54.58 kB 54.58 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js = 177.39 kB 177.39 kB = 55.22 kB 55.22 kB
facebook-www/ReactDOM-prod.classic.js = 567.68 kB 567.70 kB = 99.95 kB 99.96 kB
facebook-www/ReactDOM-prod.modern.js = 551.53 kB 551.56 kB = 97.05 kB 97.06 kB
facebook-www/JSXDEVRuntime-prod.classic.js +4.87% 0.41 kB 0.43 kB +0.67% 0.30 kB 0.30 kB
facebook-www/JSXDEVRuntime-prod.modern.js +4.87% 0.41 kB 0.43 kB +0.67% 0.30 kB 0.30 kB
facebook-www/JSXDEVRuntime-profiling.classic.js +4.87% 0.41 kB 0.43 kB +0.67% 0.30 kB 0.30 kB
facebook-www/JSXDEVRuntime-profiling.modern.js +4.87% 0.41 kB 0.43 kB +0.67% 0.30 kB 0.30 kB
facebook-react-native/react/cjs/JSXDEVRuntime-prod.js +4.85% 0.41 kB 0.43 kB +1.28% 0.31 kB 0.32 kB
facebook-react-native/react/cjs/JSXDEVRuntime-profiling.js +4.85% 0.41 kB 0.43 kB +1.28% 0.31 kB 0.32 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
facebook-www/JSXDEVRuntime-prod.classic.js +4.87% 0.41 kB 0.43 kB +0.67% 0.30 kB 0.30 kB
facebook-www/JSXDEVRuntime-prod.modern.js +4.87% 0.41 kB 0.43 kB +0.67% 0.30 kB 0.30 kB
facebook-www/JSXDEVRuntime-profiling.classic.js +4.87% 0.41 kB 0.43 kB +0.67% 0.30 kB 0.30 kB
facebook-www/JSXDEVRuntime-profiling.modern.js +4.87% 0.41 kB 0.43 kB +0.67% 0.30 kB 0.30 kB
facebook-react-native/react/cjs/JSXDEVRuntime-prod.js +4.85% 0.41 kB 0.43 kB +1.28% 0.31 kB 0.32 kB
facebook-react-native/react/cjs/JSXDEVRuntime-profiling.js +4.85% 0.41 kB 0.43 kB +1.28% 0.31 kB 0.32 kB
facebook-react-native/react/cjs/JSXRuntime-prod.js +1.36% 1.47 kB 1.49 kB +0.69% 0.72 kB 0.73 kB
facebook-react-native/react/cjs/JSXRuntime-profiling.js +1.36% 1.47 kB 1.49 kB +0.69% 0.72 kB 0.73 kB
oss-stable-semver/react-is/umd/react-is.production.min.js +1.12% 2.32 kB 2.35 kB +0.92% 0.87 kB 0.88 kB
oss-stable/react-is/umd/react-is.production.min.js +1.12% 2.32 kB 2.35 kB +0.92% 0.87 kB 0.88 kB
oss-experimental/react-is/umd/react-is.production.min.js +1.10% 2.36 kB 2.39 kB +0.91% 0.88 kB 0.89 kB
oss-stable-semver/react-dom/umd/react-dom-server-rendering-stub.production.min.js +0.72% 3.60 kB 3.63 kB +0.60% 1.33 kB 1.34 kB
oss-stable/react-dom/umd/react-dom-server-rendering-stub.production.min.js +0.72% 3.63 kB 3.66 kB +0.44% 1.35 kB 1.36 kB
oss-experimental/react-dom/umd/react-dom-server-rendering-stub.production.min.js +0.72% 3.64 kB 3.66 kB +0.52% 1.35 kB 1.36 kB
oss-experimental/scheduler/umd/scheduler-unstable_mock.production.min.js +0.53% 4.93 kB 4.95 kB +0.34% 2.06 kB 2.07 kB
oss-stable-semver/scheduler/umd/scheduler-unstable_mock.production.min.js +0.53% 4.93 kB 4.95 kB +0.34% 2.06 kB 2.07 kB
oss-stable/scheduler/umd/scheduler-unstable_mock.production.min.js +0.53% 4.93 kB 4.95 kB +0.34% 2.06 kB 2.07 kB
facebook-www/SchedulerPostTask-prod.classic.js +0.48% 4.14 kB 4.16 kB +0.43% 1.17 kB 1.17 kB
facebook-www/SchedulerPostTask-prod.modern.js +0.48% 4.14 kB 4.16 kB +0.43% 1.17 kB 1.17 kB
facebook-www/SchedulerPostTask-profiling.classic.js +0.48% 4.14 kB 4.16 kB +0.43% 1.17 kB 1.17 kB
facebook-www/SchedulerPostTask-profiling.modern.js +0.48% 4.14 kB 4.16 kB +0.43% 1.17 kB 1.17 kB
facebook-react-native/react-is/cjs/ReactIs-prod.js +0.41% 4.83 kB 4.85 kB +0.59% 1.19 kB 1.20 kB
facebook-react-native/react-is/cjs/ReactIs-profiling.js +0.41% 4.83 kB 4.85 kB +0.59% 1.19 kB 1.20 kB
oss-experimental/react-debug-tools/cjs/react-debug-tools.production.min.js +0.38% 6.81 kB 6.84 kB +0.35% 2.54 kB 2.55 kB
oss-stable-semver/react-debug-tools/cjs/react-debug-tools.production.min.js +0.38% 6.81 kB 6.84 kB +0.35% 2.54 kB 2.55 kB
oss-stable/react-debug-tools/cjs/react-debug-tools.production.min.js +0.38% 6.81 kB 6.84 kB +0.35% 2.54 kB 2.55 kB
facebook-www/ReactIs-prod.classic.js +0.37% 5.34 kB 5.36 kB +0.54% 1.30 kB 1.31 kB
facebook-www/ReactIs-prod.modern.js +0.37% 5.34 kB 5.36 kB +0.54% 1.30 kB 1.31 kB
oss-stable-semver/react/umd/react.profiling.min.js +0.33% 7.81 kB 7.83 kB +0.26% 3.08 kB 3.09 kB
oss-stable-semver/react/umd/react.production.min.js +0.33% 7.81 kB 7.83 kB +0.23% 3.08 kB 3.09 kB
oss-stable/react/umd/react.profiling.min.js +0.33% 7.83 kB 7.86 kB +0.26% 3.11 kB 3.11 kB
oss-stable/react/umd/react.production.min.js +0.33% 7.83 kB 7.86 kB +0.23% 3.10 kB 3.11 kB
oss-experimental/react/umd/react.profiling.min.js +0.28% 9.24 kB 9.26 kB +0.20% 3.54 kB 3.55 kB
oss-experimental/react/umd/react.production.min.js +0.28% 9.24 kB 9.26 kB +0.20% 3.54 kB 3.55 kB
oss-experimental/use-sync-external-store/cjs/use-sync-external-store.production.js +0.24% 0.41 kB 0.41 kB = 0.26 kB 0.26 kB
oss-stable-semver/use-sync-external-store/cjs/use-sync-external-store.production.js +0.24% 0.41 kB 0.41 kB = 0.26 kB 0.26 kB
oss-stable/use-sync-external-store/cjs/use-sync-external-store.production.js +0.24% 0.41 kB 0.41 kB = 0.26 kB 0.26 kB
oss-experimental/react/cjs/react-jsx-dev-runtime.profiling.js +0.23% 0.43 kB 0.43 kB +0.34% 0.30 kB 0.30 kB
oss-stable-semver/react/cjs/react-jsx-dev-runtime.profiling.js +0.23% 0.43 kB 0.43 kB +0.34% 0.30 kB 0.30 kB
oss-stable/react/cjs/react-jsx-dev-runtime.profiling.js +0.23% 0.43 kB 0.43 kB +0.34% 0.30 kB 0.30 kB
oss-experimental/react/cjs/react-jsx-dev-runtime.production.js +0.23% 0.43 kB 0.43 kB = 0.30 kB 0.30 kB
oss-stable-semver/react/cjs/react-jsx-dev-runtime.production.js +0.23% 0.43 kB 0.43 kB = 0.30 kB 0.30 kB
oss-stable/react/cjs/react-jsx-dev-runtime.production.js +0.23% 0.43 kB 0.43 kB = 0.30 kB 0.30 kB
oss-stable-semver/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.production.min.js +0.22% 11.63 kB 11.65 kB +0.18% 4.41 kB 4.42 kB
oss-stable/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.production.min.js +0.22% 11.63 kB 11.65 kB +0.18% 4.41 kB 4.42 kB
oss-stable-semver/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.production.min.js +0.22% 11.75 kB 11.78 kB +0.16% 4.45 kB 4.45 kB
oss-stable/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.production.min.js +0.22% 11.75 kB 11.78 kB +0.16% 4.45 kB 4.45 kB
oss-experimental/react-dom/umd/react-dom-test-utils.production.min.js +0.20% 12.75 kB 12.78 kB +0.14% 4.90 kB 4.91 kB
oss-stable-semver/react-dom/umd/react-dom-test-utils.production.min.js +0.20% 12.75 kB 12.78 kB +0.14% 4.90 kB 4.91 kB
oss-stable/react-dom/umd/react-dom-test-utils.production.min.js +0.20% 12.75 kB 12.78 kB +0.14% 4.90 kB 4.91 kB
oss-experimental/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.production.min.js +0.20% 12.93 kB 12.96 kB +0.15% 4.77 kB 4.78 kB

Generated by 🚫 dangerJS against a21c5af

@hoxyq
Copy link
Contributor Author

hoxyq commented Nov 9, 2023

By looking at the https://react-builds.vercel.app/commits/a21c5afe9675a731b65183d3e8b0f19aa5201aa3/files/facebook-www, I can validate that production and profiling FB-bundles now preserve header style.

Copy link
Member

@kassens kassens left a comment

Choose a reason for hiding this comment

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

The complexity of this build script is a bit annoying, but that's just a side note.

Looks good to me!

@hoxyq hoxyq merged commit c47c306 into facebook:main Nov 9, 2023
@hoxyq hoxyq deleted the refactor/preserve-header-format-in-artifacts branch November 9, 2023 16:00
github-actions bot pushed a commit that referenced this pull request Nov 9, 2023
In order to make Haste work with React's artifacts, It is important to
keep headers in this format:
```
/**
* ...
...
* ...
*/
```

For optimization purposes, Closure compiler will actually modify these
headers by removing * prefixes, which is expected.
We should pass sources to the compiler without license headers, with
these changes the current flow will be:
1. Apply top-level definitions. For UMD-bundles, for example, or
DEV-only bundles (e. g. `if (__DEV__) { ...`)
2. Apply licence headers for artifacts with sourcemaps: oss-production
and oss-profiling bundles, they don't need to preserve the header format
to comply with Haste. We need to apply these headers before passing
sources to Closure, so it can build correct mappings for sourcemaps.
3. Pass these sources to closure compiler for minification and
sourcemaps building.
4. Apply licence headers for artifacts without sourcemaps: dev bundles,
fb bundles. This way the header style will be preserved and not changed
by Closure.

DiffTrain build for [c47c306](c47c306)
kodiakhq bot pushed a commit to vercel/next.js that referenced this pull request Nov 10, 2023
EdisonVan pushed a commit to EdisonVan/react that referenced this pull request Apr 15, 2024
In order to make Haste work with React's artifacts, It is important to
keep headers in this format:
```
/**
* ...
...
* ...
*/
```

For optimization purposes, Closure compiler will actually modify these
headers by removing * prefixes, which is expected.
We should pass sources to the compiler without license headers, with
these changes the current flow will be:
1. Apply top-level definitions. For UMD-bundles, for example, or
DEV-only bundles (e. g. `if (__DEV__) { ...`)
2. Apply licence headers for artifacts with sourcemaps: oss-production
and oss-profiling bundles, they don't need to preserve the header format
to comply with Haste. We need to apply these headers before passing
sources to Closure, so it can build correct mappings for sourcemaps.
3. Pass these sources to closure compiler for minification and
sourcemaps building.
4. Apply licence headers for artifacts without sourcemaps: dev bundles,
fb bundles. This way the header style will be preserved and not changed
by Closure.
bigfootjon pushed a commit that referenced this pull request Apr 18, 2024
In order to make Haste work with React's artifacts, It is important to
keep headers in this format:
```
/**
* ...
...
* ...
*/
```

For optimization purposes, Closure compiler will actually modify these
headers by removing * prefixes, which is expected.
We should pass sources to the compiler without license headers, with
these changes the current flow will be:
1. Apply top-level definitions. For UMD-bundles, for example, or
DEV-only bundles (e. g. `if (__DEV__) { ...`)
2. Apply licence headers for artifacts with sourcemaps: oss-production
and oss-profiling bundles, they don't need to preserve the header format
to comply with Haste. We need to apply these headers before passing
sources to Closure, so it can build correct mappings for sourcemaps.
3. Pass these sources to closure compiler for minification and
sourcemaps building.
4. Apply licence headers for artifacts without sourcemaps: dev bundles,
fb bundles. This way the header style will be preserved and not changed
by Closure.

DiffTrain build for commit c47c306.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants