Socket
Socket
Sign inDemoInstall

@pmmmwh/react-refresh-webpack-plugin

Package Overview
Dependencies
25
Maintainers
1
Versions
62
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.3.0-beta.0 to 0.3.0-beta.1

src/loader/index.js

22

package.json
{
"name": "@pmmmwh/react-refresh-webpack-plugin",
"version": "0.3.0-beta.0",
"version": "0.3.0-beta.1",
"description": "An **EXPERIMENTAL** Webpack plugin to enable \"Fast Refresh\" (also previously known as _Hot Reloading_) for React components.",

@@ -35,22 +35,22 @@ "keywords": [

"lint:fix": "yarn lint --fix",
"format": "prettier --write \"**/*.{js,jsx,json,md}\"",
"format:check": "prettier --check \"**/*.{js,jsx,json,md}\""
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,md}\""
},
"dependencies": {
"ansi-html": "^0.0.7",
"error-stack-parser": "^2.0.4",
"error-stack-parser": "^2.0.6",
"html-entities": "^1.2.1",
"lodash.debounce": "^4.0.8",
"react-dev-utils": "^9.1.0"
"native-url": "^0.2.6"
},
"devDependencies": {
"eslint": "^6.7.2",
"eslint-config-prettier": "^6.7.0",
"prettier": "^1.18.2",
"react-refresh": "^0.7.0",
"webpack": "^4.41.2",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"prettier": "^2.0.2",
"react-refresh": "^0.8.1",
"webpack": "^4.42.1",
"webpack-hot-middleware": "^2.25.0"
},
"peerDependencies": {
"react-refresh": ">= 0.7",
"react-refresh": "^0.8.1",
"sockjs-client": "^1.4.0",

@@ -57,0 +57,0 @@ "webpack-hot-middleware": "^2.25.0"

# React Refresh Webpack Plugin
[![NPM Version](https://img.shields.io/npm/v/@pmmmwh/react-refresh-webpack-plugin)](https://www.npmjs.com/package/@pmmmwh/react-refresh-webpack-plugin)
[![Latest Version](https://img.shields.io/npm/v/@pmmmwh/react-refresh-webpack-plugin/latest)](https://www.npmjs.com/package/@pmmmwh/react-refresh-webpack-plugin/v/latest)
[![Next Version](https://img.shields.io/npm/v/@pmmmwh/react-refresh-webpack-plugin/next)](https://www.npmjs.com/package/@pmmmwh/react-refresh-webpack-plugin/v/next)
[![License](https://img.shields.io/github/license/pmmmwh/react-refresh-webpack-plugin)](./LICENSE)

@@ -91,3 +92,3 @@

```js
module.exports = api => {
module.exports = (api) => {
// This caches the Babel config by environment.

@@ -106,14 +107,36 @@ api.cache.using(() => process.env.NODE_ENV);

## Options
More sample projects for common Webpack development setups are available in the [examples](https://github.com/pmmmwh/react-refresh-webpack-plugin/tree/master/examples) folder.
This plugin accepts a few options that are specifically targeted for advanced users.
> Note: If you are using TypeScript (instead of Babel) as a transpiler, you will still need to use `babel-loader` to process your source code.
> Check out this [sample project](https://github.com/pmmmwh/react-refresh-webpack-plugin/tree/master/examples/typescript-without-babel) on how to set this up.
### `options.disableRefreshCheck`
### Polyfill for Older Browsers (WDS Only)
Type: `boolean`
Default: `false`
If you need to develop on IE11, you will need to polyfill the DOM URL API.
This can be done by adding the following before any of your code in the main entry (either one is fine):
Disables detection of react-refresh's Babel plugin.
Useful if you do not parse JS files within `node_modules`, or if you have a Babel setup not entirely controlled by Webpack.
**Using `url-polyfill`**
```js
import 'url-polyfill';
```
**Using `core-js`**
```js
import 'core-js/features/url';
import 'core-js/features/url-search-params';
```
**Using `react-app-polyfill`**
```js
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
```
## Options
This plugin accepts a few options that are specifically targeted for advanced users.
### `options.forceEnable`

@@ -168,2 +191,21 @@

### `options.sockHost`
Type: `string`
Default: effectively `window.location.hostname`
Set this if you are running webpack on a host other than `window.location.hostname`. This is used by the error overlay module.
### `options.sockPort`
Type: `number`
Default: effectively `window.location.port`
Set this if you are running webpack on a port other than `window.location.port`
### `options.sockPath`
Type: `string`
Default: `/sockjs-node`
### `options.useLegacyWDSSockets`

@@ -170,0 +212,0 @@

@@ -47,3 +47,3 @@ const { Template } = require('webpack');

// Webpack generates this line whenever the mainTemplate is called
const moduleInitializationLineNumber = lines.findIndex(line =>
const moduleInitializationLineNumber = lines.findIndex((line) =>
line.startsWith('modules[moduleId].call')

@@ -50,0 +50,0 @@ );

@@ -11,2 +11,6 @@ /** @typedef {string | string[] | import('webpack').Entry} StaticEntry */

const injectRefreshEntry = (originalEntry, options) => {
const sockHost = options.sockHost ? `&sockHost=${options.sockHost}` : '';
const sockPort = options.sockPort ? `&sockPort=${options.sockPort}` : '';
const sockPath = options.sockPath ? `&sockPath=${options.sockPath}` : '';
const queryParams = `?options${sockHost}${sockPort}${sockPath}`;
const entryInjects = [

@@ -18,5 +22,3 @@ // Legacy WDS SockJS integration

// Error overlay runtime
options.overlay && options.overlay.entry,
// React-refresh Babel transform detection
require.resolve('../runtime/BabelDetectComponent'),
options.overlay && options.overlay.entry + queryParams,
].filter(Boolean);

@@ -45,3 +47,3 @@

return (...args) =>
Promise.resolve(originalEntry(...args)).then(resolvedEntry =>
Promise.resolve(originalEntry(...args)).then((resolvedEntry) =>
injectRefreshEntry(resolvedEntry, options)

@@ -48,0 +50,0 @@ );

/** @type {import('../types').ReactRefreshPluginOptions} */
const defaultOptions = {
disableRefreshCheck: false,
forceEnable: false,

@@ -22,2 +21,12 @@ useLegacyWDSSockets: false,

if (typeof validatedOptions.disableRefreshCheck !== 'undefined') {
console.warn(
[
'The "disableRefreshCheck" option has been deprecated and will not have any effect on how the plugin parses files.',
'Please remove it from your configuration.',
].join(' ')
);
delete validatedOptions.disableRefreshCheck;
}
if (

@@ -24,0 +33,0 @@ typeof validatedOptions.overlay !== 'undefined' &&

@@ -39,8 +39,10 @@ const path = require('path');

const providePlugin = new webpack.ProvidePlugin({
[errorOverlay]: this.options.overlay && require.resolve(this.options.overlay.module),
[refreshUtils]: require.resolve('./runtime/utils'),
[refreshUtils]: require.resolve('./runtime/refreshUtils'),
...(!!this.options.overlay && {
[errorOverlay]: require.resolve(this.options.overlay.module),
}),
});
providePlugin.apply(compiler);
compiler.hooks.beforeRun.tap(this.constructor.name, compiler => {
compiler.hooks.beforeRun.tap(this.constructor.name, (compiler) => {
// Check for existence of HotModuleReplacementPlugin in the plugin list

@@ -52,3 +54,3 @@ // It is the foundation to this plugin working correctly

// because a project might contain multiple references to Webpack
plugin => plugin.constructor.name === 'HotModuleReplacementPlugin'
(plugin) => plugin.constructor.name === 'HotModuleReplacementPlugin'
)

@@ -62,4 +64,4 @@ ) {

compiler.hooks.normalModuleFactory.tap(this.constructor.name, nmf => {
nmf.hooks.afterResolve.tap(this.constructor.name, data => {
compiler.hooks.normalModuleFactory.tap(this.constructor.name, (nmf) => {
nmf.hooks.afterResolve.tap(this.constructor.name, (data) => {
// Inject refresh loader to all JavaScript-like files

@@ -85,3 +87,3 @@ if (

compiler.hooks.compilation.tap(this.constructor.name, compilation => {
compiler.hooks.compilation.tap(this.constructor.name, (compilation) => {
compilation.mainTemplate.hooks.require.tap(

@@ -105,3 +107,3 @@ this.constructor.name,

contentHashType: 'javascript',
hashWithLength: length => mainTemplate.renderCurrentHashCode(hash, length),
hashWithLength: (length) => mainTemplate.renderCurrentHashCode(hash, length),
noChunkHash: mainTemplate.useChunkHash(chunk),

@@ -123,40 +125,2 @@ });

);
compilation.hooks.finishModules.tap(this.constructor.name, modules => {
if (!this.options.disableRefreshCheck) {
for (const module of modules) {
const refreshPluginInjection = /\$RefreshReg\$/;
/** @type {undefined | null | string} */
const moduleSource = module._source && module._source.source();
// Some module might not have the _source property,
// so we have to gracefully skip them.
if (!moduleSource) {
continue;
}
// Check for the function transform by the Babel plugin.
if (
module.resource === require.resolve('./runtime/BabelDetectComponent.js') &&
!refreshPluginInjection.test(moduleSource)
) {
const transformNotDetectedError = new Error(
[
'React Refresh Plugin:',
'The plugin is unable to detect transformed code from react-refresh.',
'Did you forget to include "react-refresh/babel" in your list of Babel plugins?',
'Note: you can disable this check by setting "disableRefreshCheck: true".',
].join(' ')
);
// We cannot throw here as it will halt compilation.
// Warnings/Errors will get swallowed unless we explicitly push it to the stack.
compilation.warnings.push(transformNotDetectedError);
// Early exit for performance
break;
}
}
}
});
});

@@ -163,0 +127,0 @@ }

@@ -173,3 +173,3 @@ const debounce = require('lodash.debounce');

function render() {
ensureRootExists(function() {
ensureRootExists(function () {
const currentFocus = rootDocument.activeElement;

@@ -313,3 +313,3 @@ let currentFocusId;

function isWebpackCompileError(error) {
return /Module [A-z ]+\(from/.test(error.message);
return /Module [A-z ]+\(from/.test(error.message) || /Cannot find module/.test(error.message);
}

@@ -316,0 +316,0 @@

// eslint-disable-next-line no-unused-vars
/* global __resourceQuery, __webpack_dev_server_client__ */
const url = require('url');
const url = require('native-url');
const loadWHMEventSource = require('./WHMEventSource');

@@ -11,3 +11,3 @@

*/
function createSocket(messageHandler) {
function createSocket(messageHandler, options) {
// This adds support for custom WDS socket transportModes

@@ -18,11 +18,9 @@ // In the future, we should add support for custom clients to better support WDM

const connection = new SocketClient(
// TODO: Dynamically generate this to handle resourceQuery
// TODO: Use resourceQuery to fix servers under proxies
url.format({
protocol: window.location.protocol,
hostname: window.location.hostname,
port: window.location.port,
hostname: options.sockHost || window.location.hostname,
port: options.sockPort || window.location.port,
// TODO: Support usage of custom sockets after WDS 4.0 is released
// Ref: https://github.com/webpack/webpack-dev-server/pull/2055
pathname: '/sockjs-node',
pathname: options.sockPath || '/sockjs-node',
})

@@ -29,0 +27,0 @@ );

@@ -1,7 +0,4 @@

// TODO: Implement handling of this
// eslint-disable-next-line no-unused-vars
/* global __resourceQuery */
/* global __resourceQuery, __react_refresh_error_overlay__ */
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
const ErrorOverlay = require('../overlay');
const formatWebpackErrors = require('./formatWebpackErrors');
const createSocket = require('./createSocket');

@@ -24,4 +21,4 @@ const {

function tryDismissErrorOverlay() {
ErrorOverlay.clearCompileError();
ErrorOverlay.clearRuntimeErrors(!hasRuntimeErrors);
__react_refresh_error_overlay__.clearCompileError();
__react_refresh_error_overlay__.clearRuntimeErrors(!hasRuntimeErrors);
hasRuntimeErrors = false;

@@ -50,9 +47,6 @@ }

const formatted = formatWebpackMessages({
errors: errors,
warnings: [],
});
const formattedErrors = formatWebpackErrors(errors);
// Only show the first error
ErrorOverlay.showCompileError(formatted.errors[0]);
__react_refresh_error_overlay__.showCompileError(formattedErrors[0]);
}

@@ -69,2 +63,5 @@

case 'ok':
case 'still-ok':
case 'warnings':
// TODO: Implement handling for warnings
handleCompileSuccess();

@@ -80,12 +77,17 @@ break;

let overrides = {};
if (__resourceQuery) {
overrides = require('querystring').parse(__resourceQuery.slice(1));
}
// Registers handlers for compile errors
createSocket(compileMessageHandler);
createSocket(compileMessageHandler, overrides);
// Registers handlers for runtime errors
registerErrorHandler(function handleError(error) {
hasRuntimeErrors = true;
ErrorOverlay.handleRuntimeError(error);
__react_refresh_error_overlay__.handleRuntimeError(error);
});
registerUnhandledRejectionHandler(function handleUnhandledPromiseRejection(error) {
hasRuntimeErrors = true;
ErrorOverlay.handleRuntimeError(error);
__react_refresh_error_overlay__.handleRuntimeError(error);
});

@@ -8,5 +8,5 @@ if (process.env.NODE_ENV !== 'production' && typeof window !== 'undefined') {

// Setup placeholder functions
window.$RefreshReg$ = function() {};
window.$RefreshSig$ = function() {
return function(type) {
window.$RefreshReg$ = function () {};
window.$RefreshSig$ = function () {
return function (type) {
return type;

@@ -32,3 +32,3 @@ };

*/
window.$RefreshReg$ = function(type, id) {
window.$RefreshReg$ = function (type, id) {
const typeId = moduleId + ' ' + id;

@@ -35,0 +35,0 @@ Refresh.register(type, typeId);

@@ -9,6 +9,11 @@ /**

* @typedef {Object} ReactRefreshPluginOptions
* @property {boolean} [disableRefreshCheck] Disables detection of react-refresh's Babel plugin.
* @property {boolean} [disableRefreshCheck] Disables detection of react-refresh's Babel plugin. (Deprecated since v0.3.0)
* @property {boolean} [forceEnable] Enables the plugin forcefully.
* @property {boolean | ErrorOverlayOptions} [overlay] Modifies how the error overlay integration works in the plugin.
* @property {string} [sockHost] The socket host to use for the error overlay integration.
* @property {string} [sockPath] The socket path to use for the error overlay integration.
* @property {number} [sockPort] The socket port to use for the error overlay integration.
* @property {boolean} [useLegacyWDSSockets] Uses a custom SocketJS implementation for older versions of webpack-dev-server.
*/
module.exports = {};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc