Skip to content

Commit 78325e7

Browse files
authored
Merge pull request #79 from rileylnapier/rileyDev
feat(Adding new component ReportChunkNames): Adds an alternative way …
2 parents d6ee9d2 + 9924963 commit 78325e7

File tree

6 files changed

+73
-7
lines changed

6 files changed

+73
-7
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,33 @@ export default function serverRender(req, res) => {
213213
`)
214214
```
215215

216+
> NOTE: this requires that the bundling and rendering happen within the same context. The module, react-universal-component/server holds a global cache of all the universal components that are rendered and makes them available via `flushChunkNames`
217+
218+
If you build step and your render step are separate (i.e. using a static site generator like `react-static`) we can use a Provider type component to locate the components that should be included on the client. This is not the recommended use of locating chunk names and only should be used when absolutely necessary. It uses React's context functionality to pass the `report` function to react-universal-component.
219+
220+
```js
221+
import { ReportChunks } from 'react-universal-component'
222+
import flushChunks from 'webpack-flush-chunks'
223+
import ReactDOM from 'react-dom/server'
224+
225+
function renderToHtml () => {
226+
let chunkNames = []
227+
const appHtml =
228+
ReactDOM.renderToString(
229+
<ReportChunks report={chunkName => chunkNames.push(chunkName)}>
230+
<App />
231+
</ReportChunks>,
232+
),
233+
)
234+
235+
const { scripts } = flushChunks(webpackStats, {
236+
chunkNames,
237+
})
238+
239+
return appHtml
240+
}
241+
```
242+
216243
217244
## Preload
218245

server.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module.exports = {
22
flushModuleIds: require('./dist/requireUniversalModule').flushModuleIds,
33
flushChunkNames: require('./dist/requireUniversalModule').flushChunkNames,
4-
clearChunks: require('./dist/requireUniversalModule').clearChunks
4+
clearChunks: require('./dist/requireUniversalModule').clearChunks,
5+
ReportChunks: require('./dist/report-chunks').default
56
}

src/flowTypes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export type OnError = (error: Object, info: { isServer: boolean }) => void
7777

7878
export type RequireAsync = (props: Object, context: Object) => Promise<?any>
7979
export type RequireSync = (props: Object, context: Object) => ?any
80-
export type AddModule = (props: Object) => void
80+
export type AddModule = (props: Object) => ?string
8181
export type Mod = Object | Function
8282
export type Tools = {
8383
requireAsync: RequireAsync,

src/index.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
import { DefaultLoading, DefaultError, isServer, createElement } from './utils'
1717

1818
export { CHUNK_NAMES, MODULE_IDS } from './requireUniversalModule'
19+
export { default as ReportChunks } from './report-chunks'
1920

2021
let hasBabelPlugin = false
2122

@@ -75,7 +76,8 @@ export default function universal<Props: Props>(
7576
}
7677

7778
static contextTypes = {
78-
store: PropTypes.object
79+
store: PropTypes.object,
80+
report: PropTypes.func
7981
}
8082

8183
constructor(props: Props, context: {}) {
@@ -102,7 +104,11 @@ export default function universal<Props: Props>(
102104
}
103105

104106
this._asyncOnly = asyncOnly
105-
addModule(this.props) // record the module for SSR flushing :)
107+
const chunkName = addModule(this.props) // record the module for SSR flushing :)
108+
109+
if (this.context.report) {
110+
this.context.report(chunkName)
111+
}
106112

107113
if (Component || isServer) {
108114
this.handleBefore(true, true, isServer)

src/report-chunks.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// @flow
2+
3+
import React from 'react'
4+
import PropTypes from 'prop-types'
5+
6+
type Props = {
7+
report: Function,
8+
children: Object
9+
}
10+
11+
export default class ReportChunks extends React.Component<void, Props, *> {
12+
static propTypes = {
13+
report: PropTypes.func.isRequired
14+
}
15+
16+
static childContextTypes = {
17+
report: PropTypes.func.isRequired
18+
}
19+
20+
getChildContext() {
21+
return {
22+
report: this.props.report
23+
}
24+
}
25+
26+
render() {
27+
return React.Children.only(this.props.children)
28+
}
29+
}

src/requireUniversalModule.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,21 +133,24 @@ export default function requireUniversalModule<Props: Props>(
133133
return prom
134134
}
135135

136-
const addModule = (props: Object): void => {
136+
const addModule = (props: Object): ?string => {
137137
if (isServer || isTest) {
138138
if (chunkName) {
139139
const name = callForString(chunkName, props)
140140
if (name) CHUNK_NAMES.add(name)
141-
if (!isTest) return // makes tests way smaller to run both kinds
141+
if (!isTest) return name // makes tests way smaller to run both kinds
142142
}
143143

144144
if (isWebpack()) {
145145
const weakId = callForString(resolve, props)
146146
if (weakId) MODULE_IDS.add(weakId)
147+
return weakId
147148
}
148-
else if (!isWebpack()) {
149+
150+
if (!isWebpack()) {
149151
const modulePath = callForString(path, props)
150152
if (modulePath) MODULE_IDS.add(modulePath)
153+
return modulePath
151154
}
152155
}
153156
}

0 commit comments

Comments
 (0)