Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,8 @@ tasks.register('bundleReactForTest', NpmTask) {
environment = ['FORCE_COLOR': 'true']
}

tasks.register('bundleReactServerBrowserForTest', NpmTask) {
dependsOn npmInstall
args = ['run', 'build:react-server-browser-test-bundle']
inputs.file('src/test/js/react-bundle-server-browser-entry.js')
inputs.file('package-lock.json')
outputs.file('build/resources/test/test-fixtures/react-bundle-server-browser.js')
environment = ['FORCE_COLOR': 'true']
}

test {
dependsOn bundleReactForTest, bundleReactServerBrowserForTest
dependsOn bundleReactForTest
useJUnitPlatform {
}
}
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@
"postcov": "npm run lcov",
"reinstall": "npm run clean && npm run local",
"build:react-test-bundle": "esbuild src/test/js/react-bundle-entry.js --bundle --format=iife --platform=neutral --define:process.env.NODE_ENV=\\\"production\\\" --outfile=build/resources/test/test-fixtures/react-bundle.js",
"build:react-server-browser-test-bundle": "esbuild src/test/js/react-bundle-server-browser-entry.js --bundle --format=iife --platform=neutral --define:process.env.NODE_ENV=\\\"production\\\" --outfile=build/resources/test/test-fixtures/react-bundle-server-browser.js",
"rollup:nodePolyfills": "npx rollup --config rollup.config.nodePolyfills.mjs",
"test": "npm run test:jest && npm run test:deno",
"test:deno": "deno test --coverage=build/deno/coverage --env-file=src/deno/.env --importmap=src/deno/importmap.json --no-check src/deno/**/*.test.ts",
Expand Down
29 changes: 0 additions & 29 deletions src/main/resources/lib/enonic/polyfill-react4xp/nodePolyfills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,6 @@ import {TextEncoder} from '@sinonjs/text-encoding';
import 'core-js/modules/web.atob.js';
import 'core-js/modules/web.btoa.js';

// Transitional MessageChannel shim: react-dom/server.browser constructs a
// MessageChannel at module-load time (unconditionally, before any render call) for
// its streaming scheduler. With this minimal polyfill, the module loads and
// renderToString — which doesn't touch the channel — works.
//
// LIMITATIONS: postMessage is intentionally a no-op. The streaming APIs
// (renderToReadableStream, prerender) WILL silently hang because the no-op timers
// can never deliver messages. For streaming, consumers must use
// react-dom/server.edge (which has no MessageChannel dependency).
//
// Remove this once @enonic/react4xp's webpack config aliases react-dom/server to
// react-dom/server.edge — see https://github.com/facebook/react/issues/31827
function MessagePortShim(this: { onmessage: ((ev: { data: unknown }) => void) | null; postMessage: (data: unknown) => void }) {
this.onmessage = null;
this.postMessage = function () { /* no-op: SSR has no async */ };
}

(function (context) {
//──────────────────────────────────────────────────────────────────────────
// Timers: When doing SSR it makes no sense to do anything asyncronously.
Expand All @@ -38,17 +21,5 @@ function MessagePortShim(this: { onmessage: ((ev: { data: unknown }) => void) |
if (typeof context['TextEncoder'] === 'undefined') {
context['TextEncoder'] = TextEncoder;
}

//──────────────────────────────────────────────────────────────────────────
// MessageChannel: see comment above MessagePortShim.
//──────────────────────────────────────────────────────────────────────────
if (typeof context['MessageChannel'] === 'undefined') {
context['MessageChannel'] = function MessageChannel(this: { port1: object; port2: object }) {
// @ts-expect-error TS2350: 'new' expression with non-constructor type.
this.port1 = new MessagePortShim();
// @ts-expect-error TS2350: 'new' expression with non-constructor type.
this.port2 = new MessagePortShim();
};
}
//@ts-expect-error TS2695: Left side of comma operator is unused and has no side effects.
})((1, eval)('this') as Partial<ContextWithTimers>);
Original file line number Diff line number Diff line change
Expand Up @@ -144,36 +144,6 @@ void render_real_react_component_via_server_edge()
}
}

@Test
void render_real_react_component_via_server_browser_with_message_channel_shim()
{
// server.browser constructs `new MessageChannel()` at module-load time. This test
// pins the contract that the transitional shim in nodePolyfills.ts lets the module
// load and that renderToString (via server-legacy.browser) produces HTML.
final String reactBundle = readClasspathResource( "/test-fixtures/react-bundle-server-browser.js" );

final Map<String, String> fixtures = new HashMap<>();
fixtures.put( POLYFILL_BASICS, readClasspathResource( POLYFILL_BASICS ) );
fixtures.put( POLYFILL_NODE, readClasspathResource( POLYFILL_NODE ) );
fixtures.put( CHUNKS_GLOBALS_JSON, "{ \"main\": { \"js\": \"globals.js\" } }" );
fixtures.put( GLOBALS_JS,
reactBundle + "\n" + "globalThis.React4xp = {" + " '_components/Greeter': {" + " default: function(props) {" +
" return React.createElement('h1', null, 'Hello, ' + props.name + '!');" + " }" + " }" + "};" );

final Renderer renderer = new Renderer( strictReader( fixtures ), testConfig(), 11L, engine, freshSource() );
try
{
final Map<String, String> result = renderer.render( "_components/Greeter", "{\"name\":\"World\"}", new String[0] );

assertNull( result.get( KEY_ERROR ), "expected success, got error: " + result.get( KEY_ERROR ) );
assertEquals( "<h1>Hello, World!</h1>", result.get( KEY_HTML ) );
}
finally
{
renderer.close();
}
}

@Test
void render_unknown_entry_propagates_illegal_state()
{
Expand Down
15 changes: 0 additions & 15 deletions src/test/js/react-bundle-server-browser-entry.js

This file was deleted.

Loading