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