temp fix cra bug with public_url in development mode

This commit is contained in:
pavelbannov 2019-07-15 12:33:28 +03:00
parent b73d0829c6
commit ff1d098eac
9 changed files with 1728 additions and 2 deletions

View File

@ -14,6 +14,8 @@ call npm ci --prefix web/ASC.Web.Client
echo "ASC.Web.People.Client"
call npm ci --prefix products/ASC.People/Client
xcopy build\cra\*.* products\ASC.People\Client\node_modules\ /E /R /Y
echo "ASC.Web.sln"
call dotnet build ASC.Web.sln /fl1 /flp1:LogFile=build/ASC.Web.log;Verbosity=Normal

View File

@ -0,0 +1,476 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
const address = require('address');
const fs = require('fs');
const path = require('path');
const url = require('url');
const chalk = require('chalk');
const detect = require('detect-port-alt');
const isRoot = require('is-root');
const inquirer = require('inquirer');
const clearConsole = require('./clearConsole');
const formatWebpackMessages = require('./formatWebpackMessages');
const getProcessForPort = require('./getProcessForPort');
const typescriptFormatter = require('./typescriptFormatter');
const forkTsCheckerWebpackPlugin = require('./ForkTsCheckerWebpackPlugin');
const isInteractive = process.stdout.isTTY;
function prepareUrls(protocol, host, port, pathname = '/') {
const formatUrl = hostname =>
url.format({
protocol,
hostname,
port,
pathname,
});
const prettyPrintUrl = hostname =>
url.format({
protocol,
hostname,
port: chalk.bold(port),
pathname,
});
const isUnspecifiedHost = host === '0.0.0.0' || host === '::';
let prettyHost, lanUrlForConfig, lanUrlForTerminal;
if (isUnspecifiedHost) {
prettyHost = 'localhost';
try {
// This can only return an IPv4 address
lanUrlForConfig = address.ip();
if (lanUrlForConfig) {
// Check if the address is a private ip
// https://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces
if (
/^10[.]|^172[.](1[6-9]|2[0-9]|3[0-1])[.]|^192[.]168[.]/.test(
lanUrlForConfig
)
) {
// Address is private, format it for later use
lanUrlForTerminal = prettyPrintUrl(lanUrlForConfig);
} else {
// Address is not private, so we will discard it
lanUrlForConfig = undefined;
}
}
} catch (_e) {
// ignored
}
} else {
prettyHost = host;
}
const localUrlForTerminal = prettyPrintUrl(prettyHost);
const localUrlForBrowser = formatUrl(prettyHost);
return {
lanUrlForConfig,
lanUrlForTerminal,
localUrlForTerminal,
localUrlForBrowser,
};
}
function printInstructions(appName, urls, useYarn) {
console.log();
console.log(`You can now view ${chalk.bold(appName)} in the browser.`);
console.log();
if (urls.lanUrlForTerminal) {
console.log(
` ${chalk.bold('Local:')} ${urls.localUrlForTerminal}`
);
console.log(
` ${chalk.bold('On Your Network:')} ${urls.lanUrlForTerminal}`
);
} else {
console.log(` ${urls.localUrlForTerminal}`);
}
console.log();
console.log('Note that the development build is not optimized.');
console.log(
`To create a production build, use ` +
`${chalk.cyan(`${useYarn ? 'yarn' : 'npm run'} build`)}.`
);
console.log();
}
function createCompiler({
appName,
config,
devSocket,
urls,
useYarn,
useTypeScript,
webpack,
}) {
// "Compiler" is a low-level interface to Webpack.
// It lets us listen to some events and provide our own custom messages.
let compiler;
try {
compiler = webpack(config);
} catch (err) {
console.log(chalk.red('Failed to compile.'));
console.log();
console.log(err.message || err);
console.log();
process.exit(1);
}
// "invalid" event fires when you have changed a file, and Webpack is
// 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.hooks.invalid.tap('invalid', () => {
if (isInteractive) {
clearConsole();
}
console.log('Compiling...');
});
let isFirstCompile = true;
let tsMessagesPromise;
let tsMessagesResolver;
if (useTypeScript) {
compiler.hooks.beforeCompile.tap('beforeCompile', () => {
tsMessagesPromise = new Promise(resolve => {
tsMessagesResolver = msgs => resolve(msgs);
});
});
forkTsCheckerWebpackPlugin
.getCompilerHooks(compiler)
.receive.tap('afterTypeScriptCheck', (diagnostics, lints) => {
const allMsgs = [...diagnostics, ...lints];
const format = message =>
`${message.file}\n${typescriptFormatter(message, true)}`;
tsMessagesResolver({
errors: allMsgs.filter(msg => msg.severity === 'error').map(format),
warnings: allMsgs
.filter(msg => msg.severity === 'warning')
.map(format),
});
});
}
// "done" event fires when Webpack has finished recompiling the bundle.
// Whether or not you have warnings or errors, you will get this event.
compiler.hooks.done.tap('done', async stats => {
if (isInteractive) {
clearConsole();
}
// 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.
// We only construct the warnings and errors for speed:
// https://github.com/facebook/create-react-app/issues/4492#issuecomment-421959548
const statsData = stats.toJson({
all: false,
warnings: true,
errors: true,
});
if (useTypeScript && statsData.errors.length === 0) {
const delayedMsg = setTimeout(() => {
console.log(
chalk.yellow(
'Files successfully emitted, waiting for typecheck results...'
)
);
}, 100);
const messages = await tsMessagesPromise;
clearTimeout(delayedMsg);
statsData.errors.push(...messages.errors);
statsData.warnings.push(...messages.warnings);
// Push errors and warnings into compilation result
// to show them after page refresh triggered by user.
stats.compilation.errors.push(...messages.errors);
stats.compilation.warnings.push(...messages.warnings);
if (messages.errors.length > 0) {
devSocket.errors(messages.errors);
} else if (messages.warnings.length > 0) {
devSocket.warnings(messages.warnings);
}
if (isInteractive) {
clearConsole();
}
}
const messages = formatWebpackMessages(statsData);
const isSuccessful = !messages.errors.length && !messages.warnings.length;
if (isSuccessful) {
console.log(chalk.green('Compiled successfully!'));
}
if (isSuccessful && (isInteractive || isFirstCompile)) {
printInstructions(appName, urls, useYarn);
}
isFirstCompile = false;
// If errors exist, only show errors.
if (messages.errors.length) {
// Only keep the first error. Others are often indicative
// of the same problem, but confuse the reader with noise.
if (messages.errors.length > 1) {
messages.errors.length = 1;
}
console.log(chalk.red('Failed to compile.\n'));
console.log(messages.errors.join('\n\n'));
return;
}
// Show warnings if no errors were found.
if (messages.warnings.length) {
console.log(chalk.yellow('Compiled with warnings.\n'));
console.log(messages.warnings.join('\n\n'));
// Teach some ESLint tricks.
console.log(
'\nSearch for the ' +
chalk.underline(chalk.yellow('keywords')) +
' to learn more about each warning.'
);
console.log(
'To ignore, add ' +
chalk.cyan('// eslint-disable-next-line') +
' to the line before.\n'
);
}
});
// You can safely remove this after ejecting.
// We only use this block for testing of Create React App itself:
const isSmokeTest = process.argv.some(
arg => arg.indexOf('--smoke-test') > -1
);
if (isSmokeTest) {
compiler.hooks.failed.tap('smokeTest', async () => {
await tsMessagesPromise;
process.exit(1);
});
compiler.hooks.done.tap('smokeTest', async stats => {
await tsMessagesPromise;
if (stats.hasErrors() || stats.hasWarnings()) {
process.exit(1);
} else {
process.exit(0);
}
});
}
return compiler;
}
function resolveLoopback(proxy) {
const o = url.parse(proxy);
o.host = undefined;
if (o.hostname !== 'localhost') {
return proxy;
}
// Unfortunately, many languages (unlike node) do not yet support IPv6.
// This means even though localhost resolves to ::1, the application
// must fall back to IPv4 (on 127.0.0.1).
// We can re-enable this in a few years.
/*try {
o.hostname = address.ipv6() ? '::1' : '127.0.0.1';
} catch (_ignored) {
o.hostname = '127.0.0.1';
}*/
try {
// Check if we're on a network; if we are, chances are we can resolve
// localhost. Otherwise, we can just be safe and assume localhost is
// IPv4 for maximum compatibility.
if (!address.ip()) {
o.hostname = '127.0.0.1';
}
} catch (_ignored) {
o.hostname = '127.0.0.1';
}
return url.format(o);
}
// 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 (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) +
'.'
);
console.log(
'See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (' +
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.end(
'Proxy error: Could not proxy request ' +
req.url +
' from ' +
host +
' to ' +
proxy +
' (' +
err.code +
').'
);
};
}
function prepareProxy(proxy, appPublicFolder) {
// `proxy` lets you specify alternate servers for specific requests.
if (!proxy) {
return undefined;
}
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.')
);
process.exit(1);
}
// If proxy is specified, let it handle any request except for files in the public folder.
function mayProxy(pathname) {
const maybePublicPath = path.resolve(appPublicFolder, pathname.slice(1));
return !fs.existsSync(maybePublicPath);
}
if (!/^http(s)?:\/\//.test(proxy)) {
console.log(
chalk.red(
'When "proxy" is specified in package.json it must start with either http:// or https://'
)
);
process.exit(1);
}
let target;
if (process.platform === 'win32') {
target = resolveLoopback(proxy);
} else {
target = proxy;
}
return [
{
target,
logLevel: 'silent',
// 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 as a string, we need to decide which fallback to use.
// We use a heuristic: We want to proxy all the requests that are not meant
// for static assets and as all the requests for static assets will be using
// `GET` method, we can proxy all non-`GET` requests.
// For `GET` requests, 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()` wont generally accept text/html.
// If this heuristic doesnt work well for you, use `src/setupProxy.js`.
context: function(pathname, req) {
return (
req.method !== 'GET' ||
(mayProxy(pathname) &&
req.headers.accept &&
req.headers.accept.indexOf('text/html') === -1)
);
},
onProxyReq: proxyReq => {
// Browsers may send Origin headers even with same-origin
// requests. To prevent CORS issues, we have to change
// the Origin to match the target URL.
if (proxyReq.getHeader('origin')) {
proxyReq.setHeader('origin', target);
}
},
onError: onProxyError(target),
secure: false,
changeOrigin: true,
ws: true,
xfwd: true,
},
];
}
function choosePort(host, defaultPort) {
return detect(defaultPort, host).then(
port =>
new Promise(resolve => {
if (port === defaultPort) {
return resolve(port);
}
const message =
process.platform !== 'win32' && defaultPort < 1024 && !isRoot()
? `Admin permissions are required to run a server on a port below 1024.`
: `Something is already running on port ${defaultPort}.`;
if (isInteractive) {
clearConsole();
const existingProcess = getProcessForPort(defaultPort);
const question = {
type: 'confirm',
name: 'shouldChangePort',
message:
chalk.yellow(
message +
`${existingProcess ? ` Probably:\n ${existingProcess}` : ''}`
) + '\n\nWould you like to run the app on another port instead?',
default: true,
};
inquirer.prompt(question).then(answer => {
if (answer.shouldChangePort) {
resolve(port);
} else {
resolve(null);
}
});
} else {
console.log(chalk.red(message));
resolve(null);
}
}),
err => {
throw new Error(
chalk.red(`Could not find an open port at ${chalk.bold(host)}.`) +
'\n' +
('Network error message: ' + err.message || err) +
'\n'
);
}
);
}
module.exports = {
choosePort,
createCompiler,
prepareProxy,
prepareUrls,
};

View File

@ -0,0 +1,276 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
// This alternative WebpackDevServer combines the functionality of:
// https://github.com/webpack/webpack-dev-server/blob/webpack-1/client/index.js
// https://github.com/webpack/webpack/blob/webpack-1/hot/dev-server.js
// It only supports their simplest configuration (hot updates on same server).
// It makes some opinionated choices on top, like adding a syntax error overlay
// that looks similar to our console output. The error overlay is inspired by:
// https://github.com/glenjamin/webpack-hot-middleware
var SockJS = require('sockjs-client');
var stripAnsi = require('strip-ansi');
var url = require('url');
var launchEditorEndpoint = require('./launchEditorEndpoint');
var formatWebpackMessages = require('./formatWebpackMessages');
var ErrorOverlay = require('react-error-overlay');
ErrorOverlay.setEditorHandler(function editorHandler(errorLocation) {
// Keep this sync with errorOverlayMiddleware.js
fetch(
launchEditorEndpoint +
'?fileName=' +
window.encodeURIComponent(errorLocation.fileName) +
'&lineNumber=' +
window.encodeURIComponent(errorLocation.lineNumber || 1) +
'&colNumber=' +
window.encodeURIComponent(errorLocation.colNumber || 1)
);
});
// We need to keep track of if there has been a runtime error.
// Essentially, we cannot guarantee application state was not corrupted by the
// runtime error. To prevent confusing behavior, we forcibly reload the entire
// application. This is handled below when we are notified of a compile (code
// change).
// See https://github.com/facebook/create-react-app/issues/3096
var hadRuntimeError = false;
ErrorOverlay.startReportingRuntimeErrors({
onError: function() {
hadRuntimeError = true;
},
filename: '/static/js/bundle.js',
});
if (module.hot && typeof module.hot.dispose === 'function') {
module.hot.dispose(function() {
// TODO: why do we need this?
ErrorOverlay.stopReportingRuntimeErrors();
});
}
// Connect to WebpackDevServer via a socket.
var connection = new SockJS(
url.format({
protocol: window.location.protocol,
hostname: window.location.hostname,
port: window.location.port,
// Hardcoded in WebpackDevServer
pathname: window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/")) + '/sockjs-node',
})
);
// Unlike WebpackDevServer client, we won't try to reconnect
// to avoid spamming the console. Disconnect usually happens
// when developer stops the server.
connection.onclose = function() {
if (typeof console !== 'undefined' && typeof console.info === 'function') {
console.info(
'The development server has disconnected.\nRefresh the page if necessary.'
);
}
};
// Remember some state related to hot module replacement.
var isFirstCompilation = true;
var mostRecentCompilationHash = null;
var hasCompileErrors = false;
function clearOutdatedErrors() {
// Clean up outdated compile errors, if any.
if (typeof console !== 'undefined' && typeof console.clear === 'function') {
if (hasCompileErrors) {
console.clear();
}
}
}
// Successful compilation.
function handleSuccess() {
clearOutdatedErrors();
var isHotUpdate = !isFirstCompilation;
isFirstCompilation = false;
hasCompileErrors = false;
// Attempt to apply hot updates or reload.
if (isHotUpdate) {
tryApplyUpdates(function onHotUpdateSuccess() {
// Only dismiss it when we're sure it's a hot update.
// Otherwise it would flicker right before the reload.
tryDismissErrorOverlay();
});
}
}
// Compilation with warnings (e.g. ESLint).
function handleWarnings(warnings) {
clearOutdatedErrors();
var isHotUpdate = !isFirstCompilation;
isFirstCompilation = false;
hasCompileErrors = false;
function printWarnings() {
// Print warnings to the console.
var formatted = formatWebpackMessages({
warnings: warnings,
errors: [],
});
if (typeof console !== 'undefined' && typeof console.warn === 'function') {
for (var i = 0; i < formatted.warnings.length; i++) {
if (i === 5) {
console.warn(
'There were more warnings in other files.\n' +
'You can find a complete log in the terminal.'
);
break;
}
console.warn(stripAnsi(formatted.warnings[i]));
}
}
}
printWarnings();
// Attempt to apply hot updates or reload.
if (isHotUpdate) {
tryApplyUpdates(function onSuccessfulHotUpdate() {
// Only dismiss it when we're sure it's a hot update.
// Otherwise it would flicker right before the reload.
tryDismissErrorOverlay();
});
}
}
// Compilation with errors (e.g. syntax error or missing modules).
function handleErrors(errors) {
clearOutdatedErrors();
isFirstCompilation = false;
hasCompileErrors = true;
// "Massage" webpack messages.
var formatted = formatWebpackMessages({
errors: errors,
warnings: [],
});
// Only show the first error.
ErrorOverlay.reportBuildError(formatted.errors[0]);
// Also log them to the console.
if (typeof console !== 'undefined' && typeof console.error === 'function') {
for (var i = 0; i < formatted.errors.length; i++) {
console.error(stripAnsi(formatted.errors[i]));
}
}
// Do not attempt to reload now.
// We will reload on next success instead.
}
function tryDismissErrorOverlay() {
if (!hasCompileErrors) {
ErrorOverlay.dismissBuildError();
}
}
// There is a newer version of the code available.
function handleAvailableHash(hash) {
// Update last known compilation hash.
mostRecentCompilationHash = hash;
}
// Handle messages from the server.
connection.onmessage = function(e) {
var message = JSON.parse(e.data);
switch (message.type) {
case 'hash':
handleAvailableHash(message.data);
break;
case 'still-ok':
case 'ok':
handleSuccess();
break;
case 'content-changed':
// Triggered when a file from `contentBase` changed.
window.location.reload();
break;
case 'warnings':
handleWarnings(message.data);
break;
case 'errors':
handleErrors(message.data);
break;
default:
// Do nothing.
}
};
// Is there a newer version of this code available?
function isUpdateAvailable() {
/* globals __webpack_hash__ */
// __webpack_hash__ is the hash of the current compilation.
// It's a global variable injected by Webpack.
return mostRecentCompilationHash !== __webpack_hash__;
}
// Webpack disallows updates in other states.
function canApplyUpdates() {
return module.hot.status() === 'idle';
}
// Attempt to update code on the fly, fall back to a hard reload.
function tryApplyUpdates(onHotUpdateSuccess) {
if (!module.hot) {
// HotModuleReplacementPlugin is not in Webpack configuration.
window.location.reload();
return;
}
if (!isUpdateAvailable() || !canApplyUpdates()) {
return;
}
function handleApplyUpdates(err, updatedModules) {
if (err || !updatedModules || hadRuntimeError) {
window.location.reload();
return;
}
if (typeof onHotUpdateSuccess === 'function') {
// Maybe we want to do something.
onHotUpdateSuccess();
}
if (isUpdateAvailable()) {
// While we were updating, there was a new update! Do it again.
tryApplyUpdates();
}
}
// https://webpack.github.io/docs/hot-module-replacement.html#check
var result = module.hot.check(/* autoApply */ true, handleApplyUpdates);
// // Webpack 2 returns a Promise instead of invoking a callback
if (result && result.then) {
result.then(
function(updatedModules) {
handleApplyUpdates(null, updatedModules);
},
function(err) {
handleApplyUpdates(err, null);
}
);
}
}

View File

@ -0,0 +1,676 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// @remove-on-eject-end
'use strict';
const fs = require('fs');
const isWsl = require('is-wsl');
const path = require('path');
const webpack = require('webpack');
const resolve = require('resolve');
const PnpWebpackPlugin = require('pnp-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const safePostCssParser = require('postcss-safe-parser');
const ManifestPlugin = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const paths = require('./paths');
const modules = require('./modules');
const getClientEnvironment = require('./env');
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin');
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
// @remove-on-eject-begin
const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier');
// @remove-on-eject-end
const postcssNormalize = require('postcss-normalize');
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
// Some apps do not need the benefits of saving a web request, so not inlining the chunk
// makes for a smoother build process.
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
const imageInlineSizeLimit = parseInt(
process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'
);
// Check if TypeScript is setup
const useTypeScript = fs.existsSync(paths.appTsConfig);
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
// This is the production and development configuration.
// It is focused on developer experience, fast rebuilds, and a minimal bundle.
module.exports = function(webpackEnv) {
const isEnvDevelopment = webpackEnv === 'development';
const isEnvProduction = webpackEnv === 'production';
// 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.
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.
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.
const publicUrl = publicPath.slice(0, -1);
// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);
// common function to get style loaders
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
isEnvDevelopment && require.resolve('style-loader'),
isEnvProduction && {
loader: MiniCssExtractPlugin.loader,
options: shouldUseRelativeAssetPaths ? { publicPath: '../../' } : {},
},
{
loader: require.resolve('css-loader'),
options: cssOptions,
},
{
// Options for PostCSS as we reference these options twice
// Adds vendor prefixing based on your specified browser support in
// package.json
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebook/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
}),
// Adds PostCSS Normalize as the reset css with default options,
// so that it honors browserslist config in package.json
// which in turn let's users customize the target behavior as per their needs.
postcssNormalize(),
],
sourceMap: isEnvProduction && shouldUseSourceMap,
},
},
].filter(Boolean);
if (preProcessor) {
loaders.push({
loader: require.resolve(preProcessor),
options: {
sourceMap: isEnvProduction && shouldUseSourceMap,
},
});
}
return loaders;
};
return {
mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
// Stop compilation early in production
bail: isEnvProduction,
devtool: isEnvProduction
? shouldUseSourceMap
? 'source-map'
: false
: isEnvDevelopment && 'cheap-module-source-map',
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
entry: [
// Include an alternative client for WebpackDevServer. A client's job is to
// connect to WebpackDevServer by a socket and get notified about changes.
// When you save a file, the client will either apply hot updates (in case
// of CSS changes), or refresh the page (in case of JS changes). When you
// make a syntax error, this client will display a syntax error overlay.
// Note: instead of the default WebpackDevServer client, we use a custom one
// to bring better experience for Create React App users. You can replace
// the line below with these two lines if you prefer the stock client:
// require.resolve('webpack-dev-server/client') + '?/',
// require.resolve('webpack/hot/dev-server'),
isEnvDevelopment &&
require.resolve('react-dev-utils/webpackHotDevClient'),
// Finally, this is your app's code:
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.
].filter(Boolean),
output: {
// The build folder.
path: isEnvProduction ? paths.appBuild : undefined,
// Add /* filename */ comments to generated require()s in the output.
pathinfo: isEnvDevelopment,
// There will be one main bundle, and one file per asynchronous chunk.
// In development, it does not produce real files.
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
// TODO: remove this when upgrading to webpack 5
futureEmitAssets: true,
// There are also additional JS chunk files if you use code splitting.
chunkFilename: isEnvProduction
? 'static/js/[name].[contenthash:8].chunk.js'
: isEnvDevelopment && 'static/js/[name].chunk.js',
// We inferred the "public path" (such as / or /my-project) from homepage.
// We use "/" in development.
publicPath: publicPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: isEnvProduction
? info =>
path
.relative(paths.appSrc, info.absoluteResourcePath)
.replace(/\\/g, '/')
: isEnvDevelopment &&
(info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
},
optimization: {
minimize: isEnvProduction,
minimizer: [
// This is only used in production mode
new TerserPlugin({
terserOptions: {
parse: {
// we want terser to parse ecma 8 code. However, we don't want it
// to apply any minfication steps that turns valid ecma 5 code
// into invalid ecma 5 code. This is why the 'compress' and 'output'
// sections only apply transformations that are ecma 5 safe
// https://github.com/facebook/create-react-app/pull/4234
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
// Disabled because of an issue with Uglify breaking seemingly valid code:
// https://github.com/facebook/create-react-app/issues/2376
// Pending further investigation:
// https://github.com/mishoo/UglifyJS2/issues/2011
comparisons: false,
// Disabled because of an issue with Terser breaking valid code:
// https://github.com/facebook/create-react-app/issues/5250
// Pending futher investigation:
// https://github.com/terser-js/terser/issues/120
inline: 2,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebook/create-react-app/issues/2488
ascii_only: true,
},
},
// Use multi-process parallel running to improve the build speed
// Default number of concurrent runs: os.cpus().length - 1
// Disabled on WSL (Windows Subsystem for Linux) due to an issue with Terser
// https://github.com/webpack-contrib/terser-webpack-plugin/issues/21
parallel: !isWsl,
// Enable file caching
cache: true,
sourceMap: shouldUseSourceMap,
}),
// This is only used in production mode
new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
parser: safePostCssParser,
map: shouldUseSourceMap
? {
// `inline: false` forces the sourcemap to be output into a
// separate file
inline: false,
// `annotation: true` appends the sourceMappingURL to the end of
// the css file, helping the browser find the sourcemap
annotation: true,
}
: false,
},
}),
],
// Automatically split vendor and commons
// https://twitter.com/wSokra/status/969633336732905474
// https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366
splitChunks: {
chunks: 'all',
name: false,
},
// Keep the runtime chunk separated to enable long term caching
// https://twitter.com/wSokra/status/969679223278505985
runtimeChunk: true,
},
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebook/create-react-app/issues/253
modules: ['node_modules', paths.appNodeModules].concat(
modules.additionalModulePaths || []
),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebook/create-react-app/issues/290
// `web` extension prefixes have been added for better support
// for React Native Web.
extensions: paths.moduleFileExtensions
.map(ext => `.${ext}`)
.filter(ext => useTypeScript || !ext.includes('ts')),
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',
},
plugins: [
// Adds support for installing with Plug'n'Play, leading to faster installs and adding
// guards against forgotten dependencies and such.
PnpWebpackPlugin,
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
],
},
resolveLoader: {
plugins: [
// Also related to Plug'n'Play, but this time it tells Webpack to load its loaders
// from the current package.
PnpWebpackPlugin.moduleLoader(module),
],
},
module: {
strictExportPresence: true,
rules: [
// Disable require.ensure as it's not a standard language feature.
{ parser: { requireEnsure: false } },
// First, run the linter.
// It's important to do this before Babel processes the JS.
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
enforce: 'pre',
use: [
{
options: {
formatter: require.resolve('react-dev-utils/eslintFormatter'),
eslintPath: require.resolve('eslint'),
// @remove-on-eject-begin
baseConfig: {
extends: [require.resolve('eslint-config-react-app')],
},
ignore: false,
useEslintrc: false,
// @remove-on-eject-end
},
loader: require.resolve('eslint-loader'),
},
],
include: paths.appSrc,
},
{
// "oneOf" will traverse all following loaders until one will
// match the requirements. When no loader matches it will fall
// back to the "file" loader at the end of the loader list.
oneOf: [
// "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$/],
loader: require.resolve('url-loader'),
options: {
limit: imageInlineSizeLimit,
name: 'static/media/[name].[hash:8].[ext]',
},
},
// Process application JS with Babel.
// The preset includes JSX, Flow, TypeScript, and some ESnext features.
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
),
// @remove-on-eject-begin
babelrc: false,
configFile: false,
presets: [require.resolve('babel-preset-react-app')],
// Make sure we have a unique cache identifier, erring on the
// side of caution.
// We remove this when the user ejects because the default
// is sane and uses Babel options. Instead of options, we use
// the react-scripts and babel-preset-react-app versions.
cacheIdentifier: getCacheIdentifier(
isEnvProduction
? 'production'
: isEnvDevelopment && 'development',
[
'babel-plugin-named-asset-import',
'babel-preset-react-app',
'react-dev-utils',
'react-scripts',
]
),
// @remove-on-eject-end
plugins: [
[
require.resolve('babel-plugin-named-asset-import'),
{
loaderMap: {
svg: {
ReactComponent: '@svgr/webpack?-svgo,+ref![path]',
},
},
},
],
],
// 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,
cacheCompression: isEnvProduction,
compact: isEnvProduction,
},
},
// Process any JS outside of the app with Babel.
// Unlike the application JS, we only compile the standard ES features.
{
test: /\.(js|mjs)$/,
exclude: /@babel(?:\/|\\{1,2})runtime/,
loader: require.resolve('babel-loader'),
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [
[
require.resolve('babel-preset-react-app/dependencies'),
{ helpers: true },
],
],
cacheDirectory: true,
cacheCompression: isEnvProduction,
// @remove-on-eject-begin
cacheIdentifier: getCacheIdentifier(
isEnvProduction
? 'production'
: isEnvDevelopment && 'development',
[
'babel-plugin-named-asset-import',
'babel-preset-react-app',
'react-dev-utils',
'react-scripts',
]
),
// @remove-on-eject-end
// If an error happens in a package, it's possible to be
// because it was compiled. Thus, we don't want the browser
// debugger to show the original code. Instead, the code
// being evaluated would be much more helpful.
sourceMaps: false,
},
},
// "postcss" loader applies autoprefixer to our CSS.
// "css" loader resolves paths in CSS and adds assets as dependencies.
// "style" loader turns CSS into JS modules that inject <style> tags.
// In production, we use MiniCSSExtractPlugin to extract that CSS
// to a file, but in development "style" loader enables hot editing
// of CSS.
// By default we support CSS Modules with the extension .module.css
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
}),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
// using the extension .module.css
{
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: true,
getLocalIdent: getCSSModuleLocalIdent,
}),
},
// Opt-in support for SASS (using .scss or .sass extensions).
// By default we support SASS Modules with the
// extensions .module.scss or .module.sass
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'sass-loader'
),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules, but using SASS
// using the extension .module.scss or .module.sass
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: true,
getLocalIdent: getCSSModuleLocalIdent,
},
'sass-loader'
),
},
// "file" loader makes sure those assets get served by WebpackDevServer.
// When you `import` an asset, you get its (virtual) filename.
// In production, they would get copied to the `build` folder.
// This loader doesn't use a "test" so it will catch all modules
// that fall through the other loaders.
{
loader: require.resolve('file-loader'),
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
// ** STOP ** Are you adding a new loader?
// Make sure to add the new loader(s) before the "file" loader.
],
},
],
},
plugins: [
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin(
Object.assign(
{},
{
inject: true,
template: paths.appHtml,
},
isEnvProduction
? {
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}
: undefined
)
),
// Inlines the webpack runtime script. This script is too small to warrant
// a network request.
isEnvProduction &&
shouldInlineRuntimeChunk &&
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime~.+[.]js/]),
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// It will be an empty string unless you specify "homepage"
// in `package.json`, in which case it will be the pathname of that URL.
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
// This gives some necessary context to module not found errors, such as
// the requesting resource.
new ModuleNotFoundPlugin(paths.appPath),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV is set to production
// during a production build.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env.stringified),
// This is necessary to emit hot updates (currently CSS only):
isEnvDevelopment && new webpack.HotModuleReplacementPlugin(),
// Watcher doesn't work well if you mistype casing in a path so we use
// a plugin that prints an error when you attempt to do this.
// See https://github.com/facebook/create-react-app/issues/240
isEnvDevelopment && new CaseSensitivePathsPlugin(),
// If you require a missing module and then `npm install` it, you still have
// 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/facebook/create-react-app/issues/186
isEnvDevelopment &&
new WatchMissingNodeModulesPlugin(paths.appNodeModules),
isEnvProduction &&
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
}),
// 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',
publicPath: publicPath,
generate: (seed, files) => {
const manifestFiles = files.reduce(function(manifest, file) {
manifest[file.name] = file.path;
return manifest;
}, seed);
return {
files: manifestFiles,
};
},
}),
// Moment.js is an extremely popular library that bundles large locale files
// by default due to how Webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// Generate a service worker script that will precache, and keep up to date,
// the HTML & assets that are part of the Webpack build.
isEnvProduction &&
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true,
exclude: [/\.map$/, /asset-manifest\.json$/],
importWorkboxFrom: 'cdn',
navigateFallback: publicUrl + '/index.html',
navigateFallbackBlacklist: [
// Exclude URLs starting with /_, as they're likely an API call
new RegExp('^/_'),
// Exclude URLs containing a dot, as they're likely a resource in
// public/ and not a SPA route
new RegExp('/[^/]+\\.[^/]+$'),
],
}),
// TypeScript type checking
useTypeScript &&
new ForkTsCheckerWebpackPlugin({
typescript: resolve.sync('typescript', {
basedir: paths.appNodeModules,
}),
async: isEnvDevelopment,
useTypescriptIncrementalApi: true,
checkSyntacticErrors: true,
resolveModuleNameModule: process.versions.pnp
? `${__dirname}/pnpTs.js`
: undefined,
resolveTypeReferenceDirectiveModule: process.versions.pnp
? `${__dirname}/pnpTs.js`
: undefined,
tsconfig: paths.appTsConfig,
reportFiles: [
'**',
'!**/__tests__/**',
'!**/?(*.)(spec|test).*',
'!**/src/setupProxy.*',
'!**/src/setupTests.*',
],
watch: paths.appSrc,
silent: true,
// The formatter is invoked directly in WebpackDevServerUtils during development
formatter: isEnvProduction ? typescriptFormatter : undefined,
}),
].filter(Boolean),
// 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: {
module: 'empty',
dgram: 'empty',
dns: 'mock',
fs: 'empty',
http2: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
},
// Turn off performance processing because we utilize
// our own hints via the FileSizeReporter
performance: false,
};
};

View File

@ -0,0 +1,113 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// @remove-on-eject-end
'use strict';
const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');
const evalSourceMapMiddleware = require('react-dev-utils/evalSourceMapMiddleware');
const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');
const ignoredFiles = require('react-dev-utils/ignoredFiles');
const paths = require('./paths');
const fs = require('fs');
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const host = process.env.HOST || '0.0.0.0';
module.exports = function(proxy, allowedHost) {
return {
// WebpackDevServer 2.4.3 introduced a security fix that prevents remote
// websites from potentially accessing local content through DNS rebinding:
// https://github.com/webpack/webpack-dev-server/issues/887
// https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a
// However, it made several existing use cases such as development in cloud
// environment or subdomains in development significantly more complicated:
// https://github.com/facebook/create-react-app/issues/2271
// https://github.com/facebook/create-react-app/issues/2233
// While we're investigating better solutions, for now we will take a
// compromise. Since our WDS configuration only serves files in the `public`
// folder we won't consider accessing them a vulnerability. However, if you
// use the `proxy` feature, it gets more dangerous because it can expose
// remote code execution vulnerabilities in backends like Django and Rails.
// So we will disable the host check normally, but enable it if you have
// specified the `proxy` setting. Finally, we let you override it if you
// really know what you're doing with a special environment variable.
disableHostCheck:
!proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true',
// Enable gzip compression of generated files.
compress: true,
// Silence WebpackDevServer's own logs since they're generally not useful.
// It will still show compile warnings and errors with this setting.
clientLogLevel: 'none',
// By default WebpackDevServer serves physical files from current directory
// in addition to all the virtual build products that it serves from memory.
// This is confusing because those files wont automatically be available in
// production build folder unless we copy them. However, copying the whole
// project directory is dangerous because we may expose sensitive files.
// Instead, we establish a convention that only files in `public` directory
// get served. Our build script will copy `public` into the `build` folder.
// In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
// Note that we only recommend to use `public` folder as an escape hatch
// for files like `favicon.ico`, `manifest.json`, and libraries that are
// for some reason broken when imported through Webpack. If you just want to
// use an image, put it in `src` and `import` it from JavaScript instead.
contentBase: paths.appPublic,
// By default files from `contentBase` will not trigger a page reload.
watchContentBase: true,
// Enable hot reloading server. It will provide /sockjs-node/ endpoint
// for the WebpackDevServer client so it can learn when the files were
// updated. The WebpackDevServer client is included as an entry point
// in the Webpack development configuration. Note that only changes
// to CSS are currently hot reloaded. JS changes will refresh the browser.
hot: true,
// It is important to tell WebpackDevServer to use the same "root" path
// as we specified in the config.
publicPath: paths.servedPath.slice(0, -1),
// WebpackDevServer is noisy by default so we emit custom message instead
// by listening to the compiler events with `compiler.hooks[...].tap` calls above.
quiet: true,
// Reportedly, this avoids CPU overload on some systems.
// https://github.com/facebook/create-react-app/issues/293
// src/node_modules is not ignored to support absolute imports
// https://github.com/facebook/create-react-app/issues/1065
watchOptions: {
ignored: ignoredFiles(paths.appSrc),
},
// Enable HTTPS if the HTTPS environment variable is set to 'true'
https: protocol === 'https',
host,
overlay: false,
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebook/create-react-app/issues/387.
disableDotRule: true,
index: paths.servedPath,
},
public: allowedHost,
proxy,
before(app, server) {
if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(app);
}
// This lets us fetch source contents from webpack for the error overlay
app.use(evalSourceMapMiddleware(server));
// This lets us open files from the runtime error overlay.
app.use(errorOverlayMiddleware());
// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.
// We do this in development to avoid hitting the production cache if
// it used the same host and port.
// https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
app.use(noopServiceWorkerMiddleware());
},
};
};

167
build/cra/react-scripts/scripts/start.js vendored Normal file
View File

@ -0,0 +1,167 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// @remove-on-eject-end
'use strict';
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
throw err;
});
// Ensure environment variables are read.
require('../config/env');
// @remove-on-eject-begin
// Do the preflight check (only happens before eject).
const verifyPackageTree = require('./utils/verifyPackageTree');
if (process.env.SKIP_PREFLIGHT_CHECK !== 'true') {
verifyPackageTree();
}
const verifyTypeScriptSetup = require('./utils/verifyTypeScriptSetup');
verifyTypeScriptSetup();
// @remove-on-eject-end
const fs = require('fs');
const chalk = require('react-dev-utils/chalk');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const clearConsole = require('react-dev-utils/clearConsole');
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
const {
choosePort,
createCompiler,
prepareProxy,
prepareUrls,
} = require('react-dev-utils/WebpackDevServerUtils');
const openBrowser = require('react-dev-utils/openBrowser');
const paths = require('../config/paths');
const configFactory = require('../config/webpack.config');
const createDevServerConfig = require('../config/webpackDevServer.config');
const useYarn = fs.existsSync(paths.yarnLockFile);
const isInteractive = process.stdout.isTTY;
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
}
// Tools like Cloud9 rely on this.
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
const HOST = process.env.HOST || '0.0.0.0';
if (process.env.HOST) {
console.log(
chalk.cyan(
`Attempting to bind to HOST environment variable: ${chalk.yellow(
chalk.bold(process.env.HOST)
)}`
)
);
console.log(
`If this was unintentional, check that you haven't mistakenly set it in your shell.`
);
console.log(
`Learn more here: ${chalk.yellow('https://bit.ly/CRA-advanced-config')}`
);
console.log();
}
// We require that you explicitly set browsers and do not fall back to
// browserslist defaults.
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
checkBrowsers(paths.appPath, isInteractive)
.then(() => {
// We attempt to use the default port but if it is busy, we offer the user to
// run on a different port. `choosePort()` Promise resolves to the next free port.
return choosePort(HOST, DEFAULT_PORT);
})
.then(port => {
if (port == null) {
// We have not found a port.
return;
}
const config = configFactory('development');
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const appName = require(paths.appPackageJson).name;
const useTypeScript = fs.existsSync(paths.appTsConfig);
const urls = prepareUrls(
protocol,
HOST,
port,
paths.servedPath.slice(0, -1)
);
const devSocket = {
warnings: warnings =>
devServer.sockWrite(devServer.sockets, 'warnings', warnings),
errors: errors =>
devServer.sockWrite(devServer.sockets, 'errors', errors),
};
// Create a webpack compiler that is configured with custom messages.
const compiler = createCompiler({
appName,
config,
devSocket,
urls,
useYarn,
useTypeScript,
webpack,
});
// Load proxy config
const proxySetting = require(paths.appPackageJson).proxy;
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
// Serve webpack assets generated by the compiler over a web server.
const serverConfig = createDevServerConfig(
proxyConfig,
urls.lanUrlForConfig
);
const devServer = new WebpackDevServer(compiler, serverConfig);
// Launch WebpackDevServer.
devServer.listen(port, HOST, err => {
if (err) {
return console.log(err);
}
if (isInteractive) {
clearConsole();
}
// We used to support resolving modules according to `NODE_PATH`.
// This now has been deprecated in favor of jsconfig/tsconfig.json
// This lets you use absolute paths in imports inside large monorepos:
if (process.env.NODE_PATH) {
console.log(
chalk.yellow(
'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
)
);
console.log();
}
console.log(chalk.cyan('Starting the development server...\n'));
openBrowser(urls.localUrlForBrowser);
});
['SIGINT', 'SIGTERM'].forEach(function(sig) {
process.on(sig, function() {
devServer.close();
process.exit();
});
});
})
.catch(err => {
if (err && err.message) {
console.log(err.message);
}
process.exit(1);
});

View File

@ -58,9 +58,23 @@
}
location /products/people {
rewrite /products/people/(.*) /$1 break;
proxy_pass http://localhost:5002;
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
location ~ /sockjs-node {
rewrite products/people/(.*) /$1 break;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://localhost:5002;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

View File

@ -0,0 +1,2 @@
PUBLIC_URL=/products/people
PORT=5002

View File

@ -48,7 +48,7 @@
"extends": "react-app"
},
"scripts": {
"start": "rimraf ./build && set PORT=5002 && react-scripts start",
"start": "rimraf ./build && react-scripts start",
"build": "react-scripts build",
"test": "cross-env CI=true react-scripts test --env=jsdom",
"eject": "react-scripts eject",