3// Do this as the first thing so that any code reading it knows the right env.
4process.env.BABEL_ENV = 'production';
5process.env.NODE_ENV = 'production';
7// Makes the script crash on unhandled rejections instead of silently
8// ignoring them. In the future, promise rejections that are not handled will
9// terminate the Node.js process with a non-zero exit code.
10process.on('unhandledRejection', err => {
14// Ensure environment variables are read.
15require('../config/env');
18const path = require('path');
19const chalk = require('react-dev-utils/chalk');
20const fs = require('fs-extra');
21const webpack = require('webpack');
22const configFactory = require('../config/webpack.config');
23const paths = require('../config/paths');
24const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
25const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
26const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
27const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
28const printBuildError = require('react-dev-utils/printBuildError');
30const measureFileSizesBeforeBuild =
31 FileSizeReporter.measureFileSizesBeforeBuild;
32const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
33const useYarn = fs.existsSync(paths.yarnLockFile);
35// These sizes are pretty large. We'll warn for bundles exceeding them.
36const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
37const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
39const isInteractive = process.stdout.isTTY;
41// Warn and crash if required files are missing
42if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
46// Generate configuration
47const config = configFactory('production');
49// We require that you explicitly set browsers and do not fall back to
50// browserslist defaults.
51const { checkBrowsers } = require('react-dev-utils/browsersHelper');
52checkBrowsers(paths.appPath, isInteractive)
54 // First, read the current file sizes in build directory.
55 // This lets us display how much they changed later.
56 return measureFileSizesBeforeBuild(paths.appBuild);
58 .then(previousFileSizes => {
59 // Remove all content but keep the directory so that
60 // if you're in it, you don't end up in Trash
61 fs.emptyDirSync(paths.appBuild);
62 // Merge with the public folder
64 // Start the webpack build
65 return build(previousFileSizes);
68 ({ stats, previousFileSizes, warnings }) => {
69 if (warnings.length) {
70 console.log(chalk.yellow('Compiled with warnings.\n'));
71 console.log(warnings.join('\n\n'));
74 chalk.underline(chalk.yellow('keywords')) +
75 ' to learn more about each warning.'
79 chalk.cyan('// eslint-disable-next-line') +
80 ' to the line before.\n'
83 console.log(chalk.green('Compiled successfully.\n'));
86 console.log('File sizes after gzip:\n');
87 printFileSizesAfterBuild(
91 WARN_AFTER_BUNDLE_GZIP_SIZE,
92 WARN_AFTER_CHUNK_GZIP_SIZE
96 const appPackage = require(paths.appPackageJson);
97 const publicUrl = paths.publicUrl;
98 const publicPath = config.output.publicPath;
99 const buildFolder = path.relative(process.cwd(), paths.appBuild);
100 printHostingInstructions(
109 console.log(chalk.red('Failed to compile.\n'));
110 printBuildError(err);
115 if (err && err.message) {
116 console.log(err.message);
121// Create the production build and print the deployment instructions.
122function build(previousFileSizes) {
123 // We used to support resolving modules according to `NODE_PATH`.
124 // This now has been deprecated in favor of jsconfig/tsconfig.json
125 // This lets you use absolute paths in imports inside large monorepos:
126 if (process.env.NODE_PATH) {
129 'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
135 console.log('Creating an optimized production build...');
137 const compiler = webpack(config);
138 return new Promise((resolve, reject) => {
139 compiler.run((err, stats) => {
145 messages = formatWebpackMessages({
146 errors: [err.message],
150 messages = formatWebpackMessages(
151 stats.toJson({ all: false, warnings: true, errors: true })
154 if (messages.errors.length) {
155 // Only keep the first error. Others are often indicative
156 // of the same problem, but confuse the reader with noise.
157 if (messages.errors.length > 1) {
158 messages.errors.length = 1;
160 return reject(new Error(messages.errors.join('\n\n')));
164 (typeof process.env.CI !== 'string' ||
165 process.env.CI.toLowerCase() !== 'false') &&
166 messages.warnings.length
170 '\nTreating warnings as errors because process.env.CI = true.\n' +
171 'Most CI servers set it automatically.\n'
174 return reject(new Error(messages.warnings.join('\n\n')));
180 warnings: messages.warnings,
186function copyPublicFolder() {
187 fs.copySync(paths.appPublic, paths.appBuild, {
189 filter: file => file !== paths.appHtml,
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list