mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Merge v3-beta into master (#2809)
* Add examples/with-redux-code-splitting. (#2721) * #1757 Relay Modern Example (#2696) * Add ReasonML example (#2640) * Add ReasonML example * Add a gitignore specifically for the reasonml example * Allow custom className for <Main /> (#2802) * 3.0.2 * Remove beta information from the README. * 3.0.3 * Remove unnecessary lookup in example with emotion (#2731) * Document SCSS/Less (#2742) * Document SCSS/Less * Add missing word * Add docs for examples dir * Add extra example * uppercase J * Add with pkg example (#2751) * Add custom server micro example (#2750) * Ease running multiple examples at the same time with process.env.PORT (#2753) * Add line-height rule for error page h2 (#2761) * Add support for fetching multiple translation files (#2743) * Add support for fetching multiple translation files * Cleanup * Clear missed interval (#2611) * clear missed interval * remove trailing whitespace * Relay Modern Example (#1757) (#2773) * Simplification of Relay Modern Example (#1757) (#2776) * Use deterministic names for dynamic import (#2788) * Always use the same name for the same dynamic import. * Add unit tests for the modulePath generation. * Allow tests to run correctly on Windows. * Make the chunk name a bit pretty. * Fix tests to run on Windows. * 3.0.4 * Revert "Make the chunk name a bit pretty." (#2792) This reverts commit 0c9e8cf2271955e74ab9f752b5869b98c1dc60f9. * 3.0.5 * Use _ as the divider for dynamic import name splitter. (#2793) Using - gives us some weird webpack errors. * 3.0.6 * next/dynamic Error Message Tweaks (#2798) * Fixed issue (#2804) https://github.com/zeit/next.js/issues/2800 * docs(material-ui): move the source code to Material-UI repository (#2808)
This commit is contained in:
parent
b543795fc0
commit
eba9ebef5f
2
examples/with-reasonml/.gitignore
vendored
Normal file
2
examples/with-reasonml/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
bs
|
||||
.merlin
|
32
examples/with-reasonml/README.md
Normal file
32
examples/with-reasonml/README.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-reasonml)
|
||||
# Example app using ReasonML & ReasonReact components
|
||||
|
||||
## How to use
|
||||
|
||||
Download the example [or clone the repo](https://github.com/zeit/next.js):
|
||||
|
||||
```bash
|
||||
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-reasonml
|
||||
cd with-reasonml
|
||||
```
|
||||
|
||||
Install it and run:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
|
||||
|
||||
```bash
|
||||
now
|
||||
```
|
||||
|
||||
## The idea behind the example
|
||||
|
||||
This example features:
|
||||
|
||||
* An app that mixes together JavaScript and ReasonML components and functions
|
||||
* An app with two pages which has a common Counter component
|
||||
* That Counter component maintain the counter inside its module. This is used primarily to illustrate that modules get initialized once and their state variables persist in runtime
|
7
examples/with-reasonml/bsconfig.json
Normal file
7
examples/with-reasonml/bsconfig.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "with-reasonml",
|
||||
"sources": ["components", "pages"],
|
||||
"bs-dependencies": ["reason-react"],
|
||||
"reason": { "react-jsx": 2 },
|
||||
"package-specs": ["commonjs"]
|
||||
}
|
14
examples/with-reasonml/components/Counter.re
Normal file
14
examples/with-reasonml/components/Counter.re
Normal file
|
@ -0,0 +1,14 @@
|
|||
let component = ReasonReact.statefulComponent "Counter";
|
||||
let make _children => {
|
||||
...component,
|
||||
initialState: fun () => 0,
|
||||
render: fun self => {
|
||||
let countMsg = "Count: " ^ (string_of_int self.state);
|
||||
let onClick _evt {ReasonReact.state} => ReasonReact.Update (state + 1);
|
||||
|
||||
<div>
|
||||
<p> (ReasonReact.stringToElement countMsg) </p>
|
||||
<button onClick=(self.update onClick)> (ReasonReact.stringToElement "Add") </button>
|
||||
</div>
|
||||
}
|
||||
};
|
13
examples/with-reasonml/components/Header.re
Normal file
13
examples/with-reasonml/components/Header.re
Normal file
|
@ -0,0 +1,13 @@
|
|||
let component = ReasonReact.statelessComponent "Header";
|
||||
let styles = ReactDOMRe.Style.make
|
||||
marginRight::"10px"
|
||||
();
|
||||
let make _children => {
|
||||
...component,
|
||||
render: fun _self => {
|
||||
<div>
|
||||
<a href="/" style=styles> (ReasonReact.stringToElement "Home") </a>
|
||||
<a href="/about" style=styles> (ReasonReact.stringToElement "About") </a>
|
||||
</div>
|
||||
}
|
||||
};
|
0
examples/with-reasonml/index.js
Normal file
0
examples/with-reasonml/index.js
Normal file
31
examples/with-reasonml/lib/js/components/counter.js
Normal file
31
examples/with-reasonml/lib/js/components/counter.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Generated by BUCKLESCRIPT VERSION 1.8.1, PLEASE EDIT WITH CARE
|
||||
'use strict';
|
||||
|
||||
var Block = require("bs-platform/lib/js/block.js");
|
||||
var Curry = require("bs-platform/lib/js/curry.js");
|
||||
var React = require("react");
|
||||
var Pervasives = require("bs-platform/lib/js/pervasives.js");
|
||||
var ReasonReact = require("reason-react/lib/js/src/reasonReact.js");
|
||||
|
||||
var component = ReasonReact.statefulComponent("Counter");
|
||||
|
||||
function make() {
|
||||
var newrecord = component.slice();
|
||||
newrecord[/* render */9] = (function (self) {
|
||||
var countMsg = "Count: " + Pervasives.string_of_int(self[/* state */3]);
|
||||
var onClick = function (_, param) {
|
||||
return /* Update */Block.__(0, [param[/* state */3] + 1 | 0]);
|
||||
};
|
||||
return React.createElement("div", undefined, React.createElement("p", undefined, countMsg), React.createElement("button", {
|
||||
onClick: Curry._1(self[/* update */2], onClick)
|
||||
}, "Add"));
|
||||
});
|
||||
newrecord[/* initialState */10] = (function () {
|
||||
return 0;
|
||||
});
|
||||
return newrecord;
|
||||
}
|
||||
|
||||
exports.component = component;
|
||||
exports.make = make;
|
||||
/* component Not a pure module */
|
30
examples/with-reasonml/lib/js/components/header.js
Normal file
30
examples/with-reasonml/lib/js/components/header.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Generated by BUCKLESCRIPT VERSION 1.8.1, PLEASE EDIT WITH CARE
|
||||
'use strict';
|
||||
|
||||
var React = require("react");
|
||||
var ReasonReact = require("reason-react/lib/js/src/reasonReact.js");
|
||||
|
||||
var component = ReasonReact.statelessComponent("Header");
|
||||
|
||||
var styles = {
|
||||
marginRight: "10px"
|
||||
};
|
||||
|
||||
function make() {
|
||||
var newrecord = component.slice();
|
||||
newrecord[/* render */9] = (function () {
|
||||
return React.createElement("div", undefined, React.createElement("a", {
|
||||
style: styles,
|
||||
href: "/"
|
||||
}, "Home"), React.createElement("a", {
|
||||
style: styles,
|
||||
href: "/about"
|
||||
}, "About"));
|
||||
});
|
||||
return newrecord;
|
||||
}
|
||||
|
||||
exports.component = component;
|
||||
exports.styles = styles;
|
||||
exports.make = make;
|
||||
/* component Not a pure module */
|
17
examples/with-reasonml/lib/js/components/link.js
Normal file
17
examples/with-reasonml/lib/js/components/link.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Generated by BUCKLESCRIPT VERSION 1.8.1, PLEASE EDIT WITH CARE
|
||||
'use strict';
|
||||
|
||||
var Link = require("next/link");
|
||||
var Js_boolean = require("bs-platform/lib/js/js_boolean.js");
|
||||
var ReasonReact = require("reason-react/lib/js/src/reasonReact.js");
|
||||
|
||||
function make(href, $staropt$star, children) {
|
||||
var prefetch = $staropt$star ? $staropt$star[0] : /* false */0;
|
||||
return ReasonReact.wrapJsForReason(Link, {
|
||||
prefetch: Js_boolean.to_js_boolean(prefetch),
|
||||
href: href
|
||||
}, children);
|
||||
}
|
||||
|
||||
exports.make = make;
|
||||
/* next/link Not a pure module */
|
26
examples/with-reasonml/lib/js/pages/about.js
Normal file
26
examples/with-reasonml/lib/js/pages/about.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Generated by BUCKLESCRIPT VERSION 1.8.1, PLEASE EDIT WITH CARE
|
||||
'use strict';
|
||||
|
||||
var React = require("react");
|
||||
var Header = require("../components/header.js");
|
||||
var Counter = require("../components/counter.js");
|
||||
var ReasonReact = require("reason-react/lib/js/src/reasonReact.js");
|
||||
|
||||
var component = ReasonReact.statelessComponent("About");
|
||||
|
||||
function make() {
|
||||
var newrecord = component.slice();
|
||||
newrecord[/* render */9] = (function () {
|
||||
return React.createElement("div", undefined, ReasonReact.element(/* None */0, /* None */0, Header.make(/* array */[])), React.createElement("p", undefined, "This is the about page."), ReasonReact.element(/* None */0, /* None */0, Counter.make(/* array */[])));
|
||||
});
|
||||
return newrecord;
|
||||
}
|
||||
|
||||
var jsComponent = ReasonReact.wrapReasonForJs(component, (function () {
|
||||
return make(/* array */[]);
|
||||
}));
|
||||
|
||||
exports.component = component;
|
||||
exports.make = make;
|
||||
exports.jsComponent = jsComponent;
|
||||
/* component Not a pure module */
|
26
examples/with-reasonml/lib/js/pages/index.js
Normal file
26
examples/with-reasonml/lib/js/pages/index.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Generated by BUCKLESCRIPT VERSION 1.8.1, PLEASE EDIT WITH CARE
|
||||
'use strict';
|
||||
|
||||
var React = require("react");
|
||||
var Header = require("../components/header.js");
|
||||
var Counter = require("../components/counter.js");
|
||||
var ReasonReact = require("reason-react/lib/js/src/reasonReact.js");
|
||||
|
||||
var component = ReasonReact.statelessComponent("Index");
|
||||
|
||||
function make() {
|
||||
var newrecord = component.slice();
|
||||
newrecord[/* render */9] = (function () {
|
||||
return React.createElement("div", undefined, ReasonReact.element(/* None */0, /* None */0, Header.make(/* array */[])), React.createElement("p", undefined, "HOME PAGE is here!"), ReasonReact.element(/* None */0, /* None */0, Counter.make(/* array */[])));
|
||||
});
|
||||
return newrecord;
|
||||
}
|
||||
|
||||
var jsComponent = ReasonReact.wrapReasonForJs(component, (function () {
|
||||
return make(/* array */[]);
|
||||
}));
|
||||
|
||||
exports.component = component;
|
||||
exports.make = make;
|
||||
exports.jsComponent = jsComponent;
|
||||
/* component Not a pure module */
|
26
examples/with-reasonml/package.json
Normal file
26
examples/with-reasonml/package.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "with-reasonml",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"dev": "next -w",
|
||||
"build": "next build",
|
||||
"start": "next start -w"
|
||||
},
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"babel-plugin-bucklescript": "^0.2.3-1",
|
||||
"bs-platform": "^1.8.1",
|
||||
"next": "^2.4.7",
|
||||
"react": "^15.6.1",
|
||||
"react-dom": "^15.6.1",
|
||||
"reason-react": "^0.2.3"
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
"next/babel"
|
||||
],
|
||||
"plugins": [
|
||||
"babel-plugin-bucklescript"
|
||||
]
|
||||
}
|
||||
}
|
15
examples/with-reasonml/pages/About.re
Normal file
15
examples/with-reasonml/pages/About.re
Normal file
|
@ -0,0 +1,15 @@
|
|||
let component = ReasonReact.statelessComponent "About";
|
||||
let make _children => {
|
||||
...component,
|
||||
render: fun _self => {
|
||||
<div>
|
||||
<Header />
|
||||
<p>(ReasonReact.stringToElement "This is the about page.")</p>
|
||||
<Counter />
|
||||
</div>
|
||||
}
|
||||
};
|
||||
let jsComponent =
|
||||
ReasonReact.wrapReasonForJs
|
||||
::component
|
||||
(fun _jsProps => make [||])
|
15
examples/with-reasonml/pages/Index.re
Normal file
15
examples/with-reasonml/pages/Index.re
Normal file
|
@ -0,0 +1,15 @@
|
|||
let component = ReasonReact.statelessComponent "Index";
|
||||
let make _children => {
|
||||
...component,
|
||||
render: fun _self => {
|
||||
<div>
|
||||
<Header />
|
||||
<p>(ReasonReact.stringToElement "HOME PAGE is here!")</p>
|
||||
<Counter />
|
||||
</div>
|
||||
}
|
||||
};
|
||||
let jsComponent =
|
||||
ReasonReact.wrapReasonForJs
|
||||
::component
|
||||
(fun _jsProps => make [||])
|
4
examples/with-reasonml/pages/about.js
Normal file
4
examples/with-reasonml/pages/about.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { jsComponent as About } from './about.re'
|
||||
import React from 'react'
|
||||
|
||||
export default () => <About />
|
3
examples/with-reasonml/pages/index.js
Normal file
3
examples/with-reasonml/pages/index.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import { jsComponent as Index } from './index.re'
|
||||
|
||||
export default () => <Index />
|
32
examples/with-redux-code-splitting/README.md
Normal file
32
examples/with-redux-code-splitting/README.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-redux-code-splitting)
|
||||
|
||||
# Redux with code splitting example
|
||||
|
||||
## How to use
|
||||
|
||||
Download the example [or clone the repo](https://github.com/zeit/next.js):
|
||||
|
||||
```bash
|
||||
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-redux-code-splitting
|
||||
cd with-redux-code-splitting
|
||||
```
|
||||
|
||||
Install it and run:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
|
||||
|
||||
```bash
|
||||
now
|
||||
```
|
||||
|
||||
## The idea behind the example
|
||||
|
||||
Redux uses single store per application and usually it causes problems for code splitting when you want to load actions and reducers used on the current page only.
|
||||
|
||||
This example utilizes [fast-redux](https://github.com/dogada/fast-redux) to split Redux's actions and reducers across pages. In result each page's javascript bundle contains only code that is used on the page. When user navigates to a new page, its actions and reducers are connected to the single shared application store.
|
12
examples/with-redux-code-splitting/config/redux.js
Normal file
12
examples/with-redux-code-splitting/config/redux.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { createStore, applyMiddleware } from 'redux'
|
||||
import { composeWithDevTools } from 'redux-devtools-extension'
|
||||
import thunkMiddleware from 'redux-thunk'
|
||||
import withRedux from 'next-redux-wrapper'
|
||||
import { rootReducer } from 'fast-redux'
|
||||
|
||||
export const initStore = (initialState = {}) => {
|
||||
return createStore(rootReducer, initialState,
|
||||
composeWithDevTools(applyMiddleware(thunkMiddleware)))
|
||||
}
|
||||
|
||||
export const reduxPage = (comp) => withRedux(initStore)(comp)
|
32
examples/with-redux-code-splitting/containers/about.js
Normal file
32
examples/with-redux-code-splitting/containers/about.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
import React from 'react'
|
||||
import {bindActionCreators} from 'redux'
|
||||
import {connect} from 'react-redux'
|
||||
import {namespaceConfig} from 'fast-redux'
|
||||
import Link from 'next/link'
|
||||
|
||||
const DEFAULT_STATE = {version: 1}
|
||||
|
||||
const {actionCreator, getState: getAboutState} = namespaceConfig('about', DEFAULT_STATE)
|
||||
|
||||
const bumpVersion = actionCreator(function bumpVersion (state, increment) {
|
||||
return {...state, version: state.version + increment}
|
||||
})
|
||||
|
||||
const About = ({ version, bumpVersion }) => (
|
||||
<div>
|
||||
<h1>About us</h1>
|
||||
<h3>Current version: {version}</h3>
|
||||
<p><button onClick={(e) => bumpVersion(1)}>Bump version!</button></p>
|
||||
<Link href='/'><a>Homepage</a></Link>
|
||||
</div>
|
||||
)
|
||||
|
||||
function mapStateToProps (state) {
|
||||
return getAboutState(state, 'version')
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({ bumpVersion }, dispatch)
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(About)
|
32
examples/with-redux-code-splitting/containers/homepage.js
Normal file
32
examples/with-redux-code-splitting/containers/homepage.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
import React from 'react'
|
||||
import {bindActionCreators} from 'redux'
|
||||
import {connect} from 'react-redux'
|
||||
import {namespaceConfig} from 'fast-redux'
|
||||
import Link from 'next/link'
|
||||
|
||||
const DEFAULT_STATE = {build: 1}
|
||||
|
||||
const {actionCreator, getState: getHomepageState} = namespaceConfig('homepage', DEFAULT_STATE)
|
||||
|
||||
const bumpBuild = actionCreator(function bumpBuild (state, increment) {
|
||||
return {...state, build: state.build + increment}
|
||||
})
|
||||
|
||||
const Homepage = ({ build, bumpBuild }) => (
|
||||
<div>
|
||||
<h1>Homepage</h1>
|
||||
<h3>Current build: {build}</h3>
|
||||
<p><button onClick={(e) => bumpBuild(1)}>Bump build!</button></p>
|
||||
<Link href='/about'><a>About Us</a></Link>
|
||||
</div>
|
||||
)
|
||||
|
||||
function mapStateToProps (state) {
|
||||
return getHomepageState(state)
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return bindActionCreators({ bumpBuild }, dispatch)
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Homepage)
|
22
examples/with-redux-code-splitting/package.json
Normal file
22
examples/with-redux-code-splitting/package.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "with-redux-code-splitting",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"fast-redux": "~0.3.0",
|
||||
"next": "latest",
|
||||
"next-redux-wrapper": "~1.3.2",
|
||||
"react": "~15.6.1",
|
||||
"react-dom": "~15.6.1",
|
||||
"react-redux": "~5.0.5",
|
||||
"redux": "~3.7.2",
|
||||
"redux-devtools-extension": "~2.13.2",
|
||||
"redux-thunk": "~2.2.0"
|
||||
},
|
||||
"author": "Dmytro V. Dogadailo (https://dogada.org)",
|
||||
"license": "ISC"
|
||||
}
|
4
examples/with-redux-code-splitting/pages/about.js
Normal file
4
examples/with-redux-code-splitting/pages/about.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
import {reduxPage} from '../config/redux'
|
||||
import About from '../containers/about'
|
||||
|
||||
export default reduxPage(About)
|
4
examples/with-redux-code-splitting/pages/index.js
Normal file
4
examples/with-redux-code-splitting/pages/index.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
import {reduxPage} from '../config/redux'
|
||||
import Homepage from '../containers/homepage'
|
||||
|
||||
export default reduxPage(Homepage)
|
|
@ -1 +1 @@
|
|||
RELAY_ENDPOINT=https://api.graph.cool/relay/v1/next-js-with-relay-modern-example
|
||||
RELAY_ENDPOINT=https://api.graph.cool/relay/v1/next-js-with-relay-modern-example
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
"standard": {
|
||||
"parser": "babel-eslint",
|
||||
"ignore": [
|
||||
"**/node_modules/**"
|
||||
"**/node_modules/**",
|
||||
"**/examples/**/lib/**"
|
||||
]
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
|
@ -96,14 +96,19 @@ export class Head extends Component {
|
|||
}
|
||||
|
||||
export class Main extends Component {
|
||||
static propTypes = {
|
||||
className: PropTypes.string
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
_documentProps: PropTypes.any
|
||||
}
|
||||
|
||||
render () {
|
||||
const { html, errorHtml } = this.context._documentProps
|
||||
const { className } = this.props
|
||||
return (
|
||||
<div>
|
||||
<div className={className}>
|
||||
<div id='__next' dangerouslySetInnerHTML={{ __html: html }} />
|
||||
<div id='__next-error' dangerouslySetInnerHTML={{ __html: errorHtml }} />
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue