UNPKG

4.73 kBJavaScriptView Raw
1// @remove-on-eject-begin
2/**
3 * Copyright (c) 2015-present, Facebook, Inc.
4 * All rights reserved.
5 *
6 * This source code is licensed under the BSD-style license found in the
7 * LICENSE file in the root directory of this source tree. An additional grant
8 * of patent rights can be found in the PATENTS file in the same directory.
9 */
10// @remove-on-eject-end
11'use strict';
12
13// Do this as the first thing so that any code reading it knows the right env.
14process.env.BABEL_ENV = 'production';
15process.env.NODE_ENV = 'production';
16
17// Makes the script crash on unhandled rejections instead of silently
18// ignoring them. In the future, promise rejections that are not handled will
19// terminate the Node.js process with a non-zero exit code.
20process.on('unhandledRejection', err => {
21 throw err;
22});
23
24// Ensure environment variables are read.
25require('../config/env');
26
27const path = require('path');
28const chalk = require('chalk');
29const fs = require('fs-extra');
30const webpack = require('webpack');
31const config = require('../config/webpack.config.prod');
32const paths = require('../config/paths');
33const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
34const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
35const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
36const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
37
38const measureFileSizesBeforeBuild = FileSizeReporter.measureFileSizesBeforeBuild;
39const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
40const useYarn = fs.existsSync(paths.yarnLockFile);
41
42// Warn and crash if required files are missing
43if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
44 process.exit(1);
45}
46
47// First, read the current file sizes in build directory.
48// This lets us display how much they changed later.
49measureFileSizesBeforeBuild(paths.appBuild)
50 .then(previousFileSizes => {
51 // Remove all content but keep the directory so that
52 // if you're in it, you don't end up in Trash
53 fs.emptyDirSync(paths.appBuild);
54 // Merge with the public folder
55 copyPublicFolder();
56 // Start the webpack build
57 return build(previousFileSizes);
58 })
59 .then(
60 ({ stats, previousFileSizes, warnings }) => {
61 if (warnings.length) {
62 console.log(chalk.yellow('Compiled with warnings.\n'));
63 console.log(warnings.join('\n\n'));
64 console.log(
65 '\nSearch for the ' +
66 chalk.underline(chalk.yellow('keywords')) +
67 ' to learn more about each warning.'
68 );
69 console.log(
70 'To ignore, add ' +
71 chalk.cyan('// eslint-disable-next-line') +
72 ' to the line before.\n'
73 );
74 } else {
75 console.log(chalk.green('Compiled successfully.\n'));
76 }
77
78 console.log('File sizes after gzip:\n');
79 printFileSizesAfterBuild(stats, previousFileSizes, paths.appBuild);
80 console.log();
81
82 const appPackage = require(paths.appPackageJson);
83 const publicUrl = paths.publicUrl;
84 const publicPath = config.output.publicPath;
85 const buildFolder = path.relative(process.cwd(), paths.appBuild);
86 printHostingInstructions(
87 appPackage,
88 publicUrl,
89 publicPath,
90 buildFolder,
91 useYarn
92 );
93 },
94 err => {
95 console.log(chalk.red('Failed to compile.\n'));
96 console.log((err.message || err) + '\n');
97 process.exit(1);
98 }
99 );
100
101// Create the production build and print the deployment instructions.
102function build(previousFileSizes) {
103 console.log('Creating an optimized production build...');
104
105 let compiler = webpack(config);
106 return new Promise((resolve, reject) => {
107 compiler.run((err, stats) => {
108 if (err) {
109 return reject(err);
110 }
111 const messages = formatWebpackMessages(stats.toJson({}, true));
112 if (messages.errors.length) {
113 return reject(new Error(messages.errors.join('\n\n')));
114 }
115 if (
116 process.env.CI &&
117 (typeof process.env.CI !== 'string' ||
118 process.env.CI.toLowerCase() !== 'false') &&
119 messages.warnings.length
120 ) {
121 console.log(
122 chalk.yellow(
123 '\nTreating warnings as errors because process.env.CI = true.\n' +
124 'Most CI servers set it automatically.\n'
125 )
126 );
127 return reject(new Error(messages.warnings.join('\n\n')));
128 }
129 return resolve({
130 stats,
131 previousFileSizes,
132 warnings: messages.warnings,
133 });
134 });
135 });
136}
137
138function copyPublicFolder() {
139 fs.copySync(paths.appPublic, paths.appBuild, {
140 dereference: true,
141 filter: file => file !== paths.appHtml,
142 });
143}