Skip to content

Commit

Permalink
Wiki to Docusaurus (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajchili authored and antonybudianto committed Oct 2, 2018
1 parent 5445930 commit 5961afc
Show file tree
Hide file tree
Showing 7 changed files with 268 additions and 0 deletions.
6 changes: 6 additions & 0 deletions docs/code-splitting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
id: code-splitting
title: Code Splitting
---

CRA Universal supports code-splitting with SSR using [loadable-components](https://github.com/smooth-code/loadable-components). Please see `./packages/demo` for example.
45 changes: 45 additions & 0 deletions docs/deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
id: deployment
title: Deployment
---

Here are some deployment services you can try:

These tutorials assumed that you've build your app using `cra-universal build`

### [Now by Zeit](https://zeit.co/now)
- Edit `package.json`, remove `build`, and `test` scripts
- and update your npm `start` script to `node build/bundle.js`
- Run command `now` inside `./dist`
- Optional: you might need to remove your sourcemaps for free plan

___

### [Firebase Functions by Google](https://firebase.google.com)
https://medium.com/@antonybudianto/server-side-rendering-with-react-and-firebase-functions-cd67fdb2b605
- Copy `./dist` inside your `./functions/` and rename it to `./functions/server`
- Update your rewrite on `firebase.json`
```json
{
"source": "**",
"function": "app"
}
```
- Update your `webpack.config.js`
```js
module.exports = {
// For Firebase function/package bundle
entry: './src/app.js', // Initially, it's ./src/index.js
```
- Update your `index.js`
```js
const functions = require('firebase-functions');

// Copy your `dist` into here and rename it into `server`
const app = require('./server/build/bundle');

exports.app = functions.https.onRequest(app);
```
- Add your server dependencies into your function `package.json`
- Remove `./build/index.html` (let firebase function serve it)
- Deploy using Firebase CLI `firebase deploy`
45 changes: 45 additions & 0 deletions docs/integrate-react-router.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
id: integrate-react-router
title: Integrate React Router
---

This is how you integrate [React Router](https://github.com/ReactTraining/react-router) into server side rendering:

```js
// server/app.js

// you can use `async` function too
function handleUniversalRender(req, res) {
const context = {};
const stream = ReactDOMServer.renderToNodeStream(
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
);

if (context.url) {
res.redirect(301, context.url);
return;
}

return stream;
}

const app = createReactAppExpress({
clientBuildPath,
universalRender: handleUniversalRender
});
```

**Note:** Make sure `App.js` didn't render `BrowserRouter`, but put it on `src/index.js` or outer files

```js
// src/index.js

ReactDOM.hydrate(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
```
62 changes: 62 additions & 0 deletions docs/integrate-redux.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
id: integrate-redux
title: Integrate Redux
---

```jsx
// src/index.js

// Grab the state from a global variable injected into the server-generated HTML
const preloadedState = window.__PRELOADED_STATE__

// Allow the passed state to be garbage-collected
delete window.__PRELOADED_STATE__

const store = createStore(
reducer,
preloadedState,
applyMiddleware(thunk)
)
```

```js
// server/src/app.js

import path from "path";
import React from "react";
import { renderToNodeStream } from "react-dom/server";
import { Provider } from "react-redux";
import { createReactAppExpress } from "@cra-express/core";

import App from "../../src/App";
import configureStore from "../../src/store/index.js";
const clientBuildPath = path.resolve(__dirname, "client");

function handleUniversalRender(req, res) {
const initialState = {};
const store = configureStore(initialState);
const stream = renderToNodeStream(
<Provider store={store}>
<App />
</Provider>
);
return stream;
}

const app = createReactAppExpress({
clientBuildPath,
universalRender: handleUniversalRender,
onFinish(req, res, html) {
const state = store.getState();
const finalHtml = html.replace('{{SCRIPT}}', `<script>
window.__PRELOADED_STATE__ = ${JSON.stringify(state).replace(/</g, '\\u003c')};
</script>`);
return finalHtml;
}
});

module.exports = app;
```

References:
https://redux.js.org/recipes/server-rendering
82 changes: 82 additions & 0 deletions docs/integrate-typeScript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
id: integrade-typescript
title: Integrate TypeScript
---

> Credits: @Zummer
```javascript
// package.json
"scripts": {
"u-init": "cra-universal init"
}
```

Extract server folder for customization
```sh
npm run u-init
```

Install required dep:
```sh
npm install -D webpack-merge ts-loader
```

Create crau.config.js in cra root folder
```
touch crau.config.js
```

```javascript
// crau.config.js
const webpackMerge = require('webpack-merge');

const myCustomConfig = {
resolve: {
extensions: ['.ts', '.tsx']
},
module: {
rules: [
{
test: /\.(ts|tsx)$/,
exclude: [/node_modules/],
use: [
{
loader: 'ts-loader'
}
]
},
]
}
};

module.exports = {
webpackPlugins: [],
modifyWebpack: (config) => webpackMerge(config, myCustomConfig)
};
```

``` javascript
// tslint.json
{
...
"rules": {
"no-console": false
}
}
```

```javascript
// tsconfig.json
{
"compilerOptions": {
...
"rootDirs": ["src", "server"],
...
},
"exclude": [
"server-build",
...
]
}
```
17 changes: 17 additions & 0 deletions docs/known-issues.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
id: known-issues
title: Known Issues
---

List of known issues:
- Importing svg/img file will cause runtime warning on development (asset import didn't re-hydrate properly due filename mismatch), but the errors are gone after production build
- Solution: https://github.com/antonybudianto/cra-universal/issues/16#issuecomment-392305234
- Latest React Loadable `v5.x.x` is not compatible, for now please stick to version `v4.x.x` or use [loadable-components](https://github.com/smooth-code/loadable-components)
- Using renderToNodeStream limits you to:
- render helmet on server
- isomorphic css
- sending custom status code based on app router context
- If you enabled Service worker, it's expected to see non-rendered page when viewing the page source (somehow page source will show SW-cached page). You can use curl to check the rendered page
- Fetching data based on route is on Alpha stage, please visit [@cra-express/redux-prefetcher](https://github.com/antonybudianto/create-react-app-express/tree/master/packages/redux-prefetcher)

If you've ideas on how to solve the issue, please discuss or send a PR!
11 changes: 11 additions & 0 deletions docs/prefetching.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
id: prefetching
title: Prefetching
---

## Introduction

One advantage being an SSR app is the ability to fetch from server instead of client. Imagine you want to fetch the article on the server so that the Googlebots/crawlers able to crawl and index your page.
It's good for pages which are best rendered on server.

Check out [@cra-express/redux-prefetcher](https://github.com/antonybudianto/create-react-app-express/tree/master/packages/redux-prefetcher)

0 comments on commit 5961afc

Please sign in to comment.