Skip to content

Commit

Permalink
feat($dynamicExpressions): allow apps not using the babel-plugin to c…
Browse files Browse the repository at this point in the history
…reate dynamic components just b
  • Loading branch information
faceyspacey committed Nov 14, 2017
1 parent 49afd2b commit 8cc2ec2
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 18 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ module.exports = {
'import/no-named-default': 1,
'no-unused-vars': 1,
'import/no-unresolved': 1,
'react/no-multi-comp': 1,
'flowtype/no-weak-types': 0,
camelcase: 0,
'import/no-dynamic-require': 0,
Expand Down
24 changes: 24 additions & 0 deletions __test-helpers__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,27 @@ export const dynamicBabelNodeComponent = ({ page }) => ({
id: page,
file: `${page}.js`
})

export const createDynamicComponentAndOptions = (
delay,
components,
error = new Error('test error')
) => {
const asyncImport = async page => {
await waitFor(delay)
const Component = components[page]
if (Component) return Component
throw error
}

const load = ({ page }) =>
Promise.all([asyncImport(page), 'css']).then(prom => prom[0])

const options = {
chunkName: ({ page }) => page,
path: ({ page }) => createPath(page),
resolve: ({ page }) => createPath(page)
}

return { load, options }
}
26 changes: 26 additions & 0 deletions __tests__/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,32 @@ exports[`advanced babel-plugin 2`] = `
</p>
`;

exports[`advanced componentWillReceiveProps: changes component (dynamic require) (no babel plugin) 1`] = `
<div>
Loading...
</div>
`;

exports[`advanced componentWillReceiveProps: changes component (dynamic require) (no babel plugin) 2`] = `
<p>
MyComponent
{"page":"MyComponent"}
</p>
`;

exports[`advanced componentWillReceiveProps: changes component (dynamic require) (no babel plugin) 3`] = `
<div>
Loading...
</div>
`;

exports[`advanced componentWillReceiveProps: changes component (dynamic require) (no babel plugin) 4`] = `
<p>
MyComponent
{"page":"MyComponent2"}
</p>
`;

exports[`advanced componentWillReceiveProps: changes component (dynamic require) 1`] = `
<div>
Loading...
Expand Down
31 changes: 30 additions & 1 deletion __tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import {
createDynamicComponent,
createBablePluginComponent,
createDynamicBablePluginComponent,
dynamicBabelNodeComponent
dynamicBabelNodeComponent,
createDynamicComponentAndOptions
} from '../__test-helpers__'

describe('async lifecycle', () => {
Expand Down Expand Up @@ -676,4 +677,32 @@ describe('advanced', () => {

expect(component.toJSON()).toMatchSnapshot() // loaded
})

it('componentWillReceiveProps: changes component (dynamic require) (no babel plugin)', async () => {
const components = { MyComponent, MyComponent2 }
const { load, options } = createDynamicComponentAndOptions(0, components)

const Component = universal(load, options)

class Container extends React.Component {
render() {
const page = (this.state && this.state.page) || 'MyComponent'
return <Component page={page} />
}
}

let instance
const component = renderer.create(<Container ref={i => (instance = i)} />)
expect(component.toJSON()).toMatchSnapshot() // loading...

await waitFor(2)
expect(component.toJSON()).toMatchSnapshot() // loaded

instance.setState({ page: 'MyComponent2' })

expect(component.toJSON()).toMatchSnapshot() // loading...
await waitFor(2)

expect(component.toJSON()).toMatchSnapshot() // loaded
})
})
21 changes: 4 additions & 17 deletions src/requireUniversalModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default function requireUniversalModule<Props: Props>(

const config = getConfig(isDynamic, universalConfig, options, props)
const { chunkName, path, resolve, load } = config
const asyncOnly = !path && !resolve
const asyncOnly = (!path && !resolve) || typeof chunkName === 'function'

const requireSync = (props: Object, context: Object): ?any => {
let exp = loadFromCache(chunkName, props, modCache)
Expand Down Expand Up @@ -153,23 +153,10 @@ export default function requireUniversalModule<Props: Props>(
}

const shouldUpdate = (next, prev): boolean => {
if (asyncOnly) {
const cacheKey = callForString(chunkName, next)
const cacheKey = callForString(chunkName, next)

const config = getConfig(isDynamic, universalConfig, options, prev)
const prevCacheKey = callForString(config.chunkName, prev)

return cacheKey !== prevCacheKey
}

// below is what the babel-plugin triggers

if (!prevProps) return false

const cacheKey = callForString(chunkName, props)

const config = getConfig(isDynamic, universalConfig, options, prevProps)
const prevCacheKey = callForString(config.chunkName, prevProps)
const config = getConfig(isDynamic, universalConfig, options, prev)
const prevCacheKey = callForString(config.chunkName, prev)

return cacheKey !== prevCacheKey
}
Expand Down

0 comments on commit 8cc2ec2

Please sign in to comment.