Skip to content

Commit

Permalink
Migrate cra express (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
antonybudianto authored Jul 17, 2018
1 parent ed61932 commit abb3038
Show file tree
Hide file tree
Showing 94 changed files with 9,833 additions and 2,428 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["env"]
}
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
build
coverage
coverage
lib
lerna-debug.log
25 changes: 10 additions & 15 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@

language: node_js
node_js:
- "8"
- "6"
- "6.11.5"
before_script:
- yarn bootstrap
script:
- npm link
- npm t
- cd ./docs
- yarn
- npm link cra-universal
- npm t
- npm run build
- npm run crau:build
- cd ../templates
- yarn
- npm link cra-universal
- npm t
- npm run build
- npm run crau:build
- npm test
- yarn build
- yarn crau:build
after_script:
- yarn global add codecov
- codecov
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
13 changes: 13 additions & 0 deletions lerna.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"lerna": "2.11.0",
"packages": [
"packages/*",
"packages/@cra-express/*",
"packages/cra-universal/templates"
],
"version": "4.0.0-0",
"npmClient": "yarn",
"npmClientArgs": [
"--no-lockfile"
]
}
81 changes: 33 additions & 48 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,59 +1,44 @@
{
"name": "cra-universal",
"version": "3.2.2",
"description": "Create React App Universal CLI",
"main": "src/index.js",
"files": [
"src",
"templates/server"
],
"bin": {
"cra-universal": "./src/index.js"
},
"keywords": [
"ssr",
"create-react-app",
"cra",
"universal",
"cli",
"express"
],
"name": "cra-universal-monorepo",
"description": "CRA Universal Monorepo",
"private": true,
"scripts": {
"release": "np --no-yarn --yolo",
"test": "jest --config=jest-config.json --coverage"
"build": "lerna run build",
"crau:build": "lerna run crau:build",
"test": "lerna run test:ci",
"watch": "lerna run --parallel watch",
"test:ul": "lerna exec --scope @cra-express/universal-loader -- jest",
"test:rp": "lerna exec --scope @cra-express/redux-prefetcher -- jest",
"bootstrap": "lerna bootstrap",
"clean": "lerna clean",
"clean:build": "lerna exec -- rimraf lib",
"prerelease": "npm run build",
"release": "lerna publish",
"ls": "lerna ls",
"release:next": "npm run release -- --npm-tag=next"
},
"author": "Antony Budianto <antonybudianto@gmail.com>",
"repository": {
"type": "git",
"url": "https://github.com/antonybudianto/cra-universal.git"
"url": "git+https://github.com/antonybudianto/cra-universal.git"
},
"keywords": [
"express",
"react",
"create-react-app",
"ssr"
],
"author": "Antony Budianto <antonybudianto@gmail.com>",
"license": "MIT",
"dependencies": {
"@cra-express/core": "^2.2.5",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-plugin-dynamic-import-node": "^2.0.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"babel-preset-react-app": "^3.1.2",
"chalk": "^2.4.1",
"css-loader": "^1.0.0",
"del": "^3.0.0",
"fs-extra": "6.0.1",
"has-yarn": "^1.0.0",
"inquirer": "^6.0.0",
"isomorphic-style-loader": "^4.0.0",
"multiview": "^2.5.3",
"null-loader": "^0.1.1",
"start-server-webpack-plugin": "3.0.0-rc3",
"url-loader": "^1.0.1",
"webpack": "^4.15.1",
"webpack-cli": "^3.0.8",
"webpack-node-externals": "^1.7.2",
"yargs": "12.0.1"
"bugs": {
"url": "https://github.com/antonybudianto/cra-universal/issues"
},
"homepage": "https://github.com/antonybudianto/cra-universal#readme",
"devDependencies": {
"jest": "^23.3.0"
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-react-app": "^3.1.2",
"jest": "^23.4.1",
"lerna": "^2.11.0",
"rimraf": "^2.6.2"
}
}
31 changes: 31 additions & 0 deletions packages/@cra-express/core/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "@cra-express/core",
"version": "4.0.0-0",
"description": "",
"main": "lib/index.js",
"files": [
"lib"
],
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "babel src -d lib --ignore spec.js",
"test": "exit 0"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
},
"dependencies": {
"@cra-express/static-loader": "^4.0.0-0",
"@cra-express/universal-loader": "^4.0.0-0",
"express": "4.16.2"
},
"devDependencies": {
"react": "*",
"react-dom": "*"
},
"author": "",
"license": "MIT"
}
12 changes: 12 additions & 0 deletions packages/@cra-express/core/src/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const express = require('express');
const staticLoader = require('@cra-express/static-loader').default;
const universalLoader = require('@cra-express/universal-loader').default;

function createReactAppExpress (options) {
const app = express();
staticLoader(app, options);
universalLoader(app, options);
return app;
}

export default createReactAppExpress;
8 changes: 8 additions & 0 deletions packages/@cra-express/core/src/handle-universal-render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const React = require('react');
const { renderToNodeStream } = require('react-dom/server');

function handleUniversalRender(reactElement) {
return (req, res) => renderToNodeStream(reactElement);
}

export default handleUniversalRender;
7 changes: 7 additions & 0 deletions packages/@cra-express/core/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import createReactAppExpress from './app';
import handleUniversalRender from './handle-universal-render';

export {
createReactAppExpress,
handleUniversalRender
};
71 changes: 71 additions & 0 deletions packages/@cra-express/redux-prefetcher/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# @cra-express/redux-prefetcher

> Alpha stage, API may change, don't use on production yet!
> Simple utility to map your routes and prefetch your data on server using Redux as store
## Prerequisites
- Redux
- React Router with array config
- Promise support

## Start
```
npm i @cra-express/redux-prefetcher
```

## Use
```js
// server.js
import { getInitialData } from '@cra-express/redux-prefetcher'
import { renderToNodeStream } = from 'react-dom/server';

import routes from './my-app-routes'
import reducer from './my-app-reducer'

function handleUniversalRender (req, res) {
const ctx = { req, res }
const store = createStore(reducer);
return getInitialData(ctx, store, routes)
.then(() => {
return renderToNodeStream(<App />)
})
}
```

```js
// MyView.js
import React, { Component } from 'react'
import { connect } from 'react-redux'

import { fetchTodo } from './my-todo-reducer'

class MyView extends Component {
static loadData({ ctx, store, match }) {
// ctx is object containing express req and res objects
// store is redux store
// match is router match information, you can get params here
return store.dispatch(fetchTodo())
}

render() {
return (
<ul>
{
this.props.todo.data.map((t, i) => (
<li key={i}>{t}</li>
))
}
</ul>
)
}
}

const mapStateToProps = state => ({
todo: state.todo
})

export default connect(mapStateToProps)(MyView)
```

## License
MIT
29 changes: 29 additions & 0 deletions packages/@cra-express/redux-prefetcher/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@cra-express/redux-prefetcher",
"version": "4.0.0-0",
"description": "Redux Prefetcher for prefetching on server",
"main": "lib/index.js",
"files": [
"lib"
],
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "babel src -d lib --ignore spec.js",
"test:ci": "jest --coverage"
},
"author": "Antony Budianto <antonybudianto@gmail.com>",
"license": "MIT",
"dependencies": {
"react-router-config": "^1.0.0-beta.4"
},
"peerDependencies": {
"react": "*",
"react-router": "*"
},
"devDependencies": {
"react": "^16.3.2",
"react-router": "^4.2.0"
}
}
18 changes: 18 additions & 0 deletions packages/@cra-express/redux-prefetcher/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { matchRoutes } from 'react-router-config'

export function getInitialData(ctx, store, routes) {
const promises = matchRoutes(routes, ctx.req.path)
.map(({ route, match }) => {
return {
component: route.component,
match
}
})
.filter(result => result.component.loadData)
.map(result => result.component.loadData({
ctx,
store,
match: result.match
}))
return Promise.all(promises)
}
50 changes: 50 additions & 0 deletions packages/@cra-express/redux-prefetcher/src/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { getInitialData } from './index'

test('should success without any loadData', (done) => {
const ctx = {
req: {
path: '/'
}
}
const store = {}
const TestComp = function () {
return null
}
const routes = [
{
component: TestComp
}
]
const prom = getInitialData(ctx, store, routes)
.then(result => {
expect(result.length).toBe(0)
done()
})
})

test('should filter route with loadData', (done) => {
const ctx = {
req: {
path: '/'
}
}
const store = {}
const TestComp = function () {
return null
}
TestComp.loadData = jest.fn()
const routes = [
{
component: TestComp
},
{
component: () => {}
}
]
const prom = getInitialData(ctx, store, routes)
.then(result => {
expect(result.length).toBe(1)
expect(TestComp.loadData).toHaveBeenCalled()
done()
})
})
Loading

0 comments on commit abb3038

Please sign in to comment.