UNPKG

6.85 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.NODE_ENV = 'production';
15
16// Load environment variables from .env file. Suppress warnings using silent
17// if this file is missing. dotenv will never modify any environment variables
18// that have already been set.
19// https://github.com/motdotla/dotenv
20require('dotenv').config({silent: true});
21
22var chalk = require('chalk');
23var fs = require('fs-extra');
24var path = require('path');
25var url = require('url');
26var webpack = require('webpack');
27var config = require('../config/webpack.config.prod');
28var paths = require('../config/paths');
29var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
30var FileSizeReporter = require('react-dev-utils/FileSizeReporter');
31var measureFileSizesBeforeBuild = FileSizeReporter.measureFileSizesBeforeBuild;
32var printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
33
34var useYarn = fs.existsSync(paths.yarnLockFile);
35
36// Warn and crash if required files are missing
37if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
38 process.exit(1);
39}
40
41// First, read the current file sizes in build directory.
42// This lets us display how much they changed later.
43measureFileSizesBeforeBuild(paths.appBuild).then(previousFileSizes => {
44 // Remove all content but keep the directory so that
45 // if you're in it, you don't end up in Trash
46 fs.emptyDirSync(paths.appBuild);
47
48 // Start the webpack build
49 build(previousFileSizes);
50
51 // Merge with the public folder
52 copyPublicFolder();
53});
54
55// Print out errors
56function printErrors(summary, errors) {
57 console.log(chalk.red(summary));
58 console.log();
59 errors.forEach(err => {
60 console.log(err.message || err);
61 console.log();
62 });
63}
64
65// Create the production build and print the deployment instructions.
66function build(previousFileSizes) {
67 console.log('Creating an optimized production build...');
68 webpack(config).run((err, stats) => {
69 if (err) {
70 printErrors('Failed to compile.', [err]);
71 process.exit(1);
72 }
73
74 if (stats.compilation.errors.length) {
75 printErrors('Failed to compile.', stats.compilation.errors);
76 process.exit(1);
77 }
78
79 if (process.env.CI && stats.compilation.warnings.length) {
80 printErrors('Failed to compile. When process.env.CI = true, warnings are treated as failures. Most CI servers set this automatically.', stats.compilation.warnings);
81 process.exit(1);
82 }
83
84 console.log(chalk.green('Compiled successfully.'));
85 console.log();
86
87 console.log('File sizes after gzip:');
88 console.log();
89 printFileSizesAfterBuild(stats, previousFileSizes);
90 console.log();
91
92 var appPackage = require(paths.appPackageJson);
93 var publicUrl = paths.publicUrl;
94 var publicPath = config.output.publicPath;
95 var publicPathname = url.parse(publicPath).pathname;
96 if (publicUrl && publicUrl.indexOf('.github.io/') !== -1) {
97 // "homepage": "http://user.github.io/project"
98 console.log('The project was built assuming it is hosted at ' + chalk.green(publicPathname) + '.');
99 console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.');
100 console.log();
101 console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.');
102 console.log('To publish it at ' + chalk.green(publicUrl) + ', run:');
103 // If script deploy has been added to package.json, skip the instructions
104 if (typeof appPackage.scripts.deploy === 'undefined') {
105 console.log();
106 if (useYarn) {
107 console.log(' ' + chalk.cyan('yarn') + ' add --dev gh-pages');
108 } else {
109 console.log(' ' + chalk.cyan('npm') + ' install --save-dev gh-pages');
110 }
111 console.log();
112 console.log('Add the following script in your ' + chalk.cyan('package.json') + '.');
113 console.log();
114 console.log(' ' + chalk.dim('// ...'));
115 console.log(' ' + chalk.yellow('"scripts"') + ': {');
116 console.log(' ' + chalk.dim('// ...'));
117 console.log(' ' + chalk.yellow('"predeploy"') + ': ' + chalk.yellow('"npm run build",'));
118 console.log(' ' + chalk.yellow('"deploy"') + ': ' + chalk.yellow('"gh-pages -d build"'));
119 console.log(' }');
120 console.log();
121 console.log('Then run:');
122 }
123 console.log();
124 console.log(' ' + chalk.cyan(useYarn ? 'yarn' : 'npm') + ' run deploy');
125 console.log();
126 } else if (publicPath !== '/') {
127 // "homepage": "http://mywebsite.com/project"
128 console.log('The project was built assuming it is hosted at ' + chalk.green(publicPath) + '.');
129 console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.');
130 console.log();
131 console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.');
132 console.log();
133 } else {
134 if (publicUrl) {
135 // "homepage": "http://mywebsite.com"
136 console.log('The project was built assuming it is hosted at ' + chalk.green(publicUrl) + '.');
137 console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.');
138 console.log();
139 } else {
140 // no homepage
141 console.log('The project was built assuming it is hosted at the server root.');
142 console.log('To override this, specify the ' + chalk.green('homepage') + ' in your ' + chalk.cyan('package.json') + '.');
143 console.log('For example, add this to build it for GitHub Pages:')
144 console.log();
145 console.log(' ' + chalk.green('"homepage"') + chalk.cyan(': ') + chalk.green('"http://myname.github.io/myapp"') + chalk.cyan(','));
146 console.log();
147 }
148 var build = path.relative(process.cwd(), paths.appBuild);
149 console.log('The ' + chalk.cyan(build) + ' folder is ready to be deployed.');
150 console.log('You may serve it with a static server:');
151 console.log();
152 if (useYarn) {
153 console.log(` ${chalk.cyan('yarn')} global add serve`);
154 } else {
155 console.log(` ${chalk.cyan('npm')} install -g serve`);
156 }
157 console.log(` ${chalk.cyan('serve')} -s build`);
158 console.log();
159 }
160 });
161}
162
163function copyPublicFolder() {
164 fs.copySync(paths.appPublic, paths.appBuild, {
165 dereference: true,
166 filter: file => file !== paths.appHtml
167 });
168}