rollipop 1.0.0-beta.2 → 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.
@@ -14,6 +14,14 @@ const command = {
14
14
  description: "Path to the CLI configuration file",
15
15
  parse: resolvePath
16
16
  },
17
+ {
18
+ name: "--config-cmd <string>",
19
+ description: "Accepted for React Native Xcode compatibility; ignored."
20
+ },
21
+ {
22
+ name: "--load-config <string>",
23
+ description: "Accepted for React Native Xcode compatibility; ignored."
24
+ },
17
25
  {
18
26
  name: "--entry-file <path>",
19
27
  description: "Path to the root JS file, either absolute or relative to JS root"
package/dist/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "1.0.0-beta.2";
2
+ var version = "1.0.0-beta.4";
3
3
  //#endregion
4
4
  export { version };
@@ -21,7 +21,7 @@ var RollipopDevframeController = class {
21
21
  this.definition = defineDevframe({
22
22
  id: "rollipop",
23
23
  name: "Rollipop",
24
- version: "1.0.0-beta.2",
24
+ version: "1.0.0-beta.4",
25
25
  packageName: "rollipop",
26
26
  homepage: "https://github.com/rollipop-dev/rollipop",
27
27
  description: "React Native development dashboard powered by Rollipop.",
@@ -16,7 +16,7 @@ async function setupDevframe(context, server, inspectorDeviceServer) {
16
16
  const controller = new RollipopDevframeController(context, createAgentToolContext(context));
17
17
  const devtools = initHub({
18
18
  name: DEVFRAME_NAME,
19
- version: "1.0.0-beta.2",
19
+ version: "1.0.0-beta.4",
20
20
  base: ROLLIPOP_DEVFRAME_BASE,
21
21
  cwd: context.config.root,
22
22
  ui: createUi({
@@ -39,6 +39,9 @@ async function setupDevframe(context, server, inspectorDeviceServer) {
39
39
  mcp: mcpEnabled ? { path: ROLLIPOP_DEVFRAME_MCP_PATH } : false,
40
40
  origin: context.serverBaseUrl,
41
41
  configure: async (devtoolsContext) => {
42
+ (await devtoolsContext.rpc.sharedState.get("devframe:user-settings")).mutate((state) => {
43
+ state.autoCollapseEdgeToolbar ??= false;
44
+ });
42
45
  await controller.definition.setup(devtoolsContext);
43
46
  await invokeDevToolsSetup(devtoolsContext, server, context.config.plugins ?? []);
44
47
  }
@@ -28,7 +28,7 @@ var FileStorage = class FileStorage {
28
28
  this.dataFilePath = path.join(FileStorage.getPath(basePath, { prepare: true }), DATA_FILENAME);
29
29
  if (fs.existsSync(this.dataFilePath)) {
30
30
  const loadedData = JSON.parse(fs.readFileSync(this.dataFilePath, "utf-8"));
31
- if ("version" in loadedData && loadedData.version === "1.0.0-beta.2") this.data = loadedData;
31
+ if ("version" in loadedData && loadedData.version === "1.0.0-beta.4") this.data = loadedData;
32
32
  else {
33
33
  this.data = createDefaultData();
34
34
  this.flush();
@@ -1,3 +1,4 @@
1
+ import { resolveWorkletsConfig } from "./worklets.js";
1
2
  import { RollipopReactNativeTransformer } from "@rollipop/rolldown/experimental";
2
3
  //#region src/utils/transform.ts
3
4
  const transformers = /* @__PURE__ */ new WeakMap();
@@ -8,7 +9,7 @@ function transformWithRollipop(id, code, config) {
8
9
  envName: config.mode,
9
10
  runtimeTarget: config.runtimeTarget,
10
11
  flow: config.transform.flow,
11
- worklets: config.experimental.worklets,
12
+ worklets: resolveWorkletsConfig(config.experimental.worklets, config),
12
13
  swc: {
13
14
  externalHelpers: true,
14
15
  ...config.transform.swc?.native
@@ -0,0 +1,7 @@
1
+ import { RollipopReactNativeWorkletsConfig as WorkletsConfig } from "../config/types.js";
2
+ import "../config/index.js";
3
+ import { ResolvedConfig } from "../config/defaults.js";
4
+ import { RollipopReactNativeWorkletsConfig } from "@rollipop/rolldown/experimental";
5
+ //#region src/utils/worklets.d.ts
6
+ export declare function resolveWorkletsConfig(worklets: WorkletsConfig | undefined, { root, mode }: Pick<ResolvedConfig, 'root' | 'mode'>): RollipopReactNativeWorkletsConfig | undefined;
7
+ //#endregion
@@ -0,0 +1,32 @@
1
+ import { resolvePackageJson } from "./node-resolve.js";
2
+ import { satisfies } from "semver";
3
+ //#region src/utils/worklets.ts
4
+ function resolveWorkletsConfig(worklets, { root, mode }) {
5
+ if (worklets == null) return;
6
+ const { pluginVersion, reanimatedVersion, ...options } = worklets;
7
+ const defaults = {
8
+ ...options,
9
+ isRelease: options.isRelease ?? mode === "production"
10
+ };
11
+ if (pluginVersion != null) return {
12
+ ...defaults,
13
+ pluginVersion
14
+ };
15
+ if (reanimatedVersion != null) return {
16
+ ...defaults,
17
+ reanimatedVersion
18
+ };
19
+ const installedReanimatedVersion = resolvePackageJson(root, "react-native-reanimated")?.version;
20
+ if (installedReanimatedVersion != null && satisfies(installedReanimatedVersion, "3.x", { includePrerelease: true })) return {
21
+ ...defaults,
22
+ reanimatedVersion: installedReanimatedVersion
23
+ };
24
+ const installedWorkletsVersion = resolvePackageJson(root, "react-native-worklets")?.version;
25
+ if (installedWorkletsVersion != null) return {
26
+ ...defaults,
27
+ pluginVersion: installedWorkletsVersion
28
+ };
29
+ throw new Error("Could not resolve a worklet runtime. Install react-native-reanimated 3.x or react-native-worklets, or set reanimatedVersion or pluginVersion in the worklets configuration.");
30
+ }
31
+ //#endregion
32
+ export { resolveWorkletsConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rollipop",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.4",
4
4
  "homepage": "https://github.com/rollipop-dev/rollipop#readme",
5
5
  "bugs": {
6
6
  "url": "https://github.com/rollipop-dev/rollipop/issues"
@@ -67,8 +67,8 @@
67
67
  "@react-native-community/cli-server-api": "20.2.0",
68
68
  "@react-native-community/cli-types": "20.2.0",
69
69
  "@react-native/dev-middleware": "0.88.0",
70
- "@rollipop/dashboard": "1.0.0-beta.2",
71
- "@rollipop/rolldown": "1.1.1",
70
+ "@rollipop/dashboard": "1.0.0-beta.4",
71
+ "@rollipop/rolldown": "1.2.0",
72
72
  "@swc/core": "1.16.13",
73
73
  "@swc/helpers": "0.5.23",
74
74
  "@types/ws": "8.18.2",
@@ -2,12 +2,13 @@ import fs from 'node:fs';
2
2
  import { stripVTControlCharacters } from 'node:util';
3
3
  import vm from 'node:vm';
4
4
 
5
+ import { DevRuntime } from '@rollipop/rolldown/experimental/runtime';
5
6
  import { transformSync } from '@swc/core';
6
7
  import * as prettyFormat from 'pretty-format';
7
8
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vite-plus/test';
8
9
 
9
10
  import type { HMRContext } from '../../types/hmr';
10
- import type { HMRGraphRuntime, ModuleGraphDelta } from '../../types/runtime';
11
+ import type { HMRGraphRuntime } from '../../types/runtime';
11
12
 
12
13
  const clientCode = transformSync(
13
14
  fs.readFileSync(new URL('../hmr-client.ts', import.meta.url), 'utf8'),
@@ -18,73 +19,6 @@ const clientCode = transformSync(
18
19
  },
19
20
  ).code;
20
21
 
21
- class FakeDevRuntime {
22
- clientId: string;
23
- hooks: {
24
- createModuleHotContext(moduleId: string): unknown;
25
- onModuleCacheRemoval(moduleId: string): void;
26
- } | null = null;
27
- private readonly factories = new Map<string, (id: string) => void>();
28
- private readonly importers = new Map<string, Set<string>>();
29
- private readonly modules = new Map<string, { exports: any }>();
30
-
31
- constructor(clientId: string) {
32
- this.clientId = clientId;
33
- }
34
-
35
- registerGraph(delta: ModuleGraphDelta) {
36
- for (let index = 0; index < delta.localCount; index++) {
37
- const importer = delta.ids[index];
38
- for (const targetIndex of delta.edges[index]) {
39
- const target = delta.ids[targetIndex];
40
- const importers = this.importers.get(target) ?? new Set();
41
- importers.add(importer);
42
- this.importers.set(target, importers);
43
- }
44
- }
45
- }
46
-
47
- registerFactory(id: string, _kind: 'esm' | 'cjs', factory: (id: string) => void) {
48
- this.factories.set(id, factory);
49
- }
50
-
51
- registerModule(id: string, exportsHolder: { exports: any }) {
52
- this.modules.set(id, exportsHolder);
53
- }
54
-
55
- getImporters(id: string) {
56
- return [...(this.importers.get(id) ?? [])];
57
- }
58
-
59
- isExecuted(id: string) {
60
- return this.modules.has(id);
61
- }
62
-
63
- hasFactory(id: string) {
64
- return this.factories.has(id);
65
- }
66
-
67
- removeModuleCache(id: string) {
68
- this.modules.delete(id);
69
- this.hooks?.onModuleCacheRemoval(id);
70
- }
71
-
72
- initModule(id: string) {
73
- if (!this.modules.has(id)) {
74
- this.factories.get(id)?.(id);
75
- }
76
- return this.loadExports(id);
77
- }
78
-
79
- loadExports(id: string) {
80
- return this.modules.get(id)?.exports ?? {};
81
- }
82
-
83
- createModuleHotContext(moduleId: string) {
84
- return this.hooks?.createModuleHotContext(moduleId);
85
- }
86
- }
87
-
88
22
  class FakeWebSocket {
89
23
  static readonly CONNECTING = 0;
90
24
  static readonly OPEN = 1;
@@ -124,7 +58,7 @@ describe('HMR runtime', () => {
124
58
  reload.mockReset();
125
59
  FakeWebSocket.instances = [];
126
60
  Object.assign(globalThis, {
127
- DevRuntime: FakeDevRuntime,
61
+ DevRuntime,
128
62
  WebSocket: FakeWebSocket,
129
63
  __rollipop_runtime__: undefined,
130
64
  __turboModuleProxy: undefined,
@@ -133,6 +67,7 @@ describe('HMR runtime', () => {
133
67
  });
134
68
 
135
69
  afterEach(() => {
70
+ delete (globalThis as any).__rollipop_require__;
136
71
  delete (globalThis as any).globalEvalWithSourceUrl;
137
72
  delete (globalThis as any).__rollipop_runtime__;
138
73
  });
@@ -143,6 +78,145 @@ describe('HMR runtime', () => {
143
78
  expect((runtime.createModuleHotContext('entry.js') as any).runtime).toBe(runtime);
144
79
  });
145
80
 
81
+ describe('initial bundle factories and cache', () => {
82
+ it.each(['esm', 'cjs'])(
83
+ 'reuses an initial %s factory after eviction through either executor',
84
+ async (kind) => {
85
+ const { runtime } = await setupRuntime();
86
+ const bundleRequire = createBundleRequire();
87
+ let executions = 0;
88
+ bundleRequire.m['parent.js'] = (_global, module, exports) => {
89
+ const value = ++executions;
90
+ if (kind === 'esm') {
91
+ Object.defineProperty(exports, 'value', { get: () => value });
92
+ runtime.registerModule('parent.js', { exports });
93
+ } else {
94
+ runtime.registerModule('parent.js', module);
95
+ module.exports = () => value;
96
+ }
97
+ };
98
+ const readValue = (exports: any) => (kind === 'esm' ? exports.value : exports());
99
+
100
+ expect(runtime.hasFactory('parent.js')).toBe(true);
101
+ expect(runtime.isExecuted('parent.js')).toBe(false);
102
+ const first = bundleRequire('parent.js');
103
+ expect(runtime.initModule('parent.js')).toBe(first);
104
+ expect(runtime.loadExports('parent.js')).toBe(first);
105
+ expect(readValue(first)).toBe(1);
106
+
107
+ runtime.removeModuleCache('parent.js');
108
+ expect(bundleRequire.c['parent.js']).toBeUndefined();
109
+ expect(runtime.isExecuted('parent.js')).toBe(false);
110
+ const second = runtime.initModule('parent.js');
111
+ expect(bundleRequire('parent.js')).toBe(second);
112
+ expect(readValue(second)).toBe(2);
113
+
114
+ runtime.removeModuleCache('parent.js');
115
+ const third = bundleRequire('parent.js');
116
+ expect(runtime.loadExports('parent.js')).toBe(third);
117
+ expect(readValue(third)).toBe(3);
118
+ },
119
+ );
120
+
121
+ it.each(['esm', 'cjs'])(
122
+ 'uses the latest %s patch from ordinary require after repeated eviction',
123
+ async (kind) => {
124
+ const { runtime } = await setupRuntime();
125
+ const bundleRequire = createBundleRequire();
126
+ const original = vi.fn((_global, module: BundleModule) => {
127
+ runtime.registerModule('dep.js', module);
128
+ module.exports = { value: 'initial' };
129
+ });
130
+ bundleRequire.m['dep.js'] = original;
131
+ expect(bundleRequire('dep.js')).toEqual({ value: 'initial' });
132
+
133
+ for (let version = 1; version <= 2; version++) {
134
+ const factory = vi.fn((id: string) => {
135
+ const holder = { exports: {} as any };
136
+ runtime.registerModule(id, holder);
137
+ if (kind === 'esm') {
138
+ Object.defineProperty(holder.exports, 'value', { get: () => version });
139
+ } else {
140
+ holder.exports = () => version;
141
+ }
142
+ });
143
+ runtime.registerFactory('dep.js', factory, version);
144
+ runtime.removeModuleCache('dep.js');
145
+ const updated = runtime.initModule('dep.js');
146
+ expect(bundleRequire('dep.js')).toBe(updated);
147
+ expect(kind === 'esm' ? (updated as any).value : (updated as any)()).toBe(version);
148
+
149
+ const stale = vi.fn();
150
+ runtime.registerFactory('dep.js', stale, version - 1);
151
+ runtime.removeModuleCache('dep.js');
152
+ const reexecuted = bundleRequire('dep.js');
153
+ expect(runtime.initModule('dep.js')).toBe(reexecuted);
154
+ expect(runtime.loadExports('dep.js')).toBe(reexecuted);
155
+ expect(kind === 'esm' ? reexecuted.value : reexecuted()).toBe(version);
156
+ expect(factory).toHaveBeenCalledTimes(2);
157
+ expect(stale).not.toHaveBeenCalled();
158
+ }
159
+ expect(original).toHaveBeenCalledOnce();
160
+ },
161
+ );
162
+
163
+ it.each([null, undefined, 0, false])(
164
+ 'shares CommonJS module.exports reassignment to %s',
165
+ async (value) => {
166
+ const { runtime } = await setupRuntime();
167
+ const bundleRequire = createBundleRequire();
168
+ const module = { exports: {} as any };
169
+ runtime.registerModule('dep.cjs', module);
170
+ module.exports = value;
171
+ expect(bundleRequire('dep.cjs')).toBe(value);
172
+ expect(runtime.loadExports('dep.cjs')).toBe(value);
173
+ expect(runtime.initModule('dep.cjs')).toBe(value);
174
+ },
175
+ );
176
+
177
+ it('recognizes modules cached only by the bundle and removes both caches before disposal', async () => {
178
+ const { runtime } = await setupRuntime();
179
+ const bundleRequire = createBundleRequire();
180
+ const exports = { value: 'cached' };
181
+ bundleRequire.c['helper.js'] = { exports };
182
+ expect(runtime.isExecuted('helper.js')).toBe(true);
183
+ expect(runtime.loadExports('helper.js')).toBe(exports);
184
+ expect(runtime.initModule('helper.js')).toBe(exports);
185
+ const dispose = vi.fn(() => {
186
+ expect(bundleRequire.c['helper.js']).toBeUndefined();
187
+ expect(runtime.isExecuted('helper.js')).toBe(false);
188
+ });
189
+ runtime.createModuleHotContext('helper.js').dispose(dispose);
190
+ runtime.removeModuleCache('helper.js');
191
+ expect(dispose).toHaveBeenCalledOnce();
192
+ });
193
+
194
+ it('shares the bundle holder when a side-effect module registers without exports', async () => {
195
+ const { runtime } = await setupRuntime();
196
+ const bundleRequire = createBundleRequire();
197
+ bundleRequire.m['side-effect.js'] = () => runtime.registerModule('side-effect.js');
198
+ const exports = bundleRequire('side-effect.js');
199
+ expect(bundleRequire('side-effect.js')).toBe(exports);
200
+ expect(runtime.initModule('side-effect.js')).toBe(exports);
201
+ expect(runtime.loadExports('side-effect.js')).toBe(exports);
202
+ });
203
+
204
+ it('reloads when an invalidated non-component module has no accepting ancestor', async () => {
205
+ const { runtime } = await setupRuntime();
206
+ const bundleRequire = createBundleRequire();
207
+ runtime.registerGraph({ ids: ['route.js', 'entry.js'], localCount: 2, edges: [[], [0]] });
208
+ const entry = vi.fn((_global, module: BundleModule) => {
209
+ runtime.registerModule('entry.js', module);
210
+ runtime.registerModule('route.js', { exports: { Router: {} } });
211
+ });
212
+ bundleRequire.m['entry.js'] = entry;
213
+ bundleRequire('entry.js');
214
+ runtime.createModuleHotContext('route.js').invalidate();
215
+ await vi.waitFor(() => expect(reload).toHaveBeenCalledOnce());
216
+ expect(entry).toHaveBeenCalledOnce();
217
+ });
218
+ });
219
+
146
220
  describe('client logs', () => {
147
221
  const formatter = { format: prettyFormat.format, plugins: prettyFormat.plugins };
148
222
 
@@ -527,7 +601,7 @@ describe('HMR runtime', () => {
527
601
  const evaluate = vi.fn((source: string) => (0, eval)(source));
528
602
  globalThis.globalEvalWithSourceUrl = evaluate;
529
603
  const { runtime, socket } = await setupRuntime();
530
- runtime.registerFactory('dep.js', 'esm', (id) => {
604
+ runtime.registerFactory('dep.js', (id) => {
531
605
  runtime.registerModule(id, { exports: { value: 'before' } });
532
606
  });
533
607
 
@@ -565,7 +639,7 @@ describe('HMR runtime', () => {
565
639
  });
566
640
  runtime.registerModule('dep.js', { exports: {} });
567
641
  runtime.registerModule('entry.js', { exports: { value: 'before' } });
568
- runtime.registerFactory('entry.js', 'esm', (id) => {
642
+ runtime.registerFactory('entry.js', (id) => {
569
643
  runtime.registerModule(id, { exports: { value: 'after' } });
570
644
  runtime.createModuleHotContext(id).accept();
571
645
  });
@@ -711,9 +785,34 @@ function createPatch(value: string, createHotContext = true) {
711
785
  edges: [[], [0]],
712
786
  dynamicEdges: [[], []]
713
787
  });
714
- __rolldown_runtime__.registerFactory("dep.js", "esm", function (id) {
788
+ __rolldown_runtime__.registerFactory("dep.js", function (id) {
715
789
  __rolldown_runtime__.registerModule(id, { exports: { value: "${value}" } });
716
790
  ${createHotContext ? '__rolldown_runtime__.createModuleHotContext(id);' : ''}
717
791
  });
718
792
  })(globalThis.__rollipop_runtime__.graphs.get("host").runtime);`;
719
793
  }
794
+
795
+ type BundleModule = { exports: any };
796
+ type BundleRequire = {
797
+ (id: string): any;
798
+ m: Record<
799
+ string,
800
+ (global: unknown, module: BundleModule, exports: any, require: BundleRequire) => void
801
+ >;
802
+ c: Record<string, BundleModule>;
803
+ };
804
+
805
+ function createBundleRequire() {
806
+ const require: BundleRequire = Object.assign(
807
+ (id: string) => {
808
+ if (require.c[id] !== undefined) return require.c[id].exports;
809
+ const module = { exports: {} };
810
+ require.c[id] = module;
811
+ require.m[id].call(module.exports, globalThis, module, module.exports, require);
812
+ return module.exports;
813
+ },
814
+ { m: {} as BundleRequire['m'], c: {} as BundleRequire['c'] },
815
+ );
816
+ (globalThis as any).__rollipop_require__ = require;
817
+ return require;
818
+ }
@@ -315,7 +315,7 @@ class HMRClient implements HMRClientNativeInterface {
315
315
  case 'hmr:update-start':
316
316
  connection.pendingUpdatesCount++;
317
317
  connection.compileErrorMessage = null;
318
- DevLoadingView.showMessage(`Refreshing ${connection.graph.id}...`, 'refresh');
318
+ DevLoadingView.showMessage('Refreshing...', 'refresh');
319
319
  break;
320
320
  case 'hmr:update':
321
321
  this.dismissRedbox();
@@ -25,6 +25,19 @@ declare global {
25
25
  // DO NOT EDIT THIS CLASS NAME (`DevRuntime`)
26
26
  declare const DevRuntime: typeof DefaultDevRuntime;
27
27
 
28
+ type BundleModule = { exports: any };
29
+ interface BundleRequire {
30
+ (id: string): any;
31
+ m: Record<
32
+ string,
33
+ (global: unknown, module: BundleModule, exports: any, require: BundleRequire) => void
34
+ >;
35
+ c: Record<string, BundleModule>;
36
+ }
37
+
38
+ // Defined in the enclosing Rollipop bundle, separately for each bundle runtime.
39
+ declare const __rollipop_require__: BundleRequire;
40
+
28
41
  var BaseDevRuntime = DevRuntime;
29
42
 
30
43
  interface AcceptCallback {
@@ -194,6 +207,69 @@ class ReactNativeDevRuntime extends BaseDevRuntime {
194
207
  };
195
208
  }
196
209
 
210
+ hasFactory(moduleId: string) {
211
+ return (
212
+ super.hasFactory(moduleId) ||
213
+ (typeof __rollipop_require__ !== 'undefined' && __rollipop_require__.m[moduleId] != null)
214
+ );
215
+ }
216
+
217
+ isExecuted(moduleId: string) {
218
+ return (
219
+ super.isExecuted(moduleId) ||
220
+ (typeof __rollipop_require__ !== 'undefined' && __rollipop_require__.c[moduleId] != null)
221
+ );
222
+ }
223
+
224
+ loadExports(moduleId: string) {
225
+ if (!super.isExecuted(moduleId) && typeof __rollipop_require__ !== 'undefined') {
226
+ const module = __rollipop_require__.c[moduleId];
227
+ if (module != null) {
228
+ return module.exports;
229
+ }
230
+ }
231
+ return super.loadExports(moduleId);
232
+ }
233
+
234
+ initModule(moduleId: string) {
235
+ if (this.isExecuted(moduleId)) {
236
+ return this.loadExports(moduleId);
237
+ }
238
+ if (super.hasFactory(moduleId) || !this.hasFactory(moduleId)) {
239
+ return super.initModule(moduleId);
240
+ }
241
+ return __rollipop_require__(moduleId);
242
+ }
243
+
244
+ registerFactory(moduleId: string, factory: (id: string) => void, stamp?: number) {
245
+ super.registerFactory(moduleId, factory, stamp);
246
+ if (typeof __rollipop_require__ !== 'undefined') {
247
+ __rollipop_require__.m[moduleId] = (_global, module) => {
248
+ // require() has already inserted an empty cache entry.
249
+ // The base executor bypasses that entry and selects the latest factory accepted by its stamp.
250
+ module.exports = super.initModule(moduleId);
251
+ };
252
+ }
253
+ }
254
+
255
+ registerModule(moduleId: string, module?: BundleModule) {
256
+ module ??=
257
+ typeof __rollipop_require__ !== 'undefined' ? __rollipop_require__.c[moduleId] : undefined;
258
+ module ??= { exports: {} };
259
+ super.registerModule(moduleId, module);
260
+ if (typeof __rollipop_require__ !== 'undefined') {
261
+ // Share the holder itself so CommonJS module.exports reassignments stay live.
262
+ __rollipop_require__.c[moduleId] = module;
263
+ }
264
+ }
265
+
266
+ removeModuleCache(moduleId: string) {
267
+ if (typeof __rollipop_require__ !== 'undefined') {
268
+ delete __rollipop_require__.c[moduleId];
269
+ }
270
+ super.removeModuleCache(moduleId);
271
+ }
272
+
197
273
  private createHotContext(moduleId: string) {
198
274
  let data = this.moduleHotData.get(moduleId);
199
275
  if (data == null) {