mirror of
https://github.com/wassname/talk.git
synced 2026-06-27 19:01:24 +08:00
c9a0ab8848
* chore: upgrade fluent * chore: upgrade metascraper * chore: upgrade akismet-api * chore: upgrade apollo-server-express * chore: upgrade archiver * chore: upgrade bull * chore: upgrade express, cheerio, content-security-policy-builder * chore: upgrade convict * chore: upgrade cors, cron * chore: upgrade csv-stringify * chore: upgrade dompurify * chore: upgrade dotenv * chore: upgrade express-static-gzip * chore: upgrade fs-extra * chore: upgrade graphql-js * chore: upgrade graphql packages * chore: upgrade html-minifier * chore: upgrade html-to-text * chore: upgrade ioredis * chore: upgrade joi * chore: upgrade jsdom * chore: upgrade jsonwebtoken * chore: upgrade juice * chore: upgrade jwks-rsa ad linkifyjs * chore: upgrade lodash * chore: upgrade luxon * chore: upgrade metascraper * chore: upgrade mongodb * chore: upgrade ms * chore: upgrade node and node-fetch types * chore: upgrade nodemailer nunjucks and typescript-eslint * chore: Upgrade passport * upgrade: prom-client react-helmet source-map-support stack-utils * chore: upgrade uuid * chore: upgrade @babel packages * chore: upgrade types * chore: upgrade autoprefixer * chore: upgrade jest * chore: upgrade ts-jest * chore: remove linkify.d.ts * chore: upgrade bowser * chore: case-sensitive-paths-webpack-plugin * chore: upgrade classnames * chore: upgrade commander * chore: upgrade comment-json * chore: upgrade cross-spawn compression-webpack-plugin del * chore: upgrade build and watch related dependencies * chore: upgrade css-vars-ponyfill * chore: upgrade eslint and css-vars-ponyfill * chore: upgrade enzyme and eventemitter2 * fix: form bug * chore: upgrade farce * chore: upgrade final form * chore: upgrade react-popper * chore: upgrade flat and fork-ts-checker-webpack-plugin * chore: upgrade husky and gulp related, intersection observer * chore: upgrade lint-staged * chore: upgrade marked, loader-utils, mini-css-extract-plugin * chore: upgrade postcss-nested, proxy-polyfill, pstree.remy * chore: upgrade prettier * chore: fix prettier changes, upgrade react * chore: mute createFactory deprecated message * chore: upgrade react-copy-to-clipbard, react-axe, react-dom, react-test-renderer, react-timeago * chore: upgrade react-transistion-group, react-responsive * chore: upgrade types * chore: upgrade react-dev-utils, react-error-overlay regenerator-runtime * chore: upgrade types, sinon, sockjs-client, strip-ansi * chore: upgrade types, fonts * chore: upgrade nunjucks, ts-node, typescript-snapshot-plugin, wait-for-expect * chore: upgrade eslint packages * chore: upgrade fluent, types * chore: upgrade jsdom dep * chore: upgrade mongo * chore: upgrade deps * chore: upgrade typescript, recompose * chore: upgrade prettier * chore: remove obsolete prettier config * chore: upgrade jsdom types * chore: upgrade typescript-eslint * chore: upgrad deps * chore: upgrade deps * chore: upgrade relay related modules * chore: upgrade docz WIP * chore: upgrade docz * chore: add guard * chore: remove obsolete line * chore: comment * chore: refactors * fix: hook count change error
294 lines
8.6 KiB
JavaScript
294 lines
8.6 KiB
JavaScript
/**
|
|
* 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.
|
|
*
|
|
* This file is taken from create-react-app.
|
|
* We disabled tty support, removed unessential parts to us and
|
|
* added support for `warningsFilter` and Multi Webpack Config.
|
|
*
|
|
* TODO: (cvle) The `forkTsCheckerWebpackPlugin` hooks are not working atm.
|
|
*/
|
|
"use strict";
|
|
|
|
/* eslint-disable no-console */
|
|
|
|
const address = require("address");
|
|
const url = require("url");
|
|
const chalk = require("chalk");
|
|
const clearConsole = require("react-dev-utils/clearConsole");
|
|
const formatWebpackMessages = require("react-dev-utils/formatWebpackMessages");
|
|
const typescriptFormatter = require("react-dev-utils/typescriptFormatter");
|
|
const forkTsCheckerWebpackPlugin = require("react-dev-utils/ForkTsCheckerWebpackPlugin");
|
|
|
|
// (cvle): Changed to false as we are sharing the tty with other processes.
|
|
// const isInteractive = process.stdout.isTTY && false;
|
|
const isInteractive = false;
|
|
|
|
function prepareUrls(protocol, host, port) {
|
|
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;
|
|
let lanUrlForConfig;
|
|
let 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;
|
|
const tsMessagesPromises = [];
|
|
|
|
if (useTypeScript) {
|
|
compiler.compilers.forEach((singleCompiler) => {
|
|
let tsMessagesPromise;
|
|
let tsMessagesResolver;
|
|
singleCompiler.hooks.beforeCompile.tap("beforeCompile", () => {
|
|
tsMessagesPromise = new Promise((resolve) => {
|
|
tsMessagesResolver = (msgs) => resolve(msgs);
|
|
});
|
|
tsMessagesPromises.push(tsMessagesPromise);
|
|
});
|
|
|
|
const tsCheckerHooks = forkTsCheckerWebpackPlugin.getCompilerHooks(
|
|
singleCompiler
|
|
);
|
|
|
|
// now access hooks just like before
|
|
// TODO: (cvle) this doesn't work currently.
|
|
tsCheckerHooks.waiting.tap("yourListenerName", () => {
|
|
console.log("waiting for typecheck results");
|
|
});
|
|
|
|
// TODO: (cvle) this doesn't work currently.
|
|
tsCheckerHooks.receive.tap(
|
|
"afterTypeScriptCheck",
|
|
(diagnostics, lints) => {
|
|
console.log("RECEIVED");
|
|
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 statOptions = {
|
|
all: false,
|
|
warnings: true,
|
|
errors: true,
|
|
...config.stats,
|
|
};
|
|
if (Array.isArray(config)) {
|
|
statOptions.children = config.map((c) => c.stats || {});
|
|
}
|
|
const statsData = stats.toJson(statOptions);
|
|
|
|
if (useTypeScript && statsData.errors.length === 0) {
|
|
const delayedMsg = setTimeout(() => {
|
|
console.log(
|
|
chalk.yellow(
|
|
"Files successfully emitted, waiting for typecheck results..."
|
|
)
|
|
);
|
|
}, 100);
|
|
|
|
// Get back all tscheck results.
|
|
const results = await Promise.all(tsMessagesPromises);
|
|
clearTimeout(delayedMsg);
|
|
|
|
results.forEach((msgs) => {
|
|
statsData.errors.push(...msgs.errors);
|
|
statsData.warnings.push(...msgs.warnings);
|
|
|
|
// Push errors and warnings into compilation result
|
|
// to show them after page refresh triggered by user.
|
|
stats.compilation.errors.push(...msgs.errors);
|
|
stats.compilation.warnings.push(...msgs.warnings);
|
|
|
|
if (msgs.errors.length > 0) {
|
|
devSocket.errors(msgs.errors);
|
|
} else if (msgs.warnings.length > 0) {
|
|
devSocket.warnings(msgs.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"
|
|
);
|
|
}
|
|
});
|
|
|
|
return compiler;
|
|
}
|
|
|
|
module.exports = {
|
|
createCompiler,
|
|
prepareUrls,
|
|
};
|