Skip to content

chore: release v0.6.0 #851

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Apr 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*dist/
*node_modules/
*umd/
*__tmp__

# Ignore examples because they might have custom ESLint configurations
Expand Down
1 change: 0 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
"globals": {
"__DEBUG__": true,
"WDS_VERSION": true,
"WEBPACK_VERSION": true,
"browser": true,
"window": true
},
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

# distribution
*dist
*umd

# misc
.DS_Store
Expand All @@ -19,6 +20,4 @@ yarn-error.log*
.vscode

# test artifacts
*.yalc
*__tmp__
yalc.lock
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*dist/
*node_modules/
*umd/
*__tmp__
File renamed without changes.
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,29 @@
## 0.6.0 (Unknown)

### BREAKING

- Minimum required Node.js version has been bumped to `18.12.0`.
- Minimum required `webpack` version has been bumped to `5.2.0`.
- Minimum supported `webpack-dev-server` version has been bumped to `4.8.0`.
- Minimum supported `webpack-plugin-serve` version has been bumped to `1.0.0`.
- `overlay.sockHost`, `overlay.sockPath`, `overlay.sockPort`, `overlay.sockProtocol` and `overlay.useURLPolyfill` have all been removed (#850).
It was necessary to support WDS below `4.8.0` (published in April 2022).
It is no-longer necessary as a direct integration with WDS is now possible.

### Features

- Added helper script to better support use cases where React and/or React-DOM are externalized (#852)

### Fixes

- Ensure plugin injected entries are no-op in production (#900)

### Internal

- Dropped support for Webpack 4 / WDS 3 (#850, #904)
- Migrated from `ansi-html` to `anser` in error overlay (#854)
- Bumped all development dependencies (#905)

## 0.5.16 (31 Mar 2025)

### Fixes
Expand Down
39 changes: 20 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
[![Latest Version][npm:latest:badge]][npm:latest]
[![Next Version][npm:next:badge]][npm:next]

An **EXPERIMENTAL** Webpack plugin to enable "Fast Refresh" (also known as _Hot Reloading_) for React components.
A Webpack plugin to enable "Fast Refresh" (also known as _Hot Reloading_) for React components.

> This plugin is not 100% stable.
> We're hoping to land a v1 release soon - please help us by reporting any issues you've encountered!

## Getting Started
Expand All @@ -28,23 +27,25 @@ and thus cannot be made compatible.

We recommend using the following versions:

| Dependency | Version |
| --------------- | ---------------------------- |
| `react` | `16.13.0`+, `17.x` or `18.x` |
| `react-dom` | `16.13.0`+, `17.x` or `18.x` |
| `react-refresh` | `0.10.0`+ |
| `webpack` | `4.46.0`+ or `5.2.0`+ |
| Dependency | Version |
| --------------- | ------------------------------------ |
| `Node.js` | `18.12.0`+, `20.x`, `22.x` |
| `react` | `16.13.0`+, `17.x`, `18.x` or `19.x` |
| `react-dom` | `16.13.0`+, `17.x`, `18.x` or `19.x |
| `react-refresh` | `0.10.0`+ |
| `webpack` | `5.2.0`+ |

<details>
<summary>Minimum requirements</summary>
<br />

| Dependency | Version |
| --------------- | -------- |
| `react` | `16.9.0` |
| `react-dom` | `16.9.0` |
| `react-refresh` | `0.10.0` |
| `webpack` | `4.43.0` |
| Dependency | Version |
| --------------- | --------- |
| `Node.js` | `18.12.0` |
| `react` | `16.9.0` |
| `react-dom` | `16.9.0` |
| `react-refresh` | `0.10.0` |
| `webpack` | `5.2.0` |

</details>

Expand Down Expand Up @@ -319,11 +320,11 @@ but you can set the [`overlay.sockIntegration`](docs/API.md#sockintegration) opt

The supported versions are as follows:

| Dependency | Version |
| ------------------------ | -------------------------- |
| `webpack-dev-server` | `3.6.0`+ or `4.x` or `5.x` |
| `webpack-hot-middleware` | `2.x` |
| `webpack-plugin-serve` | `0.x` or `1.x` |
| Dependency | Version |
| ------------------------ | ----------------- |
| `webpack-dev-server` | `4.8.0`+ or `5.x` |
| `webpack-hot-middleware` | `2.x` |
| `webpack-plugin-serve` | `1.x` |

## API

Expand Down
175 changes: 89 additions & 86 deletions client/ErrorOverlayEntry.js
Original file line number Diff line number Diff line change
@@ -1,100 +1,103 @@
/* global __react_refresh_error_overlay__, __react_refresh_socket__, __resourceQuery */
/* global __react_refresh_error_overlay__, __react_refresh_socket__ */

const events = require('./utils/errorEventHandlers.js');
const formatWebpackErrors = require('./utils/formatWebpackErrors.js');
const runWithPatchedUrl = require('./utils/patchUrl.js');
const runWithRetry = require('./utils/retry.js');
if (process.env.NODE_ENV !== 'production') {
const events = require('./utils/errorEventHandlers.js');
const formatWebpackErrors = require('./utils/formatWebpackErrors.js');
const runWithRetry = require('./utils/retry.js');

// Setup error states
let isHotReload = false;
let hasRuntimeErrors = false;
// Setup error states
let isHotReload = false;
let hasRuntimeErrors = false;

/**
* Try dismissing the compile error overlay.
* This will also reset runtime error records (if any),
* because we have new source to evaluate.
* @returns {void}
*/
function tryDismissErrorOverlay() {
__react_refresh_error_overlay__.clearCompileError();
__react_refresh_error_overlay__.clearRuntimeErrors(!hasRuntimeErrors);
hasRuntimeErrors = false;
}
/**
* Try dismissing the compile error overlay.
* This will also reset runtime error records (if any),
* because we have new source to evaluate.
* @returns {void}
*/
const tryDismissErrorOverlay = function () {
__react_refresh_error_overlay__.clearCompileError();
__react_refresh_error_overlay__.clearRuntimeErrors(!hasRuntimeErrors);
hasRuntimeErrors = false;
};

/**
* A function called after a compile success signal is received from Webpack.
* @returns {void}
*/
function handleCompileSuccess() {
isHotReload = true;
/**
* A function called after a compile success signal is received from Webpack.
* @returns {void}
*/
const handleCompileSuccess = function () {
isHotReload = true;

if (isHotReload) {
tryDismissErrorOverlay();
}
}
if (isHotReload) {
tryDismissErrorOverlay();
}
};

/**
* A function called after a compile errored signal is received from Webpack.
* @param {string[]} errors
* @returns {void}
*/
function handleCompileErrors(errors) {
isHotReload = true;
/**
* A function called after a compile errored signal is received from Webpack.
* @param {string[]} errors
* @returns {void}
*/
const handleCompileErrors = function (errors) {
isHotReload = true;

const formattedErrors = formatWebpackErrors(errors);
const formattedErrors = formatWebpackErrors(errors);

// Only show the first error
__react_refresh_error_overlay__.showCompileError(formattedErrors[0]);
}
// Only show the first error
__react_refresh_error_overlay__.showCompileError(formattedErrors[0]);
};

/**
* Handles compilation messages from Webpack.
* Integrates with a compile error overlay.
* @param {*} message A Webpack HMR message sent via WebSockets.
* @returns {void}
*/
function compileMessageHandler(message) {
switch (message.type) {
case 'ok':
case 'still-ok':
case 'warnings': {
// TODO: Implement handling for warnings
handleCompileSuccess();
break;
}
case 'errors': {
handleCompileErrors(message.data);
break;
}
default: {
// Do nothing.
/**
* Handles compilation messages from Webpack.
* Integrates with a compile error overlay.
* @param {*} message A Webpack HMR message sent via WebSockets.
* @returns {void}
*/
const compileMessageHandler = function (message) {
switch (message.type) {
case 'ok':
case 'still-ok':
case 'warnings': {
// TODO: Implement handling for warnings
handleCompileSuccess();
break;
}
case 'errors': {
handleCompileErrors(message.data);
break;
}
default: {
// Do nothing.
}
}
}
}
};

if (process.env.NODE_ENV !== 'production') {
if (typeof window !== 'undefined') {
runWithPatchedUrl(function setupOverlay() {
// Only register if no other overlay have been registered
if (!window.__reactRefreshOverlayInjected && __react_refresh_socket__) {
// Registers handlers for compile errors with retry -
// This is to prevent mismatching injection order causing errors to be thrown
runWithRetry(function initSocket() {
__react_refresh_socket__.init(compileMessageHandler, __resourceQuery);
}, 3);
// Registers handlers for runtime errors
events.handleError(function handleError(error) {
hasRuntimeErrors = true;
__react_refresh_error_overlay__.handleRuntimeError(error);
});
events.handleUnhandledRejection(function handleUnhandledPromiseRejection(error) {
hasRuntimeErrors = true;
__react_refresh_error_overlay__.handleRuntimeError(error);
});

// Mark overlay as injected to prevent double-injection
window.__reactRefreshOverlayInjected = true;
}
// Only register if no other overlay have been registered
if (
typeof window !== 'undefined' &&
!window.__reactRefreshOverlayInjected &&
__react_refresh_socket__
) {
// Registers handlers for compile errors with retry -
// This is to prevent mismatching injection order causing errors to be thrown
runWithRetry(
function initSocket() {
__react_refresh_socket__.init(compileMessageHandler);
},
3,
'Failed to set up the socket connection.'
);
// Registers handlers for runtime errors
events.handleError(function handleError(error) {
hasRuntimeErrors = true;
__react_refresh_error_overlay__.handleRuntimeError(error);
});
events.handleUnhandledRejection(function handleUnhandledPromiseRejection(error) {
hasRuntimeErrors = true;
__react_refresh_error_overlay__.handleRuntimeError(error);
});

// Mark overlay as injected to prevent double-injection
window.__reactRefreshOverlayInjected = true;
}
}
6 changes: 3 additions & 3 deletions client/ReactRefreshEntry.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/* global __react_refresh_library__ */

const safeThis = require('core-js-pure/features/global-this');
const RefreshRuntime = require('react-refresh/runtime');

if (process.env.NODE_ENV !== 'production') {
const safeThis = require('core-js-pure/features/global-this');
const RefreshRuntime = require('react-refresh/runtime');

if (typeof safeThis !== 'undefined') {
var $RefreshInjected$ = '__reactRefreshInjected';
// Namespace the injected flag (if necessary) for monorepo compatibility
Expand Down
40 changes: 0 additions & 40 deletions client/utils/patchUrl.js

This file was deleted.

4 changes: 2 additions & 2 deletions client/utils/retry.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
function runWithRetry(callback, maxRetries) {
function runWithRetry(callback, maxRetries, message) {
function executeWithRetryAndTimeout(currentCount) {
try {
if (currentCount > maxRetries - 1) {
console.warn('[React Refresh] Failed to set up the socket connection.');
console.warn('[React Refresh]', message);
return;
}

Expand Down
Loading