-
Notifications
You must be signed in to change notification settings - Fork 47.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Run Closure on non-minified prod builds, too #28827
Run Closure on non-minified prod builds, too #28827
Conversation
What could be important:
|
The headers are still there, I added them post-Closure |
Failing tests should be fixed after rebase on master now that #28593 landed. |
Nice! |
604dea8
to
cd1f695
Compare
Why don't we let Closure generate the source maps and just conditionally enable the renaming there? Alternatively, do we even need the renaming? Wouldn't that typically happen anyway as a minification step in product bundling (in various build systems?) Since the build is already pretty complicated and slow it'd be nice to avoid adding more steps… |
FYI sizebot failed because the summary is too large: https://app.circleci.com/pipelines/github/facebook/react/52317/workflows/cfa1d5b9-b4cb-40d1-89db-f06f98f94c85/jobs/838157 Summary for this PR can be seen in https://output.circle-artifacts.com/output/job/17d7076d-4cf5-4552-acc0-63e9a29ef9c4/artifacts/0/sizebot-message.md In #28845, we'll fallback to a link to CI with the full report. |
That is indeed what I want to do, this first PR is meant to demonstrate that Closure + a later mangling step (via Terser in this case, since that's what much of the OSS community uses) is equivalent to Closure with mangling enabled. |
Regarding this, though:
That's how it works in main already, but the problem is that the source maps map to a pre-Closure "source", which means it doesn't have as much inlining and dead code elimination applied to it. If we are going to ship source maps (which again I'd prefer not to) then it should map to something like the Meta production builds — identical program structure, just without mangled names. |
In facebook#26446 we started publishing non-minified versions of our production build artifacts, along with source maps, for easier debugging of React when running in production mode. The way it's currently set up is that these builds are generated *before* Closure compiler has run. Which means it's missing many of the optimizations that are in the final build, like dead code elimination. This PR changes the build process to run Closure on the non-minified production builds, too, by moving the sourcemap generation to later in the pipeline. The non-minified builds will still preserve the original symbol names, and we'll use Prettier to add back whitespace. This is the exact same approach we've been using for years to generate production builds for Meta. The idea is that the only difference between the minified and non- minified builds is whitespace and symbol mangling. The semantic structure of the program should be identical. To implement this, I disabled symbol mangling when running Closure compiler. Then, in a later step, the symbols are mangled by Terser. This is when the source maps are generated.
cd1f695
to
44ca36d
Compare
The size diff is too large to display in a single comment. The CircleCI job contains an artifact called 'sizebot-message.md' with the full message. |
In #26446 we started publishing non-minified versions of our production build artifacts, along with source maps, for easier debugging of React when running in production mode. The way it's currently set up is that these builds are generated *before* Closure compiler has run. Which means it's missing many of the optimizations that are in the final build, like dead code elimination. This PR changes the build process to run Closure on the non-minified production builds, too, by moving the sourcemap generation to later in the pipeline. The non-minified builds will still preserve the original symbol names, and we'll use Prettier to add back whitespace. This is the exact same approach we've been using for years to generate production builds for Meta. The idea is that the only difference between the minified and non- minified builds is whitespace and symbol mangling. The semantic structure of the program should be identical. To implement this, I disabled symbol mangling when running Closure compiler. Then, in a later step, the symbols are mangled by Terser. This is when the source maps are generated. DiffTrain build for commit 0e0b693.
In #26446 we started publishing non-minified versions of our production build artifacts, along with source maps, for easier debugging of React when running in production mode. The way it's currently set up is that these builds are generated *before* Closure compiler has run. Which means it's missing many of the optimizations that are in the final build, like dead code elimination. This PR changes the build process to run Closure on the non-minified production builds, too, by moving the sourcemap generation to later in the pipeline. The non-minified builds will still preserve the original symbol names, and we'll use Prettier to add back whitespace. This is the exact same approach we've been using for years to generate production builds for Meta. The idea is that the only difference between the minified and non- minified builds is whitespace and symbol mangling. The semantic structure of the program should be identical. To implement this, I disabled symbol mangling when running Closure compiler. Then, in a later step, the symbols are mangled by Terser. This is when the source maps are generated. DiffTrain build for [0e0b693](0e0b693)
This disables symbol renaming in production builds. The original variable and function names are preserved. All other forms of compression applied by Closure (dead code elimination, inlining, etc) are unchanged — the final program is identical to what we were producing before, just in a more readable form. The motivation is to make it easier to debug React issues that only occur in production — the same reason we decided to start shipping sourcemaps in facebook#28827 and facebook#28827. However, because most apps run their own minification step on their npm dependencies, it's not necessary for us to minify the symbols before publishing — it'll be handled the app, if desired. This is the same strategy Meta has used to ship React for years. The React build itself has unminified symbols, but they get minified as part of Meta's regular build pipeline. Even if an app does not minify their npm dependencies, gzip covers most of the cost of symbol renaming anyway. This saves us from having to ship sourcemaps, which means even apps that don't have sourcemaps configured will be able to debug the React build as easily as they would any other npm dependency.
This disables symbol renaming in production builds. The original variable and function names are preserved. All other forms of compression applied by Closure (dead code elimination, inlining, etc) are unchanged — the final program is identical to what we were producing before, just in a more readable form. The motivation is to make it easier to debug React issues that only occur in production — the same reason we decided to start shipping sourcemaps in facebook#28827 and facebook#28827. However, because most apps run their own minification step on their npm dependencies, it's not necessary for us to minify the symbols before publishing — it'll be handled the app, if desired. This is the same strategy Meta has used to ship React for years. The React build itself has unminified symbols, but they get minified as part of Meta's regular build pipeline. Even if an app does not minify their npm dependencies, gzip covers most of the cost of symbol renaming anyway. This saves us from having to ship sourcemaps, which means even apps that don't have sourcemaps configured will be able to debug the React build as easily as they would any other npm dependency.
This disables symbol renaming in production builds. The original variable and function names are preserved. All other forms of compression applied by Closure (dead code elimination, inlining, etc) are unchanged — the final program is identical to what we were producing before, just in a more readable form. The motivation is to make it easier to debug React issues that only occur in production — the same reason we decided to start shipping sourcemaps in facebook#28827 and facebook#28827. However, because most apps run their own minification step on their npm dependencies, it's not necessary for us to minify the symbols before publishing — it'll be handled the app, if desired. This is the same strategy Meta has used to ship React for years. The React build itself has unminified symbols, but they get minified as part of Meta's regular build pipeline. Even if an app does not minify their npm dependencies, gzip covers most of the cost of symbol renaming anyway. This saves us from having to ship sourcemaps, which means even apps that don't have sourcemaps configured will be able to debug the React build as easily as they would any other npm dependency.
This disables symbol renaming in production builds. The original variable and function names are preserved. All other forms of compression applied by Closure (dead code elimination, inlining, etc) are unchanged — the final program is identical to what we were producing before, just in a more readable form. The motivation is to make it easier to debug React issues that only occur in production — the same reason we decided to start shipping sourcemaps in facebook#28827 and facebook#28827. However, because most apps run their own minification step on their npm dependencies, it's not necessary for us to minify the symbols before publishing — it'll be handled the app, if desired. This is the same strategy Meta has used to ship React for years. The React build itself has unminified symbols, but they get minified as part of Meta's regular build pipeline. Even if an app does not minify their npm dependencies, gzip covers most of the cost of symbol renaming anyway. This saves us from having to ship sourcemaps, which means even apps that don't have sourcemaps configured will be able to debug the React build as easily as they would any other npm dependency.
This disables symbol renaming in production builds. The original variable and function names are preserved. All other forms of compression applied by Closure (dead code elimination, inlining, etc) are unchanged — the final program is identical to what we were producing before, just in a more readable form. The motivation is to make it easier to debug React issues that only occur in production — the same reason we decided to start shipping sourcemaps in facebook#28827 and facebook#28827. However, because most apps run their own minification step on their npm dependencies, it's not necessary for us to minify the symbols before publishing — it'll be handled the app, if desired. This is the same strategy Meta has used to ship React for years. The React build itself has unminified symbols, but they get minified as part of Meta's regular build pipeline. Even if an app does not minify their npm dependencies, gzip covers most of the cost of symbol renaming anyway. This saves us from having to ship sourcemaps, which means even apps that don't have sourcemaps configured will be able to debug the React build as easily as they would any other npm dependency.
This disables symbol renaming in production builds. The original variable and function names are preserved. All other forms of compression applied by Closure (dead code elimination, inlining, etc) are unchanged — the final program is identical to what we were producing before, just in a more readable form. The motivation is to make it easier to debug React issues that only occur in production — the same reason we decided to start shipping sourcemaps in #28827 and #28827. However, because most apps run their own minification step on their npm dependencies, it's not necessary for us to minify the symbols before publishing — it'll be handled the app, if desired. This is the same strategy Meta has used to ship React for years. The React build itself has unminified symbols, but they get minified as part of Meta's regular build pipeline. Even if an app does not minify their npm dependencies, gzip covers most of the cost of symbol renaming anyway. This saves us from having to ship sourcemaps, which means even apps that don't have sourcemaps configured will be able to debug the React build as easily as they would any other npm dependency.
This disables symbol renaming in production builds. The original variable and function names are preserved. All other forms of compression applied by Closure (dead code elimination, inlining, etc) are unchanged — the final program is identical to what we were producing before, just in a more readable form. The motivation is to make it easier to debug React issues that only occur in production — the same reason we decided to start shipping sourcemaps in #28827 and #28827. However, because most apps run their own minification step on their npm dependencies, it's not necessary for us to minify the symbols before publishing — it'll be handled the app, if desired. This is the same strategy Meta has used to ship React for years. The React build itself has unminified symbols, but they get minified as part of Meta's regular build pipeline. Even if an app does not minify their npm dependencies, gzip covers most of the cost of symbol renaming anyway. This saves us from having to ship sourcemaps, which means even apps that don't have sourcemaps configured will be able to debug the React build as easily as they would any other npm dependency. DiffTrain build for [857ee8c](857ee8c)
In #26446 we started publishing non-minified versions of our production build artifacts, along with source maps, for easier debugging of React when running in production mode. The way it's currently set up is that these builds are generated *before* Closure compiler has run. Which means it's missing many of the optimizations that are in the final build, like dead code elimination. This PR changes the build process to run Closure on the non-minified production builds, too, by moving the sourcemap generation to later in the pipeline. The non-minified builds will still preserve the original symbol names, and we'll use Prettier to add back whitespace. This is the exact same approach we've been using for years to generate production builds for Meta. The idea is that the only difference between the minified and non- minified builds is whitespace and symbol mangling. The semantic structure of the program should be identical. To implement this, I disabled symbol mangling when running Closure compiler. Then, in a later step, the symbols are mangled by Terser. This is when the source maps are generated. DiffTrain build for commit 0e0b693.
In #26446 we started publishing non-minified versions of our production build artifacts, along with source maps, for easier debugging of React when running in production mode.
The way it's currently set up is that these builds are generated before Closure compiler has run. Which means it's missing many of the optimizations that are in the final build, like dead code elimination.
This PR changes the build process to run Closure on the non-minified production builds, too, by moving the sourcemap generation to later in the pipeline.
The non-minified builds will still preserve the original symbol names, and we'll use Prettier to add back whitespace. This is the exact same approach we've been using for years to generate production builds for Meta.
The idea is that the only difference between the minified and non- minified builds is whitespace and symbol mangling. The semantic structure of the program should be identical.
To implement this, I disabled symbol mangling when running Closure compiler. Then, in a later step, the symbols are mangled by Terser. This is when the source maps are generated.