build.js 6.3 KB

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