Skip to content

Commit 7c85938

Browse files
committed
Create a --stats flag for react-scripts build. Update README.
To analyze Webpack bundles, a "stats" JSON is required. This PR allows that file to be created and saved to the `build` directory, so that users can use it with Webpack-specific insight tools like `webpack-bundle-analyzer` without ejecting their application. Updated the README to include details for how to do this.
1 parent c1b0175 commit 7c85938

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

packages/react-scripts/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"babel-loader": "8.0.0-beta.0",
3131
"babel-plugin-named-asset-import": "^0.1.0",
3232
"babel-preset-react-app": "^3.1.1",
33+
"bfj": "5.2.0",
3334
"case-sensitive-paths-webpack-plugin": "2.1.2",
3435
"chalk": "2.4.1",
3536
"css-loader": "0.28.11",

packages/react-scripts/scripts/build.js

+16-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const path = require('path');
3333
const chalk = require('chalk');
3434
const fs = require('fs-extra');
3535
const webpack = require('webpack');
36+
const bfj = require('bfj');
3637
const config = require('../config/webpack.config.prod');
3738
const paths = require('../config/paths');
3839
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
@@ -55,6 +56,10 @@ if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
5556
process.exit(1);
5657
}
5758

59+
// Process CLI arguments
60+
const argv = process.argv.slice(2);
61+
const writeStatsJson = argv.indexOf('--stats') !== -1;
62+
5863
// We require that you explictly set browsers and do not fall back to
5964
// browserslist defaults.
6065
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
@@ -161,11 +166,20 @@ function build(previousFileSizes) {
161166
);
162167
return reject(new Error(messages.warnings.join('\n\n')));
163168
}
164-
return resolve({
169+
170+
const resolveArgs = {
165171
stats,
166172
previousFileSizes,
167173
warnings: messages.warnings,
168-
});
174+
};
175+
if (writeStatsJson) {
176+
return bfj
177+
.write(paths.appBuild + '/bundle-stats.json', stats.toJson())
178+
.then(() => resolve(resolveArgs))
179+
.catch(error => reject(new Error(error)));
180+
}
181+
182+
return resolve(resolveArgs);
169183
});
170184
});
171185
}

packages/react-scripts/template/README.md

+48
Original file line numberDiff line numberDiff line change
@@ -2048,6 +2048,14 @@ will affect your users' experience.
20482048
20492049
## Analyzing the Bundle Size
20502050
2051+
When your app grows in size, it's easy for bundles to become bloated. The first step to solving large bundles is understanding what's in them!
2052+
2053+
There are many different tools available to analyze bundles, but they typically rely on either **sourcemaps** or **webpack-specific JSON stats**.
2054+
2055+
### Using Sourcemaps
2056+
2057+
When building for production, sourcemaps are automatically created adjacent to the JS files in `build/static/js`.
2058+
20512059
[Source map explorer](https://www.npmjs.com/package/source-map-explorer) analyzes
20522060
JavaScript bundles using the source maps. This helps you understand where code
20532061
bloat is coming from.
@@ -2082,6 +2090,46 @@ npm run build
20822090
npm run analyze
20832091
```
20842092
2093+
### Using Webpack Stats JSON
2094+
2095+
> Note: this feature is available with [email protected] and higher.
2096+
2097+
Webpack can produce a JSON manifest that details the bundles, and several tools can use that file to do analysis.
2098+
2099+
Unlike with sourcemaps, the JSON file isn't created automatically on build. You must pass a `--stats` flag:
2100+
2101+
```sh
2102+
npm run build -- --stats
2103+
```
2104+
2105+
Once the build is complete, you should have a JSON file located at `build/bundle-stats.json`.
2106+
2107+
The quickest way to get insight into your bundle is to drag and drop that JSON file into [Webpack Visualizer](https://chrisbateman.github.io/webpack-visualizer/).
2108+
2109+
Another very popular tool is [`webpack-bundle-analyzer`](https://www.npmjs.com/package/webpack-bundle-analyzer).
2110+
2111+
To use `webpack-bundle-analyzer`, start by installing it from NPM:
2112+
2113+
```sh
2114+
npm install --save webpack-bundle-analyzer
2115+
# or, with Yarn:
2116+
yarn add webpack-bundle-analyzer
2117+
```
2118+
2119+
2120+
In `package.json`, add the following line to `scripts`:
2121+
2122+
```diff
2123+
"scripts": {
2124+
+ "analyze": "npm run build -- --stats && webpack-bundle-analyzer build/bundle-stats.json",
2125+
"start": "react-scripts start",
2126+
"build": "react-scripts build",
2127+
"build:with-stats": "react-scripts build",
2128+
"test": "react-scripts test --env=jsdom",
2129+
```
2130+
2131+
When you run `npm run analyze`, a new build will be created, and a browser tab should open automatically, displaying the sizes of the modules within your bundle.
2132+
20852133
## Deployment
20862134
20872135
`npm run build` creates a `build` directory with a production build of your app. Set up your favorite HTTP server so that a visitor to your site is served `index.html`, and requests to static paths like `/static/js/main.<hash>.js` are served with the contents of the `/static/js/main.<hash>.js` file.

0 commit comments

Comments
 (0)