diff --git a/bin/react-scripts.js b/bin/react-scripts.js index 94a799fd89d..8a1175c99ea 100755 --- a/bin/react-scripts.js +++ b/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/config/env.js b/config/env.js index 5f49ffaa17a..c018467a95b 100644 --- a/config/env.js +++ b/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/config/jest/babelTransform.js b/config/jest/babelTransform.js index 838d0ca9175..bee55b1b156 100644 --- a/config/jest/babelTransform.js +++ b/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/config/jest/fileTransform.js b/config/jest/fileTransform.js index 060ee259de2..89027bdc702 100644 --- a/config/jest/fileTransform.js +++ b/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/config/paths.js b/config/paths.js index 83f234d6c62..76397756040 100644 --- a/config/paths.js +++ b/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/config/webpack.config.dev.js b/config/webpack.config.dev.js index 214373b81b8..c7948b66f6e 100644 --- a/config/webpack.config.dev.js +++ b/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/config/webpack.config.prod.js b/config/webpack.config.prod.js index 5a2388d29c3..979ed4e4d6d 100644 --- a/config/webpack.config.prod.js +++ b/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/config/webpackDevServer.config.js b/config/webpackDevServer.config.js index 89fd48bc524..37d9d1a750e 100644 --- a/config/webpackDevServer.config.js +++ b/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/fixtures/kitchensink/integration/env.test.js b/fixtures/kitchensink/integration/env.test.js index c3169c987a9..b90d12ab12e 100644 --- a/fixtures/kitchensink/integration/env.test.js +++ b/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/fixtures/kitchensink/integration/initDOM.js b/fixtures/kitchensink/integration/initDOM.js index 3cfb182148a..4d6f531ea84 100644 --- a/fixtures/kitchensink/integration/initDOM.js +++ b/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/fixtures/kitchensink/integration/syntax.test.js b/fixtures/kitchensink/integration/syntax.test.js index 8fe1990f20a..fc2a717befe 100644 --- a/fixtures/kitchensink/integration/syntax.test.js +++ b/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/fixtures/kitchensink/integration/webpack.test.js b/fixtures/kitchensink/integration/webpack.test.js index 43b3f1209f7..031786e0ee7 100644 --- a/fixtures/kitchensink/integration/webpack.test.js +++ b/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/fixtures/kitchensink/src/App.js b/fixtures/kitchensink/src/App.js index ac55f7767e6..67de182b59e 100644 --- a/fixtures/kitchensink/src/App.js +++ b/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/fixtures/kitchensink/src/absoluteLoad.js b/fixtures/kitchensink/src/absoluteLoad.js index a1fe21e48ff..0d01bc0a227 100644 --- a/fixtures/kitchensink/src/absoluteLoad.js +++ b/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/fixtures/kitchensink/src/features/env/FileEnvVariables.js b/fixtures/kitchensink/src/features/env/FileEnvVariables.js index ff874b62812..a8a1e98fe71 100644 --- a/fixtures/kitchensink/src/features/env/FileEnvVariables.js +++ b/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/fixtures/kitchensink/src/features/env/NodePath.js b/fixtures/kitchensink/src/features/env/NodePath.js index e4b868e47b6..eb1a45c0f12 100644 --- a/fixtures/kitchensink/src/features/env/NodePath.js +++ b/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/fixtures/kitchensink/src/features/env/PublicUrl.js b/fixtures/kitchensink/src/features/env/PublicUrl.js index 4c61be73956..4ea9b96f8b2 100644 --- a/fixtures/kitchensink/src/features/env/PublicUrl.js +++ b/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/fixtures/kitchensink/src/features/env/ShellEnvVariables.js b/fixtures/kitchensink/src/features/env/ShellEnvVariables.js index 243bfc00935..8449097d69a 100644 --- a/fixtures/kitchensink/src/features/env/ShellEnvVariables.js +++ b/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/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js b/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js index 48516d43fd3..3d18a5edeac 100644 --- a/fixtures/kitchensink/src/features/syntax/ArrayDestructuring.js +++ b/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/fixtures/kitchensink/src/features/syntax/ArraySpread.js b/fixtures/kitchensink/src/features/syntax/ArraySpread.js index 9998589a138..4f9b174eb6f 100644 --- a/fixtures/kitchensink/src/features/syntax/ArraySpread.js +++ b/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/fixtures/kitchensink/src/features/syntax/AsyncAwait.js b/fixtures/kitchensink/src/features/syntax/AsyncAwait.js index b5b6013f93c..6924d4f92d8 100644 --- a/fixtures/kitchensink/src/features/syntax/AsyncAwait.js +++ b/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/fixtures/kitchensink/src/features/syntax/ClassProperties.js b/fixtures/kitchensink/src/features/syntax/ClassProperties.js index 63bd7ab0512..7be21952da5 100644 --- a/fixtures/kitchensink/src/features/syntax/ClassProperties.js +++ b/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/fixtures/kitchensink/src/features/syntax/ComputedProperties.js b/fixtures/kitchensink/src/features/syntax/ComputedProperties.js index e345283eaaa..fc64c2a86e3 100644 --- a/fixtures/kitchensink/src/features/syntax/ComputedProperties.js +++ b/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/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js b/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js index 399280d0190..e97902545e1 100644 --- a/fixtures/kitchensink/src/features/syntax/CustomInterpolation.js +++ b/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/fixtures/kitchensink/src/features/syntax/DefaultParameters.js b/fixtures/kitchensink/src/features/syntax/DefaultParameters.js index fd4054e56cb..74bbe4d3c17 100644 --- a/fixtures/kitchensink/src/features/syntax/DefaultParameters.js +++ b/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/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js b/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js index c2345f5ce54..ede416944fc 100644 --- a/fixtures/kitchensink/src/features/syntax/DestructuringAndAwait.js +++ b/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/fixtures/kitchensink/src/features/syntax/Generators.js b/fixtures/kitchensink/src/features/syntax/Generators.js index 170f00a7f0d..77b7bffd252 100644 --- a/fixtures/kitchensink/src/features/syntax/Generators.js +++ b/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/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js b/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js index 025920b7f31..14fa6969ee5 100644 --- a/fixtures/kitchensink/src/features/syntax/ObjectDestructuring.js +++ b/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/fixtures/kitchensink/src/features/syntax/ObjectSpread.js b/fixtures/kitchensink/src/features/syntax/ObjectSpread.js index d5de0aef31a..bf3fb26b80c 100644 --- a/fixtures/kitchensink/src/features/syntax/ObjectSpread.js +++ b/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/fixtures/kitchensink/src/features/syntax/Promises.js b/fixtures/kitchensink/src/features/syntax/Promises.js index 8b362fccf2c..26438012cf2 100644 --- a/fixtures/kitchensink/src/features/syntax/Promises.js +++ b/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/fixtures/kitchensink/src/features/syntax/RestAndDefault.js b/fixtures/kitchensink/src/features/syntax/RestAndDefault.js index 47d011f2eae..411ce33d4b9 100644 --- a/fixtures/kitchensink/src/features/syntax/RestAndDefault.js +++ b/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/fixtures/kitchensink/src/features/syntax/RestParameters.js b/fixtures/kitchensink/src/features/syntax/RestParameters.js index 1a6cf7c1687..aaca55c0f96 100644 --- a/fixtures/kitchensink/src/features/syntax/RestParameters.js +++ b/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/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js b/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js index ff46e1c72f8..738a0b103ef 100644 --- a/fixtures/kitchensink/src/features/syntax/TemplateInterpolation.js +++ b/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/fixtures/kitchensink/src/features/webpack/CssInclusion.js b/fixtures/kitchensink/src/features/webpack/CssInclusion.js index 7c46c7208b7..ab7c9a2d86e 100644 --- a/fixtures/kitchensink/src/features/webpack/CssInclusion.js +++ b/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/fixtures/kitchensink/src/features/webpack/ImageInclusion.js b/fixtures/kitchensink/src/features/webpack/ImageInclusion.js index c4560ff9dae..a6ca7aaa818 100644 --- a/fixtures/kitchensink/src/features/webpack/ImageInclusion.js +++ b/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/fixtures/kitchensink/src/features/webpack/JsonInclusion.js b/fixtures/kitchensink/src/features/webpack/JsonInclusion.js index 552a8be7b1a..e81f7639736 100644 --- a/fixtures/kitchensink/src/features/webpack/JsonInclusion.js +++ b/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/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js b/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js index b3bdbe9fcbc..7f824c2f292 100644 --- a/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js +++ b/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/fixtures/kitchensink/src/features/webpack/SvgInclusion.js b/fixtures/kitchensink/src/features/webpack/SvgInclusion.js index f82e5f2911c..8876021aed6 100644 --- a/fixtures/kitchensink/src/features/webpack/SvgInclusion.js +++ b/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/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js b/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js index a9ac8f00cf1..70b046e9532 100644 --- a/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js +++ b/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/fixtures/kitchensink/src/index.js b/fixtures/kitchensink/src/index.js index dc1143691f2..46fb0dd2e55 100644 --- a/fixtures/kitchensink/src/index.js +++ b/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/fixtures/kitchensink/src/subfolder/lol.js b/fixtures/kitchensink/src/subfolder/lol.js index c844f831d31..979cb3e7206 100644 --- a/fixtures/kitchensink/src/subfolder/lol.js +++ b/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/scripts/build.js b/scripts/build.js index 05cefa0393e..548ff3cc68e 100644 --- a/scripts/build.js +++ b/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/scripts/eject.js b/scripts/eject.js index 39a40546bde..68c43d25068 100644 --- a/scripts/eject.js +++ b/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/scripts/init.js b/scripts/init.js index 352bf0f41c5..b8a820c821d 100644 --- a/scripts/init.js +++ b/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/scripts/start.js b/scripts/start.js index 349871be747..142a1f6d705 100644 --- a/scripts/start.js +++ b/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/scripts/test.js b/scripts/test.js index de3a9691897..e3a0094f982 100644 --- a/scripts/test.js +++ b/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/scripts/utils/addWebpackMiddleware.js b/scripts/utils/addWebpackMiddleware.js index b3ff2548458..d2a97507237 100644 --- a/scripts/utils/addWebpackMiddleware.js +++ b/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/scripts/utils/createJestConfig.js b/scripts/utils/createJestConfig.js index 0174237a0f8..5ba7fd16cb2 100644 --- a/scripts/utils/createJestConfig.js +++ b/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/scripts/utils/createWebpackCompiler.js b/scripts/utils/createWebpackCompiler.js index 246f4b63cbe..a333165b082 100644 --- a/scripts/utils/createWebpackCompiler.js +++ b/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/template/src/index.js b/template/src/index.js index 54c5ef1a427..5d76a18a853 100644 --- a/template/src/index.js +++ b/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'));