setup
This commit is contained in:
		
							
								
								
									
										217
									
								
								scripts/build.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								scripts/build.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,217 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
// Do this as the first thing so that any code reading it knows the right env.
 | 
			
		||||
process.env.BABEL_ENV = 'production';
 | 
			
		||||
process.env.NODE_ENV = 'production';
 | 
			
		||||
 | 
			
		||||
// Makes the script crash on unhandled rejections instead of silently
 | 
			
		||||
// ignoring them. In the future, promise rejections that are not handled will
 | 
			
		||||
// terminate the Node.js process with a non-zero exit code.
 | 
			
		||||
process.on('unhandledRejection', err => {
 | 
			
		||||
  throw err;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Ensure environment variables are read.
 | 
			
		||||
require('../config/env');
 | 
			
		||||
 | 
			
		||||
const path = require('path');
 | 
			
		||||
const chalk = require('react-dev-utils/chalk');
 | 
			
		||||
const fs = require('fs-extra');
 | 
			
		||||
const bfj = require('bfj');
 | 
			
		||||
const webpack = require('webpack');
 | 
			
		||||
const configFactory = require('../config/webpack.config');
 | 
			
		||||
const paths = require('../config/paths');
 | 
			
		||||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
 | 
			
		||||
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
 | 
			
		||||
const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
 | 
			
		||||
const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
 | 
			
		||||
const printBuildError = require('react-dev-utils/printBuildError');
 | 
			
		||||
 | 
			
		||||
const measureFileSizesBeforeBuild =
 | 
			
		||||
  FileSizeReporter.measureFileSizesBeforeBuild;
 | 
			
		||||
const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
 | 
			
		||||
const useYarn = fs.existsSync(paths.yarnLockFile);
 | 
			
		||||
 | 
			
		||||
// These sizes are pretty large. We'll warn for bundles exceeding them.
 | 
			
		||||
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
 | 
			
		||||
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
 | 
			
		||||
 | 
			
		||||
const isInteractive = process.stdout.isTTY;
 | 
			
		||||
 | 
			
		||||
// Warn and crash if required files are missing
 | 
			
		||||
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
 | 
			
		||||
  process.exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const argv = process.argv.slice(2);
 | 
			
		||||
const writeStatsJson = argv.indexOf('--stats') !== -1;
 | 
			
		||||
 | 
			
		||||
// Generate configuration
 | 
			
		||||
const config = configFactory('production');
 | 
			
		||||
 | 
			
		||||
// We require that you explicitly set browsers and do not fall back to
 | 
			
		||||
// browserslist defaults.
 | 
			
		||||
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
 | 
			
		||||
checkBrowsers(paths.appPath, isInteractive)
 | 
			
		||||
  .then(() => {
 | 
			
		||||
    // First, read the current file sizes in build directory.
 | 
			
		||||
    // This lets us display how much they changed later.
 | 
			
		||||
    return measureFileSizesBeforeBuild(paths.appBuild);
 | 
			
		||||
  })
 | 
			
		||||
  .then(previousFileSizes => {
 | 
			
		||||
    // Remove all content but keep the directory so that
 | 
			
		||||
    // if you're in it, you don't end up in Trash
 | 
			
		||||
    fs.emptyDirSync(paths.appBuild);
 | 
			
		||||
    // Merge with the public folder
 | 
			
		||||
    copyPublicFolder();
 | 
			
		||||
    // Start the webpack build
 | 
			
		||||
    return build(previousFileSizes);
 | 
			
		||||
  })
 | 
			
		||||
  .then(
 | 
			
		||||
    ({ stats, previousFileSizes, warnings }) => {
 | 
			
		||||
      if (warnings.length) {
 | 
			
		||||
        console.log(chalk.yellow('Compiled with warnings.\n'));
 | 
			
		||||
        console.log(warnings.join('\n\n'));
 | 
			
		||||
        console.log(
 | 
			
		||||
          '\nSearch for the ' +
 | 
			
		||||
            chalk.underline(chalk.yellow('keywords')) +
 | 
			
		||||
            ' to learn more about each warning.'
 | 
			
		||||
        );
 | 
			
		||||
        console.log(
 | 
			
		||||
          'To ignore, add ' +
 | 
			
		||||
            chalk.cyan('// eslint-disable-next-line') +
 | 
			
		||||
            ' to the line before.\n'
 | 
			
		||||
        );
 | 
			
		||||
      } else {
 | 
			
		||||
        console.log(chalk.green('Compiled successfully.\n'));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      console.log('File sizes after gzip:\n');
 | 
			
		||||
      printFileSizesAfterBuild(
 | 
			
		||||
        stats,
 | 
			
		||||
        previousFileSizes,
 | 
			
		||||
        paths.appBuild,
 | 
			
		||||
        WARN_AFTER_BUNDLE_GZIP_SIZE,
 | 
			
		||||
        WARN_AFTER_CHUNK_GZIP_SIZE
 | 
			
		||||
      );
 | 
			
		||||
      console.log();
 | 
			
		||||
 | 
			
		||||
      const appPackage = require(paths.appPackageJson);
 | 
			
		||||
      const publicUrl = paths.publicUrlOrPath;
 | 
			
		||||
      const publicPath = config.output.publicPath;
 | 
			
		||||
      const buildFolder = path.relative(process.cwd(), paths.appBuild);
 | 
			
		||||
      printHostingInstructions(
 | 
			
		||||
        appPackage,
 | 
			
		||||
        publicUrl,
 | 
			
		||||
        publicPath,
 | 
			
		||||
        buildFolder,
 | 
			
		||||
        useYarn
 | 
			
		||||
      );
 | 
			
		||||
    },
 | 
			
		||||
    err => {
 | 
			
		||||
      const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
 | 
			
		||||
      if (tscCompileOnError) {
 | 
			
		||||
        console.log(
 | 
			
		||||
          chalk.yellow(
 | 
			
		||||
            'Compiled with the following type errors (you may want to check these before deploying your app):\n'
 | 
			
		||||
          )
 | 
			
		||||
        );
 | 
			
		||||
        printBuildError(err);
 | 
			
		||||
      } else {
 | 
			
		||||
        console.log(chalk.red('Failed to compile.\n'));
 | 
			
		||||
        printBuildError(err);
 | 
			
		||||
        process.exit(1);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  )
 | 
			
		||||
  .catch(err => {
 | 
			
		||||
    if (err && err.message) {
 | 
			
		||||
      console.log(err.message);
 | 
			
		||||
    }
 | 
			
		||||
    process.exit(1);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
// Create the production build and print the deployment instructions.
 | 
			
		||||
function build(previousFileSizes) {
 | 
			
		||||
  console.log('Creating an optimized production build...');
 | 
			
		||||
 | 
			
		||||
  const compiler = webpack(config);
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    compiler.run((err, stats) => {
 | 
			
		||||
      let messages;
 | 
			
		||||
      if (err) {
 | 
			
		||||
        if (!err.message) {
 | 
			
		||||
          return reject(err);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let errMessage = err.message;
 | 
			
		||||
 | 
			
		||||
        // Add additional information for postcss errors
 | 
			
		||||
        if (Object.prototype.hasOwnProperty.call(err, 'postcssNode')) {
 | 
			
		||||
          errMessage +=
 | 
			
		||||
            '\nCompileError: Begins at CSS selector ' +
 | 
			
		||||
            err['postcssNode'].selector;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        messages = formatWebpackMessages({
 | 
			
		||||
          errors: [errMessage],
 | 
			
		||||
          warnings: [],
 | 
			
		||||
        });
 | 
			
		||||
      } else {
 | 
			
		||||
        messages = formatWebpackMessages(
 | 
			
		||||
          stats.toJson({ all: false, warnings: true, errors: true })
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
      if (messages.errors.length) {
 | 
			
		||||
        // Only keep the first error. Others are often indicative
 | 
			
		||||
        // of the same problem, but confuse the reader with noise.
 | 
			
		||||
        if (messages.errors.length > 1) {
 | 
			
		||||
          messages.errors.length = 1;
 | 
			
		||||
        }
 | 
			
		||||
        return reject(new Error(messages.errors.join('\n\n')));
 | 
			
		||||
      }
 | 
			
		||||
      if (
 | 
			
		||||
        process.env.CI &&
 | 
			
		||||
        (typeof process.env.CI !== 'string' ||
 | 
			
		||||
          process.env.CI.toLowerCase() !== 'false') &&
 | 
			
		||||
        messages.warnings.length
 | 
			
		||||
      ) {
 | 
			
		||||
        // Ignore sourcemap warnings in CI builds. See #8227 for more info.
 | 
			
		||||
        const filteredWarnings = messages.warnings.filter(
 | 
			
		||||
          w => !/Failed to parse source map/.test(w)
 | 
			
		||||
        );
 | 
			
		||||
        if (filteredWarnings.length) {
 | 
			
		||||
          console.log(
 | 
			
		||||
            chalk.yellow(
 | 
			
		||||
              '\nTreating warnings as errors because process.env.CI = true.\n' +
 | 
			
		||||
                'Most CI servers set it automatically.\n'
 | 
			
		||||
            )
 | 
			
		||||
          );
 | 
			
		||||
          return reject(new Error(filteredWarnings.join('\n\n')));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const resolveArgs = {
 | 
			
		||||
        stats,
 | 
			
		||||
        previousFileSizes,
 | 
			
		||||
        warnings: messages.warnings,
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      if (writeStatsJson) {
 | 
			
		||||
        return bfj
 | 
			
		||||
          .write(paths.appBuild + '/bundle-stats.json', stats.toJson())
 | 
			
		||||
          .then(() => resolve(resolveArgs))
 | 
			
		||||
          .catch(error => reject(new Error(error)));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return resolve(resolveArgs);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function copyPublicFolder() {
 | 
			
		||||
  fs.copySync(paths.appPublic, paths.appBuild, {
 | 
			
		||||
    dereference: true,
 | 
			
		||||
    filter: file => file !== paths.appHtml,
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										154
									
								
								scripts/start.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								scripts/start.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
// Do this as the first thing so that any code reading it knows the right env.
 | 
			
		||||
process.env.BABEL_ENV = 'development';
 | 
			
		||||
process.env.NODE_ENV = 'development';
 | 
			
		||||
 | 
			
		||||
// Makes the script crash on unhandled rejections instead of silently
 | 
			
		||||
// ignoring them. In the future, promise rejections that are not handled will
 | 
			
		||||
// terminate the Node.js process with a non-zero exit code.
 | 
			
		||||
process.on('unhandledRejection', err => {
 | 
			
		||||
  throw err;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Ensure environment variables are read.
 | 
			
		||||
require('../config/env');
 | 
			
		||||
 | 
			
		||||
const fs = require('fs');
 | 
			
		||||
const chalk = require('react-dev-utils/chalk');
 | 
			
		||||
const webpack = require('webpack');
 | 
			
		||||
const WebpackDevServer = require('webpack-dev-server');
 | 
			
		||||
const clearConsole = require('react-dev-utils/clearConsole');
 | 
			
		||||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
 | 
			
		||||
const {
 | 
			
		||||
  choosePort,
 | 
			
		||||
  createCompiler,
 | 
			
		||||
  prepareProxy,
 | 
			
		||||
  prepareUrls,
 | 
			
		||||
} = require('react-dev-utils/WebpackDevServerUtils');
 | 
			
		||||
const openBrowser = require('react-dev-utils/openBrowser');
 | 
			
		||||
const semver = require('semver');
 | 
			
		||||
const paths = require('../config/paths');
 | 
			
		||||
const configFactory = require('../config/webpack.config');
 | 
			
		||||
const createDevServerConfig = require('../config/webpackDevServer.config');
 | 
			
		||||
const getClientEnvironment = require('../config/env');
 | 
			
		||||
const react = require(require.resolve('react', { paths: [paths.appPath] }));
 | 
			
		||||
 | 
			
		||||
const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
 | 
			
		||||
const useYarn = fs.existsSync(paths.yarnLockFile);
 | 
			
		||||
const isInteractive = process.stdout.isTTY;
 | 
			
		||||
 | 
			
		||||
// Warn and crash if required files are missing
 | 
			
		||||
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
 | 
			
		||||
  process.exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tools like Cloud9 rely on this.
 | 
			
		||||
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
 | 
			
		||||
const HOST = process.env.HOST || '0.0.0.0';
 | 
			
		||||
 | 
			
		||||
if (process.env.HOST) {
 | 
			
		||||
  console.log(
 | 
			
		||||
    chalk.cyan(
 | 
			
		||||
      `Attempting to bind to HOST environment variable: ${chalk.yellow(
 | 
			
		||||
        chalk.bold(process.env.HOST)
 | 
			
		||||
      )}`
 | 
			
		||||
    )
 | 
			
		||||
  );
 | 
			
		||||
  console.log(
 | 
			
		||||
    `If this was unintentional, check that you haven't mistakenly set it in your shell.`
 | 
			
		||||
  );
 | 
			
		||||
  console.log(
 | 
			
		||||
    `Learn more here: ${chalk.yellow('https://cra.link/advanced-config')}`
 | 
			
		||||
  );
 | 
			
		||||
  console.log();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// We require that you explicitly set browsers and do not fall back to
 | 
			
		||||
// browserslist defaults.
 | 
			
		||||
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
 | 
			
		||||
checkBrowsers(paths.appPath, isInteractive)
 | 
			
		||||
  .then(() => {
 | 
			
		||||
    // We attempt to use the default port but if it is busy, we offer the user to
 | 
			
		||||
    // run on a different port. `choosePort()` Promise resolves to the next free port.
 | 
			
		||||
    return choosePort(HOST, DEFAULT_PORT);
 | 
			
		||||
  })
 | 
			
		||||
  .then(port => {
 | 
			
		||||
    if (port == null) {
 | 
			
		||||
      // We have not found a port.
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const config = configFactory('development');
 | 
			
		||||
    const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
 | 
			
		||||
    const appName = require(paths.appPackageJson).name;
 | 
			
		||||
 | 
			
		||||
    const useTypeScript = fs.existsSync(paths.appTsConfig);
 | 
			
		||||
    const urls = prepareUrls(
 | 
			
		||||
      protocol,
 | 
			
		||||
      HOST,
 | 
			
		||||
      port,
 | 
			
		||||
      paths.publicUrlOrPath.slice(0, -1)
 | 
			
		||||
    );
 | 
			
		||||
    // Create a webpack compiler that is configured with custom messages.
 | 
			
		||||
    const compiler = createCompiler({
 | 
			
		||||
      appName,
 | 
			
		||||
      config,
 | 
			
		||||
      urls,
 | 
			
		||||
      useYarn,
 | 
			
		||||
      useTypeScript,
 | 
			
		||||
      webpack,
 | 
			
		||||
    });
 | 
			
		||||
    // Load proxy config
 | 
			
		||||
    const proxySetting = require(paths.appPackageJson).proxy;
 | 
			
		||||
    const proxyConfig = prepareProxy(
 | 
			
		||||
      proxySetting,
 | 
			
		||||
      paths.appPublic,
 | 
			
		||||
      paths.publicUrlOrPath
 | 
			
		||||
    );
 | 
			
		||||
    // Serve webpack assets generated by the compiler over a web server.
 | 
			
		||||
    const serverConfig = {
 | 
			
		||||
      ...createDevServerConfig(proxyConfig, urls.lanUrlForConfig),
 | 
			
		||||
      host: HOST,
 | 
			
		||||
      port,
 | 
			
		||||
    };
 | 
			
		||||
    const devServer = new WebpackDevServer(serverConfig, compiler);
 | 
			
		||||
    // Launch WebpackDevServer.
 | 
			
		||||
    devServer.startCallback(() => {
 | 
			
		||||
      if (isInteractive) {
 | 
			
		||||
        clearConsole();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (env.raw.FAST_REFRESH && semver.lt(react.version, '16.10.0')) {
 | 
			
		||||
        console.log(
 | 
			
		||||
          chalk.yellow(
 | 
			
		||||
            `Fast Refresh requires React 16.10 or higher. You are using React ${react.version}.`
 | 
			
		||||
          )
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      console.log(chalk.cyan('Starting the development server...\n'));
 | 
			
		||||
      openBrowser(urls.localUrlForBrowser);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    ['SIGINT', 'SIGTERM'].forEach(function (sig) {
 | 
			
		||||
      process.on(sig, function () {
 | 
			
		||||
        devServer.close();
 | 
			
		||||
        process.exit();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (process.env.CI !== 'true') {
 | 
			
		||||
      // Gracefully exit when stdin ends
 | 
			
		||||
      process.stdin.on('end', function () {
 | 
			
		||||
        devServer.close();
 | 
			
		||||
        process.exit();
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  .catch(err => {
 | 
			
		||||
    if (err && err.message) {
 | 
			
		||||
      console.log(err.message);
 | 
			
		||||
    }
 | 
			
		||||
    process.exit(1);
 | 
			
		||||
  });
 | 
			
		||||
							
								
								
									
										52
									
								
								scripts/test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								scripts/test.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
// Do this as the first thing so that any code reading it knows the right env.
 | 
			
		||||
process.env.BABEL_ENV = 'test';
 | 
			
		||||
process.env.NODE_ENV = 'test';
 | 
			
		||||
process.env.PUBLIC_URL = '';
 | 
			
		||||
 | 
			
		||||
// Makes the script crash on unhandled rejections instead of silently
 | 
			
		||||
// ignoring them. In the future, promise rejections that are not handled will
 | 
			
		||||
// terminate the Node.js process with a non-zero exit code.
 | 
			
		||||
process.on('unhandledRejection', err => {
 | 
			
		||||
  throw err;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Ensure environment variables are read.
 | 
			
		||||
require('../config/env');
 | 
			
		||||
 | 
			
		||||
const jest = require('jest');
 | 
			
		||||
const execSync = require('child_process').execSync;
 | 
			
		||||
let argv = process.argv.slice(2);
 | 
			
		||||
 | 
			
		||||
function isInGitRepository() {
 | 
			
		||||
  try {
 | 
			
		||||
    execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
 | 
			
		||||
    return true;
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function isInMercurialRepository() {
 | 
			
		||||
  try {
 | 
			
		||||
    execSync('hg --cwd . root', { stdio: 'ignore' });
 | 
			
		||||
    return true;
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Watch unless on CI or explicitly running all tests
 | 
			
		||||
if (
 | 
			
		||||
  !process.env.CI &&
 | 
			
		||||
  argv.indexOf('--watchAll') === -1 &&
 | 
			
		||||
  argv.indexOf('--watchAll=false') === -1
 | 
			
		||||
) {
 | 
			
		||||
  // https://github.com/facebook/create-react-app/issues/5210
 | 
			
		||||
  const hasSourceControl = isInGitRepository() || isInMercurialRepository();
 | 
			
		||||
  argv.push(hasSourceControl ? '--watch' : '--watchAll');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
jest.run(argv);
 | 
			
		||||
		Reference in New Issue
	
	Block a user