mirror of
https://github.com/idanoo/GoScrobble
synced 2025-07-01 21:52:19 +00:00
0.2.0 - Mid migration
This commit is contained in:
parent
139e6a915e
commit
7e38fdbd7d
42393 changed files with 5358157 additions and 62 deletions
228
web/node_modules/react-scripts/scripts/build.js
generated
vendored
Normal file
228
web/node_modules/react-scripts/scripts/build.js
generated
vendored
Normal file
|
@ -0,0 +1,228 @@
|
|||
// @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 = 'production';
|
||||
process.env.NODE_ENV = 'production';
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
// ignoring them. In the future, promise rejections that are not handled will
|
||||
// terminate the Node.js process with a non-zero exit code.
|
||||
process.on('unhandledRejection', err => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
// Ensure environment variables are read.
|
||||
require('../config/env');
|
||||
// @remove-on-eject-begin
|
||||
// Do the preflight checks (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 path = require('path');
|
||||
const chalk = require('react-dev-utils/chalk');
|
||||
const fs = require('fs-extra');
|
||||
const bfj = require('bfj');
|
||||
const webpack = require('webpack');
|
||||
const configFactory = require('../config/webpack.config');
|
||||
const paths = require('../config/paths');
|
||||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
|
||||
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
|
||||
const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
|
||||
const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
|
||||
const printBuildError = require('react-dev-utils/printBuildError');
|
||||
|
||||
const measureFileSizesBeforeBuild =
|
||||
FileSizeReporter.measureFileSizesBeforeBuild;
|
||||
const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
|
||||
const useYarn = fs.existsSync(paths.yarnLockFile);
|
||||
|
||||
// These sizes are pretty large. We'll warn for bundles exceeding them.
|
||||
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
|
||||
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
|
||||
|
||||
const isInteractive = process.stdout.isTTY;
|
||||
|
||||
// Warn and crash if required files are missing
|
||||
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const argv = process.argv.slice(2);
|
||||
const writeStatsJson = argv.indexOf('--stats') !== -1;
|
||||
|
||||
// Generate configuration
|
||||
const config = configFactory('production');
|
||||
|
||||
// We require that you explicitly set browsers and do not fall back to
|
||||
// browserslist defaults.
|
||||
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
|
||||
checkBrowsers(paths.appPath, isInteractive)
|
||||
.then(() => {
|
||||
// First, read the current file sizes in build directory.
|
||||
// This lets us display how much they changed later.
|
||||
return measureFileSizesBeforeBuild(paths.appBuild);
|
||||
})
|
||||
.then(previousFileSizes => {
|
||||
// Remove all content but keep the directory so that
|
||||
// if you're in it, you don't end up in Trash
|
||||
fs.emptyDirSync(paths.appBuild);
|
||||
// Merge with the public folder
|
||||
copyPublicFolder();
|
||||
// Start the webpack build
|
||||
return build(previousFileSizes);
|
||||
})
|
||||
.then(
|
||||
({ stats, previousFileSizes, warnings }) => {
|
||||
if (warnings.length) {
|
||||
console.log(chalk.yellow('Compiled with warnings.\n'));
|
||||
console.log(warnings.join('\n\n'));
|
||||
console.log(
|
||||
'\nSearch for the ' +
|
||||
chalk.underline(chalk.yellow('keywords')) +
|
||||
' to learn more about each warning.'
|
||||
);
|
||||
console.log(
|
||||
'To ignore, add ' +
|
||||
chalk.cyan('// eslint-disable-next-line') +
|
||||
' to the line before.\n'
|
||||
);
|
||||
} else {
|
||||
console.log(chalk.green('Compiled successfully.\n'));
|
||||
}
|
||||
|
||||
console.log('File sizes after gzip:\n');
|
||||
printFileSizesAfterBuild(
|
||||
stats,
|
||||
previousFileSizes,
|
||||
paths.appBuild,
|
||||
WARN_AFTER_BUNDLE_GZIP_SIZE,
|
||||
WARN_AFTER_CHUNK_GZIP_SIZE
|
||||
);
|
||||
console.log();
|
||||
|
||||
const appPackage = require(paths.appPackageJson);
|
||||
const publicUrl = paths.publicUrlOrPath;
|
||||
const publicPath = config.output.publicPath;
|
||||
const buildFolder = path.relative(process.cwd(), paths.appBuild);
|
||||
printHostingInstructions(
|
||||
appPackage,
|
||||
publicUrl,
|
||||
publicPath,
|
||||
buildFolder,
|
||||
useYarn
|
||||
);
|
||||
},
|
||||
err => {
|
||||
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
|
||||
if (tscCompileOnError) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Compiled with the following type errors (you may want to check these before deploying your app):\n'
|
||||
)
|
||||
);
|
||||
printBuildError(err);
|
||||
} else {
|
||||
console.log(chalk.red('Failed to compile.\n'));
|
||||
printBuildError(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
)
|
||||
.catch(err => {
|
||||
if (err && err.message) {
|
||||
console.log(err.message);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Create the production build and print the deployment instructions.
|
||||
function build(previousFileSizes) {
|
||||
console.log('Creating an optimized production build...');
|
||||
|
||||
const compiler = webpack(config);
|
||||
return new Promise((resolve, reject) => {
|
||||
compiler.run((err, stats) => {
|
||||
let messages;
|
||||
if (err) {
|
||||
if (!err.message) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
let errMessage = err.message;
|
||||
|
||||
// Add additional information for postcss errors
|
||||
if (Object.prototype.hasOwnProperty.call(err, 'postcssNode')) {
|
||||
errMessage +=
|
||||
'\nCompileError: Begins at CSS selector ' +
|
||||
err['postcssNode'].selector;
|
||||
}
|
||||
|
||||
messages = formatWebpackMessages({
|
||||
errors: [errMessage],
|
||||
warnings: [],
|
||||
});
|
||||
} else {
|
||||
messages = formatWebpackMessages(
|
||||
stats.toJson({ all: false, warnings: true, errors: true })
|
||||
);
|
||||
}
|
||||
if (messages.errors.length) {
|
||||
// Only keep the first error. Others are often indicative
|
||||
// of the same problem, but confuse the reader with noise.
|
||||
if (messages.errors.length > 1) {
|
||||
messages.errors.length = 1;
|
||||
}
|
||||
return reject(new Error(messages.errors.join('\n\n')));
|
||||
}
|
||||
if (
|
||||
process.env.CI &&
|
||||
(typeof process.env.CI !== 'string' ||
|
||||
process.env.CI.toLowerCase() !== 'false') &&
|
||||
messages.warnings.length
|
||||
) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'\nTreating warnings as errors because process.env.CI = true.\n' +
|
||||
'Most CI servers set it automatically.\n'
|
||||
)
|
||||
);
|
||||
return reject(new Error(messages.warnings.join('\n\n')));
|
||||
}
|
||||
|
||||
const resolveArgs = {
|
||||
stats,
|
||||
previousFileSizes,
|
||||
warnings: messages.warnings,
|
||||
};
|
||||
|
||||
if (writeStatsJson) {
|
||||
return bfj
|
||||
.write(paths.appBuild + '/bundle-stats.json', stats.toJson())
|
||||
.then(() => resolve(resolveArgs))
|
||||
.catch(error => reject(new Error(error)));
|
||||
}
|
||||
|
||||
return resolve(resolveArgs);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function copyPublicFolder() {
|
||||
fs.copySync(paths.appPublic, paths.appBuild, {
|
||||
dereference: true,
|
||||
filter: file => file !== paths.appHtml,
|
||||
});
|
||||
}
|
340
web/node_modules/react-scripts/scripts/eject.js
generated
vendored
Normal file
340
web/node_modules/react-scripts/scripts/eject.js
generated
vendored
Normal file
|
@ -0,0 +1,340 @@
|
|||
// @remove-file-on-eject
|
||||
/**
|
||||
* 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';
|
||||
|
||||
// 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;
|
||||
});
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const prompts = require('prompts');
|
||||
const execSync = require('child_process').execSync;
|
||||
const chalk = require('react-dev-utils/chalk');
|
||||
const paths = require('../config/paths');
|
||||
const createJestConfig = require('./utils/createJestConfig');
|
||||
const spawnSync = require('react-dev-utils/crossSpawn').sync;
|
||||
const os = require('os');
|
||||
|
||||
const green = chalk.green;
|
||||
const cyan = chalk.cyan;
|
||||
|
||||
function getGitStatus() {
|
||||
try {
|
||||
let stdout = execSync(`git status --porcelain`, {
|
||||
stdio: ['pipe', 'pipe', 'ignore'],
|
||||
}).toString();
|
||||
return stdout.trim();
|
||||
} catch (e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function tryGitAdd(appPath) {
|
||||
try {
|
||||
spawnSync(
|
||||
'git',
|
||||
['add', path.join(appPath, 'config'), path.join(appPath, 'scripts')],
|
||||
{
|
||||
stdio: 'inherit',
|
||||
}
|
||||
);
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
chalk.cyan.bold(
|
||||
'NOTE: Create React App 2+ supports TypeScript, Sass, CSS Modules and more without ejecting: ' +
|
||||
'https://reactjs.org/blog/2018/10/01/create-react-app-v2.html'
|
||||
)
|
||||
);
|
||||
console.log();
|
||||
|
||||
prompts({
|
||||
type: 'confirm',
|
||||
name: 'shouldEject',
|
||||
message: 'Are you sure you want to eject? This action is permanent.',
|
||||
initial: false,
|
||||
}).then(answer => {
|
||||
if (!answer.shouldEject) {
|
||||
console.log(cyan('Close one! Eject aborted.'));
|
||||
return;
|
||||
}
|
||||
|
||||
const gitStatus = getGitStatus();
|
||||
if (gitStatus) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
'This git repository has untracked files or uncommitted changes:'
|
||||
) +
|
||||
'\n\n' +
|
||||
gitStatus
|
||||
.split('\n')
|
||||
.map(line => line.match(/ .*/g)[0].trim())
|
||||
.join('\n') +
|
||||
'\n\n' +
|
||||
chalk.red(
|
||||
'Remove untracked files, stash or commit any changes, and try again.'
|
||||
)
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('Ejecting...');
|
||||
|
||||
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.'
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
const folders = ['config', 'config/jest', 'scripts'];
|
||||
|
||||
// Make shallow array of files paths
|
||||
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);
|
||||
|
||||
// Prepare Jest config early in case it throws
|
||||
const jestConfig = createJestConfig(
|
||||
filePath => path.posix.join('<rootDir>', filePath),
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
console.log();
|
||||
console.log(cyan(`Copying files into ${appPath}`));
|
||||
|
||||
folders.forEach(folder => {
|
||||
fs.mkdirSync(path.join(appPath, folder));
|
||||
});
|
||||
|
||||
files.forEach(file => {
|
||||
let content = fs.readFileSync(file, 'utf8');
|
||||
|
||||
// Skip flagged files
|
||||
if (content.match(/\/\/ @remove-file-on-eject/)) {
|
||||
return;
|
||||
}
|
||||
content =
|
||||
content
|
||||
// Remove dead code from .js files on eject
|
||||
.replace(
|
||||
/\/\/ @remove-on-eject-begin([\s\S]*?)\/\/ @remove-on-eject-end/gm,
|
||||
''
|
||||
)
|
||||
// Remove dead code from .applescript files on eject
|
||||
.replace(
|
||||
/-- @remove-on-eject-begin([\s\S]*?)-- @remove-on-eject-end/gm,
|
||||
''
|
||||
)
|
||||
.trim() + '\n';
|
||||
console.log(` Adding ${cyan(file.replace(ownPath, ''))} to the project`);
|
||||
fs.writeFileSync(file.replace(ownPath, appPath), content);
|
||||
});
|
||||
console.log();
|
||||
|
||||
const ownPackage = require(path.join(ownPath, 'package.json'));
|
||||
const appPackage = require(path.join(appPath, 'package.json'));
|
||||
|
||||
console.log(cyan('Updating the dependencies'));
|
||||
const ownPackageName = ownPackage.name;
|
||||
if (appPackage.devDependencies) {
|
||||
// We used to put react-scripts in devDependencies
|
||||
if (appPackage.devDependencies[ownPackageName]) {
|
||||
console.log(` Removing ${cyan(ownPackageName)} from devDependencies`);
|
||||
delete appPackage.devDependencies[ownPackageName];
|
||||
}
|
||||
}
|
||||
appPackage.dependencies = appPackage.dependencies || {};
|
||||
if (appPackage.dependencies[ownPackageName]) {
|
||||
console.log(` Removing ${cyan(ownPackageName)} from dependencies`);
|
||||
delete appPackage.dependencies[ownPackageName];
|
||||
}
|
||||
Object.keys(ownPackage.dependencies).forEach(key => {
|
||||
// For some reason optionalDependencies end up in dependencies after install
|
||||
if (
|
||||
ownPackage.optionalDependencies &&
|
||||
ownPackage.optionalDependencies[key]
|
||||
) {
|
||||
return;
|
||||
}
|
||||
console.log(` Adding ${cyan(key)} to dependencies`);
|
||||
appPackage.dependencies[key] = ownPackage.dependencies[key];
|
||||
});
|
||||
// Sort the deps
|
||||
const unsortedDependencies = appPackage.dependencies;
|
||||
appPackage.dependencies = {};
|
||||
Object.keys(unsortedDependencies)
|
||||
.sort()
|
||||
.forEach(key => {
|
||||
appPackage.dependencies[key] = unsortedDependencies[key];
|
||||
});
|
||||
console.log();
|
||||
|
||||
console.log(cyan('Updating the scripts'));
|
||||
delete appPackage.scripts['eject'];
|
||||
Object.keys(appPackage.scripts).forEach(key => {
|
||||
Object.keys(ownPackage.bin).forEach(binKey => {
|
||||
const regex = new RegExp(binKey + ' (\\w+)', 'g');
|
||||
if (!regex.test(appPackage.scripts[key])) {
|
||||
return;
|
||||
}
|
||||
appPackage.scripts[key] = appPackage.scripts[key].replace(
|
||||
regex,
|
||||
'node scripts/$1.js'
|
||||
);
|
||||
console.log(
|
||||
` Replacing ${cyan(`"${binKey} ${key}"`)} with ${cyan(
|
||||
`"node scripts/${key}.js"`
|
||||
)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
console.log();
|
||||
console.log(cyan('Configuring package.json'));
|
||||
// Add Jest config
|
||||
console.log(` Adding ${cyan('Jest')} configuration`);
|
||||
appPackage.jest = jestConfig;
|
||||
|
||||
// Add Babel config
|
||||
console.log(` Adding ${cyan('Babel')} preset`);
|
||||
appPackage.babel = {
|
||||
presets: ['react-app'],
|
||||
};
|
||||
|
||||
// Add ESlint config
|
||||
if (!appPackage.eslintConfig) {
|
||||
console.log(` Adding ${cyan('ESLint')} configuration`);
|
||||
appPackage.eslintConfig = {
|
||||
extends: 'react-app',
|
||||
};
|
||||
}
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(appPath, 'package.json'),
|
||||
JSON.stringify(appPackage, null, 2) + os.EOL
|
||||
);
|
||||
console.log();
|
||||
|
||||
if (fs.existsSync(paths.appTypeDeclarations)) {
|
||||
try {
|
||||
// Read app declarations file
|
||||
let content = fs.readFileSync(paths.appTypeDeclarations, 'utf8');
|
||||
const ownContent =
|
||||
fs.readFileSync(paths.ownTypeDeclarations, 'utf8').trim() + os.EOL;
|
||||
|
||||
// Remove react-scripts reference since they're getting a copy of the types in their project
|
||||
content =
|
||||
content
|
||||
// Remove react-scripts types
|
||||
.replace(
|
||||
/^\s*\/\/\/\s*<reference\s+types.+?"react-scripts".*\/>.*(?:\n|$)/gm,
|
||||
''
|
||||
)
|
||||
.trim() + os.EOL;
|
||||
|
||||
fs.writeFileSync(
|
||||
paths.appTypeDeclarations,
|
||||
(ownContent + os.EOL + content).trim() + os.EOL
|
||||
);
|
||||
} catch (e) {
|
||||
// It's not essential that this succeeds, the TypeScript user should
|
||||
// be able to re-create these types with ease.
|
||||
}
|
||||
}
|
||||
|
||||
// "Don't destroy what isn't ours"
|
||||
if (ownPath.indexOf(appPath) === 0) {
|
||||
try {
|
||||
// remove react-scripts and react-scripts binaries from app node_modules
|
||||
Object.keys(ownPackage.bin).forEach(binKey => {
|
||||
fs.removeSync(path.join(appPath, 'node_modules', '.bin', binKey));
|
||||
});
|
||||
fs.removeSync(ownPath);
|
||||
} catch (e) {
|
||||
// It's not essential that this succeeds
|
||||
}
|
||||
}
|
||||
|
||||
if (fs.existsSync(paths.yarnLockFile)) {
|
||||
const windowsCmdFilePath = path.join(
|
||||
appPath,
|
||||
'node_modules',
|
||||
'.bin',
|
||||
'react-scripts.cmd'
|
||||
);
|
||||
let windowsCmdFileContent;
|
||||
if (process.platform === 'win32') {
|
||||
// https://github.com/facebook/create-react-app/pull/3806#issuecomment-357781035
|
||||
// Yarn is diligent about cleaning up after itself, but this causes the react-scripts.cmd file
|
||||
// to be deleted while it is running. This trips Windows up after the eject completes.
|
||||
// We'll read the batch file and later "write it back" to match npm behavior.
|
||||
try {
|
||||
windowsCmdFileContent = fs.readFileSync(windowsCmdFilePath);
|
||||
} catch (err) {
|
||||
// If this fails we're not worse off than if we didn't try to fix it.
|
||||
}
|
||||
}
|
||||
|
||||
console.log(cyan('Running yarn...'));
|
||||
spawnSync('yarnpkg', ['--cwd', process.cwd()], { stdio: 'inherit' });
|
||||
|
||||
if (windowsCmdFileContent && !fs.existsSync(windowsCmdFilePath)) {
|
||||
try {
|
||||
fs.writeFileSync(windowsCmdFilePath, windowsCmdFileContent);
|
||||
} catch (err) {
|
||||
// If this fails we're not worse off than if we didn't try to fix it.
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(cyan('Running npm install...'));
|
||||
spawnSync('npm', ['install', '--loglevel', 'error'], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
}
|
||||
console.log(green('Ejected successfully!'));
|
||||
console.log();
|
||||
|
||||
if (tryGitAdd(appPath)) {
|
||||
console.log(cyan('Staged ejected files for commit.'));
|
||||
console.log();
|
||||
}
|
||||
|
||||
console.log(green('Please consider sharing why you ejected in this survey:'));
|
||||
console.log(green(' http://goo.gl/forms/Bi6CZjk1EqsdelXk1'));
|
||||
console.log();
|
||||
});
|
418
web/node_modules/react-scripts/scripts/init.js
generated
vendored
Normal file
418
web/node_modules/react-scripts/scripts/init.js
generated
vendored
Normal file
|
@ -0,0 +1,418 @@
|
|||
// @remove-file-on-eject
|
||||
/**
|
||||
* 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';
|
||||
|
||||
// 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;
|
||||
});
|
||||
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const chalk = require('react-dev-utils/chalk');
|
||||
const execSync = require('child_process').execSync;
|
||||
const spawn = require('react-dev-utils/crossSpawn');
|
||||
const { defaultBrowsers } = require('react-dev-utils/browsersHelper');
|
||||
const os = require('os');
|
||||
const verifyTypeScriptSetup = require('./utils/verifyTypeScriptSetup');
|
||||
|
||||
function isInGitRepository() {
|
||||
try {
|
||||
execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isInMercurialRepository() {
|
||||
try {
|
||||
execSync('hg --cwd . root', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function tryGitInit() {
|
||||
try {
|
||||
execSync('git --version', { stdio: 'ignore' });
|
||||
if (isInGitRepository() || isInMercurialRepository()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
execSync('git init', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.warn('Git repo not initialized', e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function tryGitCommit(appPath) {
|
||||
try {
|
||||
execSync('git add -A', { stdio: 'ignore' });
|
||||
execSync('git commit -m "Initialize project using Create React App"', {
|
||||
stdio: 'ignore',
|
||||
});
|
||||
return true;
|
||||
} catch (e) {
|
||||
// We couldn't commit in already initialized git repo,
|
||||
// maybe the commit author config is not set.
|
||||
// In the future, we might supply our own committer
|
||||
// like Ember CLI does, but for now, let's just
|
||||
// remove the Git files to avoid a half-done state.
|
||||
console.warn('Git commit not created', e);
|
||||
console.warn('Removing .git directory...');
|
||||
try {
|
||||
// unlinkSync() doesn't work on directories.
|
||||
fs.removeSync(path.join(appPath, '.git'));
|
||||
} catch (removeErr) {
|
||||
// Ignore.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function (
|
||||
appPath,
|
||||
appName,
|
||||
verbose,
|
||||
originalDirectory,
|
||||
templateName
|
||||
) {
|
||||
const appPackage = require(path.join(appPath, 'package.json'));
|
||||
const useYarn = fs.existsSync(path.join(appPath, 'yarn.lock'));
|
||||
|
||||
if (!templateName) {
|
||||
console.log('');
|
||||
console.error(
|
||||
`A template was not provided. This is likely because you're using an outdated version of ${chalk.cyan(
|
||||
'create-react-app'
|
||||
)}.`
|
||||
);
|
||||
console.error(
|
||||
`Please note that global installs of ${chalk.cyan(
|
||||
'create-react-app'
|
||||
)} are no longer supported.`
|
||||
);
|
||||
console.error(
|
||||
`You can fix this by running ${chalk.cyan(
|
||||
'npm uninstall -g create-react-app'
|
||||
)} or ${chalk.cyan(
|
||||
'yarn global remove create-react-app'
|
||||
)} before using ${chalk.cyan('create-react-app')} again.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const templatePath = path.dirname(
|
||||
require.resolve(`${templateName}/package.json`, { paths: [appPath] })
|
||||
);
|
||||
|
||||
const templateJsonPath = path.join(templatePath, 'template.json');
|
||||
|
||||
let templateJson = {};
|
||||
if (fs.existsSync(templateJsonPath)) {
|
||||
templateJson = require(templateJsonPath);
|
||||
}
|
||||
|
||||
const templatePackage = templateJson.package || {};
|
||||
|
||||
// TODO: Deprecate support for root-level `dependencies` and `scripts` in v5.
|
||||
// These should now be set under the `package` key.
|
||||
if (templateJson.dependencies || templateJson.scripts) {
|
||||
console.log();
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Root-level `dependencies` and `scripts` keys in `template.json` are deprecated.\n' +
|
||||
'This template should be updated to use the new `package` key.'
|
||||
)
|
||||
);
|
||||
console.log('For more information, visit https://cra.link/templates');
|
||||
}
|
||||
if (templateJson.dependencies) {
|
||||
templatePackage.dependencies = templateJson.dependencies;
|
||||
}
|
||||
if (templateJson.scripts) {
|
||||
templatePackage.scripts = templateJson.scripts;
|
||||
}
|
||||
|
||||
// Keys to ignore in templatePackage
|
||||
const templatePackageBlacklist = [
|
||||
'name',
|
||||
'version',
|
||||
'description',
|
||||
'keywords',
|
||||
'bugs',
|
||||
'license',
|
||||
'author',
|
||||
'contributors',
|
||||
'files',
|
||||
'browser',
|
||||
'bin',
|
||||
'man',
|
||||
'directories',
|
||||
'repository',
|
||||
'peerDependencies',
|
||||
'bundledDependencies',
|
||||
'optionalDependencies',
|
||||
'engineStrict',
|
||||
'os',
|
||||
'cpu',
|
||||
'preferGlobal',
|
||||
'private',
|
||||
'publishConfig',
|
||||
];
|
||||
|
||||
// Keys from templatePackage that will be merged with appPackage
|
||||
const templatePackageToMerge = ['dependencies', 'scripts'];
|
||||
|
||||
// Keys from templatePackage that will be added to appPackage,
|
||||
// replacing any existing entries.
|
||||
const templatePackageToReplace = Object.keys(templatePackage).filter(key => {
|
||||
return (
|
||||
!templatePackageBlacklist.includes(key) &&
|
||||
!templatePackageToMerge.includes(key)
|
||||
);
|
||||
});
|
||||
|
||||
// Copy over some of the devDependencies
|
||||
appPackage.dependencies = appPackage.dependencies || {};
|
||||
|
||||
// Setup the script rules
|
||||
const templateScripts = templatePackage.scripts || {};
|
||||
appPackage.scripts = Object.assign(
|
||||
{
|
||||
start: 'react-scripts start',
|
||||
build: 'react-scripts build',
|
||||
test: 'react-scripts test',
|
||||
eject: 'react-scripts eject',
|
||||
},
|
||||
templateScripts
|
||||
);
|
||||
|
||||
// Update scripts for Yarn users
|
||||
if (useYarn) {
|
||||
appPackage.scripts = Object.entries(appPackage.scripts).reduce(
|
||||
(acc, [key, value]) => ({
|
||||
...acc,
|
||||
[key]: value.replace(/(npm run |npm )/, 'yarn '),
|
||||
}),
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
// Setup the eslint config
|
||||
appPackage.eslintConfig = {
|
||||
extends: 'react-app',
|
||||
};
|
||||
|
||||
// Setup the browsers list
|
||||
appPackage.browserslist = defaultBrowsers;
|
||||
|
||||
// Add templatePackage keys/values to appPackage, replacing existing entries
|
||||
templatePackageToReplace.forEach(key => {
|
||||
appPackage[key] = templatePackage[key];
|
||||
});
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(appPath, 'package.json'),
|
||||
JSON.stringify(appPackage, null, 2) + os.EOL
|
||||
);
|
||||
|
||||
const readmeExists = fs.existsSync(path.join(appPath, 'README.md'));
|
||||
if (readmeExists) {
|
||||
fs.renameSync(
|
||||
path.join(appPath, 'README.md'),
|
||||
path.join(appPath, 'README.old.md')
|
||||
);
|
||||
}
|
||||
|
||||
// Copy the files for the user
|
||||
const templateDir = path.join(templatePath, 'template');
|
||||
if (fs.existsSync(templateDir)) {
|
||||
fs.copySync(templateDir, appPath);
|
||||
} else {
|
||||
console.error(
|
||||
`Could not locate supplied template: ${chalk.green(templateDir)}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// modifies README.md commands based on user used package manager.
|
||||
if (useYarn) {
|
||||
try {
|
||||
const readme = fs.readFileSync(path.join(appPath, 'README.md'), 'utf8');
|
||||
fs.writeFileSync(
|
||||
path.join(appPath, 'README.md'),
|
||||
readme.replace(/(npm run |npm )/g, 'yarn '),
|
||||
'utf8'
|
||||
);
|
||||
} catch (err) {
|
||||
// Silencing the error. As it fall backs to using default npm commands.
|
||||
}
|
||||
}
|
||||
|
||||
const gitignoreExists = fs.existsSync(path.join(appPath, '.gitignore'));
|
||||
if (gitignoreExists) {
|
||||
// Append if there's already a `.gitignore` file there
|
||||
const data = fs.readFileSync(path.join(appPath, 'gitignore'));
|
||||
fs.appendFileSync(path.join(appPath, '.gitignore'), data);
|
||||
fs.unlinkSync(path.join(appPath, 'gitignore'));
|
||||
} else {
|
||||
// Rename gitignore after the fact to prevent npm from renaming it to .npmignore
|
||||
// See: https://github.com/npm/npm/issues/1862
|
||||
fs.moveSync(
|
||||
path.join(appPath, 'gitignore'),
|
||||
path.join(appPath, '.gitignore'),
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
// Initialize git repo
|
||||
let initializedGit = false;
|
||||
|
||||
if (tryGitInit()) {
|
||||
initializedGit = true;
|
||||
console.log();
|
||||
console.log('Initialized a git repository.');
|
||||
}
|
||||
|
||||
let command;
|
||||
let remove;
|
||||
let args;
|
||||
|
||||
if (useYarn) {
|
||||
command = 'yarnpkg';
|
||||
remove = 'remove';
|
||||
args = ['add'];
|
||||
} else {
|
||||
command = 'npm';
|
||||
remove = 'uninstall';
|
||||
args = ['install', '--save', verbose && '--verbose'].filter(e => e);
|
||||
}
|
||||
|
||||
// Install additional template dependencies, if present.
|
||||
const dependenciesToInstall = Object.entries({
|
||||
...templatePackage.dependencies,
|
||||
...templatePackage.devDependencies,
|
||||
});
|
||||
if (dependenciesToInstall.length) {
|
||||
args = args.concat(
|
||||
dependenciesToInstall.map(([dependency, version]) => {
|
||||
return `${dependency}@${version}`;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// Install react and react-dom for backward compatibility with old CRA cli
|
||||
// which doesn't install react and react-dom along with react-scripts
|
||||
if (!isReactInstalled(appPackage)) {
|
||||
args = args.concat(['react', 'react-dom']);
|
||||
}
|
||||
|
||||
// Install template dependencies, and react and react-dom if missing.
|
||||
if ((!isReactInstalled(appPackage) || templateName) && args.length > 1) {
|
||||
console.log();
|
||||
console.log(`Installing template dependencies using ${command}...`);
|
||||
|
||||
const proc = spawn.sync(command, args, { stdio: 'inherit' });
|
||||
if (proc.status !== 0) {
|
||||
console.error(`\`${command} ${args.join(' ')}\` failed`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.find(arg => arg.includes('typescript'))) {
|
||||
console.log();
|
||||
verifyTypeScriptSetup();
|
||||
}
|
||||
|
||||
// Remove template
|
||||
console.log(`Removing template package using ${command}...`);
|
||||
console.log();
|
||||
|
||||
const proc = spawn.sync(command, [remove, templateName], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
if (proc.status !== 0) {
|
||||
console.error(`\`${command} ${args.join(' ')}\` failed`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create git commit if git repo was initialized
|
||||
if (initializedGit && tryGitCommit(appPath)) {
|
||||
console.log();
|
||||
console.log('Created git commit.');
|
||||
}
|
||||
|
||||
// Display the most elegant way to cd.
|
||||
// This needs to handle an undefined originalDirectory for
|
||||
// backward compatibility with old global-cli's.
|
||||
let cdpath;
|
||||
if (originalDirectory && path.join(originalDirectory, appName) === appPath) {
|
||||
cdpath = appName;
|
||||
} else {
|
||||
cdpath = appPath;
|
||||
}
|
||||
|
||||
// Change displayed command to yarn instead of yarnpkg
|
||||
const displayedCommand = useYarn ? 'yarn' : 'npm';
|
||||
|
||||
console.log();
|
||||
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(' Starts the development server.');
|
||||
console.log();
|
||||
console.log(
|
||||
chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'run '}build`)
|
||||
);
|
||||
console.log(' Bundles the app into static files for production.');
|
||||
console.log();
|
||||
console.log(chalk.cyan(` ${displayedCommand} test`));
|
||||
console.log(' Starts the test runner.');
|
||||
console.log();
|
||||
console.log(
|
||||
chalk.cyan(` ${displayedCommand} ${useYarn ? '' : '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`)}`);
|
||||
if (readmeExists) {
|
||||
console.log();
|
||||
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) {
|
||||
const dependencies = appPackage.dependencies || {};
|
||||
|
||||
return (
|
||||
typeof dependencies.react !== 'undefined' &&
|
||||
typeof dependencies['react-dom'] !== 'undefined'
|
||||
);
|
||||
}
|
182
web/node_modules/react-scripts/scripts/start.js
generated
vendored
Normal file
182
web/node_modules/react-scripts/scripts/start.js
generated
vendored
Normal file
|
@ -0,0 +1,182 @@
|
|||
// @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 semver = require('semver');
|
||||
const paths = require('../config/paths');
|
||||
const configFactory = require('../config/webpack.config');
|
||||
const createDevServerConfig = require('../config/webpackDevServer.config');
|
||||
const getClientEnvironment = require('../config/env');
|
||||
const react = require(require.resolve('react', { paths: [paths.appPath] }));
|
||||
|
||||
const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
|
||||
const useYarn = fs.existsSync(paths.yarnLockFile);
|
||||
const isInteractive = process.stdout.isTTY;
|
||||
|
||||
// Warn and crash if required files are missing
|
||||
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Tools like Cloud9 rely on this.
|
||||
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
|
||||
const HOST = process.env.HOST || '0.0.0.0';
|
||||
|
||||
if (process.env.HOST) {
|
||||
console.log(
|
||||
chalk.cyan(
|
||||
`Attempting to bind to HOST environment variable: ${chalk.yellow(
|
||||
chalk.bold(process.env.HOST)
|
||||
)}`
|
||||
)
|
||||
);
|
||||
console.log(
|
||||
`If this was unintentional, check that you haven't mistakenly set it in your shell.`
|
||||
);
|
||||
console.log(
|
||||
`Learn more here: ${chalk.yellow('https://cra.link/advanced-config')}`
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
|
||||
// We require that you explicitly set browsers and do not fall back to
|
||||
// browserslist defaults.
|
||||
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
|
||||
checkBrowsers(paths.appPath, isInteractive)
|
||||
.then(() => {
|
||||
// We attempt to use the default port but if it is busy, we offer the user to
|
||||
// run on a different port. `choosePort()` Promise resolves to the next free port.
|
||||
return choosePort(HOST, DEFAULT_PORT);
|
||||
})
|
||||
.then(port => {
|
||||
if (port == null) {
|
||||
// We have not found a port.
|
||||
return;
|
||||
}
|
||||
|
||||
const config = configFactory('development');
|
||||
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
|
||||
const appName = require(paths.appPackageJson).name;
|
||||
|
||||
const useTypeScript = fs.existsSync(paths.appTsConfig);
|
||||
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
|
||||
const urls = prepareUrls(
|
||||
protocol,
|
||||
HOST,
|
||||
port,
|
||||
paths.publicUrlOrPath.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,
|
||||
tscCompileOnError,
|
||||
webpack,
|
||||
});
|
||||
// Load proxy config
|
||||
const proxySetting = require(paths.appPackageJson).proxy;
|
||||
const proxyConfig = prepareProxy(
|
||||
proxySetting,
|
||||
paths.appPublic,
|
||||
paths.publicUrlOrPath
|
||||
);
|
||||
// Serve webpack assets generated by the compiler over a web server.
|
||||
const serverConfig = createDevServerConfig(
|
||||
proxyConfig,
|
||||
urls.lanUrlForConfig
|
||||
);
|
||||
const devServer = new WebpackDevServer(compiler, serverConfig);
|
||||
// Launch WebpackDevServer.
|
||||
devServer.listen(port, HOST, err => {
|
||||
if (err) {
|
||||
return console.log(err);
|
||||
}
|
||||
if (isInteractive) {
|
||||
clearConsole();
|
||||
}
|
||||
|
||||
if (env.raw.FAST_REFRESH && semver.lt(react.version, '16.10.0')) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
`Fast Refresh requires React 16.10 or higher. You are using React ${react.version}.`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
console.log(chalk.cyan('Starting the development server...\n'));
|
||||
openBrowser(urls.localUrlForBrowser);
|
||||
});
|
||||
|
||||
['SIGINT', 'SIGTERM'].forEach(function (sig) {
|
||||
process.on(sig, function () {
|
||||
devServer.close();
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
|
||||
if (process.env.CI !== 'true') {
|
||||
// Gracefully exit when stdin ends
|
||||
process.stdin.on('end', function () {
|
||||
devServer.close();
|
||||
process.exit();
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
if (err && err.message) {
|
||||
console.log(err.message);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
138
web/node_modules/react-scripts/scripts/test.js
generated
vendored
Normal file
138
web/node_modules/react-scripts/scripts/test.js
generated
vendored
Normal file
|
@ -0,0 +1,138 @@
|
|||
// @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 = 'test';
|
||||
process.env.NODE_ENV = 'test';
|
||||
process.env.PUBLIC_URL = '';
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
// ignoring them. In the future, promise rejections that are not handled will
|
||||
// terminate the Node.js process with a non-zero exit code.
|
||||
process.on('unhandledRejection', err => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
// Ensure environment variables are read.
|
||||
require('../config/env');
|
||||
// @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 jest = require('jest');
|
||||
const execSync = require('child_process').execSync;
|
||||
let argv = process.argv.slice(2);
|
||||
|
||||
function isInGitRepository() {
|
||||
try {
|
||||
execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isInMercurialRepository() {
|
||||
try {
|
||||
execSync('hg --cwd . root', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Watch unless on CI or explicitly running all tests
|
||||
if (
|
||||
!process.env.CI &&
|
||||
argv.indexOf('--watchAll') === -1 &&
|
||||
argv.indexOf('--watchAll=false') === -1
|
||||
) {
|
||||
// https://github.com/facebook/create-react-app/issues/5210
|
||||
const hasSourceControl = isInGitRepository() || isInMercurialRepository();
|
||||
argv.push(hasSourceControl ? '--watch' : '--watchAll');
|
||||
}
|
||||
|
||||
// @remove-on-eject-begin
|
||||
// This is not necessary after eject because we embed config into package.json.
|
||||
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
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// This is a very dirty workaround for https://github.com/facebook/jest/issues/5913.
|
||||
// We're trying to resolve the environment ourselves because Jest does it incorrectly.
|
||||
// TODO: remove this as soon as it's fixed in Jest.
|
||||
const resolve = require('resolve');
|
||||
function resolveJestDefaultEnvironment(name) {
|
||||
const jestDir = path.dirname(
|
||||
resolve.sync('jest', {
|
||||
basedir: __dirname,
|
||||
})
|
||||
);
|
||||
const jestCLIDir = path.dirname(
|
||||
resolve.sync('jest-cli', {
|
||||
basedir: jestDir,
|
||||
})
|
||||
);
|
||||
const jestConfigDir = path.dirname(
|
||||
resolve.sync('jest-config', {
|
||||
basedir: jestCLIDir,
|
||||
})
|
||||
);
|
||||
return resolve.sync(name, {
|
||||
basedir: jestConfigDir,
|
||||
});
|
||||
}
|
||||
let cleanArgv = [];
|
||||
let env = 'jsdom';
|
||||
let next;
|
||||
do {
|
||||
next = argv.shift();
|
||||
if (next === '--env') {
|
||||
env = argv.shift();
|
||||
} else if (next.indexOf('--env=') === 0) {
|
||||
env = next.substring('--env='.length);
|
||||
} else {
|
||||
cleanArgv.push(next);
|
||||
}
|
||||
} while (argv.length > 0);
|
||||
argv = cleanArgv;
|
||||
let resolvedEnv;
|
||||
try {
|
||||
resolvedEnv = resolveJestDefaultEnvironment(`jest-environment-${env}`);
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
if (!resolvedEnv) {
|
||||
try {
|
||||
resolvedEnv = resolveJestDefaultEnvironment(env);
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
const testEnvironment = resolvedEnv || env;
|
||||
argv.push('--env', testEnvironment);
|
||||
// @remove-on-eject-end
|
||||
jest.run(argv);
|
153
web/node_modules/react-scripts/scripts/utils/createJestConfig.js
generated
vendored
Normal file
153
web/node_modules/react-scripts/scripts/utils/createJestConfig.js
generated
vendored
Normal file
|
@ -0,0 +1,153 @@
|
|||
// @remove-file-on-eject
|
||||
/**
|
||||
* 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 fs = require('fs');
|
||||
const chalk = require('react-dev-utils/chalk');
|
||||
const paths = require('../../config/paths');
|
||||
const modules = require('../../config/modules');
|
||||
|
||||
module.exports = (resolve, rootDir, isEjecting) => {
|
||||
// Use this instead of `paths.testsSetup` to avoid putting
|
||||
// an absolute filename into configuration after ejecting.
|
||||
const setupTestsMatches = paths.testsSetup.match(/src[/\\]setupTests\.(.+)/);
|
||||
const setupTestsFileExtension =
|
||||
(setupTestsMatches && setupTestsMatches[1]) || 'js';
|
||||
const setupTestsFile = fs.existsSync(paths.testsSetup)
|
||||
? `<rootDir>/src/setupTests.${setupTestsFileExtension}`
|
||||
: undefined;
|
||||
|
||||
const config = {
|
||||
roots: ['<rootDir>/src'],
|
||||
|
||||
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}', '!src/**/*.d.ts'],
|
||||
|
||||
setupFiles: [
|
||||
isEjecting
|
||||
? 'react-app-polyfill/jsdom'
|
||||
: require.resolve('react-app-polyfill/jsdom'),
|
||||
],
|
||||
|
||||
setupFilesAfterEnv: setupTestsFile ? [setupTestsFile] : [],
|
||||
testMatch: [
|
||||
'<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}',
|
||||
'<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}',
|
||||
],
|
||||
testEnvironment: 'jsdom',
|
||||
testRunner: require.resolve('jest-circus/runner'),
|
||||
transform: {
|
||||
'^.+\\.(js|jsx|mjs|cjs|ts|tsx)$': resolve(
|
||||
'config/jest/babelTransform.js'
|
||||
),
|
||||
'^.+\\.css$': resolve('config/jest/cssTransform.js'),
|
||||
'^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)': resolve(
|
||||
'config/jest/fileTransform.js'
|
||||
),
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
'[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$',
|
||||
'^.+\\.module\\.(css|sass|scss)$',
|
||||
],
|
||||
modulePaths: modules.additionalModulePaths || [],
|
||||
moduleNameMapper: {
|
||||
'^react-native$': 'react-native-web',
|
||||
'^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
|
||||
...(modules.jestAliases || {}),
|
||||
},
|
||||
moduleFileExtensions: [...paths.moduleFileExtensions, 'node'].filter(
|
||||
ext => !ext.includes('mjs')
|
||||
),
|
||||
watchPlugins: [
|
||||
'jest-watch-typeahead/filename',
|
||||
'jest-watch-typeahead/testname',
|
||||
],
|
||||
resetMocks: true,
|
||||
};
|
||||
if (rootDir) {
|
||||
config.rootDir = rootDir;
|
||||
}
|
||||
const overrides = Object.assign({}, require(paths.appPackageJson).jest);
|
||||
const supportedKeys = [
|
||||
'clearMocks',
|
||||
'collectCoverageFrom',
|
||||
'coveragePathIgnorePatterns',
|
||||
'coverageReporters',
|
||||
'coverageThreshold',
|
||||
'displayName',
|
||||
'extraGlobals',
|
||||
'globalSetup',
|
||||
'globalTeardown',
|
||||
'moduleNameMapper',
|
||||
'resetMocks',
|
||||
'resetModules',
|
||||
'restoreMocks',
|
||||
'snapshotSerializers',
|
||||
'testMatch',
|
||||
'transform',
|
||||
'transformIgnorePatterns',
|
||||
'watchPathIgnorePatterns',
|
||||
];
|
||||
if (overrides) {
|
||||
supportedKeys.forEach(key => {
|
||||
if (Object.prototype.hasOwnProperty.call(overrides, key)) {
|
||||
if (Array.isArray(config[key]) || typeof config[key] !== 'object') {
|
||||
// for arrays or primitive types, directly override the config key
|
||||
config[key] = overrides[key];
|
||||
} else {
|
||||
// for object types, extend gracefully
|
||||
config[key] = Object.assign({}, config[key], overrides[key]);
|
||||
}
|
||||
|
||||
delete overrides[key];
|
||||
}
|
||||
});
|
||||
const unsupportedKeys = Object.keys(overrides);
|
||||
if (unsupportedKeys.length) {
|
||||
const isOverridingSetupFile =
|
||||
unsupportedKeys.indexOf('setupFilesAfterEnv') > -1;
|
||||
|
||||
if (isOverridingSetupFile) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
'We detected ' +
|
||||
chalk.bold('setupFilesAfterEnv') +
|
||||
' in your package.json.\n\n' +
|
||||
'Remove it from Jest configuration, and put the initialization code in ' +
|
||||
chalk.bold('src/setupTests.js') +
|
||||
'.\nThis file will be loaded automatically.\n'
|
||||
)
|
||||
);
|
||||
} else {
|
||||
console.error(
|
||||
chalk.red(
|
||||
'\nOut of the box, Create React App only supports overriding ' +
|
||||
'these Jest options:\n\n' +
|
||||
supportedKeys
|
||||
.map(key => chalk.bold(' \u2022 ' + key))
|
||||
.join('\n') +
|
||||
'.\n\n' +
|
||||
'These options in your package.json Jest configuration ' +
|
||||
'are not currently supported by Create React App:\n\n' +
|
||||
unsupportedKeys
|
||||
.map(key => chalk.bold(' \u2022 ' + key))
|
||||
.join('\n') +
|
||||
'\n\nIf you wish to override other Jest options, you need to ' +
|
||||
'eject from the default setup. You can do so by running ' +
|
||||
chalk.bold('npm run eject') +
|
||||
' but remember that this is a one-way operation. ' +
|
||||
'You may also file an issue with Create React App to discuss ' +
|
||||
'supporting more options out of the box.\n'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
return config;
|
||||
};
|
163
web/node_modules/react-scripts/scripts/utils/verifyPackageTree.js
generated
vendored
Normal file
163
web/node_modules/react-scripts/scripts/utils/verifyPackageTree.js
generated
vendored
Normal file
|
@ -0,0 +1,163 @@
|
|||
// @remove-file-on-eject
|
||||
/**
|
||||
* 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 chalk = require('react-dev-utils/chalk');
|
||||
const fs = require('fs');
|
||||
const semver = require('semver');
|
||||
const path = require('path');
|
||||
|
||||
// We assume that having wrong versions of these
|
||||
// in the tree will likely break your setup.
|
||||
// This is a relatively low-effort way to find common issues.
|
||||
function verifyPackageTree() {
|
||||
const depsToCheck = [
|
||||
// These are packages most likely to break in practice.
|
||||
// See https://github.com/facebook/create-react-app/issues/1795 for reasons why.
|
||||
// I have not included Babel here because plugins typically don't import Babel (so it's not affected).
|
||||
'babel-eslint',
|
||||
'babel-jest',
|
||||
'babel-loader',
|
||||
'eslint',
|
||||
'jest',
|
||||
'webpack',
|
||||
'webpack-dev-server',
|
||||
];
|
||||
// Inlined from semver-regex, MIT license.
|
||||
// Don't want to make this a dependency after ejecting.
|
||||
const getSemverRegex = () =>
|
||||
/\bv?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?\b/gi;
|
||||
const ownPackageJson = require('../../package.json');
|
||||
const expectedVersionsByDep = {};
|
||||
// Gather wanted deps
|
||||
depsToCheck.forEach(dep => {
|
||||
const expectedVersion = ownPackageJson.dependencies[dep];
|
||||
if (!expectedVersion) {
|
||||
throw new Error('This dependency list is outdated, fix it.');
|
||||
}
|
||||
if (!getSemverRegex().test(expectedVersion)) {
|
||||
throw new Error(
|
||||
`The ${dep} package should be pinned, instead got version ${expectedVersion}.`
|
||||
);
|
||||
}
|
||||
expectedVersionsByDep[dep] = expectedVersion;
|
||||
});
|
||||
// Verify we don't have other versions up the tree
|
||||
let currentDir = __dirname;
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
const previousDir = currentDir;
|
||||
currentDir = path.resolve(currentDir, '..');
|
||||
if (currentDir === previousDir) {
|
||||
// We've reached the root.
|
||||
break;
|
||||
}
|
||||
const maybeNodeModules = path.resolve(currentDir, 'node_modules');
|
||||
if (!fs.existsSync(maybeNodeModules)) {
|
||||
continue;
|
||||
}
|
||||
depsToCheck.forEach(dep => {
|
||||
const maybeDep = path.resolve(maybeNodeModules, dep);
|
||||
if (!fs.existsSync(maybeDep)) {
|
||||
return;
|
||||
}
|
||||
const maybeDepPackageJson = path.resolve(maybeDep, 'package.json');
|
||||
if (!fs.existsSync(maybeDepPackageJson)) {
|
||||
return;
|
||||
}
|
||||
const depPackageJson = JSON.parse(
|
||||
fs.readFileSync(maybeDepPackageJson, 'utf8')
|
||||
);
|
||||
const expectedVersion = expectedVersionsByDep[dep];
|
||||
if (!semver.satisfies(depPackageJson.version, expectedVersion)) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
`\nThere might be a problem with the project dependency tree.\n` +
|
||||
`It is likely ${chalk.bold(
|
||||
'not'
|
||||
)} a bug in Create React App, but something you need to fix locally.\n\n`
|
||||
) +
|
||||
`The ${chalk.bold(
|
||||
ownPackageJson.name
|
||||
)} package provided by Create React App requires a dependency:\n\n` +
|
||||
chalk.green(
|
||||
` "${chalk.bold(dep)}": "${chalk.bold(expectedVersion)}"\n\n`
|
||||
) +
|
||||
`Don't try to install it manually: your package manager does it automatically.\n` +
|
||||
`However, a different version of ${chalk.bold(
|
||||
dep
|
||||
)} was detected higher up in the tree:\n\n` +
|
||||
` ${chalk.bold(chalk.red(maybeDep))} (version: ${chalk.bold(
|
||||
chalk.red(depPackageJson.version)
|
||||
)}) \n\n` +
|
||||
`Manually installing incompatible versions is known to cause hard-to-debug issues.\n\n` +
|
||||
chalk.red(
|
||||
`If you would prefer to ignore this check, add ${chalk.bold(
|
||||
'SKIP_PREFLIGHT_CHECK=true'
|
||||
)} to an ${chalk.bold('.env')} file in your project.\n` +
|
||||
`That will permanently disable this message but you might encounter other issues.\n\n`
|
||||
) +
|
||||
`To ${chalk.green(
|
||||
'fix'
|
||||
)} the dependency tree, try following the steps below in the exact order:\n\n` +
|
||||
` ${chalk.cyan('1.')} Delete ${chalk.bold(
|
||||
'package-lock.json'
|
||||
)} (${chalk.underline('not')} ${chalk.bold(
|
||||
'package.json'
|
||||
)}!) and/or ${chalk.bold('yarn.lock')} in your project folder.\n` +
|
||||
` ${chalk.cyan('2.')} Delete ${chalk.bold(
|
||||
'node_modules'
|
||||
)} in your project folder.\n` +
|
||||
` ${chalk.cyan('3.')} Remove "${chalk.bold(
|
||||
dep
|
||||
)}" from ${chalk.bold('dependencies')} and/or ${chalk.bold(
|
||||
'devDependencies'
|
||||
)} in the ${chalk.bold(
|
||||
'package.json'
|
||||
)} file in your project folder.\n` +
|
||||
` ${chalk.cyan('4.')} Run ${chalk.bold(
|
||||
'npm install'
|
||||
)} or ${chalk.bold(
|
||||
'yarn'
|
||||
)}, depending on the package manager you use.\n\n` +
|
||||
`In most cases, this should be enough to fix the problem.\n` +
|
||||
`If this has not helped, there are a few other things you can try:\n\n` +
|
||||
` ${chalk.cyan('5.')} If you used ${chalk.bold(
|
||||
'npm'
|
||||
)}, install ${chalk.bold(
|
||||
'yarn'
|
||||
)} (http://yarnpkg.com/) and repeat the above steps with it instead.\n` +
|
||||
` This may help because npm has known issues with package hoisting which may get resolved in future versions.\n\n` +
|
||||
` ${chalk.cyan('6.')} Check if ${chalk.bold(
|
||||
maybeDep
|
||||
)} is outside your project directory.\n` +
|
||||
` For example, you might have accidentally installed something in your home folder.\n\n` +
|
||||
` ${chalk.cyan('7.')} Try running ${chalk.bold(
|
||||
`npm ls ${dep}`
|
||||
)} in your project folder.\n` +
|
||||
` This will tell you which ${chalk.underline(
|
||||
'other'
|
||||
)} package (apart from the expected ${chalk.bold(
|
||||
ownPackageJson.name
|
||||
)}) installed ${chalk.bold(dep)}.\n\n` +
|
||||
`If nothing else helps, add ${chalk.bold(
|
||||
'SKIP_PREFLIGHT_CHECK=true'
|
||||
)} to an ${chalk.bold('.env')} file in your project.\n` +
|
||||
`That would permanently disable this preflight check in case you want to proceed anyway.\n\n` +
|
||||
chalk.cyan(
|
||||
`P.S. We know this message is long but please read the steps above :-) We hope you find them helpful!\n`
|
||||
)
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = verifyPackageTree;
|
298
web/node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js
generated
vendored
Normal file
298
web/node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js
generated
vendored
Normal file
|
@ -0,0 +1,298 @@
|
|||
// @remove-file-on-eject
|
||||
/**
|
||||
* 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 chalk = require('react-dev-utils/chalk');
|
||||
const fs = require('fs');
|
||||
const resolve = require('resolve');
|
||||
const path = require('path');
|
||||
const paths = require('../../config/paths');
|
||||
const os = require('os');
|
||||
const semver = require('semver');
|
||||
const immer = require('react-dev-utils/immer').produce;
|
||||
const globby = require('react-dev-utils/globby').sync;
|
||||
|
||||
const hasJsxRuntime = (() => {
|
||||
if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
require.resolve('react/jsx-runtime', { paths: [paths.appPath] });
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
})();
|
||||
|
||||
function writeJson(fileName, object) {
|
||||
fs.writeFileSync(
|
||||
fileName,
|
||||
JSON.stringify(object, null, 2).replace(/\n/g, os.EOL) + os.EOL
|
||||
);
|
||||
}
|
||||
|
||||
function verifyNoTypeScript() {
|
||||
const typescriptFiles = globby(
|
||||
['**/*.(ts|tsx)', '!**/node_modules', '!**/*.d.ts'],
|
||||
{ cwd: paths.appSrc }
|
||||
);
|
||||
if (typescriptFiles.length > 0) {
|
||||
console.warn(
|
||||
chalk.yellow(
|
||||
`We detected TypeScript in your project (${chalk.bold(
|
||||
`src${path.sep}${typescriptFiles[0]}`
|
||||
)}) and created a ${chalk.bold('tsconfig.json')} file for you.`
|
||||
)
|
||||
);
|
||||
console.warn();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function verifyTypeScriptSetup() {
|
||||
let firstTimeSetup = false;
|
||||
|
||||
if (!fs.existsSync(paths.appTsConfig)) {
|
||||
if (verifyNoTypeScript()) {
|
||||
return;
|
||||
}
|
||||
writeJson(paths.appTsConfig, {});
|
||||
firstTimeSetup = true;
|
||||
}
|
||||
|
||||
const isYarn = fs.existsSync(paths.yarnLockFile);
|
||||
|
||||
// Ensure typescript is installed
|
||||
let ts;
|
||||
try {
|
||||
// TODO: Remove this hack once `globalThis` issue is resolved
|
||||
// https://github.com/jsdom/jsdom/issues/2961
|
||||
const globalThisWasDefined = !!global.globalThis;
|
||||
|
||||
ts = require(resolve.sync('typescript', {
|
||||
basedir: paths.appNodeModules,
|
||||
}));
|
||||
|
||||
if (!globalThisWasDefined && !!global.globalThis) {
|
||||
delete global.globalThis;
|
||||
}
|
||||
} catch (_) {
|
||||
console.error(
|
||||
chalk.bold.red(
|
||||
`It looks like you're trying to use TypeScript but do not have ${chalk.bold(
|
||||
'typescript'
|
||||
)} installed.`
|
||||
)
|
||||
);
|
||||
console.error(
|
||||
chalk.bold(
|
||||
'Please install',
|
||||
chalk.cyan.bold('typescript'),
|
||||
'by running',
|
||||
chalk.cyan.bold(
|
||||
isYarn ? 'yarn add typescript' : 'npm install typescript'
|
||||
) + '.'
|
||||
)
|
||||
);
|
||||
console.error(
|
||||
chalk.bold(
|
||||
'If you are not trying to use TypeScript, please remove the ' +
|
||||
chalk.cyan('tsconfig.json') +
|
||||
' file from your package root (and any TypeScript files).'
|
||||
)
|
||||
);
|
||||
console.error();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const compilerOptions = {
|
||||
// These are suggested values and will be set when not present in the
|
||||
// tsconfig.json
|
||||
// 'parsedValue' matches the output value from ts.parseJsonConfigFileContent()
|
||||
target: {
|
||||
parsedValue: ts.ScriptTarget.ES5,
|
||||
suggested: 'es5',
|
||||
},
|
||||
lib: { suggested: ['dom', 'dom.iterable', 'esnext'] },
|
||||
allowJs: { suggested: true },
|
||||
skipLibCheck: { suggested: true },
|
||||
esModuleInterop: { suggested: true },
|
||||
allowSyntheticDefaultImports: { suggested: true },
|
||||
strict: { suggested: true },
|
||||
forceConsistentCasingInFileNames: { suggested: true },
|
||||
noFallthroughCasesInSwitch: { suggested: true },
|
||||
|
||||
// These values are required and cannot be changed by the user
|
||||
// Keep this in sync with the webpack config
|
||||
module: {
|
||||
parsedValue: ts.ModuleKind.ESNext,
|
||||
value: 'esnext',
|
||||
reason: 'for import() and import/export',
|
||||
},
|
||||
moduleResolution: {
|
||||
parsedValue: ts.ModuleResolutionKind.NodeJs,
|
||||
value: 'node',
|
||||
reason: 'to match webpack resolution',
|
||||
},
|
||||
resolveJsonModule: { value: true, reason: 'to match webpack loader' },
|
||||
isolatedModules: { value: true, reason: 'implementation limitation' },
|
||||
noEmit: { value: true },
|
||||
jsx: {
|
||||
parsedValue:
|
||||
hasJsxRuntime && semver.gte(ts.version, '4.1.0-beta')
|
||||
? ts.JsxEmit.ReactJSX
|
||||
: ts.JsxEmit.React,
|
||||
value:
|
||||
hasJsxRuntime && semver.gte(ts.version, '4.1.0-beta')
|
||||
? 'react-jsx'
|
||||
: 'react',
|
||||
reason: 'to support the new JSX transform in React 17',
|
||||
},
|
||||
paths: { value: undefined, reason: 'aliased imports are not supported' },
|
||||
};
|
||||
|
||||
const formatDiagnosticHost = {
|
||||
getCanonicalFileName: fileName => fileName,
|
||||
getCurrentDirectory: ts.sys.getCurrentDirectory,
|
||||
getNewLine: () => os.EOL,
|
||||
};
|
||||
|
||||
const messages = [];
|
||||
let appTsConfig;
|
||||
let parsedTsConfig;
|
||||
let parsedCompilerOptions;
|
||||
try {
|
||||
const { config: readTsConfig, error } = ts.readConfigFile(
|
||||
paths.appTsConfig,
|
||||
ts.sys.readFile
|
||||
);
|
||||
|
||||
if (error) {
|
||||
throw new Error(ts.formatDiagnostic(error, formatDiagnosticHost));
|
||||
}
|
||||
|
||||
appTsConfig = readTsConfig;
|
||||
|
||||
// Get TS to parse and resolve any "extends"
|
||||
// Calling this function also mutates the tsconfig above,
|
||||
// adding in "include" and "exclude", but the compilerOptions remain untouched
|
||||
let result;
|
||||
parsedTsConfig = immer(readTsConfig, config => {
|
||||
result = ts.parseJsonConfigFileContent(
|
||||
config,
|
||||
ts.sys,
|
||||
path.dirname(paths.appTsConfig)
|
||||
);
|
||||
});
|
||||
|
||||
if (result.errors && result.errors.length) {
|
||||
throw new Error(
|
||||
ts.formatDiagnostic(result.errors[0], formatDiagnosticHost)
|
||||
);
|
||||
}
|
||||
|
||||
parsedCompilerOptions = result.options;
|
||||
} catch (e) {
|
||||
if (e && e.name === 'SyntaxError') {
|
||||
console.error(
|
||||
chalk.red.bold(
|
||||
'Could not parse',
|
||||
chalk.cyan('tsconfig.json') + '.',
|
||||
'Please make sure it contains syntactically correct JSON.'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
console.log(e && e.message ? `${e.message}` : '');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (appTsConfig.compilerOptions == null) {
|
||||
appTsConfig.compilerOptions = {};
|
||||
firstTimeSetup = true;
|
||||
}
|
||||
|
||||
for (const option of Object.keys(compilerOptions)) {
|
||||
const { parsedValue, value, suggested, reason } = compilerOptions[option];
|
||||
|
||||
const valueToCheck = parsedValue === undefined ? value : parsedValue;
|
||||
const coloredOption = chalk.cyan('compilerOptions.' + option);
|
||||
|
||||
if (suggested != null) {
|
||||
if (parsedCompilerOptions[option] === undefined) {
|
||||
appTsConfig = immer(appTsConfig, config => {
|
||||
config.compilerOptions[option] = suggested;
|
||||
});
|
||||
messages.push(
|
||||
`${coloredOption} to be ${chalk.bold(
|
||||
'suggested'
|
||||
)} value: ${chalk.cyan.bold(suggested)} (this can be changed)`
|
||||
);
|
||||
}
|
||||
} else if (parsedCompilerOptions[option] !== valueToCheck) {
|
||||
appTsConfig = immer(appTsConfig, config => {
|
||||
config.compilerOptions[option] = value;
|
||||
});
|
||||
messages.push(
|
||||
`${coloredOption} ${chalk.bold(
|
||||
valueToCheck == null ? 'must not' : 'must'
|
||||
)} be ${valueToCheck == null ? 'set' : chalk.cyan.bold(value)}` +
|
||||
(reason != null ? ` (${reason})` : '')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// tsconfig will have the merged "include" and "exclude" by this point
|
||||
if (parsedTsConfig.include == null) {
|
||||
appTsConfig = immer(appTsConfig, config => {
|
||||
config.include = ['src'];
|
||||
});
|
||||
messages.push(
|
||||
`${chalk.cyan('include')} should be ${chalk.cyan.bold('src')}`
|
||||
);
|
||||
}
|
||||
|
||||
if (messages.length > 0) {
|
||||
if (firstTimeSetup) {
|
||||
console.log(
|
||||
chalk.bold(
|
||||
'Your',
|
||||
chalk.cyan('tsconfig.json'),
|
||||
'has been populated with default values.'
|
||||
)
|
||||
);
|
||||
console.log();
|
||||
} else {
|
||||
console.warn(
|
||||
chalk.bold(
|
||||
'The following changes are being made to your',
|
||||
chalk.cyan('tsconfig.json'),
|
||||
'file:'
|
||||
)
|
||||
);
|
||||
messages.forEach(message => {
|
||||
console.warn(' - ' + message);
|
||||
});
|
||||
console.warn();
|
||||
}
|
||||
writeJson(paths.appTsConfig, appTsConfig);
|
||||
}
|
||||
|
||||
// Reference `react-scripts` types
|
||||
if (!fs.existsSync(paths.appTypeDeclarations)) {
|
||||
fs.writeFileSync(
|
||||
paths.appTypeDeclarations,
|
||||
`/// <reference types="react-scripts" />${os.EOL}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = verifyTypeScriptSetup;
|
Loading…
Add table
Add a link
Reference in a new issue