@sequencemedia/react-router-redux-render 2.1.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/babel.config.cjs +14 -0
- package/package.json +14 -18
- package/src/{index.js → index.mjs} +28 -42
- package/src/react-dom-server.cjs +9 -0
- package/src/react-dom-server.jsx +65 -0
- package/test/component.cjs +7 -0
- package/test/component.jsx +5 -0
- package/test/index.spec.mjs +59 -0
- package/test/routes.cjs +7 -0
- package/test/routes.jsx +14 -0
- package/.gitattributes +0 -20
- package/babel.config.js +0 -22
- package/index.js +0 -2
package/babel.config.cjs
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sequencemedia/react-router-redux-render",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Sync/async isomorphic render of React apps with React Router + Redux",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"React",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"renderToString",
|
|
13
13
|
"renderToStaticMarkup"
|
|
14
14
|
],
|
|
15
|
-
"
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./src/index.mjs",
|
|
16
17
|
"author": {
|
|
17
18
|
"name": "Jonathan Perry for Sequence Media Limited",
|
|
18
19
|
"email": "jonathanperry@sequencemedia.net",
|
|
@@ -20,41 +21,30 @@
|
|
|
20
21
|
},
|
|
21
22
|
"license": "MIT",
|
|
22
23
|
"engines": {
|
|
23
|
-
"node": ">=
|
|
24
|
+
"node": ">=18.5.0"
|
|
24
25
|
},
|
|
25
26
|
"repository": {
|
|
26
27
|
"type": "git",
|
|
27
28
|
"url": "git://github.com/sequencemedia/react-router-redux-render.git"
|
|
28
29
|
},
|
|
29
30
|
"scripts": {
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"babel": "babel src -d lib",
|
|
33
|
-
"babel:watch": "npm run babel -- -w",
|
|
34
|
-
"clean": "rimraf lib",
|
|
35
|
-
"prepublishOnly": "npm run build",
|
|
36
|
-
"prebuild": "npm run clean",
|
|
37
|
-
"lint": "eslint .",
|
|
31
|
+
"test": "NODE_ENV=test mocha test --recursive --verbose",
|
|
32
|
+
"lint": "eslint . --ext .mjs --ext .cjs",
|
|
38
33
|
"lint:fix": "npm run lint -- --fix",
|
|
39
34
|
"prepare": "husky install"
|
|
40
35
|
},
|
|
41
36
|
"dependencies": {
|
|
42
|
-
"@babel/runtime": "^7.21.5",
|
|
43
37
|
"@hapi/boom": "^10.0.1",
|
|
44
38
|
"debug": "^4.3.4"
|
|
45
39
|
},
|
|
46
40
|
"devDependencies": {
|
|
47
|
-
"@babel/cli": "^7.21.5",
|
|
48
41
|
"@babel/core": "^7.21.8",
|
|
49
42
|
"@babel/eslint-parser": "^7.21.8",
|
|
50
|
-
"@babel/plugin-proposal-export-default-from": "^7.18.10",
|
|
51
|
-
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
|
|
52
|
-
"@babel/plugin-proposal-throw-expressions": "^7.18.6",
|
|
53
|
-
"@babel/plugin-transform-runtime": "^7.21.4",
|
|
54
43
|
"@babel/preset-env": "^7.21.5",
|
|
55
44
|
"@babel/preset-react": "^7.18.6",
|
|
56
45
|
"@babel/register": "^7.21.0",
|
|
57
46
|
"@sequencemedia/hooks": "^1.0.423",
|
|
47
|
+
"chai": "^4.3.7",
|
|
58
48
|
"core-js": "^3.30.2",
|
|
59
49
|
"eslint": "^8.41.0",
|
|
60
50
|
"eslint-config-standard": "^17.0.0",
|
|
@@ -63,12 +53,18 @@
|
|
|
63
53
|
"eslint-plugin-promise": "^6.1.1",
|
|
64
54
|
"eslint-plugin-react": "^7.32.2",
|
|
65
55
|
"husky": "^8.0.3",
|
|
56
|
+
"mocha": "^10.2.0",
|
|
66
57
|
"react": "18.2.0",
|
|
67
58
|
"react-dom": "18.2.0",
|
|
68
59
|
"react-redux": "^8.0.5",
|
|
69
60
|
"react-router": "6.11.2",
|
|
70
61
|
"react-router-dom": "6.11.2",
|
|
71
62
|
"redux": "^4.2.1",
|
|
72
|
-
"rimraf": "^5.0.1"
|
|
63
|
+
"rimraf": "^5.0.1",
|
|
64
|
+
"sinon": "^15.1.0",
|
|
65
|
+
"sinon-chai": "^3.7.0"
|
|
66
|
+
},
|
|
67
|
+
"exports": {
|
|
68
|
+
".": "./src/index.mjs"
|
|
73
69
|
}
|
|
74
70
|
}
|
|
@@ -1,51 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import Boom from '@hapi/boom'
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('redux').Store} Store
|
|
3
|
+
*/
|
|
4
|
+
|
|
6
5
|
import debug from 'debug'
|
|
7
6
|
|
|
7
|
+
import Boom from '@hapi/boom'
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
getReactDOMServerRenderToString,
|
|
11
|
+
getReactDOMServerRenderToStaticMarkup
|
|
12
|
+
} from './react-dom-server.cjs'
|
|
13
|
+
|
|
8
14
|
const log = debug('@sequencemedia/react-router-redux-render')
|
|
9
15
|
|
|
10
16
|
log('`react-router-redux-render` is awake')
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
/**
|
|
19
|
+
* @param {Object.<string, any>} data
|
|
20
|
+
* @returns A boom object
|
|
21
|
+
*/
|
|
13
22
|
const notFound = (data) => Boom.notFound('Routing exception', data)
|
|
14
23
|
|
|
15
|
-
function getReactDOMServerRenderToString (store, routerProps, routes) {
|
|
16
|
-
try {
|
|
17
|
-
return ReactDOMServer.renderToString(
|
|
18
|
-
<Provider store={store}>
|
|
19
|
-
<Router {...routerProps}>
|
|
20
|
-
{routes}
|
|
21
|
-
</Router>
|
|
22
|
-
</Provider>
|
|
23
|
-
)
|
|
24
|
-
} catch (e) {
|
|
25
|
-
log(e)
|
|
26
|
-
|
|
27
|
-
throw badImplementation(e, routerProps)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function getReactDOMServerRenderToStaticMarkup (store, routerProps, routes) {
|
|
32
|
-
try {
|
|
33
|
-
return ReactDOMServer.renderToStaticMarkup(
|
|
34
|
-
<Provider store={store}>
|
|
35
|
-
<Router {...routerProps}>
|
|
36
|
-
{routes}
|
|
37
|
-
</Router>
|
|
38
|
-
</Provider>
|
|
39
|
-
)
|
|
40
|
-
} catch (e) {
|
|
41
|
-
log(e)
|
|
42
|
-
|
|
43
|
-
throw badImplementation(e, routerProps)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
24
|
/**
|
|
48
|
-
* @
|
|
25
|
+
* @param {Store} store
|
|
26
|
+
* @param {Object.<string, any>} routerProps
|
|
27
|
+
* @param {Object.<string, any>} routes
|
|
28
|
+
* @returns {string}
|
|
49
29
|
*/
|
|
50
30
|
export function renderToString (store, { location, context = {}, ...router } = {}, routes = {}) {
|
|
51
31
|
const routerProps = { ...router, location, context }
|
|
@@ -55,7 +35,10 @@ export function renderToString (store, { location, context = {}, ...router } = {
|
|
|
55
35
|
}
|
|
56
36
|
|
|
57
37
|
/**
|
|
58
|
-
* @
|
|
38
|
+
* @param {Store} store
|
|
39
|
+
* @param {Object.<string, any>} routerProps
|
|
40
|
+
* @param {Object.<string, any>} routes
|
|
41
|
+
* @returns {string}
|
|
59
42
|
*/
|
|
60
43
|
export function renderToStaticMarkup (store, { location, context = {}, ...router } = {}, routes = {}) {
|
|
61
44
|
const routerProps = { ...router, location, context }
|
|
@@ -65,11 +48,14 @@ export function renderToStaticMarkup (store, { location, context = {}, ...router
|
|
|
65
48
|
}
|
|
66
49
|
|
|
67
50
|
/**
|
|
68
|
-
* @
|
|
51
|
+
* @param {Store} store
|
|
52
|
+
* @param {Object.<string, any>} routerProps
|
|
53
|
+
* @param {Object.<string, any>} routes
|
|
54
|
+
* @returns {Promise<string>}
|
|
69
55
|
*/
|
|
70
56
|
export async function render (store, { location, context = {}, ...router } = {}, routes = {}) {
|
|
71
57
|
const routerProps = { ...router, location, context }
|
|
72
58
|
const string = getReactDOMServerRenderToString(store, routerProps, routes)
|
|
73
59
|
if (string) return string
|
|
74
|
-
throw notFound(
|
|
60
|
+
throw notFound(routerProps)
|
|
75
61
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require('@babel/register')
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
getReactDOMServerRenderToString,
|
|
5
|
+
getReactDOMServerRenderToStaticMarkup
|
|
6
|
+
} = require('./react-dom-server.jsx')
|
|
7
|
+
|
|
8
|
+
module.exports.getReactDOMServerRenderToString = getReactDOMServerRenderToString
|
|
9
|
+
module.exports.getReactDOMServerRenderToStaticMarkup = getReactDOMServerRenderToStaticMarkup
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('redux').Store} Store
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import debug from 'debug'
|
|
6
|
+
import React from 'react'
|
|
7
|
+
import ReactDOMServer from 'react-dom/server'
|
|
8
|
+
import { Provider } from 'react-redux'
|
|
9
|
+
import { StaticRouter as Router } from 'react-router-dom/server'
|
|
10
|
+
import Boom from '@hapi/boom'
|
|
11
|
+
|
|
12
|
+
const log = debug('@sequencemedia/react-redux-render')
|
|
13
|
+
|
|
14
|
+
log('`react-redux-render` is awake')
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {Error} e
|
|
18
|
+
* @param {{props: Object.<string, any>}} data
|
|
19
|
+
* @returns A boom object
|
|
20
|
+
*/
|
|
21
|
+
const badImplementation = (e, data) => Boom.boomify(e, { statusCode: 500, message: 'Rendering exception', data })
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {Store} store
|
|
25
|
+
* @param {Object.<string, any>} routerProps
|
|
26
|
+
* @param {Object.<string, any>} routes
|
|
27
|
+
* @returns {string}
|
|
28
|
+
*/
|
|
29
|
+
export function getReactDOMServerRenderToString (store, routerProps, routes) {
|
|
30
|
+
try {
|
|
31
|
+
return ReactDOMServer.renderToString(
|
|
32
|
+
<Provider store={store}>
|
|
33
|
+
<Router {...routerProps}>
|
|
34
|
+
{routes}
|
|
35
|
+
</Router>
|
|
36
|
+
</Provider>
|
|
37
|
+
)
|
|
38
|
+
} catch (e) {
|
|
39
|
+
log(e)
|
|
40
|
+
|
|
41
|
+
throw badImplementation(e, routerProps)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {Store} store
|
|
47
|
+
* @param {Object.<string, any>} routerProps
|
|
48
|
+
* @param {Object.<string, any>} routes
|
|
49
|
+
* @returns {string}
|
|
50
|
+
*/
|
|
51
|
+
export function getReactDOMServerRenderToStaticMarkup (store, routerProps, routes) {
|
|
52
|
+
try {
|
|
53
|
+
return ReactDOMServer.renderToStaticMarkup(
|
|
54
|
+
<Provider store={store}>
|
|
55
|
+
<Router {...routerProps}>
|
|
56
|
+
{routes}
|
|
57
|
+
</Router>
|
|
58
|
+
</Provider>
|
|
59
|
+
)
|
|
60
|
+
} catch (e) {
|
|
61
|
+
log(e)
|
|
62
|
+
|
|
63
|
+
throw badImplementation(e, routerProps)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import chai, { expect } from 'chai'
|
|
2
|
+
import sinonChai from 'sinon-chai'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
renderToString,
|
|
6
|
+
renderToStaticMarkup,
|
|
7
|
+
render
|
|
8
|
+
} from '@sequencemedia/react-router-redux-render'
|
|
9
|
+
|
|
10
|
+
import Routes from './routes.cjs'
|
|
11
|
+
|
|
12
|
+
chai.use(sinonChai)
|
|
13
|
+
|
|
14
|
+
describe('react-render', () => {
|
|
15
|
+
describe('`renderToString`', () => {
|
|
16
|
+
it('is a function', () => {
|
|
17
|
+
return expect(renderToString)
|
|
18
|
+
.to.be.a('function')
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
describe('`renderToStaticMarkup`', () => {
|
|
23
|
+
it('is a function', () => {
|
|
24
|
+
return expect(renderToStaticMarkup)
|
|
25
|
+
.to.be.a('function')
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
describe('`render`', () => {
|
|
30
|
+
it('is a function', () => {
|
|
31
|
+
return expect(render)
|
|
32
|
+
.to.be.a('function')
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const store = { getState () { return {} } }
|
|
37
|
+
const routerProps = { location: '/' }
|
|
38
|
+
|
|
39
|
+
describe('`renderToString()`', () => {
|
|
40
|
+
it('returns a string', () => {
|
|
41
|
+
return expect(renderToString(store, routerProps, Routes))
|
|
42
|
+
.to.equal('<h1>Component</h1>')
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
describe('`renderToStaticMarkup()`', () => {
|
|
47
|
+
it('returns a string', () => {
|
|
48
|
+
return expect(renderToStaticMarkup(store, routerProps, Routes))
|
|
49
|
+
.to.equal('<h1>Component</h1>')
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
describe('`render()`', () => {
|
|
54
|
+
it('returns a Promise resolving to a string', async () => {
|
|
55
|
+
return expect(await render(store, routerProps, Routes))
|
|
56
|
+
.to.equal('<h1>Component</h1>')
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
})
|
package/test/routes.cjs
ADDED
package/test/routes.jsx
ADDED
package/.gitattributes
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# Default behavior
|
|
2
|
-
* text=auto
|
|
3
|
-
|
|
4
|
-
# LF line endings
|
|
5
|
-
*.json text eol=lf
|
|
6
|
-
*.mjs text eol=lf
|
|
7
|
-
*.cjs text eol=lf
|
|
8
|
-
*.mts text eol=lf
|
|
9
|
-
*.js text eol=lf
|
|
10
|
-
*.ts text eol=lf
|
|
11
|
-
*.sh text eol=lf
|
|
12
|
-
.editorconfig text eol=lf
|
|
13
|
-
.eslintignore text eol=lf
|
|
14
|
-
.eslintrc text eol=lf
|
|
15
|
-
.gitattributes text eol=lf
|
|
16
|
-
.gitignore text eol=lf
|
|
17
|
-
.npmignore text eol=lf
|
|
18
|
-
.npmrc text eol=lf
|
|
19
|
-
.nvmrc text eol=lf
|
|
20
|
-
.husky/* text eol=lf
|
package/babel.config.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
compact: true,
|
|
3
|
-
comments: false,
|
|
4
|
-
presets: [
|
|
5
|
-
[
|
|
6
|
-
'@babel/env', {
|
|
7
|
-
targets: {
|
|
8
|
-
node: 'current'
|
|
9
|
-
},
|
|
10
|
-
useBuiltIns: 'usage',
|
|
11
|
-
corejs: 3
|
|
12
|
-
}
|
|
13
|
-
],
|
|
14
|
-
'@babel/react'
|
|
15
|
-
],
|
|
16
|
-
plugins: [
|
|
17
|
-
'@babel/transform-runtime',
|
|
18
|
-
'@babel/proposal-throw-expressions',
|
|
19
|
-
'@babel/proposal-export-default-from',
|
|
20
|
-
'@babel/proposal-export-namespace-from'
|
|
21
|
-
]
|
|
22
|
-
}
|
package/index.js
DELETED