From 016920e3e03c2ac607fc508572af8d3af66125a9 Mon Sep 17 00:00:00 2001 From: Nicholas Rakoto Date: Sat, 30 Sep 2017 22:02:45 +0200 Subject: [PATCH] Example: Improve ReasonML example (#3021) * Git ignore with-reasonml/lib folder The lib folder contains code generated by BuckleScript, it shouldn't be versioned. * Fix, case sensitive paths Next.js use case-sensitive-paths-webpack-plugin and BuckleScript tries to maintain the filename case. * Refactor, use a .babelrc file instead of a babel config in package.json This is the official recommended way in Next.js * Enable way, way, waaaay nicer error messages! Adds `"bsc-flags": ["-bs-super-errors"]` to the bsconfig.json file. https://reasonml.github.io/community/blog/#way-way-waaaay-nicer-error-messages * Fix npm scripts & use concurrently to run bsb & next in parallel for dev * Upgrade bs-platform * Replace statefulComponent with new reducerComponent https://github.com/reasonml/reason-react/blob/master/HISTORY.md#024 * Upgrade with-reasonml example to next.js 3 --- examples/with-reasonml/.babelrc | 8 +++++ examples/with-reasonml/.gitignore | 1 + examples/with-reasonml/README.md | 13 +++++++- examples/with-reasonml/bsconfig.json | 5 ++- examples/with-reasonml/components/Counter.re | 13 ++++++-- .../lib/js/components/counter.js | 31 ------------------- .../with-reasonml/lib/js/components/header.js | 30 ------------------ .../with-reasonml/lib/js/components/link.js | 17 ---------- examples/with-reasonml/lib/js/pages/about.js | 26 ---------------- examples/with-reasonml/lib/js/pages/index.js | 26 ---------------- examples/with-reasonml/package.json | 19 ++++-------- examples/with-reasonml/pages/about.js | 2 +- examples/with-reasonml/pages/index.js | 2 +- 13 files changed, 43 insertions(+), 150 deletions(-) create mode 100644 examples/with-reasonml/.babelrc delete mode 100644 examples/with-reasonml/lib/js/components/counter.js delete mode 100644 examples/with-reasonml/lib/js/components/header.js delete mode 100644 examples/with-reasonml/lib/js/components/link.js delete mode 100644 examples/with-reasonml/lib/js/pages/about.js delete mode 100644 examples/with-reasonml/lib/js/pages/index.js diff --git a/examples/with-reasonml/.babelrc b/examples/with-reasonml/.babelrc new file mode 100644 index 00000000..c52b579e --- /dev/null +++ b/examples/with-reasonml/.babelrc @@ -0,0 +1,8 @@ +{ + "presets": [ + "next/babel" + ], + "plugins": [ + "babel-plugin-bucklescript" + ] +} diff --git a/examples/with-reasonml/.gitignore b/examples/with-reasonml/.gitignore index ac1fa842..9d8f0bbe 100644 --- a/examples/with-reasonml/.gitignore +++ b/examples/with-reasonml/.gitignore @@ -1,2 +1,3 @@ bs .merlin +lib/ diff --git a/examples/with-reasonml/README.md b/examples/with-reasonml/README.md index b9484810..81db0dfe 100644 --- a/examples/with-reasonml/README.md +++ b/examples/with-reasonml/README.md @@ -14,6 +14,7 @@ Install it and run: ```bash npm install +npm run build npm run dev ``` @@ -22,6 +23,14 @@ Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit. ```bash now ``` +### Recommendation: + +Run BuckleScript build system `bsb -w` and `next -w` separately. For the sake +of simple convention, `npm run dev` run both `bsb` and `next` concurrently. +However, this doesn't offer the full [colorful and very, very, veeeery nice +error +output](https://reasonml.github.io/community/blog/#way-way-waaaay-nicer-error-messages) +experience that ReasonML can offer, don't miss it! ## The idea behind the example @@ -29,4 +38,6 @@ 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 +* 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 diff --git a/examples/with-reasonml/bsconfig.json b/examples/with-reasonml/bsconfig.json index 323cfbe3..30d80dc3 100644 --- a/examples/with-reasonml/bsconfig.json +++ b/examples/with-reasonml/bsconfig.json @@ -3,5 +3,8 @@ "sources": ["components", "pages"], "bs-dependencies": ["reason-react"], "reason": { "react-jsx": 2 }, - "package-specs": ["commonjs"] + "package-specs": ["commonjs"], + "bsc-flags": [ + "-bs-super-errors" + ] } diff --git a/examples/with-reasonml/components/Counter.re b/examples/with-reasonml/components/Counter.re index 3ba4ba61..43e46778 100644 --- a/examples/with-reasonml/components/Counter.re +++ b/examples/with-reasonml/components/Counter.re @@ -1,14 +1,21 @@ -let component = ReasonReact.statefulComponent "Counter"; +type action = + | Add; + +let component = ReasonReact.reducerComponent "Counter"; + let make _children => { ...component, initialState: fun () => 0, + reducer: fun action state => + switch action { + | Add => ReasonReact.Update {state + 1} + }, render: fun self => { let countMsg = "Count: " ^ (string_of_int self.state); - let onClick _evt {ReasonReact.state} => ReasonReact.Update (state + 1);

(ReasonReact.stringToElement countMsg)

- +
} }; diff --git a/examples/with-reasonml/lib/js/components/counter.js b/examples/with-reasonml/lib/js/components/counter.js deleted file mode 100644 index a1955920..00000000 --- a/examples/with-reasonml/lib/js/components/counter.js +++ /dev/null @@ -1,31 +0,0 @@ -// 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 */ diff --git a/examples/with-reasonml/lib/js/components/header.js b/examples/with-reasonml/lib/js/components/header.js deleted file mode 100644 index c01dd1d1..00000000 --- a/examples/with-reasonml/lib/js/components/header.js +++ /dev/null @@ -1,30 +0,0 @@ -// 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 */ diff --git a/examples/with-reasonml/lib/js/components/link.js b/examples/with-reasonml/lib/js/components/link.js deleted file mode 100644 index ec24595f..00000000 --- a/examples/with-reasonml/lib/js/components/link.js +++ /dev/null @@ -1,17 +0,0 @@ -// 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 */ diff --git a/examples/with-reasonml/lib/js/pages/about.js b/examples/with-reasonml/lib/js/pages/about.js deleted file mode 100644 index a4f01381..00000000 --- a/examples/with-reasonml/lib/js/pages/about.js +++ /dev/null @@ -1,26 +0,0 @@ -// 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 */ diff --git a/examples/with-reasonml/lib/js/pages/index.js b/examples/with-reasonml/lib/js/pages/index.js deleted file mode 100644 index d2013a08..00000000 --- a/examples/with-reasonml/lib/js/pages/index.js +++ /dev/null @@ -1,26 +0,0 @@ -// 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 */ diff --git a/examples/with-reasonml/package.json b/examples/with-reasonml/package.json index c1b47483..cc7f4f02 100644 --- a/examples/with-reasonml/package.json +++ b/examples/with-reasonml/package.json @@ -2,25 +2,18 @@ "name": "with-reasonml", "version": "1.0.0", "scripts": { - "dev": "next -w", - "build": "next build", - "start": "next start -w" + "dev": "concurrently \"bsb --clean-world -make-world -w\" \"next -w\"", + "build": "bsb -clean-world -make-world && next build", + "start": "bsb -clean-world -nake-world && next start -w" }, "license": "ISC", "dependencies": { "babel-plugin-bucklescript": "^0.2.3-1", - "bs-platform": "^1.8.1", - "next": "^2.4.7", + "bs-platform": "^1.9.3", + "concurrently": "^3.5.0", + "next": "^3.2.2", "react": "^15.6.1", "react-dom": "^15.6.1", "reason-react": "^0.2.3" - }, - "babel": { - "presets": [ - "next/babel" - ], - "plugins": [ - "babel-plugin-bucklescript" - ] } } diff --git a/examples/with-reasonml/pages/about.js b/examples/with-reasonml/pages/about.js index b08913f1..a9997ae5 100644 --- a/examples/with-reasonml/pages/about.js +++ b/examples/with-reasonml/pages/about.js @@ -1,4 +1,4 @@ -import { jsComponent as About } from './about.re' +import { jsComponent as About } from './About.re' import React from 'react' export default () => diff --git a/examples/with-reasonml/pages/index.js b/examples/with-reasonml/pages/index.js index 1cedf538..24ea8281 100644 --- a/examples/with-reasonml/pages/index.js +++ b/examples/with-reasonml/pages/index.js @@ -1,3 +1,3 @@ -import { jsComponent as Index } from './index.re' +import { jsComponent as Index } from './Index.re' export default () =>