@lynx-js/react-refresh-webpack-plugin-canary 0.4.0 → 0.4.1-canary-20260708-0d8a1843

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @lynx-js/react-refresh-webpack-plugin
2
2
 
3
+ ## 0.4.1-canary-20260708040538-0d8a18437178b669c77de05c337bd9f248bfa45f
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix `isComponent is not a function` crashing the HMR runtime when ReactLynx is consumed as an async external bundle. ([#2928](https://github.com/lynx-family/lynx-stack/pull/2928))
8
+
9
+ The refresh helpers were injected via `ProvidePlugin`, whose dependency edge does not participate in async-module handling, so `@lynx-js/react/refresh` resolved to a pending Promise and `isComponent`/`flush` were `undefined`. They now ship as an ESM module (`runtime/refresh.mjs`) injected by the loader as a real import, awaited through the normal async-module machinery.
10
+
3
11
  ## 0.4.0
4
12
 
5
13
  ### Minor Changes
@@ -90,13 +90,14 @@ export class ReactRefreshRspackPlugin {
90
90
  return;
91
91
  }
92
92
  const { ProvidePlugin } = compiler.webpack;
93
- const provide = {
94
- __prefresh_utils__: path.resolve(__dirname, '../runtime/refresh.cjs'),
95
- };
93
+ // `__prefresh_utils__` is injected by the loader (`../loader.cjs`) as an ESM
94
+ // import, not here — only the optional error overlay still needs
95
+ // `ProvidePlugin`.
96
96
  if (this.#options.overlay) {
97
- provide['__prefresh_errors__'] = this.#options.overlay.module;
97
+ new ProvidePlugin({
98
+ __prefresh_errors__: this.#options.overlay.module,
99
+ }).apply(compiler);
98
100
  }
99
- new ProvidePlugin(provide).apply(compiler);
100
101
  compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
101
102
  compilation.hooks.runtimeModule.tap(PLUGIN_NAME, (runtimeModule) => {
102
103
  if (runtimeModule.name === 'hot_module_replacement') {
package/loader.cjs CHANGED
@@ -9,8 +9,27 @@ const LOADER_RUNTIME = fs.readFileSync(
9
9
  'utf-8',
10
10
  );
11
11
 
12
+ const REFRESH_RUNTIME_ABS = path.resolve(__dirname, './runtime/refresh.mjs');
13
+
12
14
  const RefreshHotLoader = function RefreshHotLoader(source, inputSourceMap) {
13
- this.callback(null, source + '\n\n' + LOADER_RUNTIME, inputSourceMap);
15
+ // Inject `__prefresh_utils__` as a real ESM import (not `ProvidePlugin`): only
16
+ // harmony edges are async-awaited, so the footer sees resolved
17
+ // `isComponent`/`flush` under async externals. Relative request keeps the
18
+ // bundler-derived binding name stable across machines/snapshots.
19
+ let request = path
20
+ .relative(path.dirname(this.resourcePath), REFRESH_RUNTIME_ABS)
21
+ .replace(/\\/g, '/');
22
+ if (!request.startsWith('.')) {
23
+ request = './' + request;
24
+ }
25
+ const importPrefreshUtils = `\nimport * as __prefresh_utils__ from ${
26
+ JSON.stringify(request)
27
+ };\n`;
28
+ this.callback(
29
+ null,
30
+ source + '\n\n' + LOADER_RUNTIME + importPrefreshUtils,
31
+ inputSourceMap,
32
+ );
14
33
  };
15
34
 
16
35
  module.exports = RefreshHotLoader;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/react-refresh-webpack-plugin-canary",
3
- "version": "0.4.0",
3
+ "version": "0.4.1-canary-20260708-0d8a1843",
4
4
  "description": "A webpack plugin to hot refresh for Lynx.",
5
5
  "keywords": [
6
6
  "webpack",
@@ -39,9 +39,9 @@
39
39
  "@rspack/lite-tapable": "1.1.0",
40
40
  "@rstest/core": "0.10.5",
41
41
  "swc-loader": "^0.2.7",
42
- "@lynx-js/react": "npm:@lynx-js/react-canary@0.121.2",
43
- "@lynx-js/react-webpack-plugin": "npm:@lynx-js/react-webpack-plugin-canary@0.9.4",
42
+ "@lynx-js/react": "npm:@lynx-js/react-canary@0.122.1",
44
43
  "@lynx-js/react-refresh": "0.1.0",
44
+ "@lynx-js/react-webpack-plugin": "npm:@lynx-js/react-webpack-plugin-canary@0.9.5",
45
45
  "@lynx-js/test-tools": "0.0.0"
46
46
  },
47
47
  "peerDependencies": {
@@ -1,4 +1,8 @@
1
- const { isComponent, flush } = require('@lynx-js/react/refresh');
1
+ // ESM (imported via `../loader.cjs`), not `ProvidePlugin`:
2
+ // `@lynx-js/react/refresh` is an async module under async externals, and only a
3
+ // harmony import edge is awaited, so the injected footer sees resolved
4
+ // `isComponent`/`flush`.
5
+ import { flush, isComponent } from '@lynx-js/react/refresh';
2
6
 
3
7
  // eslint-disable-next-line
4
8
  const getExports = m => m.exports || m.__proto__.exports;
@@ -52,9 +56,4 @@ const shouldBind = m => {
52
56
  return isCitizen;
53
57
  };
54
58
 
55
- module.exports = Object.freeze({
56
- getExports,
57
- shouldBind,
58
- flush,
59
- registerExports,
60
- });
59
+ export { flush, getExports, registerExports, shouldBind };