Skip to content
This repository was archived by the owner on Oct 9, 2023. It is now read-only.

Commit 56f071f

Browse files
author
Wing Leung
committed
split client and server logic
1 parent 2c66583 commit 56f071f

File tree

6 files changed

+180
-1
lines changed

6 files changed

+180
-1
lines changed

client.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./lib/client.js');

server.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./lib/server.js');

src/client.js

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import hypernova, { load } from 'hypernova';
4+
5+
export const renderReact = (name, component) => hypernova({
6+
server() {},
7+
8+
client() {
9+
const payloads = load(name);
10+
11+
if (payloads) {
12+
payloads.forEach((payload) => {
13+
const { node, data } = payload;
14+
const element = React.createElement(component, data);
15+
16+
if (ReactDOM.hydrate) {
17+
ReactDOM.hydrate(element, node);
18+
} else {
19+
ReactDOM.render(element, node);
20+
}
21+
});
22+
}
23+
24+
return component;
25+
},
26+
});
27+
28+
export const renderReactStatic = () => hypernova({
29+
server() {},
30+
31+
client() {},
32+
});

src/server.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from 'react';
2+
import ReactDOMServer from 'react-dom/server';
3+
import hypernova, { serialize } from 'hypernova';
4+
5+
export const renderReact = (name, component) => hypernova({
6+
server() {
7+
return (props) => {
8+
const contents = ReactDOMServer.renderToString(React.createElement(component, props));
9+
return serialize(name, contents, props);
10+
};
11+
},
12+
13+
client() { },
14+
});
15+
16+
export const renderReactStatic = (name, component) => hypernova({
17+
server() {
18+
return props => ReactDOMServer.renderToStaticMarkup(React.createElement(component, props));
19+
},
20+
21+
client() {},
22+
});

test/renderReact-test.js

+89-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import ifReact from 'enzyme-adapter-react-helper/build/ifReact';
66

77
import ExampleReactComponent from './components/ExampleReactComponent';
88
import { renderReact } from '..';
9+
import { renderReact as renderReactClient } from '../lib/client';
10+
import { renderReact as renderReactServer } from '../lib/server';
911

1012
describe('renderReact', () => {
1113
let result;
@@ -40,11 +42,81 @@ describe('renderReact', () => {
4042

4143
assert(hydrateMethod.calledOnce);
4244

45+
hydrateMethod.restore();
46+
4347
delete global.window;
4448
delete global.document;
4549

50+
done();
51+
});
52+
});
53+
54+
it('calls hypernova.client (render method)', (done) => {
55+
jsdom.env(result, (err, window) => {
56+
if (err) {
57+
done(err);
58+
return;
59+
}
60+
61+
const sandbox = sinon.createSandbox();
62+
if (ReactDOM.hydrate) {
63+
sandbox.stub(ReactDOM, 'hydrate').value(undefined);
64+
}
65+
66+
const renderMethod = sinon.spy(ReactDOM, 'render');
67+
68+
global.window = window;
69+
global.document = window.document;
70+
71+
// Calling it again for the client.
72+
renderReact('ExampleReactComponent', ExampleReactComponent);
73+
74+
assert(renderMethod.calledOnce);
75+
76+
sandbox.restore();
77+
renderMethod.restore();
78+
79+
delete global.window;
80+
delete global.document;
81+
82+
done();
83+
});
84+
});
85+
});
86+
87+
describe('renderReact client side endpoint', () => {
88+
let result;
89+
beforeEach(() => {
90+
result = renderReact('ExampleReactComponent', ExampleReactComponent)({ name: 'Desmond' });
91+
});
92+
93+
it('exists', () => {
94+
assert.isFunction(renderReactClient);
95+
assert.equal(renderReactClient.length, 2);
96+
});
97+
98+
ifReact('>= 16', it, it.skip)('calls hypernova.client (hydrate method)', (done) => {
99+
jsdom.env(result, (err, window) => {
100+
if (err) {
101+
done(err);
102+
return;
103+
}
104+
105+
global.window = window;
106+
global.document = window.document;
107+
108+
const hydrateMethod = sinon.spy(ReactDOM, 'hydrate');
109+
110+
// Calling it again for the client.
111+
renderReactClient('ExampleReactComponent', ExampleReactComponent);
112+
113+
assert(hydrateMethod.calledOnce);
114+
46115
hydrateMethod.restore();
47116

117+
delete global.window;
118+
delete global.document;
119+
48120
done();
49121
});
50122
});
@@ -67,16 +139,32 @@ describe('renderReact', () => {
67139
global.document = window.document;
68140

69141
// Calling it again for the client.
70-
renderReact('ExampleReactComponent', ExampleReactComponent);
142+
renderReactClient('ExampleReactComponent', ExampleReactComponent);
71143

72144
assert(renderMethod.calledOnce);
73145

74146
sandbox.restore();
75147

148+
renderMethod.restore();
149+
76150
delete global.window;
77151
delete global.document;
78152

79153
done();
80154
});
81155
});
82156
});
157+
158+
describe('renderReact server side endpoint', () => {
159+
it('exists', () => {
160+
assert.isFunction(renderReactServer);
161+
assert.equal(renderReactServer.length, 2);
162+
});
163+
164+
it('has correct markup on server', () => {
165+
const result = renderReactServer('ExampleReactComponent', ExampleReactComponent)({ name: 'Desmond' });
166+
167+
assert.isString(result);
168+
assert.match(result, /Hello Desmond/);
169+
});
170+
});

test/renderReactStatic-test.js

+35
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { assert } from 'chai';
22

33
import ExampleReactComponent from './components/ExampleReactComponent';
44
import { renderReactStatic } from '..';
5+
import { renderReactStatic as renderReactStaticServer } from '../lib/server';
56

67
describe('renderReactStatic', () => {
78
let result;
@@ -19,3 +20,37 @@ describe('renderReactStatic', () => {
1920
assert.match(result, /Hello Zack/);
2021
});
2122
});
23+
24+
describe('renderReactStatic server side endpoint', () => {
25+
let result;
26+
beforeEach(() => {
27+
result = renderReactStaticServer('ExampleReactComponent', ExampleReactComponent)({ name: 'Zack' });
28+
});
29+
30+
it('exists', () => {
31+
assert.isFunction(renderReactStaticServer);
32+
assert.equal(renderReactStaticServer.length, 2);
33+
});
34+
35+
it('has correct markup on server', () => {
36+
assert.isString(result);
37+
assert.match(result, /Hello Zack/);
38+
});
39+
});
40+
41+
describe('renderReactStatic server side endpoint', () => {
42+
let result;
43+
beforeEach(() => {
44+
result = renderReactStaticServer('ExampleReactComponent', ExampleReactComponent)({ name: 'Zack' });
45+
});
46+
47+
it('exists', () => {
48+
assert.isFunction(renderReactStaticServer);
49+
assert.equal(renderReactStaticServer.length, 2);
50+
});
51+
52+
it('has correct markup on server', () => {
53+
assert.isString(result);
54+
assert.match(result, /Hello Zack/);
55+
});
56+
});

0 commit comments

Comments
 (0)