diff --git a/package.json b/package.json index 46bc55b0245..c95e75ee5f8 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,13 @@ "postinstall": "lerna bootstrap", "publish": "tasks/release.sh", "start": "node packages/react-scripts/scripts/start.js", - "test": "node packages/react-scripts/scripts/test.js --env=jsdom" + "test": "node packages/react-scripts/scripts/test.js --env=jsdom", + "format": "prettier --trailing-comma es5 --single-quote --write 'packages/*/*.js' 'packages/*/!(node_modules)/**/*.js'" }, "devDependencies": { "eslint": "3.16.1", "lerna": "2.0.0-beta.38", - "lerna-changelog": "^0.2.3" + "lerna-changelog": "^0.2.3", + "prettier": "^0.21.0" } } diff --git a/packages/babel-preset-react-app/index.js b/packages/babel-preset-react-app/index.js index 8236c64b54c..bba6e3fdb4b 100644 --- a/packages/babel-preset-react-app/index.js +++ b/packages/babel-preset-react-app/index.js @@ -16,21 +16,30 @@ const plugins = [ // The following two plugins use Object.assign directly, instead of Babel's // extends helper. Note that this assumes `Object.assign` is available. // { ...todo, completed: true } - [require.resolve('babel-plugin-transform-object-rest-spread'), { - useBuiltIns: true - }], + [ + require.resolve('babel-plugin-transform-object-rest-spread'), + { + useBuiltIns: true, + }, + ], // Transforms JSX - [require.resolve('babel-plugin-transform-react-jsx'), { - useBuiltIns: true - }], + [ + require.resolve('babel-plugin-transform-react-jsx'), + { + useBuiltIns: true, + }, + ], // Polyfills the runtime needed for async/await and generators - [require.resolve('babel-plugin-transform-runtime'), { - helpers: false, - polyfill: false, - regenerator: true, - // Resolve the Babel runtime relative to the config. - moduleName: path.dirname(require.resolve('babel-runtime/package')) - }] + [ + require.resolve('babel-plugin-transform-runtime'), + { + helpers: false, + polyfill: false, + regenerator: true, + // Resolve the Babel runtime relative to the config. + moduleName: path.dirname(require.resolve('babel-runtime/package')), + }, + ], ]; // This is similar to how `env` works in Babel: @@ -42,9 +51,11 @@ const plugins = [ var env = process.env.BABEL_ENV || process.env.NODE_ENV; if (env !== 'development' && env !== 'test' && env !== 'production') { throw new Error( - 'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or '+ - '`BABEL_ENV` environment variables. Valid values are "development", ' + - '"test", and "production". Instead, received: ' + JSON.stringify(env) + '.' + 'Using `babel-preset-react-app` requires that you specify `NODE_ENV` or ' + + '`BABEL_ENV` environment variables. Valid values are "development", ' + + '"test", and "production". Instead, received: ' + + JSON.stringify(env) + + '.' ); } @@ -59,7 +70,7 @@ if (env === 'development' || env === 'test') { // Adds component stack to warning messages require.resolve('babel-plugin-transform-react-jsx-source'), // Adds __self attribute to JSX which React will use for some warnings - require.resolve('babel-plugin-transform-react-jsx-self') + require.resolve('babel-plugin-transform-react-jsx-self'), ]); } @@ -67,46 +78,55 @@ if (env === 'test') { module.exports = { presets: [ // ES features necessary for user's Node version - [require('babel-preset-env').default, { - targets: { - node: 'current', + [ + require('babel-preset-env').default, + { + targets: { + node: 'current', + }, }, - }], + ], // JSX, Flow - require.resolve('babel-preset-react') + require.resolve('babel-preset-react'), ], plugins: plugins.concat([ // Compiles import() to a deferred require() - require.resolve('babel-plugin-dynamic-import-node') - ]) + require.resolve('babel-plugin-dynamic-import-node'), + ]), }; } else { module.exports = { presets: [ // Latest stable ECMAScript features - [require.resolve('babel-preset-env'), { - targets: { - // React parses on ie 9, so we should too - ie: 9, - // We currently minify with uglify - // Remove after https://github.com/mishoo/UglifyJS2/issues/448 - uglify: true + [ + require.resolve('babel-preset-env'), + { + targets: { + // React parses on ie 9, so we should too + ie: 9, + // We currently minify with uglify + // Remove after https://github.com/mishoo/UglifyJS2/issues/448 + uglify: true, + }, + // Disable polyfill transforms + useBuiltIns: false, }, - // Disable polyfill transforms - useBuiltIns: false - }], + ], // JSX, Flow - require.resolve('babel-preset-react') + require.resolve('babel-preset-react'), ], plugins: plugins.concat([ // function* () { yield 42; yield 43; } - [require.resolve('babel-plugin-transform-regenerator'), { - // Async functions are converted to generators by babel-preset-latest - async: false - }], + [ + require.resolve('babel-plugin-transform-regenerator'), + { + // Async functions are converted to generators by babel-preset-latest + async: false, + }, + ], // Adds syntax support for import() require.resolve('babel-plugin-syntax-dynamic-import'), - ]) + ]), }; if (env === 'production') { diff --git a/packages/create-react-app/createReactApp.js b/packages/create-react-app/createReactApp.js new file mode 100755 index 00000000000..da9250d4d71 --- /dev/null +++ b/packages/create-react-app/createReactApp.js @@ -0,0 +1,520 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +'use strict'; + +const validateProjectName = require('validate-npm-package-name'); +const chalk = require('chalk'); +const commander = require('commander'); +const fs = require('fs-extra'); +const path = require('path'); +const execSync = require('child_process').execSync; +const spawn = require('cross-spawn'); +const semver = require('semver'); +const dns = require('dns'); +const tmp = require('tmp'); +const unpack = require('tar-pack').unpack; +const hyperquest = require('hyperquest'); + +let projectName; + +const program = commander + .version(require('./package.json').version) + .arguments('') + .usage(`${chalk.green('')} [options]`) + .action(name => { + projectName = name; + }) + .option('--verbose', 'print additional logs') + .option( + '--scripts-version ', + 'use a non-standard version of react-scripts' + ) + .allowUnknownOption() + .on('--help', () => { + console.log(` Only ${chalk.green('')} is required.`); + console.log(); + console.log( + ` A custom ${chalk.cyan('--scripts-version')} can be one of:` + ); + console.log(` - a specific npm version: ${chalk.green('0.8.2')}`); + console.log( + ` - a custom fork published on npm: ${chalk.green('my-react-scripts')}` + ); + console.log( + ` - a .tgz archive: ${chalk.green('https://mysite.com/my-react-scripts-0.8.2.tgz')}` + ); + console.log( + ` It is not needed unless you specifically want to use a fork.` + ); + console.log(); + console.log( + ` If you have any problems, do not hesitate to file an issue:` + ); + console.log( + ` ${chalk.cyan('https://github.com/facebookincubator/create-react-app/issues/new')}` + ); + console.log(); + }) + .parse(process.argv); + +if (typeof projectName === 'undefined') { + console.error('Please specify the project directory:'); + console.log( + ` ${chalk.cyan(program.name())} ${chalk.green('')}` + ); + console.log(); + console.log('For example:'); + console.log(` ${chalk.cyan(program.name())} ${chalk.green('my-react-app')}`); + console.log(); + console.log( + `Run ${chalk.cyan(`${program.name()} --help`)} to see all options.` + ); + process.exit(1); +} + +function printValidationResults(results) { + if (typeof results !== 'undefined') { + results.forEach(error => { + console.error(chalk.red(` * ${error}`)); + }); + } +} + +const hiddenProgram = new commander.Command() + .option( + '--internal-testing-template ', + '(internal usage only, DO NOT RELY ON THIS) ' + + 'use a non-standard application template' + ) + .parse(process.argv); + +createApp( + projectName, + program.verbose, + program.scriptsVersion, + hiddenProgram.internalTestingTemplate +); + +function createApp(name, verbose, version, template) { + const root = path.resolve(name); + const appName = path.basename(root); + + checkAppName(appName); + fs.ensureDirSync(name); + if (!isSafeToCreateProjectIn(root)) { + console.log( + `The directory ${chalk.green(name)} contains files that could conflict.` + ); + console.log('Try using a new directory name.'); + process.exit(1); + } + + console.log(`Creating a new React app in ${chalk.green(root)}.`); + console.log(); + + const packageJson = { + name: appName, + version: '0.1.0', + private: true, + }; + fs.writeFileSync( + path.join(root, 'package.json'), + JSON.stringify(packageJson, null, 2) + ); + const originalDirectory = process.cwd(); + process.chdir(root); + + run(root, appName, version, verbose, originalDirectory, template); +} + +function shouldUseYarn() { + try { + execSync('yarnpkg --version', { stdio: 'ignore' }); + return true; + } catch (e) { + return false; + } +} + +function install(useYarn, dependencies, verbose, isOnline) { + return new Promise((resolve, reject) => { + let command; + let args; + if (useYarn) { + command = 'yarnpkg'; + args = ['add', '--exact']; + if (!isOnline) { + args.push('--offline'); + } + [].push.apply(args, dependencies); + + if (!isOnline) { + console.log(chalk.yellow('You appear to be offline.')); + console.log(chalk.yellow('Falling back to the local Yarn cache.')); + console.log(); + } + } else { + checkNpmVersion(); + command = 'npm'; + args = ['install', '--save', '--save-exact'].concat(dependencies); + } + + if (verbose) { + args.push('--verbose'); + } + + const child = spawn(command, args, { stdio: 'inherit' }); + child.on('close', code => { + if (code !== 0) { + reject({ + command: `${command} ${args.join(' ')}`, + }); + return; + } + resolve(); + }); + }); +} + +function run(root, appName, version, verbose, originalDirectory, template) { + const packageToInstall = getInstallPackage(version); + const allDependencies = ['react', 'react-dom', packageToInstall]; + + console.log('Installing packages. This might take a couple minutes.'); + + const useYarn = shouldUseYarn(); + getPackageName(packageToInstall) + .then(packageName => checkIfOnline(useYarn).then(isOnline => ({ + isOnline: isOnline, + packageName: packageName, + }))) + .then(info => { + const isOnline = info.isOnline; + const packageName = info.packageName; + console.log( + `Installing ${chalk.cyan('react')}, ${chalk.cyan('react-dom')}, and ${chalk.cyan(packageName)}...` + ); + console.log(); + + return install(useYarn, allDependencies, verbose, isOnline).then( + () => packageName + ); + }) + .then(packageName => { + checkNodeVersion(packageName); + + // Since react-scripts has been installed with --save + // we need to move it into devDependencies and rewrite package.json + // also ensure react dependencies have caret version range + fixDependencies(packageName); + + const scriptsPath = path.resolve( + process.cwd(), + 'node_modules', + packageName, + 'scripts', + 'init.js' + ); + const init = require(scriptsPath); + init(root, appName, verbose, originalDirectory, template); + }) + .catch(reason => { + console.log(); + console.log('Aborting installation.'); + if (reason.command) { + console.log(` ${chalk.cyan(reason.command)} has failed.`); + } else { + console.log(chalk.red('Unexpected error. Please report it as a bug:')); + console.log(reason); + } + console.log(); + + // On 'exit' we will delete these files from target directory. + const knownGeneratedFiles = [ + 'package.json', + 'npm-debug.log', + 'yarn-error.log', + 'yarn-debug.log', + 'node_modules', + ]; + const currentFiles = fs.readdirSync(path.join(root)); + currentFiles.forEach(file => { + knownGeneratedFiles.forEach(fileToMatch => { + // This will catch `(npm-debug|yarn-error|yarn-debug).log*` files + // and the rest of knownGeneratedFiles. + if ( + (fileToMatch.match(/.log/g) && file.indexOf(fileToMatch) === 0) || + file === fileToMatch + ) { + console.log(`Deleting generated file... ${chalk.cyan(file)}`); + fs.removeSync(path.join(root, file)); + } + }); + }); + const remainingFiles = fs.readdirSync(path.join(root)); + if (!remainingFiles.length) { + // Delete target folder if empty + console.log( + `Deleting ${chalk.cyan(`${appName} /`)} from ${chalk.cyan(path.resolve(root, '..'))}` + ); + process.chdir(path.resolve(root, '..')); + fs.removeSync(path.join(root)); + } + console.log('Done.'); + process.exit(1); + }); +} + +function getInstallPackage(version) { + let packageToInstall = 'react-scripts'; + const validSemver = semver.valid(version); + if (validSemver) { + packageToInstall += `@${validSemver}`; + } else if (version) { + // for tar.gz or alternative paths + packageToInstall = version; + } + return packageToInstall; +} + +function getTemporaryDirectory() { + return new Promise((resolve, reject) => { + // Unsafe cleanup lets us recursively delete the directory if it contains + // contents; by default it only allows removal if it's empty + tmp.dir({ unsafeCleanup: true }, (err, tmpdir, callback) => { + if (err) { + reject(err); + } else { + resolve({ + tmpdir: tmpdir, + cleanup: () => { + try { + callback(); + } catch (ignored) { + // Callback might throw and fail, since it's a temp directory the + // OS will clean it up eventually... + } + }, + }); + } + }); + }); +} + +function extractStream(stream, dest) { + return new Promise((resolve, reject) => { + stream.pipe( + unpack(dest, err => { + if (err) { + reject(err); + } else { + resolve(dest); + } + }) + ); + }); +} + +// Extract package name from tarball url or path. +function getPackageName(installPackage) { + if (installPackage.indexOf('.tgz') > -1) { + return getTemporaryDirectory() + .then(obj => { + let stream; + if (/^http/.test(installPackage)) { + stream = hyperquest(installPackage); + } else { + stream = fs.createReadStream(installPackage); + } + return extractStream(stream, obj.tmpdir).then(() => obj); + }) + .then(obj => { + const packageName = require(path.join(obj.tmpdir, 'package.json')).name; + obj.cleanup(); + return packageName; + }) + .catch(err => { + // The package name could be with or without semver version, e.g. react-scripts-0.2.0-alpha.1.tgz + // However, this function returns package name only without semver version. + console.log( + `Could not extract the package name from the archive: ${err.message}` + ); + const assumedProjectName = installPackage.match( + /^.+\/(.+?)(?:-\d+.+)?\.tgz$/ + )[1]; + console.log( + `Based on the filename, assuming it is "${chalk.cyan(assumedProjectName)}"` + ); + return Promise.resolve(assumedProjectName); + }); + } else if (installPackage.indexOf('git+') === 0) { + // Pull package name out of git urls e.g: + // git+https://github.com/mycompany/react-scripts.git + // git+ssh://github.com/mycompany/react-scripts.git#v1.2.3 + return Promise.resolve(installPackage.match(/([^\/]+)\.git(#.*)?$/)[1]); + } else if (installPackage.indexOf('@') > 0) { + // Do not match @scope/ when stripping off @version or @tag + return Promise.resolve( + installPackage.charAt(0) + installPackage.substr(1).split('@')[0] + ); + } + return Promise.resolve(installPackage); +} + +function checkNpmVersion() { + let isNpm2 = false; + try { + const npmVersion = execSync('npm --version').toString(); + isNpm2 = semver.lt(npmVersion, '3.0.0'); + } catch (err) { + return; + } + if (!isNpm2) { + return; + } + console.log(chalk.yellow('It looks like you are using npm 2.')); + console.log( + chalk.yellow( + 'We suggest using npm 3 or Yarn for faster install times ' + + 'and less disk space usage.' + ) + ); + console.log(); +} + +function checkNodeVersion(packageName) { + const packageJsonPath = path.resolve( + process.cwd(), + 'node_modules', + packageName, + 'package.json' + ); + const packageJson = require(packageJsonPath); + if (!packageJson.engines || !packageJson.engines.node) { + return; + } + + if (!semver.satisfies(process.version, packageJson.engines.node)) { + console.error( + chalk.red( + 'You are running Node %s.\n' + + 'Create React App requires Node %s or higher. \n' + + 'Please update your version of Node.' + ), + process.version, + packageJson.engines.node + ); + process.exit(1); + } +} + +function checkAppName(appName) { + const validationResult = validateProjectName(appName); + if (!validationResult.validForNewPackages) { + console.error( + `Could not create a project called ${chalk.red(`"${appName}"`)} because of npm naming restrictions:` + ); + printValidationResults(validationResult.errors); + printValidationResults(validationResult.warnings); + process.exit(1); + } + + // TODO: there should be a single place that holds the dependencies + const dependencies = ['react', 'react-dom']; + const devDependencies = ['react-scripts']; + const allDependencies = dependencies.concat(devDependencies).sort(); + if (allDependencies.indexOf(appName) >= 0) { + console.error( + chalk.red( + `We cannot create a project called ${chalk.green(appName)} because a dependency with the same name exists.\n` + + `Due to the way npm works, the following names are not allowed:\n\n` + ) + + chalk.cyan(allDependencies.map(depName => ` ${depName}`).join('\n')) + + chalk.red('\n\nPlease choose a different project name.') + ); + process.exit(1); + } +} + +function makeCaretRange(dependencies, name) { + const version = dependencies[name]; + + if (typeof version === 'undefined') { + console.error(chalk.red(`Missing ${name} dependency in package.json`)); + process.exit(1); + } + + let patchedVersion = `^${version}`; + + if (!semver.validRange(patchedVersion)) { + console.error( + `Unable to patch ${name} dependency version because version ${chalk.red(version)} will become invalid ${chalk.red(patchedVersion)}` + ); + patchedVersion = version; + } + + dependencies[name] = patchedVersion; +} + +function fixDependencies(packageName) { + const packagePath = path.join(process.cwd(), 'package.json'); + const packageJson = require(packagePath); + + if (typeof packageJson.dependencies === 'undefined') { + console.error(chalk.red('Missing dependencies in package.json')); + process.exit(1); + } + + const packageVersion = packageJson.dependencies[packageName]; + + if (typeof packageVersion === 'undefined') { + console.error(chalk.red(`Unable to find ${packageName} in package.json`)); + process.exit(1); + } + + packageJson.devDependencies = packageJson.devDependencies || {}; + packageJson.devDependencies[packageName] = packageVersion; + delete packageJson.dependencies[packageName]; + + makeCaretRange(packageJson.dependencies, 'react'); + makeCaretRange(packageJson.dependencies, 'react-dom'); + + fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2)); +} + +// If project only contains files generated by GH, it’s safe. +// We also special case IJ-based products .idea because it integrates with CRA: +// https://github.com/facebookincubator/create-react-app/pull/368#issuecomment-243446094 +function isSafeToCreateProjectIn(root) { + const validFiles = [ + '.DS_Store', + 'Thumbs.db', + '.git', + '.gitignore', + '.idea', + 'README.md', + 'LICENSE', + 'web.iml', + ]; + return fs.readdirSync(root).every(file => validFiles.indexOf(file) >= 0); +} + +function checkIfOnline(useYarn) { + if (!useYarn) { + // Don't ping the Yarn registry. + // We'll just assume the best case. + return Promise.resolve(true); + } + + return new Promise(resolve => { + dns.resolve('registry.yarnpkg.com', err => { + resolve(err === null); + }); + }); +} diff --git a/packages/create-react-app/index.js b/packages/create-react-app/index.js index ebeae5b41b0..19a3ff09fd4 100755 --- a/packages/create-react-app/index.js +++ b/packages/create-react-app/index.js @@ -39,489 +39,19 @@ 'use strict'; var chalk = require('chalk'); -var validateProjectName = require("validate-npm-package-name"); var currentNodeVersion = process.versions.node; if (currentNodeVersion.split('.')[0] < 4) { console.error( chalk.red( - 'You are running Node ' + currentNodeVersion + '.\n' + - 'Create React App requires Node 4 or higher. \n' + - 'Please update your version of Node.' + 'You are running Node ' + + currentNodeVersion + + '.\n' + + 'Create React App requires Node 4 or higher. \n' + + 'Please update your version of Node.' ) ); process.exit(1); } -var commander = require('commander'); -var fs = require('fs-extra'); -var path = require('path'); -var execSync = require('child_process').execSync; -var spawn = require('cross-spawn'); -var semver = require('semver'); -var dns = require('dns'); -var tmp = require('tmp'); -var unpack = require('tar-pack').unpack; -var hyperquest = require('hyperquest'); - -var projectName; - -var program = commander - .version(require('./package.json').version) - .arguments('') - .usage(chalk.green('') + ' [options]') - .action(function (name) { - projectName = name; - }) - .option('--verbose', 'print additional logs') - .option('--scripts-version ', 'use a non-standard version of react-scripts') - .allowUnknownOption() - .on('--help', function () { - console.log(' Only ' + chalk.green('') + ' is required.'); - console.log(); - console.log(' A custom ' + chalk.cyan('--scripts-version') + ' can be one of:'); - console.log(' - a specific npm version: ' + chalk.green('0.8.2')); - console.log(' - a custom fork published on npm: ' + chalk.green('my-react-scripts')); - console.log(' - a .tgz archive: ' + chalk.green('https://mysite.com/my-react-scripts-0.8.2.tgz')); - console.log(' It is not needed unless you specifically want to use a fork.'); - console.log(); - console.log(' If you have any problems, do not hesitate to file an issue:'); - console.log(' ' + chalk.cyan('https://github.com/facebookincubator/create-react-app/issues/new')); - console.log(); - }) - .parse(process.argv); - -if (typeof projectName === 'undefined') { - console.error('Please specify the project directory:'); - console.log(' ' + chalk.cyan(program.name()) + chalk.green(' ')); - console.log(); - console.log('For example:'); - console.log(' ' + chalk.cyan(program.name()) + chalk.green(' my-react-app')); - console.log(); - console.log('Run ' + chalk.cyan(program.name() + ' --help') + ' to see all options.'); - process.exit(1); -} - -function printValidationResults(results) { - if (typeof results !== 'undefined') { - results.forEach(function (error) { - console.error(chalk.red(' * ' + error)); - }); - } -} - -var hiddenProgram = new commander.Command() - .option('--internal-testing-template ', '(internal usage only, DO NOT RELY ON THIS) ' + - 'use a non-standard application template') - .parse(process.argv) - -createApp(projectName, program.verbose, program.scriptsVersion, hiddenProgram.internalTestingTemplate); - -function createApp(name, verbose, version, template) { - var root = path.resolve(name); - var appName = path.basename(root); - - checkAppName(appName); - fs.ensureDirSync(name); - if (!isSafeToCreateProjectIn(root)) { - console.log('The directory ' + chalk.green(name) + ' contains files that could conflict.'); - console.log('Try using a new directory name.'); - process.exit(1); - } - - console.log( - 'Creating a new React app in ' + chalk.green(root) + '.' - ); - console.log(); - - var packageJson = { - name: appName, - version: '0.1.0', - private: true - }; - fs.writeFileSync( - path.join(root, 'package.json'), - JSON.stringify(packageJson, null, 2) - ); - var originalDirectory = process.cwd(); - process.chdir(root); - - run(root, appName, version, verbose, originalDirectory, template); -} - -function shouldUseYarn() { - try { - execSync('yarnpkg --version', {stdio: 'ignore'}); - return true; - } catch (e) { - return false; - } -} - -function install(useYarn, dependencies, verbose, isOnline) { - return new Promise(function(resolve, reject) { - var command; - var args; - if (useYarn) { - command = 'yarnpkg'; - args = [ - 'add', - '--exact', - ]; - if (!isOnline) { - args.push('--offline'); - } - [].push.apply(args, dependencies); - - if (!isOnline) { - console.log(chalk.yellow('You appear to be offline.')); - console.log(chalk.yellow('Falling back to the local Yarn cache.')); - console.log(); - } - - } else { - checkNpmVersion(); - command = 'npm'; - args = ['install', '--save', '--save-exact'].concat(dependencies); - } - - if (verbose) { - args.push('--verbose'); - } - - var child = spawn(command, args, {stdio: 'inherit'}); - child.on('close', function(code) { - if (code !== 0) { - reject({ - command: command + ' ' + args.join(' ') - }); - return; - } - resolve(); - }); - }); -} - -function run(root, appName, version, verbose, originalDirectory, template) { - var packageToInstall = getInstallPackage(version); - var allDependencies = ['react', 'react-dom', packageToInstall]; - - console.log('Installing packages. This might take a couple minutes.'); - - var useYarn = shouldUseYarn(); - getPackageName(packageToInstall) - .then(function(packageName) { - return checkIfOnline(useYarn).then(function(isOnline) { - return { - isOnline: isOnline, - packageName: packageName, - }; - }); - }) - .then(function(info) { - var isOnline = info.isOnline; - var packageName = info.packageName; - console.log( - 'Installing ' + chalk.cyan('react') + ', ' + chalk.cyan('react-dom') + - ', and ' + chalk.cyan(packageName) + '...' - ); - console.log(); - - return install(useYarn, allDependencies, verbose, isOnline).then(function() { - return packageName; - }); - }) - .then(function(packageName) { - checkNodeVersion(packageName); - - // Since react-scripts has been installed with --save - // we need to move it into devDependencies and rewrite package.json - // also ensure react dependencies have caret version range - fixDependencies(packageName); - - var scriptsPath = path.resolve( - process.cwd(), - 'node_modules', - packageName, - 'scripts', - 'init.js' - ); - var init = require(scriptsPath); - init(root, appName, verbose, originalDirectory, template); - }) - .catch(function(reason) { - console.log(); - console.log('Aborting installation.'); - if (reason.command) { - console.log(' ' + chalk.cyan(reason.command), 'has failed.') - } else { - console.log(chalk.red('Unexpected error. Please report it as a bug:')); - console.log(reason); - } - console.log(); - - // On 'exit' we will delete these files from target directory. - var knownGeneratedFiles = [ - 'package.json', 'npm-debug.log', 'yarn-error.log', 'yarn-debug.log', 'node_modules' - ]; - var currentFiles = fs.readdirSync(path.join(root)); - currentFiles.forEach(function (file) { - knownGeneratedFiles.forEach(function (fileToMatch) { - // This will catch `(npm-debug|yarn-error|yarn-debug).log*` files - // and the rest of knownGeneratedFiles. - if ((fileToMatch.match(/.log/g) && file.indexOf(fileToMatch) === 0) || file === fileToMatch) { - console.log('Deleting generated file...', chalk.cyan(file)); - fs.removeSync(path.join(root, file)); - } - }); - }); - var remainingFiles = fs.readdirSync(path.join(root)); - if (!remainingFiles.length) { - // Delete target folder if empty - console.log('Deleting', chalk.cyan(appName + '/'), 'from', chalk.cyan(path.resolve(root, '..'))); - process.chdir(path.resolve(root, '..')); - fs.removeSync(path.join(root)); - } - console.log('Done.'); - process.exit(1); - }); -} - -function getInstallPackage(version) { - var packageToInstall = 'react-scripts'; - var validSemver = semver.valid(version); - if (validSemver) { - packageToInstall += '@' + validSemver; - } else if (version) { - // for tar.gz or alternative paths - packageToInstall = version; - } - return packageToInstall; -} - -function getTemporaryDirectory() { - return new Promise(function(resolve, reject) { - // Unsafe cleanup lets us recursively delete the directory if it contains - // contents; by default it only allows removal if it's empty - tmp.dir({ unsafeCleanup: true }, function(err, tmpdir, callback) { - if (err) { - reject(err); - } else { - resolve({ - tmpdir: tmpdir, - cleanup: function() { - try { - callback(); - } catch (ignored) { - // Callback might throw and fail, since it's a temp directory the - // OS will clean it up eventually... - } - } - }); - } - }); - }); -} - -function extractStream(stream, dest) { - return new Promise(function(resolve, reject) { - stream.pipe(unpack(dest, function(err) { - if (err) { - reject(err); - } else { - resolve(dest); - } - })); - }); -} - -// Extract package name from tarball url or path. -function getPackageName(installPackage) { - if (installPackage.indexOf('.tgz') > -1) { - return getTemporaryDirectory().then(function(obj) { - var stream; - if (/^http/.test(installPackage)) { - stream = hyperquest(installPackage); - } else { - stream = fs.createReadStream(installPackage); - } - return extractStream(stream, obj.tmpdir).then(function() { - return obj; - }); - }).then(function(obj) { - var packageName = require(path.join(obj.tmpdir, 'package.json')).name; - obj.cleanup(); - return packageName; - }).catch(function(err) { - // The package name could be with or without semver version, e.g. react-scripts-0.2.0-alpha.1.tgz - // However, this function returns package name only without semver version. - console.log('Could not extract the package name from the archive: ' + err.message); - var assumedProjectName = installPackage.match(/^.+\/(.+?)(?:-\d+.+)?\.tgz$/)[1]; - console.log('Based on the filename, assuming it is "' + chalk.cyan(assumedProjectName) + '"'); - return Promise.resolve(assumedProjectName); - }); - } else if (installPackage.indexOf('git+') === 0) { - // Pull package name out of git urls e.g: - // git+https://github.com/mycompany/react-scripts.git - // git+ssh://github.com/mycompany/react-scripts.git#v1.2.3 - return Promise.resolve(installPackage.match(/([^\/]+)\.git(#.*)?$/)[1]); - } else if (installPackage.indexOf('@') > 0) { - // Do not match @scope/ when stripping off @version or @tag - return Promise.resolve(installPackage.charAt(0) + installPackage.substr(1).split('@')[0]); - } - return Promise.resolve(installPackage); -} - -function checkNpmVersion() { - var isNpm2 = false; - try { - var npmVersion = execSync('npm --version').toString(); - isNpm2 = semver.lt(npmVersion, '3.0.0'); - } catch (err) { - return; - } - if (!isNpm2) { - return; - } - console.log(chalk.yellow('It looks like you are using npm 2.')); - console.log(chalk.yellow( - 'We suggest using npm 3 or Yarn for faster install times ' + - 'and less disk space usage.' - )); - console.log(); -} - -function checkNodeVersion(packageName) { - var packageJsonPath = path.resolve( - process.cwd(), - 'node_modules', - packageName, - 'package.json' - ); - var packageJson = require(packageJsonPath); - if (!packageJson.engines || !packageJson.engines.node) { - return; - } - - if (!semver.satisfies(process.version, packageJson.engines.node)) { - console.error( - chalk.red( - 'You are running Node %s.\n' + - 'Create React App requires Node %s or higher. \n' + - 'Please update your version of Node.' - ), - process.version, - packageJson.engines.node - ); - process.exit(1); - } -} - -function checkAppName(appName) { - var validationResult = validateProjectName(appName); - if (!validationResult.validForNewPackages) { - console.error('Could not create a project called ' + chalk.red('"' + appName + '"') + ' because of npm naming restrictions:'); - printValidationResults(validationResult.errors); - printValidationResults(validationResult.warnings); - process.exit(1); - } - - // TODO: there should be a single place that holds the dependencies - var dependencies = ['react', 'react-dom']; - var devDependencies = ['react-scripts']; - var allDependencies = dependencies.concat(devDependencies).sort(); - if (allDependencies.indexOf(appName) >= 0) { - console.error( - chalk.red( - 'We cannot create a project called ' + chalk.green(appName) + ' because a dependency with the same name exists.\n' + - 'Due to the way npm works, the following names are not allowed:\n\n' - ) + - chalk.cyan( - allDependencies.map(function(depName) { - return ' ' + depName; - }).join('\n') - ) + - chalk.red('\n\nPlease choose a different project name.') - ); - process.exit(1); - } -} - -function makeCaretRange(dependencies, name) { - var version = dependencies[name]; - - if (typeof version === 'undefined') { - console.error( - chalk.red('Missing ' + name + ' dependency in package.json') - ); - process.exit(1); - } - - var patchedVersion = '^' + version; - - if (!semver.validRange(patchedVersion)) { - console.error( - 'Unable to patch ' + name + ' dependency version because version ' + chalk.red(version) + ' will become invalid ' + chalk.red(patchedVersion) - ); - patchedVersion = version; - } - - dependencies[name] = patchedVersion; -} - -function fixDependencies(packageName) { - var packagePath = path.join(process.cwd(), 'package.json'); - var packageJson = require(packagePath); - - if (typeof packageJson.dependencies === 'undefined') { - console.error( - chalk.red('Missing dependencies in package.json') - ); - process.exit(1); - } - - var packageVersion = packageJson.dependencies[packageName]; - - if (typeof packageVersion === 'undefined') { - console.error( - chalk.red('Unable to find ' + packageName + ' in package.json') - ); - process.exit(1); - } - - packageJson.devDependencies = packageJson.devDependencies || {}; - packageJson.devDependencies[packageName] = packageVersion; - delete packageJson.dependencies[packageName]; - - makeCaretRange(packageJson.dependencies, 'react'); - makeCaretRange(packageJson.dependencies, 'react-dom'); - - fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2)); -} - -// If project only contains files generated by GH, it’s safe. -// We also special case IJ-based products .idea because it integrates with CRA: -// https://github.com/facebookincubator/create-react-app/pull/368#issuecomment-243446094 -function isSafeToCreateProjectIn(root) { - var validFiles = [ - '.DS_Store', 'Thumbs.db', '.git', '.gitignore', '.idea', 'README.md', 'LICENSE', 'web.iml' - ]; - return fs.readdirSync(root) - .every(function(file) { - return validFiles.indexOf(file) >= 0; - }); -} - -function checkIfOnline(useYarn) { - if (!useYarn) { - // Don't ping the Yarn registry. - // We'll just assume the best case. - return Promise.resolve(true); - } - - return new Promise(function(resolve) { - dns.resolve('registry.yarnpkg.com', function(err) { - resolve(err === null); - }); - }); -} +require('./createReactApp'); diff --git a/packages/create-react-app/package.json b/packages/create-react-app/package.json index 4450add254c..918fcbefa56 100644 --- a/packages/create-react-app/package.json +++ b/packages/create-react-app/package.json @@ -14,7 +14,8 @@ "url": "https://github.com/facebookincubator/create-react-app/issues" }, "files": [ - "index.js" + "index.js", + "createReactApp.js" ], "bin": { "create-react-app": "./index.js" diff --git a/packages/eslint-config-react-app/index.js b/packages/eslint-config-react-app/index.js index 44066a6eacf..1c6911cb2de 100644 --- a/packages/eslint-config-react-app/index.js +++ b/packages/eslint-config-react-app/index.js @@ -30,7 +30,7 @@ module.exports = { commonjs: true, es6: true, jest: true, - node: true + node: true, }, parserOptions: { @@ -39,20 +39,18 @@ module.exports = { ecmaFeatures: { jsx: true, generators: true, - experimentalObjectRestSpread: true - } + experimentalObjectRestSpread: true, + }, }, settings: { - 'import/ignore': [ - 'node_modules' - ], + 'import/ignore': ['node_modules'], 'import/extensions': ['.js'], 'import/resolver': { node: { - extensions: ['.js', '.json'] - } - } + extensions: ['.js', '.json'], + }, + }, }, rules: { @@ -89,15 +87,18 @@ module.exports = { 'no-labels': ['warn', { allowLoop: false, allowSwitch: false }], 'no-lone-blocks': 'warn', 'no-loop-func': 'warn', - 'no-mixed-operators': ['warn', { - groups: [ - ['&', '|', '^', '~', '<<', '>>', '>>>'], - ['==', '!=', '===', '!==', '>', '>=', '<', '<='], - ['&&', '||'], - ['in', 'instanceof'] - ], - allowSamePrecedence: false - }], + 'no-mixed-operators': [ + 'warn', + { + groups: [ + ['&', '|', '^', '~', '<<', '>>', '>>>'], + ['==', '!=', '===', '!==', '>', '>=', '<', '<='], + ['&&', '||'], + ['in', 'instanceof'], + ], + allowSamePrecedence: false, + }, + ], 'no-multi-str': 'warn', 'no-native-reassign': 'warn', 'no-negated-in-lhs': 'warn', @@ -110,11 +111,7 @@ module.exports = { 'no-octal-escape': 'warn', 'no-redeclare': 'warn', 'no-regex-spaces': 'warn', - 'no-restricted-syntax': [ - 'warn', - 'LabeledStatement', - 'WithStatement', - ], + 'no-restricted-syntax': ['warn', 'LabeledStatement', 'WithStatement'], 'no-script-url': 'warn', 'no-self-assign': 'warn', 'no-self-compare': 'warn', @@ -128,27 +125,36 @@ module.exports = { 'no-restricted-globals': ['error', 'event'], 'no-unexpected-multiline': 'warn', 'no-unreachable': 'warn', - 'no-unused-expressions': ['warn', { - 'allowShortCircuit': true, - 'allowTernary': true - }], + 'no-unused-expressions': [ + 'warn', + { + allowShortCircuit: true, + allowTernary: true, + }, + ], 'no-unused-labels': 'warn', - 'no-unused-vars': ['warn', { - vars: 'local', - varsIgnorePattern: '^_', - args: 'none', - ignoreRestSiblings: true, - }], + 'no-unused-vars': [ + 'warn', + { + vars: 'local', + varsIgnorePattern: '^_', + args: 'none', + ignoreRestSiblings: true, + }, + ], 'no-use-before-define': ['warn', 'nofunc'], 'no-useless-computed-key': 'warn', 'no-useless-concat': 'warn', 'no-useless-constructor': 'warn', 'no-useless-escape': 'warn', - 'no-useless-rename': ['warn', { - ignoreDestructuring: false, - ignoreImport: false, - ignoreExport: false, - }], + 'no-useless-rename': [ + 'warn', + { + ignoreDestructuring: false, + ignoreImport: false, + ignoreExport: false, + }, + ], 'no-with': 'warn', 'no-whitespace-before-property': 'warn', 'operator-assignment': ['warn', 'always'], @@ -159,15 +165,19 @@ module.exports = { 'unicode-bom': ['warn', 'never'], 'use-isnan': 'warn', 'valid-typeof': 'warn', - 'no-restricted-properties': ['error', { - object: 'require', - property: 'ensure', - message: 'Please use import() instead. More info: https://webpack.js.org/guides/code-splitting-import/#dynamic-import' - }, { - object: 'System', - property: 'import', - message: 'Please use import() instead. More info: https://webpack.js.org/guides/code-splitting-import/#dynamic-import' - }], + 'no-restricted-properties': [ + 'error', + { + object: 'require', + property: 'ensure', + message: 'Please use import() instead. More info: https://webpack.js.org/guides/code-splitting-import/#dynamic-import', + }, + { + object: 'System', + property: 'import', + message: 'Please use import() instead. More info: https://webpack.js.org/guides/code-splitting-import/#dynamic-import', + }, + ], // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/ @@ -203,10 +213,13 @@ module.exports = { 'react/jsx-equals-spacing': ['warn', 'never'], 'react/jsx-no-duplicate-props': ['warn', { ignoreCase: true }], 'react/jsx-no-undef': 'error', - 'react/jsx-pascal-case': ['warn', { - allowAllCaps: true, - ignore: [], - }], + 'react/jsx-pascal-case': [ + 'warn', + { + allowAllCaps: true, + ignore: [], + }, + ], 'react/jsx-uses-react': 'warn', 'react/jsx-uses-vars': 'warn', 'react/no-danger-with-children': 'warn', @@ -226,6 +239,6 @@ module.exports = { // https://github.com/gajus/eslint-plugin-flowtype 'flowtype/define-flow-type': 'warn', 'flowtype/require-valid-file-annotation': 'warn', - 'flowtype/use-flow-type': 'warn' - } + 'flowtype/use-flow-type': 'warn', + }, }; diff --git a/packages/react-dev-utils/FileSizeReporter.js b/packages/react-dev-utils/FileSizeReporter.js index 08273673f92..a0db0684f4a 100644 --- a/packages/react-dev-utils/FileSizeReporter.js +++ b/packages/react-dev-utils/FileSizeReporter.js @@ -33,7 +33,7 @@ function printFileSizesAfterBuild(webpackStats, previousSizeMap) { folder: path.join('build', path.dirname(asset.name)), name: path.basename(asset.name), size: size, - sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : '') + sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : ''), }; }); assets.sort((a, b) => b.size - a.size); @@ -88,12 +88,15 @@ function measureFileSizesBeforeBuild(buildFolder) { if (!err && fileNames) { sizes = fileNames .filter(fileName => /\.(js|css)$/.test(fileName)) - .reduce((memo, fileName) => { - var contents = fs.readFileSync(fileName); - var key = removeFileNameHash(buildFolder, fileName); - memo[key] = gzipSize(contents); - return memo; - }, {}); + .reduce( + (memo, fileName) => { + var contents = fs.readFileSync(fileName); + var key = removeFileNameHash(buildFolder, fileName); + memo[key] = gzipSize(contents); + return memo; + }, + {} + ); } resolve({ root: buildFolder, diff --git a/packages/react-dev-utils/InterpolateHtmlPlugin.js b/packages/react-dev-utils/InterpolateHtmlPlugin.js index 07558f47830..ac1d3e9967d 100644 --- a/packages/react-dev-utils/InterpolateHtmlPlugin.js +++ b/packages/react-dev-utils/InterpolateHtmlPlugin.js @@ -25,7 +25,8 @@ class InterpolateHtmlPlugin { apply(compiler) { compiler.plugin('compilation', compilation => { - compilation.plugin('html-webpack-plugin-before-html-processing', + compilation.plugin( + 'html-webpack-plugin-before-html-processing', (data, callback) => { // Run HTML through a series of user-specified string replacements. Object.keys(this.replacements).forEach(key => { diff --git a/packages/react-dev-utils/ansiHTML.js b/packages/react-dev-utils/ansiHTML.js index 27a514e01d0..1144fec5e65 100644 --- a/packages/react-dev-utils/ansiHTML.js +++ b/packages/react-dev-utils/ansiHTML.js @@ -34,15 +34,15 @@ var base0E = 'a71d5d'; // Keywords, Storage, Selector, Markup Italic, Diff Chang var colors = { reset: [base05, 'transparent'], black: base05, - red: base08, /* marker, bg-invalid */ - green: base0B, /* string */ - yellow: base08, /* capitalized, jsx_tag, punctuator */ + red: base08 /* marker, bg-invalid */, + green: base0B /* string */, + yellow: base08 /* capitalized, jsx_tag, punctuator */, blue: base0C, - magenta: base0C, /* regex */ - cyan: base0E, /* keyword */ - gray: base03, /* comment, gutter */ + magenta: base0C /* regex */, + cyan: base0E /* keyword */, + gray: base03 /* comment, gutter */, lightgrey: base01, - darkgrey: base03 + darkgrey: base03, }; var anserMap = { @@ -56,20 +56,19 @@ var anserMap = { 'ansi-bright-red': 'red', 'ansi-red': 'red', 'ansi-bright-magenta': 'magenta', - 'ansi-magenta': 'magenta' + 'ansi-magenta': 'magenta', }; function ansiHTML(txt) { var arr = new Anser().ansiToJson(txt, { - use_classes: true + use_classes: true, }); var result = ''; var open = false; for (var index = 0; index < arr.length; ++index) { var c = arr[index]; - var content = c.content, - fg = c.fg; + var content = c.content, fg = c.fg; var contentParts = content.split('\n'); for (var _index = 0; _index < contentParts.length; ++_index) { diff --git a/packages/react-dev-utils/clearConsole.js b/packages/react-dev-utils/clearConsole.js index 74336284723..05ab28c44d2 100644 --- a/packages/react-dev-utils/clearConsole.js +++ b/packages/react-dev-utils/clearConsole.js @@ -10,7 +10,9 @@ 'use strict'; function clearConsole() { - process.stdout.write(process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H'); + process.stdout.write( + process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H' + ); } module.exports = clearConsole; diff --git a/packages/react-dev-utils/crashOverlay.js b/packages/react-dev-utils/crashOverlay.js index d92e793ac18..4f58e927f3c 100644 --- a/packages/react-dev-utils/crashOverlay.js +++ b/packages/react-dev-utils/crashOverlay.js @@ -68,15 +68,18 @@ var css = [ ' .cra-container {', ' width: calc(1170px - 6em);', ' }', - '}' + '}', ].join('\n'); var overlayStyle = { position: 'fixed', 'box-sizing': 'border-box', - top: '1em', left: '1em', - bottom: '1em', right: '1em', - width: 'calc(100% - 2em)', height: 'calc(100% - 2em)', + top: '1em', + left: '1em', + bottom: '1em', + right: '1em', + width: 'calc(100% - 2em)', + height: 'calc(100% - 2em)', 'border-radius': '3px', 'background-color': lightGray, padding: '4rem', @@ -88,7 +91,7 @@ var overlayStyle = { 'overflow-x': 'hidden', 'word-break': 'break-all', 'box-shadow': '0 0 6px 0 rgba(0, 0, 0, 0.5)', - 'line-height': 1.5 + 'line-height': 1.5, }; var hintsStyle = { @@ -96,12 +99,12 @@ var hintsStyle = { 'margin-top': '-3em', 'margin-bottom': '3em', 'text-align': 'right', - color: darkGray + color: darkGray, }; var hintStyle = { padding: '0.5em 1em', - cursor: 'pointer' + cursor: 'pointer', }; var closeButtonStyle = { @@ -111,55 +114,55 @@ var closeButtonStyle = { cursor: 'pointer', position: 'absolute', right: 0, - top: 0 + top: 0, }; var additionalStyle = { 'margin-bottom': '1.5em', - 'margin-top': '-4em' + 'margin-top': '-4em', }; var headerStyle = { 'font-size': '1.7em', 'font-weight': 'bold', - color: red + color: red, }; var functionNameStyle = { 'margin-top': '1em', - 'font-size': '1.2em' + 'font-size': '1.2em', }; var linkStyle = { - 'font-size': '0.9em' + 'font-size': '0.9em', }; var anchorStyle = { 'text-decoration': 'none', - color: darkGray + color: darkGray, }; var traceStyle = { - 'font-size': '1em' + 'font-size': '1em', }; var depStyle = { - 'font-size': '1.2em' + 'font-size': '1.2em', }; var primaryErrorStyle = { - 'background-color': lightRed + 'background-color': lightRed, }; var secondaryErrorStyle = { - 'background-color': yellow + 'background-color': yellow, }; var omittedFramesStyle = { color: black, 'font-size': '0.9em', - 'margin': '1.5em 0', - cursor: 'pointer' + margin: '1.5em 0', + cursor: 'pointer', }; var preStyle = { @@ -169,25 +172,25 @@ var preStyle = { 'margin-bottom': '0px', 'overflow-x': 'auto', 'font-size': '1.1em', - 'white-space': 'pre' + 'white-space': 'pre', }; var toggleStyle = { 'margin-bottom': '1.5em', color: darkGray, - cursor: 'pointer' + cursor: 'pointer', }; var codeStyle = { - 'font-family': 'Consolas, Menlo, monospace' + 'font-family': 'Consolas, Menlo, monospace', }; var hiddenStyle = { - display: 'none' + display: 'none', }; var groupStyle = { - 'margin-left': '1em' + 'margin-left': '1em', }; var _groupElemStyle = { @@ -197,24 +200,24 @@ var _groupElemStyle = { 'border-radius': '4px', 'border-style': 'solid', padding: '3px 6px', - cursor: 'pointer' + cursor: 'pointer', }; var groupElemLeft = Object.assign({}, _groupElemStyle, { 'border-top-right-radius': '0px', 'border-bottom-right-radius': '0px', - 'margin-right': '0px' + 'margin-right': '0px', }); var groupElemRight = Object.assign({}, _groupElemStyle, { 'border-top-left-radius': '0px', 'border-bottom-left-radius': '0px', - 'margin-left': '-1px' + 'margin-left': '-1px', }); var footerStyle = { 'text-align': 'center', - color: darkGray + color: darkGray, }; function applyStyles(element, styles) { @@ -244,10 +247,8 @@ function consumeEvent(e) { function accessify(node) { node.setAttribute('tabindex', 0); - node.addEventListener('keydown', function (e) { - var key = e.key, - which = e.which, - keyCode = e.keyCode; + node.addEventListener('keydown', function(e) { + var key = e.key, which = e.which, keyCode = e.keyCode; if (key === 'Enter' || which === 13 || keyCode === 13) { e.preventDefault(); e.target.click(); @@ -272,7 +273,7 @@ function renderAdditional() { applyStyles(group, groupStyle); var left = document.createElement('button'); applyStyles(left, groupElemLeft); - left.addEventListener('click', function (e) { + left.addEventListener('click', function(e) { consumeEvent(e); switchError(-1); }); @@ -280,7 +281,7 @@ function renderAdditional() { accessify(left); var right = document.createElement('button'); applyStyles(right, groupElemRight); - right.addEventListener('click', function (e) { + right.addEventListener('click', function(e) { consumeEvent(e); switchError(1); }); @@ -314,11 +315,13 @@ function absolutifyCode(component) { } function sourceCodePre(sourceLines, lineNum, columnNum) { - var main = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + var main = arguments.length > 3 && arguments[3] !== undefined + ? arguments[3] + : false; var sourceCode = []; var whiteSpace = Infinity; - sourceLines.forEach(function (_ref2) { + sourceLines.forEach(function(_ref2) { var text = _ref2.text; var m = text.match(/^\s*/); @@ -329,19 +332,23 @@ function sourceCodePre(sourceLines, lineNum, columnNum) { whiteSpace = 0; } }); - sourceLines.forEach(function (_ref3) { - var text = _ref3.text, - line = _ref3.line; + sourceLines.forEach(function(_ref3) { + var text = _ref3.text, line = _ref3.line; if (isFinite(whiteSpace)) text = text.substring(whiteSpace); sourceCode[line - 1] = text; }); sourceCode = sourceCode.join('\n'); - var ansiHighlight = codeFrame(sourceCode, lineNum, columnNum - (isFinite(whiteSpace) ? whiteSpace : 0), { - forceColor: true, - linesAbove: CONTEXT_SIZE, - linesBelow: CONTEXT_SIZE - }); + var ansiHighlight = codeFrame( + sourceCode, + lineNum, + columnNum - (isFinite(whiteSpace) ? whiteSpace : 0), + { + forceColor: true, + linesAbove: CONTEXT_SIZE, + linesBelow: CONTEXT_SIZE, + } + ); var htmlHighlight = ansiHTML(ansiHighlight); var code = document.createElement('code'); code.innerHTML = htmlHighlight; @@ -379,7 +386,7 @@ function hintsDiv() { applyStyles(hints, hintsStyle); var close = createHint('×'); - close.addEventListener('click', function () { + close.addEventListener('click', function() { unmount(); }); applyStyles(close, closeButtonStyle); @@ -401,7 +408,10 @@ function frameDiv(functionName, url, internalUrl) { var cleanedUrl = url.replace('webpack://', '.'); if (internalUrl) { - applyStyles(frameFunctionName, Object.assign({}, functionNameStyle, depStyle)); + applyStyles( + frameFunctionName, + Object.assign({}, functionNameStyle, depStyle) + ); } else { applyStyles(frameFunctionName, functionNameStyle); } @@ -424,9 +434,11 @@ function frameDiv(functionName, url, internalUrl) { function getGroupToggle(omitsCount, omitBundle) { var omittedFrames = document.createElement('div'); accessify(omittedFrames); - var text1 = document.createTextNode('\u25B6 ' + omitsCount + ' stack frames were collapsed.'); + var text1 = document.createTextNode( + '\u25B6 ' + omitsCount + ' stack frames were collapsed.' + ); omittedFrames.appendChild(text1); - omittedFrames.addEventListener('click', function () { + omittedFrames.addEventListener('click', function() { var hide = text1.textContent.match(/▲/); var list = document.getElementsByName('bundle-' + omitBundle); for (var index = 0; index < list.length; ++index) { @@ -459,9 +471,11 @@ function insertBeforeBundle(parent, omitsCount, omitBundle, actionElement) { var div = document.createElement('div'); accessify(div); div.setAttribute('name', 'bundle-' + omitBundle); - var text = document.createTextNode('\u25BC ' + omitsCount + ' stack frames were expanded.'); + var text = document.createTextNode( + '\u25BC ' + omitsCount + ' stack frames were expanded.' + ); div.appendChild(text); - div.addEventListener('click', function () { + div.addEventListener('click', function() { return actionElement.click(); }); applyStyles(div, omittedFramesStyle); @@ -470,17 +484,25 @@ function insertBeforeBundle(parent, omitsCount, omitBundle, actionElement) { parent.insertBefore(div, first); } -function traceFrame(frameSetting, frame, critical, omits, omitBundle, parentContainer, lastElement) { +function traceFrame( + frameSetting, + frame, + critical, + omits, + omitBundle, + parentContainer, + lastElement +) { var compiled = frameSetting.compiled; var functionName = frame.functionName, - fileName = frame.fileName, - lineNumber = frame.lineNumber, - columnNumber = frame.columnNumber, - scriptLines = frame.scriptLines, - sourceFileName = frame.sourceFileName, - sourceLineNumber = frame.sourceLineNumber, - sourceColumnNumber = frame.sourceColumnNumber, - sourceLines = frame.sourceLines; + fileName = frame.fileName, + lineNumber = frame.lineNumber, + columnNumber = frame.columnNumber, + scriptLines = frame.scriptLines, + sourceFileName = frame.sourceFileName, + sourceLineNumber = frame.sourceLineNumber, + sourceColumnNumber = frame.sourceColumnNumber, + sourceLines = frame.sourceLines; var url = void 0; if (!compiled && sourceFileName) { @@ -501,9 +523,18 @@ function traceFrame(frameSetting, frame, critical, omits, omitBundle, parentCont if (!internalUrl || lastElement) { if (omits.value > 0) { var omittedFrames = getGroupToggle(omits.value, omitBundle); - setTimeout(function () { - insertBeforeBundle.apply(undefined, arguments); - }.bind(undefined, parentContainer, omits.value, omitBundle, omittedFrames), 1); + setTimeout( + (function() { + insertBeforeBundle.apply(undefined, arguments); + }).bind( + undefined, + parentContainer, + omits.value, + omitBundle, + omittedFrames + ), + 1 + ); if (lastElement && internalUrl) { collapseElement = omittedFrames; } else { @@ -523,10 +554,19 @@ function traceFrame(frameSetting, frame, critical, omits, omitBundle, parentCont var hasSource = false; if (!internalUrl) { if (compiled && scriptLines.length !== 0) { - elem.appendChild(sourceCodePre(scriptLines, lineNumber, columnNumber, critical)); + elem.appendChild( + sourceCodePre(scriptLines, lineNumber, columnNumber, critical) + ); hasSource = true; } else if (!compiled && sourceLines.length !== 0) { - elem.appendChild(sourceCodePre(sourceLines, sourceLineNumber, sourceColumnNumber, critical)); + elem.appendChild( + sourceCodePre( + sourceLines, + sourceLineNumber, + sourceColumnNumber, + critical + ) + ); hasSource = true; } } @@ -538,21 +578,23 @@ function lazyFrame(parent, factory, lIndex) { var fac = factory(); if (fac == null) return; var hasSource = fac.hasSource, - elem = fac.elem, - collapseElement = fac.collapseElement; + elem = fac.elem, + collapseElement = fac.collapseElement; var elemWrapper = document.createElement('div'); elemWrapper.appendChild(elem); if (hasSource) { - (function () { + (function() { var compiledDiv = document.createElement('div'); accessify(compiledDiv); applyStyles(compiledDiv, toggleStyle); var o = frameSettings[lIndex]; - var compiledText = document.createTextNode('View ' + (o && o.compiled ? 'source' : 'compiled')); - compiledDiv.addEventListener('click', function () { + var compiledText = document.createTextNode( + 'View ' + (o && o.compiled ? 'source' : 'compiled') + ); + compiledDiv.addEventListener('click', function() { if (o) o.compiled = !o.compiled; var next = lazyFrame(parent, factory, lIndex); @@ -580,9 +622,22 @@ function traceDiv(resolvedFrames) { var index = 0; var critical = true; var omits = { value: 0, bundle: 1 }; - resolvedFrames.forEach(function (frame) { + resolvedFrames.forEach(function(frame) { var lIndex = index++; - var elem = lazyFrame(trace, traceFrame.bind(undefined, frameSettings[lIndex], frame, critical, omits, omits.bundle, trace, index === resolvedFrames.length), lIndex); + var elem = lazyFrame( + trace, + traceFrame.bind( + undefined, + frameSettings[lIndex], + frame, + critical, + omits, + omits.bundle, + trace, + index === resolvedFrames.length + ), + lIndex + ); if (elem == null) return; critical = false; trace.appendChild(elem); @@ -596,16 +651,24 @@ function traceDiv(resolvedFrames) { function footer() { var div = document.createElement('div'); applyStyles(div, footerStyle); - div.appendChild(document.createTextNode('This screen is visible only in development. It will not appear when the app crashes in production.')); + div.appendChild( + document.createTextNode( + 'This screen is visible only in development. It will not appear when the app crashes in production.' + ) + ); div.appendChild(document.createElement('br')); - div.appendChild(document.createTextNode('Open your browser’s developer console to further inspect this error.')); + div.appendChild( + document.createTextNode( + 'Open your browser’s developer console to further inspect this error.' + ) + ); return div; } function render(error, name, message, resolvedFrames) { dispose(); - frameSettings = resolvedFrames.map(function () { + frameSettings = resolvedFrames.map(function() { return { compiled: false }; }); @@ -644,7 +707,7 @@ function render(error, name, message, resolvedFrames) { container.appendChild(footer()); // Mount - document.body.appendChild(overlayReference = overlay); + document.body.appendChild((overlayReference = overlay)); } function dispose() { @@ -652,7 +715,7 @@ function dispose() { document.body.removeChild(overlayReference); overlayReference = null; var head = getHead(); - injectedCss.forEach(function (node) { + injectedCss.forEach(function(node) { head.removeChild(node); }); injectedCss = []; @@ -665,68 +728,95 @@ function unmount() { } function isInternalFile(url, sourceFileName) { - return url.indexOf('/~/') !== -1 || url.trim().indexOf(' ') !== -1 || !sourceFileName; + return url.indexOf('/~/') !== -1 || + url.trim().indexOf(' ') !== -1 || + !sourceFileName; } function renderError(index) { viewIndex = index; var _capturedErrors$index = capturedErrors[index], - error = _capturedErrors$index.error, - unhandledRejection = _capturedErrors$index.unhandledRejection, - resolvedFrames = _capturedErrors$index.resolvedFrames; + error = _capturedErrors$index.error, + unhandledRejection = _capturedErrors$index.unhandledRejection, + resolvedFrames = _capturedErrors$index.resolvedFrames; if (unhandledRejection) { - render(error, 'Unhandled Rejection (' + error.name + ')', error.message, resolvedFrames); + render( + error, + 'Unhandled Rejection (' + error.name + ')', + error.message, + resolvedFrames + ); } else { render(error, error.name, error.message, resolvedFrames); } } function crash(error) { - var unhandledRejection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - var sourceOverrides = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; + var unhandledRejection = arguments.length > 1 && arguments[1] !== undefined + ? arguments[1] + : false; + var sourceOverrides = arguments.length > 2 && arguments[2] !== undefined + ? arguments[2] + : []; if (module.hot) module.hot.decline(); - StackTraceResolve(error, CONTEXT_SIZE).then(function (resolvedFrames) { - resolvedFrames = resolvedFrames.filter(function (_ref) { - var functionName = _ref.functionName; - return functionName.indexOf('__cra_proxy_console__') === -1; - }); - var overrideCount = sourceOverrides.length, + StackTraceResolve(error, CONTEXT_SIZE) + .then(function(resolvedFrames) { + resolvedFrames = resolvedFrames.filter(function(_ref) { + var functionName = _ref.functionName; + return functionName.indexOf('__cra_proxy_console__') === -1; + }); + var overrideCount = sourceOverrides.length, frameCount = resolvedFrames.length; - var frameIndex = 0; - for (var overrideIndex = 0; overrideIndex < overrideCount; ++overrideIndex) { - var tag = sourceOverrides[overrideIndex]; - var shouldContinue = false; - for (; frameIndex < frameCount; ++frameIndex) { - var sourceFileName = resolvedFrames[frameIndex].sourceFileName; - - if (sourceFileName == null) continue; - if (sourceFileName.indexOf('/' + tag.file) !== -1) { - var prevLineNumber = resolvedFrames[frameIndex].sourceLineNumber; - if (Math.abs(prevLineNumber - tag.lineNum) < CONTEXT_SIZE) { - resolvedFrames[frameIndex].sourceLineNumber = tag.lineNum; + var frameIndex = 0; + for ( + var overrideIndex = 0; + overrideIndex < overrideCount; + ++overrideIndex + ) { + var tag = sourceOverrides[overrideIndex]; + var shouldContinue = false; + for (; frameIndex < frameCount; ++frameIndex) { + var sourceFileName = resolvedFrames[frameIndex].sourceFileName; + + if (sourceFileName == null) continue; + if (sourceFileName.indexOf('/' + tag.file) !== -1) { + var prevLineNumber = resolvedFrames[frameIndex].sourceLineNumber; + if (Math.abs(prevLineNumber - tag.lineNum) < CONTEXT_SIZE) { + resolvedFrames[frameIndex].sourceLineNumber = tag.lineNum; + } + shouldContinue = true; + break; } - shouldContinue = true; - break; } + if (shouldContinue) continue; + break; } - if (shouldContinue) continue; - break; - } - capturedErrors.push({ error: error, unhandledRejection: unhandledRejection, resolvedFrames: resolvedFrames }); - if (overlayReference !== null) renderAdditional(); - else { - renderError(viewIndex = 0); - } - }).catch(function (e) { - // This is another fail case (unlikely to happen) - // e.g. render(...) throws an error with provided arguments - console.log('Red box renderer error:', e); - unmount(); - render(null, 'Error', 'There is an error with red box. *Please* report this (see console).', []); - }); + capturedErrors.push({ + error: error, + unhandledRejection: unhandledRejection, + resolvedFrames: resolvedFrames, + }); + if (overlayReference !== null) + renderAdditional(); + else { + renderError((viewIndex = 0)); + } + }) + .catch(function(e) { + // This is another fail case (unlikely to happen) + // e.g. render(...) throws an error with provided arguments + console.log('Red box renderer error:', e); + unmount(); + render( + null, + 'Error', + 'There is an error with red box. *Please* report this (see console).', + [] + ); + }); } function switchError(offset) { @@ -737,12 +827,21 @@ function switchError(offset) { } catch (e) { console.log('Red box renderer error:', e); unmount(); - render(null, 'Error', 'There is an error with red box. *Please* report this (see console).', []); + render( + null, + 'Error', + 'There is an error with red box. *Please* report this (see console).', + [] + ); } } -window.onerror = function (messageOrEvent, source, lineno, colno, error) { - if (error == null || !(error instanceof Error) || messageOrEvent.indexOf('Script error') !== -1) { +window.onerror = function(messageOrEvent, source, lineno, colno, error) { + if ( + error == null || + !(error instanceof Error) || + messageOrEvent.indexOf('Script error') !== -1 + ) { crash(new Error(error || messageOrEvent)); // TODO: more helpful message } else { crash(error); @@ -766,13 +865,13 @@ var promiseHandler = function promiseHandler(event) { window.addEventListener('unhandledrejection', promiseHandler); var escapeHandler = function escapeHandler(event) { - var key = event.key, - keyCode = event.keyCode, - which = event.which; + var key = event.key, keyCode = event.keyCode, which = event.which; if (key === 'Escape' || keyCode === 27 || which === 27) unmount(); - else if (key === 'ArrowLeft' || keyCode === 37 || which === 37) switchError(-1); - else if (key === 'ArrowRight' || keyCode === 39 || which === 39) switchError(1); + else if (key === 'ArrowLeft' || keyCode === 37 || which === 37) + switchError(-1); + else if (key === 'ArrowRight' || keyCode === 39 || which === 39) + switchError(1); }; window.addEventListener('keydown', escapeHandler); @@ -791,29 +890,34 @@ var proxyConsole = function proxyConsole(type) { var nIndex = warning.indexOf('\n'); var message = warning; if (nIndex !== -1) message = message.substring(0, nIndex); - var stack = warning.substring(nIndex + 1).split('\n').filter(function (line) { - return line.indexOf('(at ') !== -1; - }).map(function (line) { - var prefix = '(at '; - var suffix = ')'; - line = line.substring(line.indexOf(prefix) + prefix.length); - line = line.substring(0, line.indexOf(suffix)); - var parts = line.split(/[:]/g); - if (parts.length !== 2) return null; - var file = parts[0]; - var lineNum = Number(parts[1]); - if (isNaN(lineNum)) return null; - return { file: file, lineNum: lineNum }; - }).filter(function (obj) { - return obj !== null; - }); + var stack = warning + .substring(nIndex + 1) + .split('\n') + .filter(function(line) { + return line.indexOf('(at ') !== -1; + }) + .map(function(line) { + var prefix = '(at '; + var suffix = ')'; + line = line.substring(line.indexOf(prefix) + prefix.length); + line = line.substring(0, line.indexOf(suffix)); + var parts = line.split(/[:]/g); + if (parts.length !== 2) return null; + var file = parts[0]; + var lineNum = Number(parts[1]); + if (isNaN(lineNum)) return null; + return { file: file, lineNum: lineNum }; + }) + .filter(function(obj) { + return obj !== null; + }); var error = void 0; try { throw new Error(message); } catch (e) { error = e; } - setTimeout(function () { + setTimeout(function() { return crash(error, false, stack); }); return orig.apply(this, arguments); @@ -823,7 +927,7 @@ var proxyConsole = function proxyConsole(type) { // proxyConsole('error'); if (module.hot) { - module.hot.dispose(function () { + module.hot.dispose(function() { unmount(); window.removeEventListener('unhandledrejection', promiseHandler); window.removeEventListener('keydown', escapeHandler); diff --git a/packages/react-dev-utils/formatWebpackMessages.js b/packages/react-dev-utils/formatWebpackMessages.js index bfee3ec5b65..098c48657e2 100644 --- a/packages/react-dev-utils/formatWebpackMessages.js +++ b/packages/react-dev-utils/formatWebpackMessages.js @@ -46,18 +46,15 @@ function formatMessage(message) { lines = [ lines[0], // Clean up message because "Module not found: " is descriptive enough. - lines[1].replace( - 'Cannot resolve \'file\' or \'directory\' ', '' - ).replace( - 'Cannot resolve module ', '' - ).replace( - 'Error: ', '' - ), + lines[1] + .replace("Cannot resolve 'file' or 'directory' ", '') + .replace('Cannot resolve module ', '') + .replace('Error: ', ''), // Skip all irrelevant lines. // (For some reason they only appear on the client in browser.) '', - lines[lines.length - 1] // error location is the last line - ] + lines[lines.length - 1], // error location is the last line + ]; } // Cleans up syntax error messages. @@ -108,7 +105,8 @@ function formatMessage(message) { // from user code generated by WebPack. For more information see // https://github.com/facebookincubator/create-react-app/pull/1050 message = message.replace( - /^\s*at\s((?!webpack:).)*:\d+:\d+[\s\)]*(\n|$)/gm, '' + /^\s*at\s((?!webpack:).)*:\d+:\d+[\s\)]*(\n|$)/gm, + '' ); // at ... ...:x:y return message; @@ -116,14 +114,14 @@ function formatMessage(message) { function formatWebpackMessages(json) { var formattedErrors = json.errors.map(function(message) { - return 'Error in ' + formatMessage(message) + return 'Error in ' + formatMessage(message); }); var formattedWarnings = json.warnings.map(function(message) { - return 'Warning in ' + formatMessage(message) + return 'Warning in ' + formatMessage(message); }); var result = { errors: formattedErrors, - warnings: formattedWarnings + warnings: formattedWarnings, }; if (result.errors.some(isLikelyASyntaxError)) { // If there are any syntax errors, show just them. diff --git a/packages/react-dev-utils/getProcessForPort.js b/packages/react-dev-utils/getProcessForPort.js index 24b89823eb6..2d9e531c381 100644 --- a/packages/react-dev-utils/getProcessForPort.js +++ b/packages/react-dev-utils/getProcessForPort.js @@ -18,8 +18,8 @@ var execOptions = { stdio: [ 'pipe', // stdin (default) 'pipe', // stdout (default) - 'ignore' //stderr - ] + 'ignore', //stderr + ], }; function isProcessAReactApp(processCommand) { @@ -27,7 +27,10 @@ function isProcessAReactApp(processCommand) { } function getProcessIdOnPort(port) { - return execSync('lsof -i:' + port + ' -P -t -sTCP:LISTEN', execOptions).trim(); + return execSync( + 'lsof -i:' + port + ' -P -t -sTCP:LISTEN', + execOptions + ).trim(); } function getPackageNameInDirectory(directory) { @@ -35,26 +38,30 @@ function getPackageNameInDirectory(directory) { try { return require(packagePath).name; - } catch(e) { + } catch (e) { return null; } - } function getProcessCommand(processId, processDirectory) { - var command = execSync('ps -o command -p ' + processId + ' | sed -n 2p', execOptions); + var command = execSync( + 'ps -o command -p ' + processId + ' | sed -n 2p', + execOptions + ); if (isProcessAReactApp(command)) { const packageName = getPackageNameInDirectory(processDirectory); - return (packageName) ? packageName + '\n' : command; + return packageName ? packageName + '\n' : command; } else { return command; } - } function getDirectoryOfProcessById(processId) { - return execSync('lsof -p '+ processId + ' | awk \'$4=="cwd" {print $9}\'', execOptions).trim(); + return execSync( + 'lsof -p ' + processId + ' | awk \'$4=="cwd" {print $9}\'', + execOptions + ).trim(); } function getProcessForPort(port) { @@ -63,10 +70,9 @@ function getProcessForPort(port) { var directory = getDirectoryOfProcessById(processId); var command = getProcessCommand(processId, directory); return chalk.cyan(command) + chalk.blue(' in ') + chalk.cyan(directory); - } catch(e) { + } catch (e) { return null; } } module.exports = getProcessForPort; - diff --git a/packages/react-dev-utils/openBrowser.js b/packages/react-dev-utils/openBrowser.js index 912c1819bcd..8c97f723c4f 100644 --- a/packages/react-dev-utils/openBrowser.js +++ b/packages/react-dev-utils/openBrowser.js @@ -30,22 +30,18 @@ function openBrowser(url) { // requested a different browser, we can try opening // Chrome with AppleScript. This lets us reuse an // existing tab when possible instead of creating a new one. - const shouldTryOpenChromeWithAppleScript = ( - process.platform === 'darwin' && ( - typeof browser !== 'string' || - browser === OSX_CHROME - ) - ); + const shouldTryOpenChromeWithAppleScript = process.platform === 'darwin' && + (typeof browser !== 'string' || browser === OSX_CHROME); if (shouldTryOpenChromeWithAppleScript) { try { // Try our best to reuse existing tab // on OS X Google Chrome with AppleScript execSync('ps cax | grep "Google Chrome"'); - execSync( - 'osascript openChrome.applescript ' + url, - {cwd: __dirname, stdio: 'ignore'} - ); + execSync('osascript openChrome.applescript ' + url, { + cwd: __dirname, + stdio: 'ignore', + }); return true; } catch (err) { // Ignore errors. @@ -59,11 +55,11 @@ function openBrowser(url) { if (process.platform === 'darwin' && browser === 'open') { browser = undefined; } - + // Fallback to opn // (It will always open new tab) try { - var options = {app: browser}; + var options = { app: browser }; opn(url, options).catch(() => {}); // Prevent `unhandledRejection` error. return true; } catch (err) { diff --git a/packages/react-dev-utils/prompt.js b/packages/react-dev-utils/prompt.js index e6e19cf39eb..4257924576d 100644 --- a/packages/react-dev-utils/prompt.js +++ b/packages/react-dev-utils/prompt.js @@ -16,7 +16,9 @@ var rl = require('readline'); // You can control the behavior on with `isYesDefault`. function prompt(question, isYesDefault) { if (typeof isYesDefault !== 'boolean') { - throw new Error('Provide explicit boolean isYesDefault as second argument.'); + throw new Error( + 'Provide explicit boolean isYesDefault as second argument.' + ); } return new Promise(resolve => { var rlInterface = rl.createInterface({ diff --git a/packages/react-dev-utils/webpackHotDevClient.js b/packages/react-dev-utils/webpackHotDevClient.js index b060ddea48c..77cc62be2b7 100644 --- a/packages/react-dev-utils/webpackHotDevClient.js +++ b/packages/react-dev-utils/webpackHotDevClient.js @@ -46,7 +46,7 @@ function createOverlayIframe(onIframeLoad) { } function addOverlayDivTo(iframe) { - var div = iframe.contentDocument.createElement('div'); + var div = iframe.contentDocument.createElement('div'); div.id = 'react-dev-utils-webpack-hot-dev-client-overlay-div'; div.style.position = 'fixed'; div.style.boxSizing = 'border-box'; @@ -104,8 +104,9 @@ function ensureOverlayDivExists(onOverlayDivReady) { function showErrorOverlay(message) { ensureOverlayDivExists(function onOverlayDivReady(overlayDiv) { // Make it look similar to our terminal. - overlayDiv.innerHTML = - 'Failed to compile.

' + + overlayDiv.innerHTML = 'Failed to compile.

' + ansiHTML(entities.encode(message)); }); } @@ -124,13 +125,15 @@ function destroyErrorOverlay() { } // Connect to WebpackDevServer via a socket. -var connection = new SockJS(url.format({ - protocol: window.location.protocol, - hostname: window.location.hostname, - port: window.location.port, - // Hardcoded in WebpackDevServer - pathname: '/sockjs-node' -})); +var connection = new SockJS( + url.format({ + protocol: window.location.protocol, + hostname: window.location.hostname, + port: window.location.port, + // Hardcoded in WebpackDevServer + pathname: '/sockjs-node', + }) +); // Unlike WebpackDevServer client, we won't try to reconnect // to avoid spamming the console. Disconnect usually happens @@ -207,7 +210,7 @@ function handleErrors(errors) { // "Massage" webpack messages. var formatted = formatWebpackMessages({ errors: errors, - warnings: [] + warnings: [], }); // Only show the first error. @@ -232,27 +235,27 @@ function handleAvailableHash(hash) { connection.onmessage = function(e) { var message = JSON.parse(e.data); switch (message.type) { - case 'hash': - handleAvailableHash(message.data); - break; - case 'still-ok': - case 'ok': - handleSuccess(); - break; - case 'content-changed': - // Triggered when a file from `contentBase` changed. - window.location.reload(); - break; - case 'warnings': - handleWarnings(message.data); - break; - case 'errors': - handleErrors(message.data); - break; - default: + case 'hash': + handleAvailableHash(message.data); + break; + case 'still-ok': + case 'ok': + handleSuccess(); + break; + case 'content-changed': + // Triggered when a file from `contentBase` changed. + window.location.reload(); + break; + case 'warnings': + handleWarnings(message.data); + break; + case 'errors': + handleErrors(message.data); + break; + default: // Do nothing. } -} +}; // Is there a newer version of this code available? function isUpdateAvailable() { @@ -297,7 +300,7 @@ function tryApplyUpdates(onHotUpdateSuccess) { } // https://webpack.github.io/docs/hot-module-replacement.html#check - var result = module.hot.check(/* autoApply */true, handleApplyUpdates); + var result = module.hot.check(/* autoApply */ true, handleApplyUpdates); // // Webpack 2 returns a Promise instead of invoking a callback if (result && result.then) { diff --git a/packages/react-scripts/bin/react-scripts.js b/packages/react-scripts/bin/react-scripts.js index 94a799fd89d..8a1175c99ea 100755 --- a/packages/react-scripts/bin/react-scripts.js +++ b/packages/react-scripts/bin/react-scripts.js @@ -15,36 +15,38 @@ var script = process.argv[2]; var args = process.argv.slice(3); switch (script) { -case 'build': -case 'eject': -case 'start': -case 'test': - var result = spawn.sync( - 'node', - [require.resolve('../scripts/' + script)].concat(args), - {stdio: 'inherit'} - ); - if (result.signal) { - if (result.signal === 'SIGKILL') { - console.log( - 'The build failed because the process exited too early. ' + - 'This probably means the system ran out of memory or someone called ' + - '`kill -9` on the process.' - ); - } else if (result.signal === 'SIGTERM') { - console.log( - 'The build failed because the process exited too early. ' + - 'Someone might have called `kill` or `killall`, or the system could ' + - 'be shutting down.' - ); + case 'build': + case 'eject': + case 'start': + case 'test': + var result = spawn.sync( + 'node', + [require.resolve('../scripts/' + script)].concat(args), + { stdio: 'inherit' } + ); + if (result.signal) { + if (result.signal === 'SIGKILL') { + console.log( + 'The build failed because the process exited too early. ' + + 'This probably means the system ran out of memory or someone called ' + + '`kill -9` on the process.' + ); + } else if (result.signal === 'SIGTERM') { + console.log( + 'The build failed because the process exited too early. ' + + 'Someone might have called `kill` or `killall`, or the system could ' + + 'be shutting down.' + ); + } + process.exit(1); } - process.exit(1); - } - process.exit(result.status); - break; -default: - console.log('Unknown script "' + script + '".'); - console.log('Perhaps you need to update react-scripts?'); - console.log('See: https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#updating-to-new-releases'); - break; + process.exit(result.status); + break; + default: + console.log('Unknown script "' + script + '".'); + console.log('Perhaps you need to update react-scripts?'); + console.log( + 'See: https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#updating-to-new-releases' + ); + break; } diff --git a/packages/react-scripts/config/env.js b/packages/react-scripts/config/env.js index 5f49ffaa17a..c018467a95b 100644 --- a/packages/react-scripts/config/env.js +++ b/packages/react-scripts/config/env.js @@ -12,34 +12,36 @@ // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be // injected into the application via DefinePlugin in Webpack configuration. - -var REACT_APP = /^REACT_APP_/i; +const REACT_APP = /^REACT_APP_/i; function getClientEnvironment(publicUrl) { - var raw = Object - .keys(process.env) + const raw = Object.keys(process.env) .filter(key => REACT_APP.test(key)) - .reduce((env, key) => { - env[key] = process.env[key]; - return env; - }, { - // Useful for determining whether we’re running in production mode. - // Most importantly, it switches React into the correct mode. - 'NODE_ENV': process.env.NODE_ENV || 'development', - // Useful for resolving the correct path to static assets in `public`. - // For example, . - // This should only be used as an escape hatch. Normally you would put - // images into the `src` and `import` them in code to get their paths. - 'PUBLIC_URL': publicUrl - }); + .reduce( + (env, key) => { + env[key] = process.env[key]; + return env; + }, + { + // Useful for determining whether we’re running in production mode. + // Most importantly, it switches React into the correct mode. + NODE_ENV: process.env.NODE_ENV || 'development', + // Useful for resolving the correct path to static assets in `public`. + // For example, . + // This should only be used as an escape hatch. Normally you would put + // images into the `src` and `import` them in code to get their paths. + PUBLIC_URL: publicUrl, + } + ); // Stringify all values so we can feed into Webpack DefinePlugin - var stringified = { - 'process.env': Object - .keys(raw) - .reduce((env, key) => { + const stringified = { + 'process.env': Object.keys(raw).reduce( + (env, key) => { env[key] = JSON.stringify(raw[key]); return env; - }, {}) + }, + {} + ), }; return { raw, stringified }; diff --git a/packages/react-scripts/config/jest/babelTransform.js b/packages/react-scripts/config/jest/babelTransform.js index 838d0ca9175..bee55b1b156 100644 --- a/packages/react-scripts/config/jest/babelTransform.js +++ b/packages/react-scripts/config/jest/babelTransform.js @@ -6,12 +6,11 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ - 'use strict'; const babelJest = require('babel-jest'); module.exports = babelJest.createTransformer({ presets: [require.resolve('babel-preset-react-app')], - babelrc: false + babelrc: false, }); diff --git a/packages/react-scripts/config/jest/fileTransform.js b/packages/react-scripts/config/jest/fileTransform.js index 060ee259de2..89027bdc702 100644 --- a/packages/react-scripts/config/jest/fileTransform.js +++ b/packages/react-scripts/config/jest/fileTransform.js @@ -16,6 +16,6 @@ const path = require('path'); module.exports = { process(src, filename) { - return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'; + return `module.exports = ${JSON.stringify(path.basename(filename))};`; }, }; diff --git a/packages/react-scripts/config/paths.js b/packages/react-scripts/config/paths.js index 83f234d6c62..76397756040 100644 --- a/packages/react-scripts/config/paths.js +++ b/packages/react-scripts/config/paths.js @@ -10,13 +10,13 @@ // @remove-on-eject-end 'use strict'; -var path = require('path'); -var fs = require('fs'); -var url = require('url'); +const path = require('path'); +const fs = require('fs'); +const url = require('url'); // Make sure any symlinks in the project folder are resolved: // https://github.com/facebookincubator/create-react-app/issues/637 -var appDirectory = fs.realpathSync(process.cwd()); +const appDirectory = fs.realpathSync(process.cwd()); function resolveApp(relativePath) { return path.resolve(appDirectory, relativePath); } @@ -36,20 +36,20 @@ function resolveApp(relativePath) { // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421 -var nodePaths = (process.env.NODE_PATH || '') +const nodePaths = (process.env.NODE_PATH || '') .split(process.platform === 'win32' ? ';' : ':') .filter(Boolean) .filter(folder => !path.isAbsolute(folder)) .map(resolveApp); -var envPublicUrl = process.env.PUBLIC_URL; +const envPublicUrl = process.env.PUBLIC_URL; function ensureSlash(path, needsSlash) { - var hasSlash = path.endsWith('/'); + const hasSlash = path.endsWith('/'); if (hasSlash && !needsSlash) { return path.substr(path, path.length - 1); } else if (!hasSlash && needsSlash) { - return path + '/'; + return `${path}/`; } else { return path; } @@ -66,10 +66,9 @@ function getPublicUrl(appPackageJson) { // We can't use a relative path in HTML because we don't want to load something // like /todos/42/static/js/bundle.7289d.js. We have to know the root. function getServedPath(appPackageJson) { - var publicUrl = getPublicUrl(appPackageJson); - var servedUrl = envPublicUrl || ( - publicUrl ? url.parse(publicUrl).pathname : '/' - ); + const publicUrl = getPublicUrl(appPackageJson); + const servedUrl = envPublicUrl || + (publicUrl ? url.parse(publicUrl).pathname : '/'); return ensureSlash(servedUrl, true); } @@ -86,7 +85,7 @@ module.exports = { appNodeModules: resolveApp('node_modules'), nodePaths: nodePaths, publicUrl: getPublicUrl(resolveApp('package.json')), - servedPath: getServedPath(resolveApp('package.json')) + servedPath: getServedPath(resolveApp('package.json')), }; // @remove-on-eject-begin @@ -114,12 +113,16 @@ module.exports = { ownNodeModules: resolveOwn('node_modules'), // This is empty on npm 3 }; -var ownPackageJson = require('../package.json'); -var reactScriptsPath = resolveApp(`node_modules/${ownPackageJson.name}`); -var reactScriptsLinked = fs.existsSync(reactScriptsPath) && fs.lstatSync(reactScriptsPath).isSymbolicLink(); +const ownPackageJson = require('../package.json'); +const reactScriptsPath = resolveApp(`node_modules/${ownPackageJson.name}`); +const reactScriptsLinked = fs.existsSync(reactScriptsPath) && + fs.lstatSync(reactScriptsPath).isSymbolicLink(); // config before publish: we're in ./packages/react-scripts/config/ -if (!reactScriptsLinked && __dirname.indexOf(path.join('packages', 'react-scripts', 'config')) !== -1) { +if ( + !reactScriptsLinked && + __dirname.indexOf(path.join('packages', 'react-scripts', 'config')) !== -1 +) { module.exports = { appPath: resolveApp('.'), appBuild: resolveOwn('../../build'), diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index 214373b81b8..c7948b66f6e 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -10,29 +10,29 @@ // @remove-on-eject-end 'use strict'; -var autoprefixer = require('autoprefixer'); -var webpack = require('webpack'); -var HtmlWebpackPlugin = require('html-webpack-plugin'); -var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); -var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); -var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); -var getClientEnvironment = require('./env'); -var paths = require('./paths'); +const autoprefixer = require('autoprefixer'); +const webpack = require('webpack'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); +const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); +const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); +const getClientEnvironment = require('./env'); +const paths = require('./paths'); // @remove-on-eject-begin // `path` is not used after eject - see https://github.com/facebookincubator/create-react-app/issues/1174 -var path = require('path'); +const path = require('path'); // @remove-on-eject-end // Webpack uses `publicPath` to determine where the app is being served from. // In development, we always serve from the root. This makes config easier. -var publicPath = '/'; +const publicPath = '/'; // `publicUrl` is just like `publicPath`, but we will provide it to our app // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. // Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz. -var publicUrl = ''; +const publicUrl = ''; // Get environment variables to inject into our app. -var env = getClientEnvironment(publicUrl); +const env = getClientEnvironment(publicUrl); // This is the development configuration. // It is focused on developer experience and fast rebuilds. @@ -61,7 +61,7 @@ module.exports = { // Errors should be considered fatal in development require.resolve('react-dev-utils/crashOverlay'), // Finally, this is your app's code: - paths.appIndexJs + paths.appIndexJs, // We include the app code last so that if there is a runtime error during // initialization, it doesn't blow up the WebpackDevServer client, and // changing JS code would still trigger a refresh. @@ -76,7 +76,7 @@ module.exports = { // containing code from all our entry points, and the Webpack runtime. filename: 'static/js/bundle.js', // This is the URL that app is served from. We use "/" in development. - publicPath: publicPath + publicPath: publicPath, }, resolve: { // This allows you to set a fallback for where Webpack should look for modules. @@ -93,8 +93,8 @@ module.exports = { alias: { // Support React Native Web // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ - 'react-native': 'react-native-web' - } + 'react-native': 'react-native-web', + }, }, // @remove-on-eject-begin // Resolve loaders (webpack plugins for CSS, images, transpilation) from the @@ -103,8 +103,8 @@ module.exports = { modules: [ paths.ownNodeModules, // Lerna hoists everything, so we need to look in our app directory - paths.appNodeModules - ] + paths.appNodeModules, + ], }, // @remove-on-eject-end module: { @@ -116,17 +116,19 @@ module.exports = { { test: /\.(js|jsx)$/, enforce: 'pre', - use: [{ - // @remove-on-eject-begin - // Point ESLint to our predefined config. - options: { - configFile: path.join(__dirname, '../eslintrc'), - useEslintrc: false + use: [ + { + // @remove-on-eject-begin + // Point ESLint to our predefined config. + options: { + configFile: path.join(__dirname, '../eslintrc'), + useEslintrc: false, + }, + // @remove-on-eject-end + loader: 'eslint-loader', }, - // @remove-on-eject-end - loader: 'eslint-loader' - }], - include: paths.appSrc + ], + include: paths.appSrc, }, // ** ADDING/UPDATING LOADERS ** // The "url" loader handles all assets unless explicitly excluded. @@ -146,28 +148,23 @@ module.exports = { /\.bmp$/, /\.gif$/, /\.jpe?g$/, - /\.png$/ + /\.png$/, ], loader: 'file-loader', options: { - name: 'static/media/[name].[hash:8].[ext]' - } + name: 'static/media/[name].[hash:8].[ext]', + }, }, // "url" loader works like "file" loader except that it embeds assets // smaller than specified limit in bytes as data URLs to avoid requests. // A missing `test` is equivalent to a match. { - test: [ - /\.bmp$/, - /\.gif$/, - /\.jpe?g$/, - /\.png$/ - ], + test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/], loader: 'url-loader', options: { limit: 10000, - name: 'static/media/[name].[hash:8].[ext]' - } + name: 'static/media/[name].[hash:8].[ext]', + }, }, // Process JS with Babel. { @@ -182,8 +179,8 @@ module.exports = { // This is a feature of `babel-loader` for webpack (not Babel itself). // It enables caching results in ./node_modules/.cache/babel-loader/ // directory for faster rebuilds. - cacheDirectory: true - } + cacheDirectory: true, + }, }, // "postcss" loader applies autoprefixer to our CSS. // "css" loader resolves paths in CSS and adds assets as dependencies. @@ -193,34 +190,34 @@ module.exports = { { test: /\.css$/, use: [ - 'style-loader', { + 'style-loader', + { loader: 'css-loader', options: { - importLoaders: 1 - } - }, { + importLoaders: 1, + }, + }, + { loader: 'postcss-loader', options: { ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options - plugins: function () { - return [ - autoprefixer({ - browsers: [ - '>1%', - 'last 4 versions', - 'Firefox ESR', - 'not ie < 9', // React doesn't support IE8 anyway - ] - }) - ] - } - } - } - ] - } + plugins: () => [ + autoprefixer({ + browsers: [ + '>1%', + 'last 4 versions', + 'Firefox ESR', + 'not ie < 9', // React doesn't support IE8 anyway + ], + }), + ], + }, + }, + ], + }, // ** STOP ** Are you adding a new loader? // Remember to add the new extension(s) to the "url" loader exclusion list. - ] + ], }, plugins: [ // Makes some environment variables available in index.html. @@ -246,19 +243,19 @@ module.exports = { // to restart the development server for Webpack to discover it. This plugin // makes the discovery automatic so you don't have to restart. // See https://github.com/facebookincubator/create-react-app/issues/186 - new WatchMissingNodeModulesPlugin(paths.appNodeModules) + new WatchMissingNodeModulesPlugin(paths.appNodeModules), ], // Some libraries import Node modules but don't use them in the browser. // Tell Webpack to provide empty mocks for them so importing them works. node: { fs: 'empty', net: 'empty', - tls: 'empty' + tls: 'empty', }, // Turn off performance hints during development because we don't do any // splitting or minification in interest of speed. These warnings become // cumbersome. performance: { - hints: false - } + hints: false, + }, }; diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 5a2388d29c3..979ed4e4d6d 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -10,32 +10,32 @@ // @remove-on-eject-end 'use strict'; -var autoprefixer = require('autoprefixer'); -var webpack = require('webpack'); -var HtmlWebpackPlugin = require('html-webpack-plugin'); -var ExtractTextPlugin = require('extract-text-webpack-plugin'); -var ManifestPlugin = require('webpack-manifest-plugin'); -var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); -var paths = require('./paths'); -var getClientEnvironment = require('./env'); +const autoprefixer = require('autoprefixer'); +const webpack = require('webpack'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); +const ManifestPlugin = require('webpack-manifest-plugin'); +const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); +const paths = require('./paths'); +const getClientEnvironment = require('./env'); // @remove-on-eject-begin // `path` is not used after eject - see https://github.com/facebookincubator/create-react-app/issues/1174 -var path = require('path'); +const path = require('path'); // @remove-on-eject-end // Webpack uses `publicPath` to determine where the app is being served from. // It requires a trailing slash, or the file assets will get an incorrect path. -var publicPath = paths.servedPath; +const publicPath = paths.servedPath; // Some apps do not use client-side routing with pushState. // For these, "homepage" can be set to "." to enable relative asset paths. -var shouldUseRelativeAssetPaths = publicPath === './'; +const shouldUseRelativeAssetPaths = publicPath === './'; // `publicUrl` is just like `publicPath`, but we will provide it to our app // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz. -var publicUrl = publicPath.slice(0, -1); +const publicUrl = publicPath.slice(0, -1); // Get environment variables to inject into our app. -var env = getClientEnvironment(publicUrl); +const env = getClientEnvironment(publicUrl); // Assert this just to be safe. // Development builds of React are slow and not intended for production. @@ -51,8 +51,8 @@ const cssFilename = 'static/css/[name].[contenthash:8].css'; // However, our output is structured with css, js and media folders. // To have this structure working with relative paths, we have to use custom options. const extractTextPluginOptions = shouldUseRelativeAssetPaths - // Making sure that the publicPath goes back to to build folder. - ? {publicPath: Array(cssFilename.split('/').length).join('../')} + ? // Making sure that the publicPath goes back to to build folder. + { publicPath: Array(cssFilename.split('/').length).join('../') } : {}; // This is the production configuration. @@ -65,10 +65,7 @@ module.exports = { // You can exclude the *.map files from the build during deployment. devtool: 'source-map', // In production, we only want to load the polyfills and the app code. - entry: [ - require.resolve('./polyfills'), - paths.appIndexJs - ], + entry: [require.resolve('./polyfills'), paths.appIndexJs], output: { // The build folder. path: paths.appBuild, @@ -78,7 +75,7 @@ module.exports = { filename: 'static/js/[name].[chunkhash:8].js', chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js', // We inferred the "public path" (such as / or /my-project) from homepage. - publicPath: publicPath + publicPath: publicPath, }, resolve: { // This allows you to set a fallback for where Webpack should look for modules. @@ -95,8 +92,8 @@ module.exports = { alias: { // Support React Native Web // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ - 'react-native': 'react-native-web' - } + 'react-native': 'react-native-web', + }, }, // @remove-on-eject-begin // Resolve loaders (webpack plugins for CSS, images, transpilation) from the @@ -105,8 +102,8 @@ module.exports = { modules: [ paths.ownNodeModules, // Lerna hoists everything, so we need to look in our app directory - paths.appNodeModules - ] + paths.appNodeModules, + ], }, // @remove-on-eject-end module: { @@ -118,19 +115,21 @@ module.exports = { { test: /\.(js|jsx)$/, enforce: 'pre', - use: [{ - // @remove-on-eject-begin - // Point ESLint to our predefined config. - options: { - // TODO: consider separate config for production, - // e.g. to enable no-console and no-debugger only in production. - configFile: path.join(__dirname, '../eslintrc'), - useEslintrc: false + use: [ + { + // @remove-on-eject-begin + // Point ESLint to our predefined config. + options: { + // TODO: consider separate config for production, + // e.g. to enable no-console and no-debugger only in production. + configFile: path.join(__dirname, '../eslintrc'), + useEslintrc: false, + }, + // @remove-on-eject-end + loader: 'eslint-loader', }, - // @remove-on-eject-end - loader: 'eslint-loader' - }], - include: paths.appSrc + ], + include: paths.appSrc, }, // ** ADDING/UPDATING LOADERS ** // The "url" loader handles all assets unless explicitly excluded. @@ -149,27 +148,22 @@ module.exports = { /\.bmp$/, /\.gif$/, /\.jpe?g$/, - /\.png$/ + /\.png$/, ], loader: 'file-loader', options: { - name: 'static/media/[name].[hash:8].[ext]' - } + name: 'static/media/[name].[hash:8].[ext]', + }, }, // "url" loader works just like "file" loader but it also embeds // assets smaller than specified size as data URLs to avoid requests. { - test: [ - /\.bmp$/, - /\.gif$/, - /\.jpe?g$/, - /\.png$/ - ], + test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/], loader: 'url-loader', options: { limit: 10000, - name: 'static/media/[name].[hash:8].[ext]' - } + name: 'static/media/[name].[hash:8].[ext]', + }, }, // Process JS with Babel. { @@ -197,39 +191,43 @@ module.exports = { // in the main CSS file. { test: /\.css$/, - loader: ExtractTextPlugin.extract(Object.assign({ - fallback: 'style-loader', - use: [ + loader: ExtractTextPlugin.extract( + Object.assign( { - loader: 'css-loader', - options: { - importLoaders: 1 - } - }, { - loader: 'postcss-loader', - options: { - ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options - plugins: function () { - return [ - autoprefixer({ - browsers: [ - '>1%', - 'last 4 versions', - 'Firefox ESR', - 'not ie < 9', // React doesn't support IE8 anyway - ] - }) - ] - } - } - } - ] - }, extractTextPluginOptions)) + fallback: 'style-loader', + use: [ + { + loader: 'css-loader', + options: { + importLoaders: 1, + }, + }, + { + loader: 'postcss-loader', + options: { + ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options + plugins: () => [ + autoprefixer({ + browsers: [ + '>1%', + 'last 4 versions', + 'Firefox ESR', + 'not ie < 9', // React doesn't support IE8 anyway + ], + }), + ], + }, + }, + ], + }, + extractTextPluginOptions + ) + ), // Note: this won't work without `new ExtractTextPlugin()` in `plugins`. - } + }, // ** STOP ** Are you adding a new loader? // Remember to add the new extension(s) to the "url" loader exclusion list. - ] + ], }, plugins: [ // Makes some environment variables available in index.html. @@ -252,8 +250,8 @@ module.exports = { keepClosingSlash: true, minifyJS: true, minifyCSS: true, - minifyURLs: true - } + minifyURLs: true, + }, }), // Makes some environment variables available to the JS code, for example: // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`. @@ -264,33 +262,33 @@ module.exports = { new webpack.optimize.UglifyJsPlugin({ compress: { screw_ie8: true, // React doesn't support IE8 - warnings: false + warnings: false, }, mangle: { - screw_ie8: true + screw_ie8: true, }, output: { comments: false, - screw_ie8: true + screw_ie8: true, }, - sourceMap: true + sourceMap: true, }), // Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`. new ExtractTextPlugin({ - filename: cssFilename + filename: cssFilename, }), // Generate a manifest file which contains a mapping of all asset filenames // to their corresponding output file so that tools can pick it up without // having to parse `index.html`. new ManifestPlugin({ - fileName: 'asset-manifest.json' - }) + fileName: 'asset-manifest.json', + }), ], // Some libraries import Node modules but don't use them in the browser. // Tell Webpack to provide empty mocks for them so importing them works. node: { fs: 'empty', net: 'empty', - tls: 'empty' - } + tls: 'empty', + }, }; diff --git a/packages/react-scripts/config/webpackDevServer.config.js b/packages/react-scripts/config/webpackDevServer.config.js index 89fd48bc524..37d9d1a750e 100644 --- a/packages/react-scripts/config/webpackDevServer.config.js +++ b/packages/react-scripts/config/webpackDevServer.config.js @@ -10,11 +10,11 @@ // @remove-on-eject-end 'use strict'; -var config = require('./webpack.config.dev'); -var paths = require('./paths'); +const config = require('./webpack.config.dev'); +const paths = require('./paths'); -var protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; -var host = process.env.HOST || 'localhost'; +const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; +const host = process.env.HOST || 'localhost'; module.exports = { // Enable gzip compression of generated files. @@ -54,7 +54,7 @@ module.exports = { // Reportedly, this avoids CPU overload on some systems. // https://github.com/facebookincubator/create-react-app/issues/293 watchOptions: { - ignored: /node_modules/ + ignored: /node_modules/, }, // Enable HTTPS if the HTTPS environment variable is set to 'true' https: protocol === 'https', diff --git a/packages/react-scripts/fixtures/kitchensink/integration/env.test.js b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js index c3169c987a9..b90d12ab12e 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/env.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js @@ -7,36 +7,47 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import { expect } from 'chai' -import initDOM from './initDOM' +import { expect } from 'chai'; +import initDOM from './initDOM'; describe('Integration', () => { describe('Environment variables', () => { it('file env variables', async () => { - const doc = await initDOM('file-env-variables') + const doc = await initDOM('file-env-variables'); - expect(doc.getElementById('feature-file-env-variables').textContent).to.equal('fromtheenvfile.') - }) + expect( + doc.getElementById('feature-file-env-variables').textContent + ).to.equal('fromtheenvfile.'); + }); it('NODE_PATH', async () => { - const doc = await initDOM('node-path') + const doc = await initDOM('node-path'); - expect(doc.getElementById('feature-node-path').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-node-path').childElementCount + ).to.equal(4); + }); it('PUBLIC_URL', async () => { - const doc = await initDOM('public-url') - - const prefix = process.env.NODE_ENV === 'development' ? '' : 'http://www.example.org/spa'; - expect(doc.getElementById('feature-public-url').textContent).to.equal(`${prefix}.`) - expect(doc.querySelector('head link[rel="shortcut icon"]').getAttribute('href')) - .to.equal(`${prefix}/favicon.ico`) - }) + const doc = await initDOM('public-url'); + + const prefix = process.env.NODE_ENV === 'development' + ? '' + : 'http://www.example.org/spa'; + expect(doc.getElementById('feature-public-url').textContent).to.equal( + `${prefix}.` + ); + expect( + doc.querySelector('head link[rel="shortcut icon"]').getAttribute('href') + ).to.equal(`${prefix}/favicon.ico`); + }); it('shell env variables', async () => { - const doc = await initDOM('shell-env-variables') - - expect(doc.getElementById('feature-shell-env-variables').textContent).to.equal('fromtheshell.') - }) - }) -}) + const doc = await initDOM('shell-env-variables'); + + expect( + doc.getElementById('feature-shell-env-variables').textContent + ).to.equal('fromtheshell.'); + }); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js index 3cfb182148a..4d6f531ea84 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js @@ -7,59 +7,72 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -const fs = require('fs') -const http = require('http') -const jsdom = require('jsdom') -const path = require('path') -const { expect } = require('chai') +const fs = require('fs'); +const http = require('http'); +const jsdom = require('jsdom'); +const path = require('path'); +const { expect } = require('chai'); -let getMarkup -let resourceLoader +let getMarkup; +let resourceLoader; if (process.env.E2E_FILE) { const file = path.isAbsolute(process.env.E2E_FILE) ? process.env.E2E_FILE - : path.join(process.cwd(), process.env.E2E_FILE) + : path.join(process.cwd(), process.env.E2E_FILE); - const markup = fs.readFileSync(file, 'utf8') - getMarkup = () => markup + const markup = fs.readFileSync(file, 'utf8'); + getMarkup = () => markup; - const pathPrefix = process.env.PUBLIC_URL.replace(/^https?:\/\/[^/]+\/?/, '') + const pathPrefix = process.env.PUBLIC_URL.replace(/^https?:\/\/[^/]+\/?/, ''); - resourceLoader = (resource, callback) => callback( - null, - fs.readFileSync(path.join(path.dirname(file), resource.url.pathname.replace(pathPrefix, '')), 'utf8') - ) + resourceLoader = (resource, callback) => + callback( + null, + fs.readFileSync( + path.join( + path.dirname(file), + resource.url.pathname.replace(pathPrefix, '') + ), + 'utf8' + ) + ); } else if (process.env.E2E_URL) { getMarkup = () => new Promise(resolve => { - http.get(process.env.E2E_URL, (res) => { - let rawData = '' - res.on('data', chunk => rawData += chunk) - res.on('end', () => resolve(rawData)) - }) - }) + http.get(process.env.E2E_URL, res => { + let rawData = ''; + res.on('data', chunk => rawData += chunk); + res.on('end', () => resolve(rawData)); + }); + }); - resourceLoader = (resource, callback) => resource.defaultFetch(callback) + resourceLoader = (resource, callback) => resource.defaultFetch(callback); } else { - it.only('can run jsdom (at least one of "E2E_FILE" or "E2E_URL" environment variables must be provided)', () => { - expect(new Error('This isn\'t the error you are looking for.')).to.be.undefined() - }) + it.only( + 'can run jsdom (at least one of "E2E_FILE" or "E2E_URL" environment variables must be provided)', + () => { + expect( + new Error("This isn't the error you are looking for.") + ).to.be.undefined(); + } + ); } export default feature => new Promise(async resolve => { - const markup = await getMarkup() - const host = process.env.E2E_URL || 'http://www.example.org/spa:3000' + const markup = await getMarkup(); + const host = process.env.E2E_URL || 'http://www.example.org/spa:3000'; const doc = jsdom.jsdom(markup, { features: { FetchExternalResources: ['script', 'css'], ProcessExternalResources: ['script'], }, - created: (_, win) => win.addEventListener('ReactFeatureDidMount', () => resolve(doc), true), + created: (_, win) => + win.addEventListener('ReactFeatureDidMount', () => resolve(doc), true), deferClose: true, resourceLoader, url: `${host}#${feature}`, virtualConsole: jsdom.createVirtualConsole().sendTo(console), - }) + }); - doc.close() -}) + doc.close(); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js b/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js index 8fe1990f20a..fc2a717befe 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/syntax.test.js @@ -7,99 +7,129 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import { expect } from 'chai' -import initDOM from './initDOM' +import { expect } from 'chai'; +import initDOM from './initDOM'; describe('Integration', () => { describe('Language syntax', () => { it('array destructuring', async () => { - const doc = await initDOM('array-destructuring') + const doc = await initDOM('array-destructuring'); - expect(doc.getElementById('feature-array-destructuring').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-array-destructuring').childElementCount + ).to.equal(4); + }); it('array spread', async () => { - const doc = await initDOM('array-spread') + const doc = await initDOM('array-spread'); - expect(doc.getElementById('feature-array-spread').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-array-spread').childElementCount + ).to.equal(4); + }); it('async/await', async () => { - const doc = await initDOM('async-await') + const doc = await initDOM('async-await'); - expect(doc.getElementById('feature-async-await').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-async-await').childElementCount + ).to.equal(4); + }); it('class properties', async () => { - const doc = await initDOM('class-properties') + const doc = await initDOM('class-properties'); - expect(doc.getElementById('feature-class-properties').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-class-properties').childElementCount + ).to.equal(4); + }); it('computed properties', async () => { - const doc = await initDOM('computed-properties') + const doc = await initDOM('computed-properties'); - expect(doc.getElementById('feature-computed-properties').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-computed-properties').childElementCount + ).to.equal(4); + }); it('custom interpolation', async () => { - const doc = await initDOM('custom-interpolation') + const doc = await initDOM('custom-interpolation'); - expect(doc.getElementById('feature-custom-interpolation').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-custom-interpolation').childElementCount + ).to.equal(4); + }); it('default parameters', async () => { - const doc = await initDOM('default-parameters') + const doc = await initDOM('default-parameters'); - expect(doc.getElementById('feature-default-parameters').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-default-parameters').childElementCount + ).to.equal(4); + }); it('destructuring and await', async () => { - const doc = await initDOM('destructuring-and-await') + const doc = await initDOM('destructuring-and-await'); - expect(doc.getElementById('feature-destructuring-and-await').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-destructuring-and-await').childElementCount + ).to.equal(4); + }); it('generators', async () => { - const doc = await initDOM('generators') + const doc = await initDOM('generators'); - expect(doc.getElementById('feature-generators').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-generators').childElementCount + ).to.equal(4); + }); it('object destructuring', async () => { - const doc = await initDOM('object-destructuring') + const doc = await initDOM('object-destructuring'); - expect(doc.getElementById('feature-object-destructuring').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-object-destructuring').childElementCount + ).to.equal(4); + }); it('object spread', async () => { - const doc = await initDOM('object-spread') + const doc = await initDOM('object-spread'); - expect(doc.getElementById('feature-object-spread').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-object-spread').childElementCount + ).to.equal(4); + }); it('promises', async () => { - const doc = await initDOM('promises') + const doc = await initDOM('promises'); - expect(doc.getElementById('feature-promises').childElementCount).to.equal(4) - }) + expect(doc.getElementById('feature-promises').childElementCount).to.equal( + 4 + ); + }); it('rest + default', async () => { - const doc = await initDOM('rest-and-default') + const doc = await initDOM('rest-and-default'); - expect(doc.getElementById('feature-rest-and-default').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-rest-and-default').childElementCount + ).to.equal(4); + }); it('rest parameters', async () => { - const doc = await initDOM('rest-parameters') + const doc = await initDOM('rest-parameters'); - expect(doc.getElementById('feature-rest-parameters').childElementCount).to.equal(4) - }) + expect( + doc.getElementById('feature-rest-parameters').childElementCount + ).to.equal(4); + }); it('template interpolation', async () => { - const doc = await initDOM('template-interpolation') - - expect(doc.getElementById('feature-template-interpolation').childElementCount).to.equal(4) - }) - }) -}) + const doc = await initDOM('template-interpolation'); + + expect( + doc.getElementById('feature-template-interpolation').childElementCount + ).to.equal(4); + }); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 43b3f1209f7..031786e0ee7 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -7,46 +7,57 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import { expect } from 'chai' -import initDOM from './initDOM' +import { expect } from 'chai'; +import initDOM from './initDOM'; describe('Integration', () => { describe('Webpack plugins', () => { it('css inclusion', async () => { - const doc = await initDOM('css-inclusion') + const doc = await initDOM('css-inclusion'); - expect(doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '')) - .to.match(/#feature-css-inclusion\{background:.+;color:.+}/) - }) + expect( + doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '') + ).to.match(/#feature-css-inclusion\{background:.+;color:.+}/); + }); it('image inclusion', async () => { - const doc = await initDOM('image-inclusion') + const doc = await initDOM('image-inclusion'); - expect(doc.getElementById('feature-image-inclusion').src).to.match(/^data:image\/jpeg;base64.+==$/) - }) + expect(doc.getElementById('feature-image-inclusion').src).to.match( + /^data:image\/jpeg;base64.+==$/ + ); + }); it('no ext inclusion', async () => { - const doc = await initDOM('no-ext-inclusion') + const doc = await initDOM('no-ext-inclusion'); - expect(doc.getElementById('feature-no-ext-inclusion').href).to.match(/\/static\/media\/aFileWithoutExt\.[a-f0-9]{8}\.bin$/) - }) + expect(doc.getElementById('feature-no-ext-inclusion').href).to.match( + /\/static\/media\/aFileWithoutExt\.[a-f0-9]{8}\.bin$/ + ); + }); it('json inclusion', async () => { - const doc = await initDOM('json-inclusion') + const doc = await initDOM('json-inclusion'); - expect(doc.getElementById('feature-json-inclusion').textContent).to.equal('This is an abstract.') - }) + expect(doc.getElementById('feature-json-inclusion').textContent).to.equal( + 'This is an abstract.' + ); + }); it('svg inclusion', async () => { - const doc = await initDOM('svg-inclusion') + const doc = await initDOM('svg-inclusion'); - expect(doc.getElementById('feature-svg-inclusion').src).to.match(/\/static\/media\/logo\..+\.svg$/) - }) + expect(doc.getElementById('feature-svg-inclusion').src).to.match( + /\/static\/media\/logo\..+\.svg$/ + ); + }); it('unknown ext inclusion', async () => { - const doc = await initDOM('unknown-ext-inclusion') - - expect(doc.getElementById('feature-unknown-ext-inclusion').href).to.match(/\/static\/media\/aFileWithExt\.[a-f0-9]{8}\.unknown$/) - }) - }) -}) + const doc = await initDOM('unknown-ext-inclusion'); + + expect(doc.getElementById('feature-unknown-ext-inclusion').href).to.match( + /\/static\/media\/aFileWithExt\.[a-f0-9]{8}\.unknown$/ + ); + }); + }); +}); diff --git a/packages/react-scripts/fixtures/kitchensink/src/App.js b/packages/react-scripts/fixtures/kitchensink/src/App.js index ac55f7767e6..67de182b59e 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/App.js +++ b/packages/react-scripts/fixtures/kitchensink/src/App.js @@ -11,8 +11,8 @@ import React, { Component, PropTypes, createElement } from 'react'; class BuiltEmitter extends Component { static propTypes = { - feature: PropTypes.func.isRequired - } + feature: PropTypes.func.isRequired, + }; componentDidMount() { const { feature } = this.props; @@ -31,12 +31,12 @@ class BuiltEmitter extends Component { render() { const { props: { feature }, - handleReady + handleReady, } = this; return (
{createElement(feature, { - onReady: handleReady + onReady: handleReady, })}
); @@ -56,81 +56,113 @@ class App extends Component { const feature = location.hash.slice(1); switch (feature) { case 'array-destructuring': - import('./features/syntax/ArrayDestructuring').then(f => this.setFeature(f.default)); + import( + './features/syntax/ArrayDestructuring' + ).then(f => this.setFeature(f.default)); break; case 'array-spread': - import('./features/syntax/ArraySpread').then(f => this.setFeature(f.default)); + import('./features/syntax/ArraySpread').then(f => + this.setFeature(f.default)); break; case 'async-await': - import('./features/syntax/AsyncAwait').then(f => this.setFeature(f.default)); + import('./features/syntax/AsyncAwait').then(f => + this.setFeature(f.default)); break; case 'class-properties': - import('./features/syntax/ClassProperties').then(f => this.setFeature(f.default)); + import('./features/syntax/ClassProperties').then(f => + this.setFeature(f.default)); break; case 'computed-properties': - import('./features/syntax/ComputedProperties').then(f => this.setFeature(f.default)); + import( + './features/syntax/ComputedProperties' + ).then(f => this.setFeature(f.default)); break; case 'css-inclusion': - import('./features/webpack/CssInclusion').then(f => this.setFeature(f.default)); + import('./features/webpack/CssInclusion').then(f => + this.setFeature(f.default)); break; case 'custom-interpolation': - import('./features/syntax/CustomInterpolation').then(f => this.setFeature(f.default)); + import( + './features/syntax/CustomInterpolation' + ).then(f => this.setFeature(f.default)); break; case 'default-parameters': - import('./features/syntax/DefaultParameters').then(f => this.setFeature(f.default)); + import('./features/syntax/DefaultParameters').then(f => + this.setFeature(f.default)); break; case 'destructuring-and-await': - import('./features/syntax/DestructuringAndAwait').then(f => this.setFeature(f.default)); + import( + './features/syntax/DestructuringAndAwait' + ).then(f => this.setFeature(f.default)); break; case 'file-env-variables': - import('./features/env/FileEnvVariables').then(f => this.setFeature(f.default)); + import('./features/env/FileEnvVariables').then(f => + this.setFeature(f.default)); break; case 'generators': - import('./features/syntax/Generators').then(f => this.setFeature(f.default)); + import('./features/syntax/Generators').then(f => + this.setFeature(f.default)); break; case 'image-inclusion': - import('./features/webpack/ImageInclusion').then(f => this.setFeature(f.default)); + import('./features/webpack/ImageInclusion').then(f => + this.setFeature(f.default)); break; case 'json-inclusion': - import('./features/webpack/JsonInclusion').then(f => this.setFeature(f.default)); + import('./features/webpack/JsonInclusion').then(f => + this.setFeature(f.default)); break; case 'node-path': import('./features/env/NodePath').then(f => this.setFeature(f.default)); break; case 'no-ext-inclusion': - import('./features/webpack/NoExtInclusion').then(f => this.setFeature(f.default)); + import('./features/webpack/NoExtInclusion').then(f => + this.setFeature(f.default)); break; case 'object-destructuring': - import('./features/syntax/ObjectDestructuring').then(f => this.setFeature(f.default)); + import( + './features/syntax/ObjectDestructuring' + ).then(f => this.setFeature(f.default)); break; case 'object-spread': - import('./features/syntax/ObjectSpread').then(f => this.setFeature(f.default)); + import('./features/syntax/ObjectSpread').then(f => + this.setFeature(f.default)); break; case 'promises': - import('./features/syntax/Promises').then(f => this.setFeature(f.default)); + import('./features/syntax/Promises').then(f => + this.setFeature(f.default)); break; case 'public-url': - import('./features/env/PublicUrl').then(f => this.setFeature(f.default)); + import('./features/env/PublicUrl').then(f => + this.setFeature(f.default)); break; case 'rest-and-default': - import('./features/syntax/RestAndDefault').then(f => this.setFeature(f.default)); + import('./features/syntax/RestAndDefault').then(f => + this.setFeature(f.default)); break; case 'rest-parameters': - import('./features/syntax/RestParameters').then(f => this.setFeature(f.default)); + import('./features/syntax/RestParameters').then(f => + this.setFeature(f.default)); break; case 'shell-env-variables': - import('./features/env/ShellEnvVariables').then(f => this.setFeature(f.default)); + import('./features/env/ShellEnvVariables').then(f => + this.setFeature(f.default)); break; case 'svg-inclusion': - import('./features/webpack/SvgInclusion').then(f => this.setFeature(f.default)); + import('./features/webpack/SvgInclusion').then(f => + this.setFeature(f.default)); break; case 'template-interpolation': - import('./features/syntax/TemplateInterpolation').then(f => this.setFeature(f.default)); + import( + './features/syntax/TemplateInterpolation' + ).then(f => this.setFeature(f.default)); break; case 'unknown-ext-inclusion': - import('./features/webpack/UnknownExtInclusion').then(f => this.setFeature(f.default)); + import( + './features/webpack/UnknownExtInclusion' + ).then(f => this.setFeature(f.default)); break; - default: throw new Error(`Missing feature "${feature}"`); + default: + throw new Error(`Missing feature "${feature}"`); } } diff --git a/packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js b/packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js index a1fe21e48ff..0d01bc0a227 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js +++ b/packages/react-scripts/fixtures/kitchensink/src/absoluteLoad.js @@ -11,5 +11,5 @@ export default () => [ { id: 1, name: '1' }, { id: 2, name: '2' }, { id: 3, name: '3' }, - { id: 4, name: '4' } -] + { id: 4, name: '4' }, +]; diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js index ff874b62812..a8a1e98fe71 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/FileEnvVariables.js @@ -7,8 +7,10 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React from 'react' +import React from 'react'; export default () => ( - {process.env.REACT_APP_FILE_ENV_MESSAGE}. -) + + {process.env.REACT_APP_FILE_ENV_MESSAGE}. + +); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js index e4b868e47b6..eb1a45c0f12 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js @@ -7,13 +7,13 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' -import load from 'absoluteLoad' +import React, { Component, PropTypes } from 'react'; +import load from 'absoluteLoad'; export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -32,9 +32,7 @@ export default class extends Component { render() { return (
- {this.state.users.map(user => ( -
{user.name}
- ))} + {this.state.users.map(user =>
{user.name}
)}
); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.js index 4c61be73956..4ea9b96f8b2 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/PublicUrl.js @@ -7,8 +7,8 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React from 'react' +import React from 'react'; export default () => ( {process.env.PUBLIC_URL}. -) +); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js b/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js index 243bfc00935..8449097d69a 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/env/ShellEnvVariables.js @@ -7,8 +7,10 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React from 'react' +import React from 'react'; export default () => ( - {process.env.REACT_APP_SHELL_ENV_MESSAGE}. -) + + {process.env.REACT_APP_SHELL_ENV_MESSAGE}. + +); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js index 48516d43fd3..3d18a5edeac 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js @@ -7,21 +7,16 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; function load() { - return [ - [1, '1'], - [2, '2'], - [3, '3'], - [4, '4'] - ]; + return [[1, '1'], [2, '2'], [3, '3'], [4, '4']]; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -42,7 +37,7 @@ export default class extends Component {
{this.state.users.map(user => { const [id, name] = user; - return
{name}
+ return
{name}
; })}
); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js index 9998589a138..4f9b174eb6f 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ArraySpread.js @@ -7,21 +7,21 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; function load(users) { return [ { id: 1, name: '1' }, { id: 2, name: '2' }, { id: 3, name: '3' }, - ...users + ...users, ]; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -40,9 +40,7 @@ export default class extends Component { render() { return (
- {this.state.users.map(user => ( -
{user.name}
- ))} + {this.state.users.map(user =>
{user.name}
)}
); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js index b5b6013f93c..6924d4f92d8 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/AsyncAwait.js @@ -7,21 +7,21 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; async function load() { return [ { id: 1, name: '1' }, { id: 2, name: '2' }, { id: 3, name: '3' }, - { id: 4, name: '4' } + { id: 4, name: '4' }, ]; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -40,9 +40,7 @@ export default class extends Component { render() { return (
- {this.state.users.map(user => ( -
{user.name}
- ))} + {this.state.users.map(user =>
{user.name}
)}
); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js index 63bd7ab0512..7be21952da5 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ClassProperties.js @@ -7,30 +7,28 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; users = [ { id: 1, name: '1' }, { id: 2, name: '2' }, { id: 3, name: '3' }, - { id: 4, name: '4' } + { id: 4, name: '4' }, ]; componentDidMount() { - this.props.onReady() + this.props.onReady(); } render() { return (
- {this.users.map(user => ( -
{user.name}
- ))} + {this.users.map(user =>
{user.name}
)}
); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js index e345283eaaa..fc64c2a86e3 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ComputedProperties.js @@ -7,21 +7,21 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; function load(prefix) { return [ - { id: 1, [prefix + 'name']: '1' }, - { id: 2, [prefix + 'name']: '2' }, - { id: 3, [prefix + 'name']: '3' }, - { id: 4, [prefix + 'name']: '4' } + { id: 1, [`${prefix} name`]: '1' }, + { id: 2, [`${prefix} name`]: '2' }, + { id: 3, [`${prefix} name`]: '3' }, + { id: 4, [`${prefix} name`]: '4' }, ]; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js index 399280d0190..e97902545e1 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js @@ -7,26 +7,28 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; -const styled = ([style]) => style.trim() - .split(/\s*;\s*/) - .map(rule => rule.split(/\s*:\s*/)) - .reduce((rules, rule) => ({ ...rules, [rule[0]]: rule[1] }), {}); +const styled = ([style]) => + style + .trim() + .split(/\s*;\s*/) + .map(rule => rule.split(/\s*:\s*/)) + .reduce((rules, rule) => ({ ...rules, [rule[0]]: rule[1] }), {}); function load() { return [ { id: 1, name: '1' }, { id: 2, name: '2' }, { id: 3, name: '3' }, - { id: 4, name: '4' } + { id: 4, name: '4' }, ]; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js index fd4054e56cb..74bbe4d3c17 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DefaultParameters.js @@ -7,21 +7,21 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; function load(id = 0) { return [ { id: id + 1, name: '1' }, { id: id + 2, name: '2' }, { id: id + 3, name: '3' }, - { id: id + 4, name: '4' } + { id: id + 4, name: '4' }, ]; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -40,9 +40,7 @@ export default class extends Component { render() { return (
- {this.state.users.map(user => ( -
{user.name}
- ))} + {this.state.users.map(user =>
{user.name}
)}
); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js index c2345f5ce54..ede416944fc 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js @@ -7,21 +7,23 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; async function load() { - return { users: [ - { id: 1, name: '1' }, - { id: 2, name: '2' }, - { id: 3, name: '3' }, - { id: 4, name: '4' } - ] }; + return { + users: [ + { id: 1, name: '1' }, + { id: 2, name: '2' }, + { id: 3, name: '3' }, + { id: 4, name: '4' }, + ], + }; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -40,9 +42,7 @@ export default class extends Component { render() { return (
- {this.state.users.map(user => ( -
{user.name}
- ))} + {this.state.users.map(user =>
{user.name}
)}
); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js index 170f00a7f0d..77b7bffd252 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Generators.js @@ -7,9 +7,9 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; -function * load(limit) { +function* load(limit) { let i = 1; while (i <= limit) { yield { id: i, name: i }; @@ -19,8 +19,8 @@ function * load(limit) { export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -42,9 +42,7 @@ export default class extends Component { render() { return (
- {this.state.users.map(user => ( -
{user.name}
- ))} + {this.state.users.map(user =>
{user.name}
)}
); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js index 025920b7f31..14fa6969ee5 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js @@ -7,21 +7,21 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; function load() { return [ { id: 1, name: '1' }, { id: 2, name: '2' }, { id: 3, name: '3' }, - { id: 4, name: '4' } + { id: 4, name: '4' }, ]; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -42,7 +42,7 @@ export default class extends Component {
{this.state.users.map(user => { const { id, name } = user; - return
{name}
+ return
{name}
; })}
); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js index d5de0aef31a..bf3fb26b80c 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/ObjectSpread.js @@ -7,21 +7,21 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; function load(baseUser) { return [ { id: 1, name: '1', ...baseUser }, { id: 2, name: '2', ...baseUser }, { id: 3, name: '3', ...baseUser }, - { id: 4, name: '4', ...baseUser } + { id: 4, name: '4', ...baseUser }, ]; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js index 8b362fccf2c..26438012cf2 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/Promises.js @@ -7,21 +7,21 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; function load() { return Promise.resolve([ { id: 1, name: '1' }, { id: 2, name: '2' }, { id: 3, name: '3' }, - { id: 4, name: '4' } + { id: 4, name: '4' }, ]); } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -41,9 +41,7 @@ export default class extends Component { render() { return (
- {this.state.users.map(user => ( -
{user.name}
- ))} + {this.state.users.map(user =>
{user.name}
)}
); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js index 47d011f2eae..411ce33d4b9 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestAndDefault.js @@ -7,21 +7,21 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; function load({ id, ...rest } = { id: 0, user: { id: 42, name: '42' } }) { return [ { id: id + 1, name: '1' }, { id: id + 2, name: '2' }, { id: id + 3, name: '3' }, - rest.user + rest.user, ]; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -40,9 +40,7 @@ export default class extends Component { render() { return (
- {this.state.users.map(user => ( -
{user.name}
- ))} + {this.state.users.map(user =>
{user.name}
)}
); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js index 1a6cf7c1687..aaca55c0f96 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/RestParameters.js @@ -7,21 +7,21 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; function load({ id = 0, ...rest }) { return [ { id: id + 1, name: '1' }, { id: id + 2, name: '2' }, { id: id + 3, name: '3' }, - rest.user + rest.user, ]; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -40,9 +40,7 @@ export default class extends Component { render() { return (
- {this.state.users.map(user => ( -
{user.name}
- ))} + {this.state.users.map(user =>
{user.name}
)}
); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js index ff46e1c72f8..738a0b103ef 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js @@ -7,21 +7,21 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React, { Component, PropTypes } from 'react' +import React, { Component, PropTypes } from 'react'; function load(name) { return [ { id: 1, name: `${name}1` }, { id: 2, name: `${name}2` }, { id: 3, name: `${name}3` }, - { id: 4, name: `${name}4` } + { id: 4, name: `${name}4` }, ]; } export default class extends Component { static propTypes = { - onReady: PropTypes.func.isRequired - } + onReady: PropTypes.func.isRequired, + }; constructor(props) { super(props); @@ -40,9 +40,7 @@ export default class extends Component { render() { return (
- {this.state.users.map(user => ( -
{user.name}
- ))} + {this.state.users.map(user =>
{user.name}
)}
); } diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js index 7c46c7208b7..ab7c9a2d86e 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/CssInclusion.js @@ -7,9 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React from 'react' -import './assets/style.css' +import React from 'react'; +import './assets/style.css'; -export default () => ( -

We love useless text.

-) +export default () =>

We love useless text.

; diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js index c4560ff9dae..a6ca7aaa818 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/ImageInclusion.js @@ -7,9 +7,9 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React from 'react' -import tiniestCat from './assets/tiniest-cat.jpg' +import React from 'react'; +import tiniestCat from './assets/tiniest-cat.jpg'; export default () => ( tiniest cat -) +); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js index 552a8be7b1a..e81f7639736 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/JsonInclusion.js @@ -7,9 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React from 'react' -import { abstract } from './assets/abstract.json' +import React from 'react'; +import { abstract } from './assets/abstract.json'; -export default () => ( - {abstract} -) +export default () => {abstract}; diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js index b3bdbe9fcbc..7f824c2f292 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js @@ -7,13 +7,13 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React from 'react' -import aFileWithoutExt from './assets/aFileWithoutExt' +import React from 'react'; +import aFileWithoutExt from './assets/aFileWithoutExt'; const text = aFileWithoutExt.includes('base64') ? atob(aFileWithoutExt.split('base64,')[1]).trim() - : aFileWithoutExt + : aFileWithoutExt; export default () => ( aFileWithoutExt -) +); diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js index f82e5f2911c..8876021aed6 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/SvgInclusion.js @@ -7,9 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React from 'react' -import logo from './assets/logo.svg' +import React from 'react'; +import logo from './assets/logo.svg'; -export default () => ( - logo -) +export default () => logo; diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js index a9ac8f00cf1..70b046e9532 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js @@ -7,13 +7,13 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -import React from 'react' -import aFileWithExtUnknown from './assets/aFileWithExt.unknown' +import React from 'react'; +import aFileWithExtUnknown from './assets/aFileWithExt.unknown'; const text = aFileWithExtUnknown.includes('base64') ? atob(aFileWithExtUnknown.split('base64,')[1]).trim() - : aFileWithExtUnknown + : aFileWithExtUnknown; export default () => ( aFileWithExtUnknown -) +); diff --git a/packages/react-scripts/fixtures/kitchensink/src/index.js b/packages/react-scripts/fixtures/kitchensink/src/index.js index dc1143691f2..46fb0dd2e55 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/index.js +++ b/packages/react-scripts/fixtures/kitchensink/src/index.js @@ -11,7 +11,4 @@ import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; -ReactDOM.render( - , - document.getElementById('root') -); +ReactDOM.render(, document.getElementById('root')); diff --git a/packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js b/packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js index c844f831d31..979cb3e7206 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js +++ b/packages/react-scripts/fixtures/kitchensink/src/subfolder/lol.js @@ -7,4 +7,6 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -module.exports = function() { return `haha` } +module.exports = function() { + return `haha`; +}; diff --git a/packages/react-scripts/scripts/build.js b/packages/react-scripts/scripts/build.js index 05cefa0393e..548ff3cc68e 100644 --- a/packages/react-scripts/scripts/build.js +++ b/packages/react-scripts/scripts/build.js @@ -17,21 +17,21 @@ process.env.NODE_ENV = 'production'; // if this file is missing. dotenv will never modify any environment variables // that have already been set. // https://github.com/motdotla/dotenv -require('dotenv').config({silent: true}); - -var chalk = require('chalk'); -var fs = require('fs-extra'); -var path = require('path'); -var url = require('url'); -var webpack = require('webpack'); -var config = require('../config/webpack.config.prod'); -var paths = require('../config/paths'); -var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); -var FileSizeReporter = require('react-dev-utils/FileSizeReporter'); -var measureFileSizesBeforeBuild = FileSizeReporter.measureFileSizesBeforeBuild; -var printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild; - -var useYarn = fs.existsSync(paths.yarnLockFile); +require('dotenv').config({ silent: true }); + +const chalk = require('chalk'); +const fs = require('fs-extra'); +const path = require('path'); +const url = require('url'); +const webpack = require('webpack'); +const config = require('../config/webpack.config.prod'); +const paths = require('../config/paths'); +const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); +const FileSizeReporter = require('react-dev-utils/FileSizeReporter'); + +const measureFileSizesBeforeBuild = FileSizeReporter.measureFileSizesBeforeBuild; +const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild; +const useYarn = fs.existsSync(paths.yarnLockFile); // Warn and crash if required files are missing if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { @@ -66,7 +66,7 @@ function printErrors(summary, errors) { function build(previousFileSizes) { console.log('Creating an optimized production build...'); - var compiler; + let compiler; try { compiler = webpack(config); } catch (err) { @@ -86,9 +86,12 @@ function build(previousFileSizes) { } if (process.env.CI && stats.compilation.warnings.length) { - printErrors('Failed to compile. When process.env.CI = true, warnings are treated as failures. Most CI servers set this automatically.', stats.compilation.warnings); - process.exit(1); - } + printErrors( + 'Failed to compile. When process.env.CI = true, warnings are treated as failures. Most CI servers set this automatically.', + stats.compilation.warnings + ); + process.exit(1); + } console.log(chalk.green('Compiled successfully.')); console.log(); @@ -98,74 +101,100 @@ function build(previousFileSizes) { printFileSizesAfterBuild(stats, previousFileSizes); console.log(); - var openCommand = process.platform === 'win32' ? 'start' : 'open'; - var appPackage = require(paths.appPackageJson); - var publicUrl = paths.publicUrl; - var publicPath = config.output.publicPath; - var publicPathname = url.parse(publicPath).pathname; + const openCommand = process.platform === 'win32' ? 'start' : 'open'; + const appPackage = require(paths.appPackageJson); + const publicUrl = paths.publicUrl; + const publicPath = config.output.publicPath; + const publicPathname = url.parse(publicPath).pathname; if (publicUrl && publicUrl.indexOf('.github.io/') !== -1) { // "homepage": "http://user.github.io/project" - console.log('The project was built assuming it is hosted at ' + chalk.green(publicPathname) + '.'); - console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.'); + console.log( + `The project was built assuming it is hosted at ${chalk.green(publicPathname)}.` + ); + console.log( + `You can control this with the ${chalk.green('homepage')} field in your ${chalk.cyan('package.json')}.` + ); console.log(); - console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.'); - console.log('To publish it at ' + chalk.green(publicUrl) + ', run:'); + console.log(`The ${chalk.cyan('build')} folder is ready to be deployed.`); + console.log(`To publish it at ${chalk.green(publicUrl)}, run:`); // If script deploy has been added to package.json, skip the instructions if (typeof appPackage.scripts.deploy === 'undefined') { console.log(); if (useYarn) { - console.log(' ' + chalk.cyan('yarn') + ' add --dev gh-pages'); + console.log(` ${chalk.cyan('yarn')} add --dev gh-pages`); } else { - console.log(' ' + chalk.cyan('npm') + ' install --save-dev gh-pages'); + console.log(` ${chalk.cyan('npm')} install --save-dev gh-pages`); } console.log(); - console.log('Add the following script in your ' + chalk.cyan('package.json') + '.'); + console.log( + `Add the following script in your ${chalk.cyan('package.json')}.` + ); console.log(); - console.log(' ' + chalk.dim('// ...')); - console.log(' ' + chalk.yellow('"scripts"') + ': {'); - console.log(' ' + chalk.dim('// ...')); - console.log(' ' + chalk.yellow('"predeploy"') + ': ' + chalk.yellow('"npm run build",')); - console.log(' ' + chalk.yellow('"deploy"') + ': ' + chalk.yellow('"gh-pages -d build"')); + console.log(` ${chalk.dim('// ...')}`); + console.log(` ${chalk.yellow('"scripts"')}: {`); + console.log(` ${chalk.dim('// ...')}`); + console.log( + ` ${chalk.yellow('"predeploy"')}: ${chalk.yellow('"npm run build",')}` + ); + console.log( + ` ${chalk.yellow('"deploy"')}: ${chalk.yellow('"gh-pages -d build"')}` + ); console.log(' }'); console.log(); console.log('Then run:'); } console.log(); - console.log(' ' + chalk.cyan(useYarn ? 'yarn' : 'npm') + ' run deploy'); + console.log(` ${chalk.cyan(useYarn ? 'yarn' : 'npm')} run deploy`); console.log(); } else if (publicPath !== '/') { // "homepage": "http://mywebsite.com/project" - console.log('The project was built assuming it is hosted at ' + chalk.green(publicPath) + '.'); - console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.'); + console.log( + `The project was built assuming it is hosted at ${chalk.green(publicPath)}.` + ); + console.log( + `You can control this with the ${chalk.green('homepage')} field in your ${chalk.cyan('package.json')}.` + ); console.log(); - console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.'); + console.log(`The ${chalk.cyan('build')} folder is ready to be deployed.`); console.log(); } else { if (publicUrl) { // "homepage": "http://mywebsite.com" - console.log('The project was built assuming it is hosted at ' + chalk.green(publicUrl) + '.'); - console.log('You can control this with the ' + chalk.green('homepage') + ' field in your ' + chalk.cyan('package.json') + '.'); + console.log( + `The project was built assuming it is hosted at ${chalk.green(publicUrl)}.` + ); + console.log( + `You can control this with the ${chalk.green('homepage')} field in your ${chalk.cyan('package.json')}.` + ); console.log(); } else { // no homepage - console.log('The project was built assuming it is hosted at the server root.'); - console.log('To override this, specify the ' + chalk.green('homepage') + ' in your ' + chalk.cyan('package.json') + '.'); - console.log('For example, add this to build it for GitHub Pages:') + console.log( + 'The project was built assuming it is hosted at the server root.' + ); + console.log( + `To override this, specify the ${chalk.green('homepage')} in your ${chalk.cyan('package.json')}.` + ); + console.log('For example, add this to build it for GitHub Pages:'); console.log(); - console.log(' ' + chalk.green('"homepage"') + chalk.cyan(': ') + chalk.green('"http://myname.github.io/myapp"') + chalk.cyan(',')); + console.log( + ` ${chalk.green('"homepage"')} ${chalk.cyan(':')} ${chalk.green('"http://myname.github.io/myapp"')}${chalk.cyan(',')}` + ); console.log(); } - var build = path.relative(process.cwd(), paths.appBuild); - console.log('The ' + chalk.cyan(build) + ' folder is ready to be deployed.'); - console.log('You may also serve it locally with a static server:') + const build = path.relative(process.cwd(), paths.appBuild); + console.log(`The ${chalk.cyan(build)} folder is ready to be deployed.`); + console.log('You may also serve it locally with a static server:'); console.log(); if (useYarn) { - console.log(' ' + chalk.cyan('yarn') + ' global add pushstate-server'); + console.log(` ${chalk.cyan('yarn')} global add pushstate-server`); } else { - console.log(' ' + chalk.cyan('npm') + ' install -g pushstate-server'); + console.log(` ${chalk.cyan('npm')} install -g pushstate-server`); } - console.log(' ' + chalk.cyan('pushstate-server') + ' ' + build); - console.log(' ' + chalk.cyan(openCommand) + ' http://localhost:' + (process.env.PORT || 9000)); + console.log(` ${chalk.cyan('pushstate-server')} build`); + console.log( + ` ${chalk.cyan(openCommand)} http://localhost:${process.env.PORT || 9000}` + ); console.log(); } }); @@ -174,6 +203,6 @@ function build(previousFileSizes) { function copyPublicFolder() { fs.copySync(paths.appPublic, paths.appBuild, { dereference: true, - filter: file => file !== paths.appHtml + filter: file => file !== paths.appHtml, }); } diff --git a/packages/react-scripts/scripts/eject.js b/packages/react-scripts/scripts/eject.js index 39a40546bde..68c43d25068 100644 --- a/packages/react-scripts/scripts/eject.js +++ b/packages/react-scripts/scripts/eject.js @@ -9,16 +9,16 @@ */ 'use strict'; -var fs = require('fs-extra'); -var path = require('path'); -var spawnSync = require('cross-spawn').sync; -var chalk = require('chalk'); -var prompt = require('react-dev-utils/prompt'); -var paths = require('../config/paths'); -var createJestConfig = require('./utils/createJestConfig'); +const fs = require('fs-extra'); +const path = require('path'); +const spawnSync = require('cross-spawn').sync; +const chalk = require('chalk'); +const prompt = require('react-dev-utils/prompt'); +const paths = require('../config/paths'); +const createJestConfig = require('./utils/createJestConfig'); -var green = chalk.green; -var cyan = chalk.cyan; +const green = chalk.green; +const cyan = chalk.cyan; prompt( 'Are you sure you want to eject? This action is permanent.', @@ -31,52 +31,51 @@ prompt( console.log('Ejecting...'); - var ownPath = paths.ownPath; - var appPath = paths.appPath; + const ownPath = paths.ownPath; + const appPath = paths.appPath; function verifyAbsent(file) { if (fs.existsSync(path.join(appPath, file))) { console.error( - '`' + file + '` already exists in your app folder. We cannot ' + - 'continue as you would lose all the changes in that file or directory. ' + - 'Please move or delete it (maybe make a copy for backup) and run this ' + - 'command again.' + `\`${file}\` already exists in your app folder. We cannot ` + + 'continue as you would lose all the changes in that file or directory. ' + + 'Please move or delete it (maybe make a copy for backup) and run this ' + + 'command again.' ); process.exit(1); } } - var folders = [ - 'config', - 'config/jest', - 'scripts', - 'scripts/utils', - ]; + const folders = ['config', 'config/jest', 'scripts', 'scripts/utils']; // Make shallow array of files paths - var files = folders.reduce(function (files, folder) { - return files.concat( - fs.readdirSync(path.join(ownPath, folder)) - // set full path - .map(file => path.join(ownPath, folder, file)) - // omit dirs from file list - .filter(file => fs.lstatSync(file).isFile()) - ); - }, []); + const files = folders.reduce( + (files, folder) => { + return files.concat( + fs + .readdirSync(path.join(ownPath, folder)) + // set full path + .map(file => path.join(ownPath, folder, file)) + // omit dirs from file list + .filter(file => fs.lstatSync(file).isFile()) + ); + }, + [] + ); // Ensure that the app folder is clean and we won't override any files folders.forEach(verifyAbsent); files.forEach(verifyAbsent); console.log(); - console.log(cyan('Copying files into ' + appPath)); + console.log(cyan(`Copying files into ${appPath}`)); - folders.forEach(function(folder) { - fs.mkdirSync(path.join(appPath, folder)) + folders.forEach(folder => { + fs.mkdirSync(path.join(appPath, folder)); }); - files.forEach(function(file) { - var content = fs.readFileSync(file, 'utf8'); + files.forEach(file => { + let content = fs.readFileSync(file, 'utf8'); // Skip flagged files if (content.match(/\/\/ @remove-file-on-eject/)) { @@ -84,52 +83,61 @@ prompt( } content = content // Remove dead code from .js files on eject - .replace(/\/\/ @remove-on-eject-begin([\s\S]*?)\/\/ @remove-on-eject-end/mg, '') + .replace( + /\/\/ @remove-on-eject-begin([\s\S]*?)\/\/ @remove-on-eject-end/mg, + '' + ) // Remove dead code from .applescript files on eject - .replace(/-- @remove-on-eject-begin([\s\S]*?)-- @remove-on-eject-end/mg, '') + .replace( + /-- @remove-on-eject-begin([\s\S]*?)-- @remove-on-eject-end/mg, + '' + ) .trim() + '\n'; - console.log(' Adding ' + cyan(file.replace(ownPath, '')) + ' to the project'); + console.log(` Adding ${cyan(file.replace(ownPath, ''))} to the project`); fs.writeFileSync(file.replace(ownPath, appPath), content); }); console.log(); - var ownPackage = require(path.join(ownPath, 'package.json')); - var appPackage = require(path.join(appPath, 'package.json')); - var babelConfig = JSON.parse(fs.readFileSync(path.join(ownPath, 'babelrc'), 'utf8')); - var eslintConfig = JSON.parse(fs.readFileSync(path.join(ownPath, 'eslintrc'), 'utf8')); + const ownPackage = require(path.join(ownPath, 'package.json')); + const appPackage = require(path.join(appPath, 'package.json')); + const babelConfig = JSON.parse( + fs.readFileSync(path.join(ownPath, '.babelrc'), 'utf8') + ); + const eslintConfig = JSON.parse( + fs.readFileSync(path.join(ownPath, '.eslintrc'), 'utf8') + ); console.log(cyan('Updating the dependencies')); - var ownPackageName = ownPackage.name; + const ownPackageName = ownPackage.name; if (appPackage.devDependencies[ownPackageName]) { - console.log(' Removing ' + cyan(ownPackageName) + ' from devDependencies'); + console.log(` Removing ${cyan(ownPackageName)} from devDependencies`); delete appPackage.devDependencies[ownPackageName]; } if (appPackage.dependencies[ownPackageName]) { - console.log(' Removing ' + cyan(ownPackageName) + ' from dependencies'); + console.log(` Removing ${cyan(ownPackageName)} from dependencies`); delete appPackage.dependencies[ownPackageName]; } - Object.keys(ownPackage.dependencies).forEach(function (key) { + Object.keys(ownPackage.dependencies).forEach(key => { // For some reason optionalDependencies end up in dependencies after install if (ownPackage.optionalDependencies[key]) { return; } - console.log(' Adding ' + cyan(key) + ' to devDependencies'); + console.log(` Adding ${cyan(key)} to devDependencies`); appPackage.devDependencies[key] = ownPackage.dependencies[key]; }); console.log(); console.log(cyan('Updating the scripts')); delete appPackage.scripts['eject']; - Object.keys(appPackage.scripts).forEach(function (key) { - Object.keys(ownPackage.bin).forEach(function (binKey) { - var regex = new RegExp(binKey + ' (\\w+)', 'g'); - appPackage.scripts[key] = appPackage.scripts[key] - .replace(regex, 'node scripts/$1.js'); + Object.keys(appPackage.scripts).forEach(key => { + Object.keys(ownPackage.bin).forEach(binKey => { + const regex = new RegExp(binKey + ' (\\w+)', 'g'); + appPackage.scripts[key] = appPackage.scripts[key].replace( + regex, + 'node scripts/$1.js' + ); console.log( - ' Replacing ' + - cyan('"' + binKey + ' ' + key + '"') + - ' with ' + - cyan('"node scripts/' + key + '.js"') + ` Replacing ${cyan(`"${binKey} ${key}"`)} with ${cyan(`"node scripts/${key}.js"`)}` ); }); }); @@ -137,7 +145,7 @@ prompt( console.log(); console.log(cyan('Configuring package.json')); // Add Jest config - console.log(' Adding ' + cyan('Jest') + ' configuration'); + console.log(` Adding ${cyan('Jest')} configuration`); appPackage.jest = createJestConfig( filePath => path.posix.join('', filePath), null, @@ -145,11 +153,11 @@ prompt( ); // Add Babel config - console.log(' Adding ' + cyan('Babel') + ' preset'); + console.log(` Adding ${cyan('Babel')} preset`); appPackage.babel = babelConfig; // Add ESlint config - console.log(' Adding ' + cyan('ESLint') +' configuration'); + console.log(` Adding ${cyan('ESLint')} configuration`); appPackage.eslintConfig = eslintConfig; fs.writeFileSync( @@ -162,26 +170,26 @@ prompt( if (ownPath.indexOf(appPath) === 0) { try { // remove react-scripts and react-scripts binaries from app node_modules - Object.keys(ownPackage.bin).forEach(function(binKey) { + Object.keys(ownPackage.bin).forEach(binKey => { fs.removeSync(path.join(appPath, 'node_modules', '.bin', binKey)); }); fs.removeSync(ownPath); - } catch(e) { + } catch (e) { // It's not essential that this succeeds } } if (fs.existsSync(paths.yarnLockFile)) { console.log(cyan('Running yarn...')); - spawnSync('yarnpkg', [], {stdio: 'inherit'}); + spawnSync('yarnpkg', [], { stdio: 'inherit' }); } else { console.log(cyan('Running npm install...')); - spawnSync('npm', ['install'], {stdio: 'inherit'}); + spawnSync('npm', ['install'], { stdio: 'inherit' }); } console.log(green('Ejected successfully!')); console.log(); console.log(green('Please consider sharing why you ejected in this survey:')); console.log(green(' http://goo.gl/forms/Bi6CZjk1EqsdelXk1')); - console.log() -}) + console.log(); +}); diff --git a/packages/react-scripts/scripts/init.js b/packages/react-scripts/scripts/init.js index 352bf0f41c5..b8a820c821d 100644 --- a/packages/react-scripts/scripts/init.js +++ b/packages/react-scripts/scripts/init.js @@ -7,19 +7,28 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ - 'use strict'; -var fs = require('fs-extra'); -var path = require('path'); -var spawn = require('cross-spawn'); -var chalk = require('chalk'); - -module.exports = function(appPath, appName, verbose, originalDirectory, template) { - var ownPackageName = require(path.join(__dirname, '..', 'package.json')).name; - var ownPath = path.join(appPath, 'node_modules', ownPackageName); - var appPackage = require(path.join(appPath, 'package.json')); - var useYarn = fs.existsSync(path.join(appPath, 'yarn.lock')); +const fs = require('fs-extra'); +const path = require('path'); +const spawn = require('cross-spawn'); +const chalk = require('chalk'); + +module.exports = function( + appPath, + appName, + verbose, + originalDirectory, + template +) { + const ownPackageName = require(path.join( + __dirname, + '..', + 'package.json' + )).name; + const ownPath = path.join(appPath, 'node_modules', ownPackageName); + const appPackage = require(path.join(appPath, 'package.json')); + const useYarn = fs.existsSync(path.join(appPath, 'yarn.lock')); // Copy over some of the devDependencies appPackage.dependencies = appPackage.dependencies || {}; @@ -27,10 +36,10 @@ module.exports = function(appPath, appName, verbose, originalDirectory, template // Setup the script rules appPackage.scripts = { - 'start': 'react-scripts start', - 'build': 'react-scripts build', - 'test': 'react-scripts test --env=jsdom', - 'eject': 'react-scripts eject' + start: 'react-scripts start', + build: 'react-scripts build', + test: 'react-scripts test --env=jsdom', + eject: 'react-scripts eject', }; fs.writeFileSync( @@ -38,58 +47,71 @@ module.exports = function(appPath, appName, verbose, originalDirectory, template JSON.stringify(appPackage, null, 2) ); - var readmeExists = fs.existsSync(path.join(appPath, 'README.md')); + const readmeExists = fs.existsSync(path.join(appPath, 'README.md')); if (readmeExists) { - fs.renameSync(path.join(appPath, 'README.md'), path.join(appPath, 'README.old.md')); + fs.renameSync( + path.join(appPath, 'README.md'), + path.join(appPath, 'README.old.md') + ); } // Copy the files for the user - var templatePath = template ? path.resolve(originalDirectory, template) : path.join(ownPath, 'template'); + const templatePath = template + ? path.resolve(originalDirectory, template) + : path.join(ownPath, 'template'); if (fs.existsSync(templatePath)) { fs.copySync(templatePath, appPath); } else { - console.error('Could not locate supplied template: ' + chalk.green(templatePath)); + console.error( + `Could not locate supplied template: ${chalk.green(templatePath)}` + ); return; } // Rename gitignore after the fact to prevent npm from renaming it to .npmignore // See: https://github.com/npm/npm/issues/1862 - fs.move(path.join(appPath, 'gitignore'), path.join(appPath, '.gitignore'), [], function (err) { - if (err) { - // Append if there's already a `.gitignore` file there - if (err.code === 'EEXIST') { - var data = fs.readFileSync(path.join(appPath, 'gitignore')); - fs.appendFileSync(path.join(appPath, '.gitignore'), data); - fs.unlinkSync(path.join(appPath, 'gitignore')); - } else { - throw err; + fs.move( + path.join(appPath, 'gitignore'), + path.join(appPath, '.gitignore'), + [], + err => { + if (err) { + // Append if there's already a `.gitignore` file there + if (err.code === 'EEXIST') { + const data = fs.readFileSync(path.join(appPath, 'gitignore')); + fs.appendFileSync(path.join(appPath, '.gitignore'), data); + fs.unlinkSync(path.join(appPath, 'gitignore')); + } else { + throw err; + } } } - }); + ); - var command; - var args; + let command; + let args; if (useYarn) { command = 'yarnpkg'; args = ['add']; } else { command = 'npm'; - args = [ - 'install', - '--save', - verbose && '--verbose' - ].filter(function(e) { return e; }); + args = ['install', '--save', verbose && '--verbose'].filter(e => e); } args.push('react', 'react-dom'); // Install additional template dependencies, if present - var templateDependenciesPath = path.join(appPath, '.template.dependencies.json'); + const templateDependenciesPath = path.join( + appPath, + '.template.dependencies.json' + ); if (fs.existsSync(templateDependenciesPath)) { - var templateDependencies = require(templateDependenciesPath).dependencies; - args = args.concat(Object.keys(templateDependencies).map(function (key) { - return key + '@' + templateDependencies[key]; - })); + const templateDependencies = require(templateDependenciesPath).dependencies; + args = args.concat( + Object.keys(templateDependencies).map(key => { + return `${key}@${templateDependencies[key]}`; + }) + ); fs.unlinkSync(templateDependenciesPath); } @@ -97,12 +119,12 @@ module.exports = function(appPath, appName, verbose, originalDirectory, template // which doesn't install react and react-dom along with react-scripts // or template is presetend (via --internal-testing-template) if (!isReactInstalled(appPackage) || template) { - console.log('Installing react and react-dom using ' + command + '...'); + console.log(`Installing react and react-dom using ${command}...`); console.log(); - var proc = spawn.sync(command, args, {stdio: 'inherit'}); + const proc = spawn.sync(command, args, { stdio: 'inherit' }); if (proc.status !== 0) { - console.error('`' + command + ' ' + args.join(' ') + '` failed'); + console.error(`\`${command} ${args.join(' ')}\` failed`); return; } } @@ -110,51 +132,56 @@ module.exports = function(appPath, appName, verbose, originalDirectory, template // Display the most elegant way to cd. // This needs to handle an undefined originalDirectory for // backward compatibility with old global-cli's. - var cdpath; - if (originalDirectory && - path.join(originalDirectory, appName) === appPath) { + let cdpath; + if (originalDirectory && path.join(originalDirectory, appName) === appPath) { cdpath = appName; } else { cdpath = appPath; } // Change displayed command to yarn instead of yarnpkg - var displayedCommand = useYarn ? 'yarn' : 'npm'; + const displayedCommand = useYarn ? 'yarn' : 'npm'; console.log(); - console.log('Success! Created ' + appName + ' at ' + appPath); + console.log(`Success! Created ${appName} at ${appPath}`); console.log('Inside that directory, you can run several commands:'); console.log(); - console.log(chalk.cyan(' ' + displayedCommand + ' start')); + console.log(chalk.cyan(` ${displayedCommand} start`)); console.log(' Starts the development server.'); console.log(); - console.log(chalk.cyan(' ' + displayedCommand + ' run build')); + console.log(chalk.cyan(` ${displayedCommand} run build`)); console.log(' Bundles the app into static files for production.'); console.log(); - console.log(chalk.cyan(' ' + displayedCommand + ' test')); + console.log(chalk.cyan(` ${displayedCommand} test`)); console.log(' Starts the test runner.'); console.log(); - console.log(chalk.cyan(' ' + displayedCommand + ' run eject')); - console.log(' Removes this tool and copies build dependencies, configuration files'); - console.log(' and scripts into the app directory. If you do this, you can’t go back!'); + console.log(chalk.cyan(` ${displayedCommand} run eject`)); + console.log( + ' Removes this tool and copies build dependencies, configuration files' + ); + console.log( + ' and scripts into the app directory. If you do this, you can’t go back!' + ); console.log(); console.log('We suggest that you begin by typing:'); console.log(); console.log(chalk.cyan(' cd'), cdpath); - console.log(' ' + chalk.cyan(displayedCommand + ' start')); + console.log(` ${chalk.cyan(`${displayedCommand} start`)}`); if (readmeExists) { console.log(); - console.log(chalk.yellow('You had a `README.md` file, we renamed it to `README.old.md`')); + console.log( + chalk.yellow( + 'You had a `README.md` file, we renamed it to `README.old.md`' + ) + ); } console.log(); console.log('Happy hacking!'); }; function isReactInstalled(appPackage) { - var dependencies = appPackage.dependencies || {}; + const dependencies = appPackage.dependencies || {}; - return ( - typeof dependencies.react !== 'undefined' && - typeof dependencies['react-dom'] !== 'undefined' - ) + return typeof dependencies.react !== 'undefined' && + typeof dependencies['react-dom'] !== 'undefined'; } diff --git a/packages/react-scripts/scripts/start.js b/packages/react-scripts/scripts/start.js index 349871be747..142a1f6d705 100644 --- a/packages/react-scripts/scripts/start.js +++ b/packages/react-scripts/scripts/start.js @@ -8,7 +8,6 @@ * of patent rights can be found in the PATENTS file in the same directory. */ // @remove-on-eject-end - 'use strict'; process.env.NODE_ENV = 'development'; @@ -17,26 +16,26 @@ process.env.NODE_ENV = 'development'; // if this file is missing. dotenv will never modify any environment variables // that have already been set. // https://github.com/motdotla/dotenv -require('dotenv').config({silent: true}); - -var fs = require('fs'); -var chalk = require('chalk'); -var detect = require('detect-port'); -var WebpackDevServer = require('webpack-dev-server'); -var clearConsole = require('react-dev-utils/clearConsole'); -var checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); -var getProcessForPort = require('react-dev-utils/getProcessForPort'); -var openBrowser = require('react-dev-utils/openBrowser'); -var prompt = require('react-dev-utils/prompt'); -var paths = require('../config/paths'); -var config = require('../config/webpack.config.dev'); -var devServerConfig = require('../config/webpackDevServer.config'); -var createWebpackCompiler = require('./utils/createWebpackCompiler'); -var addWebpackMiddleware = require('./utils/addWebpackMiddleware'); - -var useYarn = fs.existsSync(paths.yarnLockFile); -var cli = useYarn ? 'yarn' : 'npm'; -var isInteractive = process.stdout.isTTY; +require('dotenv').config({ silent: true }); + +const fs = require('fs'); +const chalk = require('chalk'); +const detect = require('detect-port'); +const WebpackDevServer = require('webpack-dev-server'); +const clearConsole = require('react-dev-utils/clearConsole'); +const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); +const getProcessForPort = require('react-dev-utils/getProcessForPort'); +const openBrowser = require('react-dev-utils/openBrowser'); +const prompt = require('react-dev-utils/prompt'); +const paths = require('../config/paths'); +const config = require('../config/webpack.config.dev'); +const devServerConfig = require('../config/webpackDevServer.config'); +const createWebpackCompiler = require('./utils/createWebpackCompiler'); +const addWebpackMiddleware = require('./utils/addWebpackMiddleware'); + +const useYarn = fs.existsSync(paths.yarnLockFile); +const cli = useYarn ? 'yarn' : 'npm'; +const isInteractive = process.stdout.isTTY; // Warn and crash if required files are missing if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { @@ -44,29 +43,34 @@ if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { } // Tools like Cloud9 rely on this. -var DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; +const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; function run(port) { - var protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; - var host = process.env.HOST || 'localhost'; + const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; + const host = process.env.HOST || 'localhost'; // Create a webpack compiler that is configured with custom messages. - var compiler = createWebpackCompiler(config, function onReady(showInstructions) { - if (!showInstructions) { - return; + const compiler = createWebpackCompiler( + config, + function onReady(showInstructions) { + if (!showInstructions) { + return; + } + console.log(); + console.log('The app is running at:'); + console.log(); + console.log(` ${chalk.cyan(`${protocol}://${host}:${port}/`)}`); + console.log(); + console.log('Note that the development build is not optimized.'); + console.log( + `To create a production build, use ${chalk.cyan(`${cli} run build`)}.` + ); + console.log(); } - console.log(); - console.log('The app is running at:'); - console.log(); - console.log(' ' + chalk.cyan(protocol + '://' + host + ':' + port + '/')); - console.log(); - console.log('Note that the development build is not optimized.'); - console.log('To create a production build, use ' + chalk.cyan(cli + ' run build') + '.'); - console.log(); - }); + ); // Serve webpack assets generated by the compiler over a web sever. - var devServer = new WebpackDevServer(compiler, devServerConfig); + const devServer = new WebpackDevServer(compiler, devServerConfig); // Our custom middleware proxies requests to /index.html or a remote API. addWebpackMiddleware(devServer); @@ -83,7 +87,7 @@ function run(port) { console.log(chalk.cyan('Starting the development server...')); console.log(); - openBrowser(protocol + '://' + host + ':' + port + '/'); + openBrowser(`${protocol}://${host}:${port}/`); }); } @@ -97,11 +101,11 @@ detect(DEFAULT_PORT).then(port => { if (isInteractive) { clearConsole(); - var existingProcess = getProcessForPort(DEFAULT_PORT); - var question = - chalk.yellow('Something is already running on port ' + DEFAULT_PORT + '.' + - ((existingProcess) ? ' Probably:\n ' + existingProcess : '')) + - '\n\nWould you like to run the app on another port instead?'; + const existingProcess = getProcessForPort(DEFAULT_PORT); + const question = chalk.yellow( + `Something is already running on port ${DEFAULT_PORT}.` + + `${existingProcess ? ` Probably:\n ${existingProcess}` : ''}` + ) + '\n\nWould you like to run the app on another port instead?'; prompt(question, true).then(shouldChangePort => { if (shouldChangePort) { @@ -109,6 +113,8 @@ detect(DEFAULT_PORT).then(port => { } }); } else { - console.log(chalk.red('Something is already running on port ' + DEFAULT_PORT + '.')); + console.log( + chalk.red(`Something is already running on port ${DEFAULT_PORT}.`) + ); } }); diff --git a/packages/react-scripts/scripts/test.js b/packages/react-scripts/scripts/test.js index de3a9691897..e3a0094f982 100644 --- a/packages/react-scripts/scripts/test.js +++ b/packages/react-scripts/scripts/test.js @@ -8,7 +8,6 @@ * of patent rights can be found in the PATENTS file in the same directory. */ // @remove-on-eject-end - 'use strict'; process.env.NODE_ENV = 'test'; @@ -18,7 +17,7 @@ process.env.PUBLIC_URL = ''; // if this file is missing. dotenv will never modify any environment variables // that have already been set. // https://github.com/motdotla/dotenv -require('dotenv').config({silent: true}); +require('dotenv').config({ silent: true }); const jest = require('jest'); const argv = process.argv.slice(2); @@ -33,10 +32,15 @@ if (!process.env.CI && argv.indexOf('--coverage') < 0) { const createJestConfig = require('./utils/createJestConfig'); const path = require('path'); const paths = require('../config/paths'); -argv.push('--config', JSON.stringify(createJestConfig( - relativePath => path.resolve(__dirname, '..', relativePath), - path.resolve(paths.appSrc, '..'), - false -))); +argv.push( + '--config', + JSON.stringify( + createJestConfig( + relativePath => path.resolve(__dirname, '..', relativePath), + path.resolve(paths.appSrc, '..'), + false + ) + ) +); // @remove-on-eject-end jest.run(argv); diff --git a/packages/react-scripts/scripts/utils/addWebpackMiddleware.js b/packages/react-scripts/scripts/utils/addWebpackMiddleware.js index b3ff2548458..d2a97507237 100644 --- a/packages/react-scripts/scripts/utils/addWebpackMiddleware.js +++ b/packages/react-scripts/scripts/utils/addWebpackMiddleware.js @@ -10,61 +10,84 @@ // @remove-on-eject-end 'use strict'; -var chalk = require('chalk'); -var historyApiFallback = require('connect-history-api-fallback'); -var httpProxyMiddleware = require('http-proxy-middleware'); -var paths = require('../../config/paths'); +const chalk = require('chalk'); +const historyApiFallback = require('connect-history-api-fallback'); +const httpProxyMiddleware = require('http-proxy-middleware'); +const paths = require('../../config/paths'); // We need to provide a custom onError function for httpProxyMiddleware. // It allows us to log custom error messages on the console. function onProxyError(proxy) { - return function(err, req, res){ - var host = req.headers && req.headers.host; + return (err, req, res) => { + const host = req.headers && req.headers.host; console.log( - chalk.red('Proxy error:') + ' Could not proxy request ' + chalk.cyan(req.url) + - ' from ' + chalk.cyan(host) + ' to ' + chalk.cyan(proxy) + '.' + chalk.red('Proxy error:') + + ' Could not proxy request ' + + chalk.cyan(req.url) + + ' from ' + + chalk.cyan(host) + + ' to ' + + chalk.cyan(proxy) + + '.' ); console.log( 'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' + - chalk.cyan(err.code) + ').' + chalk.cyan(err.code) + + ').' ); console.log(); // And immediately send the proper error response to the client. // Otherwise, the request will eventually timeout with ERR_EMPTY_RESPONSE on the client side. if (res.writeHead && !res.headersSent) { - res.writeHead(500); + res.writeHead(500); } - res.end('Proxy error: Could not proxy request ' + req.url + ' from ' + - host + ' to ' + proxy + ' (' + err.code + ').' + res.end( + 'Proxy error: Could not proxy request ' + + req.url + + ' from ' + + host + + ' to ' + + proxy + + ' (' + + err.code + + ').' ); - } + }; } module.exports = function addWebpackMiddleware(devServer) { // `proxy` lets you to specify a fallback server during development. // Every unrecognized request will be forwarded to it. - var proxy = require(paths.appPackageJson).proxy; - devServer.use(historyApiFallback({ - // Paths with dots should still use the history fallback. - // See https://github.com/facebookincubator/create-react-app/issues/387. - disableDotRule: true, - // For single page apps, we generally want to fallback to /index.html. - // However we also want to respect `proxy` for API calls. - // So if `proxy` is specified, we need to decide which fallback to use. - // We use a heuristic: if request `accept`s text/html, we pick /index.html. - // Modern browsers include text/html into `accept` header when navigating. - // However API calls like `fetch()` won’t generally accept text/html. - // If this heuristic doesn’t work well for you, don’t use `proxy`. - htmlAcceptHeaders: proxy ? - ['text/html'] : - ['text/html', '*/*'] - })); + const proxy = require(paths.appPackageJson).proxy; + devServer.use( + historyApiFallback({ + // Paths with dots should still use the history fallback. + // See https://github.com/facebookincubator/create-react-app/issues/387. + disableDotRule: true, + // For single page apps, we generally want to fallback to /index.html. + // However we also want to respect `proxy` for API calls. + // So if `proxy` is specified, we need to decide which fallback to use. + // We use a heuristic: if request `accept`s text/html, we pick /index.html. + // Modern browsers include text/html into `accept` header when navigating. + // However API calls like `fetch()` won’t generally accept text/html. + // If this heuristic doesn’t work well for you, don’t use `proxy`. + htmlAcceptHeaders: proxy ? ['text/html'] : ['text/html', '*/*'], + }) + ); if (proxy) { if (typeof proxy !== 'string') { - console.log(chalk.red('When specified, "proxy" in package.json must be a string.')); - console.log(chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".')); - console.log(chalk.red('Either remove "proxy" from package.json, or make it a string.')); + console.log( + chalk.red('When specified, "proxy" in package.json must be a string.') + ); + console.log( + chalk.red('Instead, the type of "proxy" was "' + typeof proxy + '".') + ); + console.log( + chalk.red( + 'Either remove "proxy" from package.json, or make it a string.' + ) + ); process.exit(1); } @@ -74,14 +97,14 @@ module.exports = function addWebpackMiddleware(devServer) { // - /*.hot-update.json (WebpackDevServer uses this too for hot reloading) // - /sockjs-node/* (WebpackDevServer uses this for hot reloading) // Tip: use https://jex.im/regulex/ to visualize the regex - var mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/; + const mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/; // Pass the scope regex both to Express and to the middleware for proxying // of both HTTP and WebSockets to work without false positives. - var hpm = httpProxyMiddleware(pathname => mayProxy.test(pathname), { + const hpm = httpProxyMiddleware(pathname => mayProxy.test(pathname), { target: proxy, logLevel: 'silent', - onProxyReq: function(proxyReq) { + onProxyReq: proxyReq => { // Browers may send Origin headers even with same-origin // requests. To prevent CORS issues, we have to change // the Origin to match the target URL. @@ -93,7 +116,7 @@ module.exports = function addWebpackMiddleware(devServer) { secure: false, changeOrigin: true, ws: true, - xfwd: true + xfwd: true, }); devServer.use(mayProxy, hpm); diff --git a/packages/react-scripts/scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js index 0174237a0f8..5ba7fd16cb2 100644 --- a/packages/react-scripts/scripts/utils/createJestConfig.js +++ b/packages/react-scripts/scripts/utils/createJestConfig.js @@ -7,7 +7,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ - 'use strict'; const fs = require('fs'); @@ -16,7 +15,9 @@ const paths = require('../../config/paths'); module.exports = (resolve, rootDir, isEjecting) => { // Use this instead of `paths.testsSetup` to avoid putting // an absolute filename into configuration after ejecting. - const setupTestsFile = fs.existsSync(paths.testsSetup) ? '/src/setupTests.js' : undefined; + const setupTestsFile = fs.existsSync(paths.testsSetup) + ? '/src/setupTests.js' + : undefined; // TODO: I don't know if it's safe or not to just use / as path separator // in Jest configs. We need help from somebody with Windows to determine this. @@ -25,23 +26,21 @@ module.exports = (resolve, rootDir, isEjecting) => { setupFiles: [resolve('config/polyfills.js')], setupTestFrameworkScriptFile: setupTestsFile, testPathIgnorePatterns: [ - '[/\\\\](build|docs|node_modules|scripts)[/\\\\]' + '[/\\\\](build|docs|node_modules|scripts)[/\\\\]', ], testEnvironment: 'node', testURL: 'http://localhost', transform: { - '^.+\\.(js|jsx)$': isEjecting ? - '/node_modules/babel-jest' + '^.+\\.(js|jsx)$': isEjecting + ? '/node_modules/babel-jest' : resolve('config/jest/babelTransform.js'), '^.+\\.css$': resolve('config/jest/cssTransform.js'), '^(?!.*\\.(js|jsx|css|json)$)': resolve('config/jest/fileTransform.js'), }, - transformIgnorePatterns: [ - '[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$' - ], + transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$'], moduleNameMapper: { - '^react-native$': 'react-native-web' - } + '^react-native$': 'react-native-web', + }, }; if (rootDir) { config.rootDir = rootDir; diff --git a/packages/react-scripts/scripts/utils/createWebpackCompiler.js b/packages/react-scripts/scripts/utils/createWebpackCompiler.js index 246f4b63cbe..a333165b082 100644 --- a/packages/react-scripts/scripts/utils/createWebpackCompiler.js +++ b/packages/react-scripts/scripts/utils/createWebpackCompiler.js @@ -10,19 +10,19 @@ // @remove-on-eject-end 'use strict'; -var chalk = require('chalk'); -var webpack = require('webpack'); -var clearConsole = require('react-dev-utils/clearConsole'); -var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); +const chalk = require('chalk'); +const webpack = require('webpack'); +const clearConsole = require('react-dev-utils/clearConsole'); +const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); -var isInteractive = process.stdout.isTTY; -var handleCompile; +const isInteractive = process.stdout.isTTY; +let handleCompile; // You can safely remove this after ejecting. // We only use this block for testing of Create React App itself: -var isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1); +const isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1); if (isSmokeTest) { - handleCompile = function (err, stats) { + handleCompile = (err, stats) => { if (err || stats.hasErrors() || stats.hasWarnings()) { process.exit(1); } else { @@ -34,8 +34,9 @@ if (isSmokeTest) { module.exports = function createWebpackCompiler(config, onReadyCallback) { // "Compiler" is a low-level interface to Webpack. // It lets us listen to some events and provide our own custom messages. + let compiler; try { - var compiler = webpack(config, handleCompile); + compiler = webpack(config, handleCompile); } catch (err) { console.log(chalk.red('Failed to compile.')); console.log(); @@ -48,18 +49,18 @@ module.exports = function createWebpackCompiler(config, onReadyCallback) { // recompiling a bundle. WebpackDevServer takes care to pause serving the // bundle, so if you refresh, it'll wait instead of serving the old one. // "invalid" is short for "bundle invalidated", it doesn't imply any errors. - compiler.plugin('invalid', function() { + compiler.plugin('invalid', () => { if (isInteractive) { clearConsole(); } console.log('Compiling...'); }); - var isFirstCompile = true; + let isFirstCompile = true; // "done" event fires when Webpack has finished recompiling the bundle. // Whether or not you have warnings or errors, you will get this event. - compiler.plugin('done', function(stats) { + compiler.plugin('done', stats => { if (isInteractive) { clearConsole(); } @@ -67,9 +68,9 @@ module.exports = function createWebpackCompiler(config, onReadyCallback) { // We have switched off the default Webpack output in WebpackDevServer // options so we are going to "massage" the warnings and errors and present // them in a readable focused way. - var messages = formatWebpackMessages(stats.toJson({}, true)); - var isSuccessful = !messages.errors.length && !messages.warnings.length; - var showInstructions = isSuccessful && (isInteractive || isFirstCompile); + const messages = formatWebpackMessages(stats.toJson({}, true)); + const isSuccessful = !messages.errors.length && !messages.warnings.length; + const showInstructions = isSuccessful && (isInteractive || isFirstCompile); if (isSuccessful) { console.log(chalk.green('Compiled successfully!')); @@ -101,8 +102,16 @@ module.exports = function createWebpackCompiler(config, onReadyCallback) { }); // Teach some ESLint tricks. console.log('You may use special comments to disable some warnings.'); - console.log('Use ' + chalk.yellow('// eslint-disable-next-line') + ' to ignore the next line.'); - console.log('Use ' + chalk.yellow('/* eslint-disable */') + ' to ignore all warnings in a file.'); + console.log( + 'Use ' + + chalk.yellow('// eslint-disable-next-line') + + ' to ignore the next line.' + ); + console.log( + 'Use ' + + chalk.yellow('/* eslint-disable */') + + ' to ignore all warnings in a file.' + ); } }); diff --git a/packages/react-scripts/template/src/index.js b/packages/react-scripts/template/src/index.js index 54c5ef1a427..5d76a18a853 100644 --- a/packages/react-scripts/template/src/index.js +++ b/packages/react-scripts/template/src/index.js @@ -3,7 +3,4 @@ import ReactDOM from 'react-dom'; import App from './App'; import './index.css'; -ReactDOM.render( - , - document.getElementById('root') -); +ReactDOM.render(, document.getElementById('root'));