Socket
Socket
Sign inDemoInstall

@pmmmwh/react-refresh-webpack-plugin

Package Overview
Dependencies
Maintainers
1
Versions
66
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@pmmmwh/react-refresh-webpack-plugin - npm Package Compare versions

Comparing version 0.5.15 to 0.6.0-beta.0

47

client/ErrorOverlayEntry.js

@@ -1,6 +0,5 @@

/* 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');

@@ -77,25 +76,27 @@

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);
});
// 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);
},
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;
}
});
// Mark overlay as injected to prevent double-injection
window.__reactRefreshOverlayInjected = true;
}
}
}

@@ -1,6 +0,6 @@

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;

@@ -7,0 +7,0 @@ }

@@ -9,15 +9,1 @@ /**

};
/**
* Gets current Webpack version according to features on the compiler instance.
* @param {import('webpack').Compiler} compiler The current Webpack compiler instance.
* @returns {number} The current Webpack version.
*/
module.exports.getWebpackVersion = (compiler) => {
if (!compiler.hooks) {
throw new Error(`[ReactRefreshPlugin] Webpack version is not supported!`);
}
// Webpack v5+ implements compiler caching
return 'cache' in compiler ? 5 : 4;
};
const { validate: validateOptions } = require('schema-utils');
const { getRefreshGlobalScope, getWebpackVersion } = require('./globals');
const { getRefreshGlobalScope } = require('./globals');
const {
getAdditionalEntries,
getIntegrationEntry,
getRefreshGlobal,
getSocketIntegration,
injectRefreshEntry,
injectRefreshLoader,

@@ -51,3 +49,2 @@ makeRefreshRuntimeModule,

const webpackVersion = getWebpackVersion(compiler);
const logger = compiler.getInfrastructureLogger(this.constructor.name);

@@ -72,75 +69,71 @@

// and fallback to patching the `entry` object for legacy workflows.
const addEntries = getAdditionalEntries({
devServer: compiler.options.devServer,
options: this.options,
const addEntries = getAdditionalEntries(this.options);
// Prepended entries does not care about injection order,
// so we can utilise EntryPlugin for simpler logic.
addEntries.prependEntries.forEach((entry) => {
new EntryPlugin(compiler.context, entry, { name: undefined }).apply(compiler);
});
if (EntryPlugin) {
// Prepended entries does not care about injection order,
// so we can utilise EntryPlugin for simpler logic.
addEntries.prependEntries.forEach((entry) => {
new EntryPlugin(compiler.context, entry, { name: undefined }).apply(compiler);
});
const integrationEntry = getIntegrationEntry(this.options.overlay.sockIntegration);
const socketEntryData = [];
compiler.hooks.make.tap(
{ name: this.constructor.name, stage: Number.POSITIVE_INFINITY },
(compilation) => {
// Exhaustively search all entries for `integrationEntry`.
// If found, mark those entries and the index of `integrationEntry`.
for (const [name, entryData] of compilation.entries.entries()) {
const index = entryData.dependencies.findIndex(
(dep) => dep.request && dep.request.includes(integrationEntry)
);
if (index !== -1) {
socketEntryData.push({ name, index });
}
const integrationEntry = getIntegrationEntry(this.options.overlay.sockIntegration);
const socketEntryData = [];
compiler.hooks.make.tap(
{ name: this.constructor.name, stage: Number.POSITIVE_INFINITY },
(compilation) => {
// Exhaustively search all entries for `integrationEntry`.
// If found, mark those entries and the index of `integrationEntry`.
for (const [name, entryData] of compilation.entries.entries()) {
const index = entryData.dependencies.findIndex(
(dep) => dep.request && dep.request.includes(integrationEntry)
);
if (index !== -1) {
socketEntryData.push({ name, index });
}
}
);
}
);
// Overlay entries need to be injected AFTER integration's entry,
// so we will loop through everything in `finishMake` instead of `make`.
// This ensures we can traverse all entry points and inject stuff with the correct order.
addEntries.overlayEntries.forEach((entry, idx, arr) => {
compiler.hooks.finishMake.tapPromise(
{ name: this.constructor.name, stage: Number.MIN_SAFE_INTEGER + (arr.length - idx - 1) },
(compilation) => {
// Only hook into the current compiler
if (compilation.compiler !== compiler) {
return Promise.resolve();
}
// Overlay entries need to be injected AFTER integration's entry,
// so we will loop through everything in `finishMake` instead of `make`.
// This ensures we can traverse all entry points and inject stuff with the correct order.
for (const [idx, entry] of addEntries.overlayEntries.entries()) {
compiler.hooks.finishMake.tapPromise(
{
name: this.constructor.name,
stage: Number.MIN_SAFE_INTEGER + (addEntries.overlayEntries.length - idx - 1),
},
(compilation) => {
// Only hook into the current compiler
if (compilation.compiler !== compiler) {
return Promise.resolve();
}
const injectData = socketEntryData.length ? socketEntryData : [{ name: undefined }];
return Promise.all(
injectData.map(({ name, index }) => {
return new Promise((resolve, reject) => {
const options = { name };
const dep = EntryPlugin.createDependency(entry, options);
compilation.addEntry(compiler.context, dep, options, (err) => {
if (err) return reject(err);
const injectData = socketEntryData.length ? socketEntryData : [{ name: undefined }];
return Promise.all(
injectData.map(({ name, index }) => {
return new Promise((resolve, reject) => {
const options = { name };
const dep = EntryPlugin.createDependency(entry, options);
compilation.addEntry(compiler.context, dep, options, (err) => {
if (err) return reject(err);
// If the entry is not a global one,
// and we have registered the index for integration entry,
// we will reorder all entry dependencies to our desired order.
// That is, to have additional entries DIRECTLY behind integration entry.
if (name && typeof index !== 'undefined') {
const entryData = compilation.entries.get(name);
entryData.dependencies.splice(
index + 1,
0,
entryData.dependencies.splice(entryData.dependencies.length - 1, 1)[0]
);
}
// If the entry is not a global one,
// and we have registered the index for integration entry,
// we will reorder all entry dependencies to our desired order.
// That is, to have additional entries DIRECTLY behind integration entry.
if (name && typeof index !== 'undefined') {
const entryData = compilation.entries.get(name);
entryData.dependencies.splice(
index + 1,
0,
entryData.dependencies.splice(entryData.dependencies.length - 1, 1)[0]
);
}
resolve();
});
resolve();
});
})
).then(() => {});
}
);
});
} else {
compiler.options.entry = injectRefreshEntry(compiler.options.entry, addEntries);
});
})
);
}
);
}

@@ -175,7 +168,4 @@

definedModules.__react_refresh_error_overlay__ = false;
definedModules.__react_refresh_polyfill_url__ = false;
definedModules.__react_refresh_socket__ = false;
} else {
definedModules.__react_refresh_polyfill_url__ = this.options.overlay.useURLPolyfill || false;
if (this.options.overlay.module) {

@@ -206,160 +196,48 @@ providedModules.__react_refresh_error_overlay__ = require.resolve(

// Tap into version-specific compilation hooks
switch (webpackVersion) {
case 4: {
const outputOptions = compilation.mainTemplate.outputOptions;
compilation.mainTemplate.hooks.require.tap(
this.constructor.name,
// Constructs the module template for react-refresh
(source, chunk, hash) => {
// Check for the output filename
// This is to ensure we are processing a JS-related chunk
let filename = outputOptions.filename;
if (typeof filename === 'function') {
// Only usage of the `chunk` property is documented by Webpack.
// However, some internal Webpack plugins uses other properties,
// so we also pass them through to be on the safe side.
filename = filename({
contentHashType: 'javascript',
chunk,
hash,
});
}
// Set factory for EntryDependency which is used to initialise the module
compilation.dependencyFactories.set(EntryDependency, normalModuleFactory);
// Check whether the current compilation is outputting to JS,
// since other plugins can trigger compilations for other file types too.
// If we apply the transform to them, their compilation will break fatally.
// One prominent example of this is the HTMLWebpackPlugin.
// If filename is falsy, something is terribly wrong and there's nothing we can do.
if (!filename || !filename.includes('.js')) {
return source;
}
const ReactRefreshRuntimeModule = makeRefreshRuntimeModule(webpack);
compilation.hooks.additionalTreeRuntimeRequirements.tap(
this.constructor.name,
// Setup react-refresh globals with a Webpack runtime module
(chunk, runtimeRequirements) => {
runtimeRequirements.add(RuntimeGlobals.interceptModuleExecution);
runtimeRequirements.add(RuntimeGlobals.moduleCache);
runtimeRequirements.add(refreshGlobal);
compilation.addRuntimeModule(chunk, new ReactRefreshRuntimeModule());
}
);
// Split template source code into lines for easier processing
const lines = source.split('\n');
// Webpack generates this line when the MainTemplate is called
const moduleInitializationLineNumber = lines.findIndex((line) =>
line.includes('modules[moduleId].call(')
);
// Unable to find call to module execution -
// this happens if the current module does not call MainTemplate.
// In this case, we will return the original source and won't mess with it.
if (moduleInitializationLineNumber === -1) {
return source;
}
const moduleInterceptor = Template.asString([
`${refreshGlobal}.setup(moduleId);`,
'try {',
Template.indent(lines[moduleInitializationLineNumber]),
'} finally {',
Template.indent(`${refreshGlobal}.cleanup(moduleId);`),
'}',
]);
return Template.asString([
...lines.slice(0, moduleInitializationLineNumber),
'',
outputOptions.strictModuleExceptionHandling
? Template.indent(moduleInterceptor)
: moduleInterceptor,
'',
...lines.slice(moduleInitializationLineNumber + 1, lines.length),
]);
}
);
compilation.mainTemplate.hooks.requireExtensions.tap(
this.constructor.name,
// Setup react-refresh globals as extensions to Webpack's require function
(source) => {
return Template.asString([source, '', getRefreshGlobal(Template)]);
}
);
normalModuleFactory.hooks.afterResolve.tap(
this.constructor.name,
// Add react-refresh loader to process files that matches specified criteria
(data) => {
return injectRefreshLoader(data, {
match,
options: { const: false, esModule: false },
});
}
);
compilation.hooks.normalModuleLoader.tap(
// `Number.POSITIVE_INFINITY` ensures this check will run only after all other taps
{ name: this.constructor.name, stage: Number.POSITIVE_INFINITY },
// Check for existence of the HMR runtime -
// it is the foundation to this plugin working correctly
(context) => {
if (!context.hot && !loggedHotWarning) {
logger.warn(
[
'Hot Module Replacement (HMR) is not enabled!',
'React Refresh requires HMR to function properly.',
].join(' ')
);
loggedHotWarning = true;
}
}
);
break;
normalModuleFactory.hooks.afterResolve.tap(
this.constructor.name,
// Add react-refresh loader to process files that matches specified criteria
(resolveData) => {
injectRefreshLoader(resolveData.createData, {
match,
options: {
const: compilation.runtimeTemplate.supportsConst(),
esModule: this.options.esModule,
},
});
}
case 5: {
// Set factory for EntryDependency which is used to initialise the module
compilation.dependencyFactories.set(EntryDependency, normalModuleFactory);
);
const ReactRefreshRuntimeModule = makeRefreshRuntimeModule(webpack);
compilation.hooks.additionalTreeRuntimeRequirements.tap(
this.constructor.name,
// Setup react-refresh globals with a Webpack runtime module
(chunk, runtimeRequirements) => {
runtimeRequirements.add(RuntimeGlobals.interceptModuleExecution);
runtimeRequirements.add(RuntimeGlobals.moduleCache);
runtimeRequirements.add(refreshGlobal);
compilation.addRuntimeModule(chunk, new ReactRefreshRuntimeModule());
}
);
normalModuleFactory.hooks.afterResolve.tap(
this.constructor.name,
// Add react-refresh loader to process files that matches specified criteria
(resolveData) => {
injectRefreshLoader(resolveData.createData, {
match,
options: {
const: compilation.runtimeTemplate.supportsConst(),
esModule: this.options.esModule,
},
});
}
);
NormalModule.getCompilationHooks(compilation).loader.tap(
// `Infinity` ensures this check will run only after all other taps
{ name: this.constructor.name, stage: Infinity },
// Check for existence of the HMR runtime -
// it is the foundation to this plugin working correctly
(context) => {
if (!context.hot && !loggedHotWarning) {
logger.warn(
[
'Hot Module Replacement (HMR) is not enabled!',
'React Refresh requires HMR to function properly.',
].join(' ')
);
loggedHotWarning = true;
}
}
);
break;
NormalModule.getCompilationHooks(compilation).loader.tap(
// `Infinity` ensures this check will run only after all other taps
{ name: this.constructor.name, stage: Infinity },
// Check for existence of the HMR runtime -
// it is the foundation to this plugin working correctly
(context) => {
if (!context.hot && !loggedHotWarning) {
logger.warn(
[
'Hot Module Replacement (HMR) is not enabled!',
'React Refresh requires HMR to function properly.',
].join(' ')
);
loggedHotWarning = true;
}
}
default: {
// Do nothing - this should be an impossible case
}
}
);
}

@@ -366,0 +244,0 @@ );

@@ -48,8 +48,3 @@ {

]
},
"sockHost": { "type": "string" },
"sockPath": { "type": "string" },
"sockPort": { "type": "number", "minimum": 0 },
"sockProtocol": { "enum": ["http", "https", "ws", "wss"] },
"useURLPolyfill": { "type": "boolean" }
}
}

@@ -56,0 +51,0 @@ }

@@ -5,8 +5,3 @@ /**

* @property {string | false} [module] The error overlay module to use.
* @property {string} [sockHost] The socket host to use (WDS only).
* @property {import('type-fest').LiteralUnion<'wds' | 'whm' | 'wps' | false, string>} [sockIntegration] Path to a JS file that sets up the Webpack socket integration.
* @property {string} [sockPath] The socket path to use (WDS only).
* @property {number} [sockPort] The socket port to use (WDS only).
* @property {'http' | 'https' | 'ws' | 'wss'} [sockProtocol] The socket protocol to use (WDS only).
* @property {boolean} [useURLPolyfill] Uses a polyfill for the DOM URL API (WDS only).
*/

@@ -13,0 +8,0 @@

@@ -1,3 +0,1 @@

const querystring = require('querystring');
/**

@@ -11,71 +9,6 @@ * @typedef {Object} AdditionalEntries

* Creates an object that contains two entry arrays: the prependEntries and overlayEntries
* @param {Object} optionsContainer This is the container for the options to this function
* @param {import('../types').NormalizedPluginOptions} optionsContainer.options Configuration options for this plugin.
* @param {import('webpack').Compiler["options"]["devServer"]} [optionsContainer.devServer] The webpack devServer config
* @param {import('../types').NormalizedPluginOptions} options Configuration options for this plugin.
* @returns {AdditionalEntries} An object that contains the Webpack entries for prepending and the overlay feature
*/
function getAdditionalEntries({ devServer, options }) {
/** @type {Record<string, string | number>} */
let resourceQuery = {};
if (devServer) {
const { client, https, http2, sockHost, sockPath, sockPort } = devServer;
let { host, path, port } = devServer;
let protocol = https || http2 ? 'https' : 'http';
if (sockHost) host = sockHost;
if (sockPath) path = sockPath;
if (sockPort) port = sockPort;
if (client && client.webSocketURL != null) {
let parsedUrl = client.webSocketURL;
if (typeof parsedUrl === 'string') parsedUrl = new URL(parsedUrl);
let auth;
if (parsedUrl.username) {
auth = parsedUrl.username;
if (parsedUrl.password) {
auth += ':' + parsedUrl.password;
}
}
if (parsedUrl.hostname != null) {
host = [auth != null && auth, parsedUrl.hostname].filter(Boolean).join('@');
}
if (parsedUrl.pathname != null) {
path = parsedUrl.pathname;
}
if (parsedUrl.port != null) {
port = !['0', 'auto'].includes(String(parsedUrl.port)) ? parsedUrl.port : undefined;
}
if (parsedUrl.protocol != null) {
protocol = parsedUrl.protocol !== 'auto' ? parsedUrl.protocol.replace(':', '') : 'ws';
}
}
if (host) resourceQuery.sockHost = host;
if (path) resourceQuery.sockPath = path;
if (port) resourceQuery.sockPort = port;
resourceQuery.sockProtocol = protocol;
}
if (options.overlay) {
const { sockHost, sockPath, sockPort, sockProtocol } = options.overlay;
if (sockHost) resourceQuery.sockHost = sockHost;
if (sockPath) resourceQuery.sockPath = sockPath;
if (sockPort) resourceQuery.sockPort = sockPort;
if (sockProtocol) resourceQuery.sockProtocol = sockProtocol;
}
// We don't need to URI encode the resourceQuery as it will be parsed by Webpack
const queryString = querystring.stringify(resourceQuery, undefined, undefined, {
/**
* @param {string} string
* @returns {string}
*/
encodeURIComponent(string) {
return string;
},
});
function getAdditionalEntries(options) {
const prependEntries = [

@@ -88,5 +21,3 @@ // React-refresh runtime

// Error overlay runtime
options.overlay &&
options.overlay.entry &&
`${require.resolve(options.overlay.entry)}${queryString ? `?${queryString}` : ''}`,
options.overlay && options.overlay.entry && require.resolve(options.overlay.entry),
].filter(Boolean);

@@ -93,0 +24,0 @@

@@ -1,2 +0,2 @@

const path = require('path');
const path = require('node:path');

@@ -3,0 +3,0 @@ /**

@@ -32,7 +32,2 @@ const { d, n } = require('../../options');

d(overlay, 'sockIntegration', defaults.sockIntegration);
d(overlay, 'sockHost');
d(overlay, 'sockPath');
d(overlay, 'sockPort');
d(overlay, 'sockProtocol');
d(options, 'useURLPolyfill');

@@ -39,0 +34,0 @@ return overlay;

@@ -8,3 +8,2 @@ // This is a patch for mozilla/source-map#349 -

const { getOptions } = require('loader-utils');
const { validate: validateOptions } = require('schema-utils');

@@ -36,3 +35,3 @@ const { SourceMapConsumer, SourceNode } = require('source-map');

function ReactRefreshLoader(source, inputSourceMap, meta) {
let options = getOptions(this);
let options = this.getOptions();
validateOptions(schema, options, {

@@ -39,0 +38,0 @@ baseDataPath: 'options',

@@ -13,3 +13,3 @@ const { SourceMapGenerator } = require('source-map');

source.split('\n').forEach((line, index) => {
source.split('\n').forEach((_, index) => {
sourceMap.addMapping({

@@ -16,0 +16,0 @@ source: resourcePath,

@@ -1,3 +0,3 @@

const { promises: fsPromises } = require('fs');
const path = require('path');
const fs = require('node:fs/promises');
const path = require('node:path');

@@ -89,3 +89,3 @@ /** @type {Map<string, string | undefined>} */

try {
const packageSource = await fsPromises.readFile(packageJsonPath, 'utf-8');
const packageSource = await fs.readFile(packageJsonPath, 'utf-8');
try {

@@ -92,0 +92,0 @@ const packageObject = JSON.parse(packageSource);

@@ -1,2 +0,2 @@

const ansiHTML = require('ansi-html');
const ansiHTML = require('ansi-html-community');
const entities = require('html-entities');

@@ -3,0 +3,0 @@ const theme = require('../theme.js');

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

@@ -39,8 +39,13 @@ "keywords": [

],
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610",
"scripts": {
"test": "run-s -c test:pre \"test:exec {@}\" test:post --",
"test:webpack-4": "cross-env WEBPACK_VERSION=4 yarn test",
"test:pre": "yarn add -D file:./",
"test:wds-4": "cross-env WDS_VERSION=4 yarn test",
"test:exec": "node scripts/test.js",
"test:post": "yarn remove @pmmmwh/react-refresh-webpack-plugin",
"test:pre": "run-s -c test:pre:*",
"test:pre:0": "yarn link",
"test:pre:1": "yarn link @pmmmwh/react-refresh-webpack-plugin",
"test:post": "run-s -c test:post:*",
"test:post:0": "yarn unlink @pmmmwh/react-refresh-webpack-plugin",
"test:post:1": "yarn unlink",
"lint": "eslint --report-unused-disable-directives --ext .js,.jsx .",

@@ -61,3 +66,2 @@ "lint:fix": "yarn lint --fix",

"html-entities": "^2.1.0",
"loader-utils": "^2.0.4",
"schema-utils": "^4.2.0",

@@ -67,13 +71,12 @@ "source-map": "^0.7.3"

"devDependencies": {
"@babel/core": "^7.14.2",
"@babel/plugin-transform-modules-commonjs": "^7.14.0",
"@types/cross-spawn": "^6.0.2",
"@babel/core": "^7.24.6",
"@babel/plugin-transform-modules-commonjs": "^7.24.6",
"@types/cross-spawn": "^6.0.6",
"@types/fs-extra": "^11.0.4",
"@types/jest": "^29.5.12",
"@types/json-schema": "^7.0.6",
"@types/module-alias": "^2.0.0",
"@types/node": "^20.5.0",
"@types/semver": "^7.3.9",
"@types/webpack": "^5.28.0",
"babel-loader": "^8.1.0",
"@types/json-schema": "^7.0.15",
"@types/module-alias": "^2.0.4",
"@types/node": "^20.13.0",
"@types/webpack": "^5.28.5",
"babel-loader": "^9.1.3",
"cross-env": "^7.0.3",

@@ -83,4 +86,4 @@ "cross-spawn": "^7.0.3",

"eslint": "^8.6.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"fs-extra": "^11.2.0",

@@ -93,32 +96,29 @@ "get-port": "^5.1.1",

"jest-location-mock": "^2.0.0",
"module-alias": "^2.2.2",
"memfs": "^4.9.2",
"module-alias": "^2.2.3",
"nanoid": "^3.1.31",
"npm-run-all": "^4.1.5",
"npm-run-all2": "^6.2.0",
"prettier": "^3.3.0",
"puppeteer": "^22.10.0",
"react-refresh": "^0.14.0",
"semver": "^7.5.2",
"react-refresh": "^0.14.2",
"sourcemap-validator": "^2.1.0",
"type-fest": "^4.0.0",
"type-fest": "^4.18.3",
"typescript": "~5.4.5",
"webpack": "^5.76.0",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4",
"webpack-cli-v4": "npm:webpack-cli@4.x",
"webpack-dev-server": "^5.0.4",
"webpack-dev-server-v3": "npm:webpack-dev-server@3.x",
"webpack-dev-server-v4": "npm:webpack-dev-server@4.x",
"webpack-hot-middleware": "^2.25.0",
"webpack-plugin-serve": "^1.4.1",
"webpack-v4": "npm:webpack@4.x",
"webpack-dev-server-v4": "npm:webpack-dev-server@^4.8.0",
"webpack-hot-middleware": "^2.26.1",
"webpack-plugin-serve": "^1.6.0",
"yn": "^4.0.0"
},
"peerDependencies": {
"@types/webpack": "4.x || 5.x",
"@types/webpack": "5.x",
"react-refresh": ">=0.10.0 <1.0.0",
"sockjs-client": "^1.4.0",
"type-fest": ">=0.17.0 <5.0.0",
"webpack": ">=4.43.0 <6.0.0",
"webpack-dev-server": "3.x || 4.x || 5.x",
"webpack": "^5.0.0",
"webpack-dev-server": "^4.8.0 || 5.x",
"webpack-hot-middleware": "2.x",
"webpack-plugin-serve": "0.x || 1.x"
"webpack-plugin-serve": "1.x"
},

@@ -149,5 +149,4 @@ "peerDependenciesMeta": {

"engines": {
"node": ">= 10.13"
},
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
"node": ">=18.12"
}
}

@@ -1,32 +0,26 @@

/* global __webpack_dev_server_client__ */
const getSocketUrlParts = require('./utils/getSocketUrlParts.js');
const getUrlFromParts = require('./utils/getUrlFromParts');
const getWDSMetadata = require('./utils/getWDSMetadata');
/**
* Initializes a socket server for HMR for webpack-dev-server.
* @param {function(*): void} messageHandler A handler to consume Webpack compilation messages.
* @param {string} [resourceQuery] Webpack's `__resourceQuery` string.
* @returns {void}
*/
function initWDSSocket(messageHandler, resourceQuery) {
if (typeof __webpack_dev_server_client__ !== 'undefined') {
let SocketClient = __webpack_dev_server_client__;
if (typeof __webpack_dev_server_client__.default !== 'undefined') {
SocketClient = __webpack_dev_server_client__.default;
}
function initWDSSocket(messageHandler) {
const { default: SockJSClient } = require('webpack-dev-server/client/clients/SockJSClient');
const { default: WebSocketClient } = require('webpack-dev-server/client/clients/WebSocketClient');
const { client } = require('webpack-dev-server/client/socket');
const wdsMeta = getWDSMetadata(SocketClient);
const urlParts = getSocketUrlParts(resourceQuery, wdsMeta);
/** @type {WebSocket} */
let connection;
if (client instanceof SockJSClient) {
connection = client.sock;
} else if (client instanceof WebSocketClient) {
connection = client.client;
} else {
throw new Error('Failed to determine WDS client type');
}
const connection = new SocketClient(getUrlFromParts(urlParts, wdsMeta));
connection.onMessage(function onSocketMessage(data) {
const message = JSON.parse(data);
messageHandler(message);
});
}
connection.addEventListener('message', function onSocketMessage(message) {
messageHandler(JSON.parse(message.data));
});
}
module.exports = { init: initWDSSocket };

@@ -11,6 +11,2 @@ export type ErrorOverlayOptions = {

/**
* The socket host to use (WDS only).
*/
sockHost?: string | undefined;
/**
* Path to a JS file that sets up the Webpack socket integration.

@@ -21,18 +17,2 @@ */

| undefined;
/**
* The socket path to use (WDS only).
*/
sockPath?: string | undefined;
/**
* The socket port to use (WDS only).
*/
sockPort?: number | undefined;
/**
* The socket protocol to use (WDS only).
*/
sockProtocol?: 'http' | 'https' | 'ws' | 'wss' | undefined;
/**
* Uses a polyfill for the DOM URL API (WDS only).
*/
useURLPolyfill?: boolean | undefined;
};

@@ -39,0 +19,0 @@ export type NormalizedErrorOverlayOptions = import('type-fest').SetRequired<

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc