Skip to content

Commit

Permalink
V4.0.0 (#176)
Browse files Browse the repository at this point in the history
* #129

* Change getDerivedStateFromProps to componentDidUpdate

* Change getDerivedStateFromProps to componentDidUpdate

* HMR now works

* All errors fixed. All tests run successfull. Before polishing.

* Polish

* Moving chunk name resolution back to slashes

* new 4v branch

* merges and bumping version

* adding codeowners

* usesBabelPlugin added back

* feat: Updated RUC to react 16.3 and up

Moving away from deprecated willMount and to the non-deprecated lifecycle

BREAKING CHANGE: Only Compatible with React 16.3 and up

* fix: ignore babel rename by default

* flow types

* updated yarn locks
  • Loading branch information
ScriptedAlchemy authored Feb 22, 2019
1 parent 3eeaa58 commit 3c21ffa
Show file tree
Hide file tree
Showing 7 changed files with 2,308 additions and 917 deletions.
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# babel-plugin-universal-import maintainers
* @ScriptedAlchemy
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ node_modules
*.log
.idea
.DS_Store
.history
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "react-universal-component",
"version": "0.0.0-development",
"version": "4.0.0-alpha.4",
"description": "A higher order component for loading components with promises",
"main": "dist/index.js",
"typings": "index.d.ts",
"author": "James FaceySpacey Gillmore <[email protected]> (http://www.faceyspacey.com)",
"contributors": [
"Zack Jackson <zackary.l.jackson@gmail.com> (https://github.com/ScriptedAlchemy)"
"Zack Jackson <zack@ScriptedAlchemy.com> (https://github.com/ScriptedAlchemy)"
],
"license": "MIT",
"bugs": {
Expand Down Expand Up @@ -65,15 +65,15 @@
"jest": "^20.0.4",
"lint-staged": "^7.2.0",
"prettier": "^1.3.1",
"react": "^16.4.1",
"react-test-renderer": "^16.4.1",
"react": "^16.4.2",
"react-test-renderer": "^16.4.2",
"rimraf": "^2.5.4",
"semantic-release": "^6.3.6",
"slash": "^1.0.0",
"travis-github-status": "^1.6.3"
},
"peerDependencies": {
"react": "*"
"react": "^16.3.0"
},
"config": {
"commitizen": {
Expand All @@ -93,6 +93,7 @@
},
"dependencies": {
"hoist-non-react-statics": "^2.2.1",
"prop-types": "^15.5.10"
"prop-types": "^15.5.10",
"react-hot-loader": "^4.3.6"
}
}
40 changes: 40 additions & 0 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import hoist from 'hoist-non-react-statics'
import UniversalComponent from './index'

export const __update = (
props,
state,
isInitialized,
isMount = false,
isSync = false,
isServer = false
) => {
if (!isInitialized) return state
if (!state.error) {
state.error = null
}
return __handleAfter(props, state, isMount, isSync, isServer)
}

/* eslint class-methods-use-this: ["error", { "exceptMethods": ["__handleAfter"] }] */
export const __handleAfter = (props, state, isMount, isSync, isServer) => {
const { mod, error } = state

if (mod && !error) {
hoist(UniversalComponent, mod, {
preload: true,
preloadWeak: true
})

if (props.onAfter) {
const { onAfter } = props
const info = { isMount, isSync, isServer }
onAfter(info, mod)
}
}
else if (error && props.onError) {
props.onError(error)
}

return state
}
229 changes: 131 additions & 98 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import React from 'react'
import PropTypes from 'prop-types'
import hoist from 'hoist-non-react-statics'
import { Context } from 'vm'
import req from './requireUniversalModule'

import type {
Config,
ConfigFunc,
Expand All @@ -19,6 +19,7 @@ import {
createDefaultRender,
isServer
} from './utils'
import { __update } from './helpers'

export { CHUNK_NAMES, MODULE_IDS } from './requireUniversalModule'
export { default as ReportChunks } from './report-chunks'
Expand Down Expand Up @@ -48,7 +49,7 @@ export default function universal<Props: Props>(
...options
} = opts

const render = userRender || createDefaultRender(Loading, Err)
const renderFunc = userRender || createDefaultRender(Loading, Err)

const isDynamic = hasBabelPlugin || testBabelPlugin
options.isDynamic = isDynamic
Expand All @@ -58,7 +59,7 @@ export default function universal<Props: Props>(

return class UniversalComponent extends React.Component<void, Props, *> {
/* eslint-disable react/sort-comp */
_mounted: boolean
_initialized: boolean
_asyncOnly: boolean

state: State
Expand Down Expand Up @@ -112,103 +113,22 @@ export default function universal<Props: Props>(
report: PropTypes.func
}

constructor(props: Props, context: {}) {
super(props, context)
this.state = { error: null }
}

componentWillMount() {
this._mounted = true

const { addModule, requireSync, requireAsync, asyncOnly } = req(
asyncModule,
options,
this.props
)

let mod

try {
mod = requireSync(this.props, this.context)
}
catch (error) {
return this.update({ error })
}

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

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

if (mod || isServer) {
this.handleBefore(true, true, isServer)
this.update({ mod }, true, true, isServer)
return
}

this.handleBefore(true, false)
this.requireAsync(requireAsync, this.props, true)
}

componentWillUnmount() {
this._mounted = false
}

componentWillReceiveProps(nextProps: Props) {
if (isDynamic || this._asyncOnly) {
const { requireSync, requireAsync, shouldUpdate } = req(
asyncModule,
options,
nextProps,
this.props
)

if (shouldUpdate(nextProps, this.props)) {
let mod

try {
mod = requireSync(nextProps, this.context)
}
catch (error) {
return this.update({ error })
}

this.handleBefore(false, !!mod)

if (!mod) {
return this.requireAsync(requireAsync, nextProps)
}

const state = { mod }

if (alwaysDelay) {
if (loadingTransition) this.update({ mod: null }) // display `loading` during componentWillReceiveProps
setTimeout(() => this.update(state, false, true), minDelay)
return
}

this.update(state, false, true)
}
else if (isHMR()) {
const mod = requireSync(nextProps, this.context)
this.setState({ mod: () => null }) // HMR /w Redux and HOCs can be finicky, so we
setTimeout(() => this.setState({ mod })) // toggle components to insure updates occur
}
}
}

requireAsync(requireAsync: RequireAsync, props: Props, isMount?: boolean) {
if (this.state.mod && loadingTransition) {
this.update({ mod: null }) // display `loading` during componentWillReceiveProps
requireAsyncInner(
requireAsync: RequireAsync,
props: Props,
state: State,
context: Context,
isMount?: boolean
) {
if (!state.mod && loadingTransition) {
this.update({ mod: null, props }) // display `loading` during componentWillReceiveProps
}

const time = new Date()

requireAsync(props, this.context)
requireAsync(props, context)
.then((mod: ?any) => {
const state = { mod }
const state = { mod, props, context }

const timeLapsed = new Date() - time
if (timeLapsed < minDelay) {
Expand All @@ -218,7 +138,7 @@ export default function universal<Props: Props>(

this.update(state, isMount)
})
.catch(error => this.update({ error }))
.catch(error => this.update({ error, props, context }))
}

update = (
Expand All @@ -227,7 +147,7 @@ export default function universal<Props: Props>(
isSync?: boolean = false,
isServer?: boolean = false
) => {
if (!this._mounted) return
if (!this._initialized) return
if (!state.error) state.error = null

this.handleAfter(state, isMount, isSync, isServer)
Expand Down Expand Up @@ -271,11 +191,124 @@ export default function universal<Props: Props>(

this.setState(state)
}
// $FlowFixMe
init(props, context) {
const { addModule, requireSync, requireAsync, asyncOnly } = req(
asyncModule,
options,
props
)

let mod

try {
mod = requireSync(props, context)
}
catch (error) {
return __update(props, { error, props, context }, this._initialized)
}

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

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

if (mod || isServer) {
this.handleBefore(true, true, isServer)
return __update(
props,
{ asyncOnly, props, mod, context },
this._initialized,
true,
true,
isServer
)
}

this.handleBefore(true, false)
this.requireAsyncInner(
requireAsync,
props,
{ props, asyncOnly, mod, context },
context,
true
)
return { mod, asyncOnly, context, props }
}

constructor(props: Props, context: {}) {
super(props, context)
this.state = this.init(this.props, this.context)
// $FlowFixMe
this.state.error = null
}

static getDerivedStateFromProps(nextProps, currentState) {
const { requireSync, shouldUpdate } = req(
asyncModule,
options,
nextProps,
currentState.props
)
if (isHMR() && shouldUpdate(currentState.props, nextProps)) {
const mod = requireSync(nextProps, currentState.context)
return { ...currentState, mod }
}
return null
}

componentDidMount() {
this._initialized = true
}

componentDidUpdate(prevProps: Props) {
if (isDynamic || this._asyncOnly) {
const { requireSync, requireAsync, shouldUpdate } = req(
asyncModule,
options,
this.props,
prevProps
)

if (shouldUpdate(this.props, prevProps)) {
let mod

try {
mod = requireSync(this.props, this.context)
}
catch (error) {
return this.update({ error })
}

this.handleBefore(false, !!mod)

if (!mod) {
return this.requireAsyncInner(requireAsync, this.props, { mod })
}

const state = { mod }

if (alwaysDelay) {
if (loadingTransition) this.update({ mod: null }) // display `loading` during componentWillReceiveProps
setTimeout(() => this.update(state, false, true), minDelay)
return
}

this.update(state, false, true)
}
}
}

componentWillUnmount() {
this._initialized = false
}

render() {
const { isLoading, error: userError, ...props } = this.props
const { mod, error } = this.state
return render(props, mod, isLoading, userError || error)
return renderFunc(props, mod, isLoading, userError || error)
}
}
}
3 changes: 2 additions & 1 deletion src/requireUniversalModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ const getConfig = (
chunkName: options.chunkName || 'default',
resolve: options.resolve || '',
path: options.path || '',
load
load,
ignoreBabelRename: true
}
}
Loading

0 comments on commit 3c21ffa

Please sign in to comment.