@rspack/plugin-react-refresh 1.0.0-beta.3 → 1.0.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/LICENSE +0 -1
  2. package/README.md +67 -3
  3. package/client/errorOverlayEntry.js +9 -7
  4. package/client/overlay/components/CompileErrorTrace.js +7 -2
  5. package/client/overlay/components/PageHeader.js +4 -2
  6. package/client/overlay/components/RuntimeErrorHeader.js +2 -1
  7. package/client/overlay/components/RuntimeErrorStack.js +2 -1
  8. package/client/overlay/index.js +10 -3
  9. package/client/overlay/utils.js +1 -1
  10. package/client/reactRefresh.js +15 -15
  11. package/client/reactRefreshEntry.js +41 -41
  12. package/client/refreshUtils.js +213 -213
  13. package/client/utils/ansi-html.js +80 -78
  14. package/client/utils/errorEventHandlers.js +2 -2
  15. package/client/utils/formatWebpackErrors.js +15 -5
  16. package/client/utils/retry.js +2 -2
  17. package/dist/index.d.ts +2 -2
  18. package/dist/index.js +21 -19
  19. package/dist/options.d.ts +1 -1
  20. package/dist/options.js +10 -10
  21. package/dist/sockets/WDSSocket.d.ts +2 -2
  22. package/dist/sockets/WDSSocket.js +2 -2
  23. package/dist/sockets/utils/getCurrentScriptSource.js +4 -4
  24. package/dist/sockets/utils/getSocketUrlParts.d.ts +1 -1
  25. package/dist/sockets/utils/getSocketUrlParts.js +13 -12
  26. package/dist/sockets/utils/getUrlFromParts.d.ts +2 -2
  27. package/dist/sockets/utils/getUrlFromParts.js +3 -3
  28. package/dist/sockets/utils/getWDSMetadata.d.ts +3 -3
  29. package/dist/sockets/utils/getWDSMetadata.js +6 -6
  30. package/dist/utils/getAdditionalEntries.d.ts +2 -2
  31. package/dist/utils/getAdditionalEntries.js +11 -11
  32. package/dist/utils/getSocketIntegration.d.ts +1 -1
  33. package/dist/utils/getSocketIntegration.js +2 -2
  34. package/package.json +31 -21
package/LICENSE CHANGED
@@ -2,7 +2,6 @@ MIT License
2
2
 
3
3
  Copyright (c) 2022-present Bytedance, Inc. and its affiliates.
4
4
 
5
-
6
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
7
6
  of this software and associated documentation files (the "Software"), to deal
8
7
  in the Software without restriction, including without limitation the rights
package/README.md CHANGED
@@ -5,11 +5,75 @@
5
5
 
6
6
  # @rspack/plugin-react-refresh
7
7
 
8
- React refresh plugin for rspack.
8
+ React refresh plugin for [Rspack](https://github.com/web-infra-dev/rspack).
9
9
 
10
- ## Documentation
10
+ ## Installation
11
11
 
12
- See [https://rspack.dev](https://rspack.dev) for details.
12
+ First you need to install this plugin and its dependencies:
13
+
14
+ ```bash
15
+ npm add @rspack/plugin-react-refresh react-refresh -D
16
+ # or
17
+ yarn add @rspack/plugin-react-refresh react-refresh -D
18
+ # or
19
+ pnpm add @rspack/plugin-react-refresh react-refresh -D
20
+ # or
21
+ bun add @rspack/plugin-react-refresh react-refresh -D
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ Enabling [React Fast Refresh](https://reactnative.dev/docs/fast-refresh) functionality primarily involves two aspects: code injection and code transformation.
27
+
28
+ - Code injection will inject some code from the [react-refresh](https://www.npmjs.com/package/react-refresh) package, as well as some custom runtime code, all of which are integrated in this plugin and can be injected through.
29
+ - Code transformation can be added through loaders, such as [jsc.transform.react.refresh](https://swc.rs/docs/configuration/compilation#jsctransformreactrefresh) for [swc-loader](https://swc.rs/docs/usage/swc-loader) or the [react-refresh/babel](https://github.com/facebook/react/tree/main/packages/react-refresh) for [babel-loader](https://github.com/babel/babel-loader).
30
+
31
+ ```js
32
+ const ReactRefreshPlugin = require('@rspack/plugin-react-refresh');
33
+ const isDev = process.env.NODE_ENV === 'development';
34
+
35
+ module.exports = {
36
+ experiments: {
37
+ rspackFuture: {
38
+ disableTransformByDefault: true,
39
+ },
40
+ },
41
+ // ...
42
+ mode: isDev ? 'development' : 'production',
43
+ module: {
44
+ rules: [
45
+ {
46
+ test: /\.jsx$/,
47
+ use: {
48
+ loader: 'builtin:swc-loader',
49
+ options: {
50
+ jsc: {
51
+ parser: {
52
+ syntax: 'ecmascript',
53
+ jsx: true,
54
+ },
55
+ transform: {
56
+ react: {
57
+ development: isDev,
58
+ refresh: isDev,
59
+ },
60
+ },
61
+ },
62
+ },
63
+ },
64
+ },
65
+ ],
66
+ },
67
+ plugins: [isDev && new ReactRefreshPlugin()].filter(Boolean),
68
+ };
69
+ ```
70
+
71
+ Compared to the previous approach, this method decouples the React Fast Refresh code injection logic from the transformation logic. The code injection logic is handled uniformly by this plugin, while the code transformation is handled by loaders. This means that this plugin can be used in conjunction with `builtin:swc-loader`, `swc-loader`, or `babel-loader`.
72
+
73
+ ## Example
74
+
75
+ - For usage with `builtin:swc-loader`, you can refer to the example at [examples/react-refresh](https://github.com/rspack-contrib/rspack-examples/tree/main/rspack/react-refresh/rspack.config.js), When using with `swc-loader`, simply replace `builtin:swc-loader` with `swc-loader`.
76
+ - For usage with `babel-loader`, you can refer to the example at [examples/react-refresh-babel-loader](https://github.com/rspack-contrib/rspack-examples/tree/main/rspack/react-refresh-babel-loader/rspack.config.js)
13
77
 
14
78
  ## License
15
79
 
@@ -94,15 +94,17 @@ if (process.env.NODE_ENV !== 'production') {
94
94
  hasRuntimeErrors = true;
95
95
  __react_refresh_error_overlay__.handleRuntimeError(error);
96
96
  });
97
- events.handleUnhandledRejection(function handleUnhandledPromiseRejection(error) {
98
- hasRuntimeErrors = true;
99
- __react_refresh_error_overlay__.handleRuntimeError(error);
100
- });
97
+ events.handleUnhandledRejection(
98
+ function handleUnhandledPromiseRejection(error) {
99
+ hasRuntimeErrors = true;
100
+ __react_refresh_error_overlay__.handleRuntimeError(error);
101
+ },
102
+ );
101
103
 
102
104
  // Mark overlay as injected to prevent double-injection
103
105
  window.__reactRefreshOverlayInjected = true;
104
106
  }
105
- };
106
- setupOverlay()
107
+ }
108
+ setupOverlay();
107
109
  }
108
- }
110
+ }
@@ -33,8 +33,13 @@ function CompileErrorTrace(document, root, props) {
33
33
 
34
34
  const stackContainer = document.createElement('pre');
35
35
  stackContainer.innerHTML = entities.decode(
36
- ansiHTML(entities.encode(errorParts.join('\n'), { level: 'html5', mode: 'nonAscii' })),
37
- { level: 'html5' }
36
+ ansiHTML(
37
+ entities.encode(errorParts.join('\n'), {
38
+ level: 'html5',
39
+ mode: 'nonAscii',
40
+ }),
41
+ ),
42
+ { level: 'html5' },
38
43
  );
39
44
  stackContainer.style.fontFamily = [
40
45
  '"Operator Mono SSm"',
@@ -23,8 +23,10 @@ function PageHeader(document, root, props) {
23
23
  pageHeaderContainer.style.left = '0';
24
24
  pageHeaderContainer.style.right = '0';
25
25
  pageHeaderContainer.style.padding = '1rem 1.5rem';
26
- pageHeaderContainer.style.paddingLeft = 'max(1.5rem, env(safe-area-inset-left))';
27
- pageHeaderContainer.style.paddingRight = 'max(1.5rem, env(safe-area-inset-right))';
26
+ pageHeaderContainer.style.paddingLeft =
27
+ 'max(1.5rem, env(safe-area-inset-left))';
28
+ pageHeaderContainer.style.paddingRight =
29
+ 'max(1.5rem, env(safe-area-inset-right))';
28
30
  pageHeaderContainer.style.position = 'fixed';
29
31
  pageHeaderContainer.style.top = props.topOffset || '0';
30
32
 
@@ -16,7 +16,8 @@ const theme = require('../theme.js');
16
16
  */
17
17
  function RuntimeErrorHeader(document, root, props) {
18
18
  const header = document.createElement('div');
19
- header.innerText = 'Error ' + (props.currentErrorIndex + 1) + ' of ' + props.totalErrors;
19
+ header.innerText =
20
+ 'Error ' + (props.currentErrorIndex + 1) + ' of ' + props.totalErrors;
20
21
  header.style.backgroundColor = '#' + theme.red;
21
22
  header.style.color = '#' + theme.white;
22
23
  header.style.fontWeight = '500';
@@ -40,7 +40,8 @@ function RuntimeErrorStack(document, root, props) {
40
40
  const currentStack = errorStacks[i];
41
41
 
42
42
  const functionName = document.createElement('code');
43
- functionName.innerHTML = ' ' + currentStack.functionName || '(anonymous function)';
43
+ functionName.innerHTML =
44
+ ' ' + currentStack.functionName || '(anonymous function)';
44
45
  functionName.style.color = '#' + theme.yellow;
45
46
  functionName.style.fontFamily = [
46
47
  '"Operator Mono SSm"',
@@ -323,7 +323,10 @@ const debouncedShowRuntimeErrors = utils.debounce(showRuntimeErrors, 30);
323
323
  * @returns {boolean} If the error is a Webpack compilation error.
324
324
  */
325
325
  function isWebpackCompileError(error) {
326
- return /Module [A-z ]+\(from/.test(error.message) || /Cannot find module/.test(error.message);
326
+ return (
327
+ /Module [A-z ]+\(from/.test(error.message) ||
328
+ /Cannot find module/.test(error.message)
329
+ );
327
330
  }
328
331
 
329
332
  /**
@@ -333,7 +336,11 @@ function isWebpackCompileError(error) {
333
336
  * @returns {void}
334
337
  */
335
338
  function handleRuntimeError(error) {
336
- if (error && !isWebpackCompileError(error) && currentRuntimeErrors.indexOf(error) === -1) {
339
+ if (
340
+ error &&
341
+ !isWebpackCompileError(error) &&
342
+ currentRuntimeErrors.indexOf(error) === -1
343
+ ) {
337
344
  currentRuntimeErrors = currentRuntimeErrors.concat(error);
338
345
  }
339
346
  debouncedShowRuntimeErrors(currentRuntimeErrors);
@@ -345,4 +352,4 @@ module.exports = Object.freeze({
345
352
  handleRuntimeError: handleRuntimeError,
346
353
  showCompileError: showCompileError,
347
354
  showRuntimeErrors: showRuntimeErrors,
348
- });
355
+ });
@@ -59,7 +59,7 @@ function removeAllChildren(element, skip) {
59
59
  /** @type {Node[]} */
60
60
  const childList = Array.prototype.slice.call(
61
61
  element.childNodes,
62
- typeof skip !== 'undefined' ? skip : 0
62
+ typeof skip !== 'undefined' ? skip : 0,
63
63
  );
64
64
 
65
65
  for (let i = 0; i < childList.length; i += 1) {
@@ -1,23 +1,23 @@
1
1
  // Thanks https://github.com/pmmmwh/react-refresh-webpack-plugin
2
- const RefreshUtils = require("./refreshUtils");
3
- const RefreshRuntime = require("react-refresh/runtime");
2
+ const RefreshUtils = require('./refreshUtils');
3
+ const RefreshRuntime = require('react-refresh/runtime');
4
4
 
5
5
  // Port from https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/loader/utils/getRefreshModuleRuntime.js#L29
6
6
  function refresh(moduleId, webpackHot) {
7
- const currentExports = RefreshUtils.getModuleExports(moduleId);
8
- const fn = exports => {
9
- RefreshUtils.executeRuntime(exports, moduleId, webpackHot);
10
- };
11
- if (typeof Promise !== "undefined" && currentExports instanceof Promise) {
12
- currentExports.then(fn);
13
- } else {
14
- fn(currentExports);
15
- }
7
+ const currentExports = RefreshUtils.getModuleExports(moduleId);
8
+ const fn = (exports) => {
9
+ RefreshUtils.executeRuntime(exports, moduleId, webpackHot);
10
+ };
11
+ if (typeof Promise !== 'undefined' && currentExports instanceof Promise) {
12
+ currentExports.then(fn);
13
+ } else {
14
+ fn(currentExports);
15
+ }
16
16
  }
17
17
 
18
18
  module.exports = {
19
- refresh,
20
- register: RefreshRuntime.register,
21
- createSignatureFunctionForTransform:
22
- RefreshRuntime.createSignatureFunctionForTransform
19
+ refresh,
20
+ register: RefreshRuntime.register,
21
+ createSignatureFunctionForTransform:
22
+ RefreshRuntime.createSignatureFunctionForTransform,
23
23
  };
@@ -8,53 +8,53 @@
8
8
  * https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/0b960573797bf38926937994c481e4fec9ed8aa6/LICENSE
9
9
  */
10
10
 
11
- var RefreshRuntime = require("react-refresh/runtime");
11
+ var RefreshRuntime = require('react-refresh/runtime');
12
12
  var safeThis = (function () {
13
- // copied from core-js-pure/features/global-this
14
- "use strict";
13
+ // copied from core-js-pure/features/global-this
14
+ 'use strict';
15
15
 
16
- var check = function (it) {
17
- return it && it.Math == Math && it;
18
- };
16
+ var check = function (it) {
17
+ return it && it.Math == Math && it;
18
+ };
19
19
 
20
- // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
21
- // eslint-disable-next-line es/no-global-this -- safe
22
- return (
23
- check(typeof globalThis == "object" && globalThis) ||
24
- check(typeof window == "object" && window) ||
25
- // eslint-disable-next-line no-restricted-globals -- safe
26
- check(typeof self == "object" && self) ||
27
- check(typeof __webpack_require__.g == "object" && __webpack_require__.g) ||
28
- // eslint-disable-next-line no-new-func -- fallback
29
- (function () {
30
- return this;
31
- })() ||
32
- this ||
33
- Function("return this")()
34
- );
20
+ // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
21
+ // eslint-disable-next-line es/no-global-this -- safe
22
+ return (
23
+ check(typeof globalThis == 'object' && globalThis) ||
24
+ check(typeof window == 'object' && window) ||
25
+ // eslint-disable-next-line no-restricted-globals -- safe
26
+ check(typeof self == 'object' && self) ||
27
+ check(typeof __webpack_require__.g == 'object' && __webpack_require__.g) ||
28
+ // eslint-disable-next-line no-new-func -- fallback
29
+ (function () {
30
+ return this;
31
+ })() ||
32
+ this ||
33
+ Function('return this')()
34
+ );
35
35
  })();
36
36
 
37
- if (process.env.NODE_ENV !== "production") {
38
- if (typeof safeThis !== "undefined") {
39
- var $RefreshInjected$ = "__reactRefreshInjected";
40
- // Namespace the injected flag (if necessary) for monorepo compatibility
41
- if (
42
- typeof __react_refresh_library__ !== "undefined" &&
43
- __react_refresh_library__
44
- ) {
45
- $RefreshInjected$ += "_" + __react_refresh_library__;
46
- }
37
+ if (process.env.NODE_ENV !== 'production') {
38
+ if (typeof safeThis !== 'undefined') {
39
+ var $RefreshInjected$ = '__reactRefreshInjected';
40
+ // Namespace the injected flag (if necessary) for monorepo compatibility
41
+ if (
42
+ typeof __react_refresh_library__ !== 'undefined' &&
43
+ __react_refresh_library__
44
+ ) {
45
+ $RefreshInjected$ += '_' + __react_refresh_library__;
46
+ }
47
47
 
48
- // Only inject the runtime if it hasn't been injected
49
- if (!safeThis[$RefreshInjected$]) {
50
- RefreshRuntime.injectIntoGlobalHook(safeThis);
48
+ // Only inject the runtime if it hasn't been injected
49
+ if (!safeThis[$RefreshInjected$]) {
50
+ RefreshRuntime.injectIntoGlobalHook(safeThis);
51
51
 
52
- // Empty implementation to avoid "ReferenceError: variable is not defined" in module which didn't pass builtin:react-refresh-loader
53
- safeThis.$RefreshSig$ = () => type => type;
54
- safeThis.$RefreshReg$ = () => {};
52
+ // Empty implementation to avoid "ReferenceError: variable is not defined" in module which didn't pass builtin:react-refresh-loader
53
+ safeThis.$RefreshSig$ = () => (type) => type;
54
+ safeThis.$RefreshReg$ = () => {};
55
55
 
56
- // Mark the runtime as injected to prevent double-injection
57
- safeThis[$RefreshInjected$] = true;
58
- }
59
- }
56
+ // Mark the runtime as injected to prevent double-injection
57
+ safeThis[$RefreshInjected$] = true;
58
+ }
59
+ }
60
60
  }