Skip to content

Commit

Permalink
Merge pull request #79 from rileylnapier/rileyDev
Browse files Browse the repository at this point in the history
feat(Adding new component ReportChunkNames): Adds an alternative way …
  • Loading branch information
faceyspacey authored Dec 8, 2017
2 parents d6ee9d2 + 9924963 commit 78325e7
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 7 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,33 @@ export default function serverRender(req, res) => {
`)
```

> 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`

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.
```js
import { ReportChunks } from 'react-universal-component'
import flushChunks from 'webpack-flush-chunks'
import ReactDOM from 'react-dom/server'
function renderToHtml () => {
let chunkNames = []
const appHtml =
ReactDOM.renderToString(
<ReportChunks report={chunkName => chunkNames.push(chunkName)}>
<App />
</ReportChunks>,
),
)
const { scripts } = flushChunks(webpackStats, {
chunkNames,
})
return appHtml
}
```
## Preload
Expand Down
3 changes: 2 additions & 1 deletion server.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
flushModuleIds: require('./dist/requireUniversalModule').flushModuleIds,
flushChunkNames: require('./dist/requireUniversalModule').flushChunkNames,
clearChunks: require('./dist/requireUniversalModule').clearChunks
clearChunks: require('./dist/requireUniversalModule').clearChunks,
ReportChunks: require('./dist/report-chunks').default
}
2 changes: 1 addition & 1 deletion src/flowTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export type OnError = (error: Object, info: { isServer: boolean }) => void

export type RequireAsync = (props: Object, context: Object) => Promise<?any>
export type RequireSync = (props: Object, context: Object) => ?any
export type AddModule = (props: Object) => void
export type AddModule = (props: Object) => ?string
export type Mod = Object | Function
export type Tools = {
requireAsync: RequireAsync,
Expand Down
10 changes: 8 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
import { DefaultLoading, DefaultError, isServer, createElement } from './utils'

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

let hasBabelPlugin = false

Expand Down Expand Up @@ -75,7 +76,8 @@ export default function universal<Props: Props>(
}

static contextTypes = {
store: PropTypes.object
store: PropTypes.object,
report: PropTypes.func
}

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

this._asyncOnly = asyncOnly
addModule(this.props) // record the module for SSR flushing :)
const chunkName = addModule(this.props) // record the module for SSR flushing :)

if (this.context.report) {
this.context.report(chunkName)
}

if (Component || isServer) {
this.handleBefore(true, true, isServer)
Expand Down
29 changes: 29 additions & 0 deletions src/report-chunks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// @flow

import React from 'react'
import PropTypes from 'prop-types'

type Props = {
report: Function,
children: Object
}

export default class ReportChunks extends React.Component<void, Props, *> {
static propTypes = {
report: PropTypes.func.isRequired
}

static childContextTypes = {
report: PropTypes.func.isRequired
}

getChildContext() {
return {
report: this.props.report
}
}

render() {
return React.Children.only(this.props.children)
}
}
9 changes: 6 additions & 3 deletions src/requireUniversalModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,21 +133,24 @@ export default function requireUniversalModule<Props: Props>(
return prom
}

const addModule = (props: Object): void => {
const addModule = (props: Object): ?string => {
if (isServer || isTest) {
if (chunkName) {
const name = callForString(chunkName, props)
if (name) CHUNK_NAMES.add(name)
if (!isTest) return // makes tests way smaller to run both kinds
if (!isTest) return name // makes tests way smaller to run both kinds
}

if (isWebpack()) {
const weakId = callForString(resolve, props)
if (weakId) MODULE_IDS.add(weakId)
return weakId
}
else if (!isWebpack()) {

if (!isWebpack()) {
const modulePath = callForString(path, props)
if (modulePath) MODULE_IDS.add(modulePath)
return modulePath
}
}
}
Expand Down

0 comments on commit 78325e7

Please sign in to comment.