Add ReasonML boilerplate

After some toil, I finally support basic ReasonML starter code.

I'm adding it to the nut-score directory because I would like to make a simple
webpage that render some nutritional facts about nuts with respect to the
ketogenic diet.

I'm not sure if I should include or exclude te .bs.js files.

See the README.md for more information.
This commit is contained in:
William Carroll 2020-03-17 22:40:48 +00:00
parent 166aed6e80
commit 209fdf5726
14 changed files with 484 additions and 0 deletions

8
.gitignore vendored
View file

@ -33,3 +33,11 @@ node_modules/
/configs/.config/fish/config.fish
/configs/.config/fish/fish_variables
/blog/public/
# ReasonML
.merlin
.bsb.lock
npm-debug.log
/nut-score/lib/bs/
/nut-score/node_modules/
/nut-score/bundleOutput/

35
nut-score/README.md Normal file
View file

@ -0,0 +1,35 @@
# Nut Score
I cloned most of this start boilerplate from
github.com/BuckleScript/bucklescript by running the following:
```shell
$ cd ~/programming
$ git clone git@github.com:BuckleScript/bucklescript
$ cp -R ./jscomp/bab/templates/react-hooks ~/briefcase/nut-score
```
## Installing
```shell
$ nix-shell
$ yarn install
```
## Developing
In one shell run:
```shell
$ nix-shell
$ yarn server
```
In another shell run:
```shell
$ nix-shell
$ yarn start
```
Now open a web browser and visit `localhost:8000`.

View file

@ -0,0 +1,14 @@
const path = require('path');
module.exports = {
entry: './src/Index.bs.js',
// If you ever want to use webpack during development, change 'production'
// to 'development' as per webpack documentation. Again, you don't have to
// use webpack or any other bundler during development! Recheck README if
// you didn't know this
mode: 'production',
output: {
path: path.join(__dirname, "bundleOutput"),
filename: 'index.js',
},
};

21
nut-score/bsconfig.json Normal file
View file

@ -0,0 +1,21 @@
{
"name": "reason-react-examples",
"reason": {
"react-jsx": 3
},
"sources": {
"dir" : "src",
"subdirs" : true
},
"bsc-flags": ["-bs-super-errors", "-bs-no-version-header"],
"package-specs": [{
"module": "commonjs",
"in-source": true
}],
"suffix": ".bs.js",
"namespace": true,
"bs-dependencies": [
"reason-react"
],
"refmt": 3
}

22
nut-score/index.html Normal file
View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ReasonReact Examples</title>
</head>
<body>
<script>
// stub a variable ReactJS checks. ReactJS assumes you're using a bundler, NodeJS or similar system that provides it the `process.env.NODE_ENV` variable.
window.process = {
env: {
NODE_ENV: 'development'
}
};
</script>
<div id="mount"></div>
<!-- This is https://github.com/marijnh/moduleserve, the secret sauce that allows us not need to bundle things during development, and have instantaneous iteration feedback, without any hot-reloading or extra build pipeline needed. -->
<script src="/moduleserve/load.js" data-module="/src/Index.bs.js"></script>
<!-- Our little watcher. Super clean. Check it out! -->
<script src="/watcher.js"></script>
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ReasonReact Examples</title>
</head>
<body>
<script src="./bundleOutput/index.js"></script>
</body>
</html>

27
nut-score/package.json Normal file
View file

@ -0,0 +1,27 @@
{
"name": "nut-score",
"version": "1.0.0",
"scripts": {
"build": "bsb -make-world",
"start": "bsb -make-world -w -ws _ ",
"clean": "bsb -clean-world",
"server": "moduleserve ./ --port 8000",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"BuckleScript",
"ReasonReact",
"reason-react"
],
"author": "",
"license": "MIT",
"dependencies": {
"react": "^16.8.1",
"react-dom": "^16.8.1",
"reason-react": ">=0.7.0"
},
"devDependencies": {
"bs-platform": "^${bsb:bs-version}",
"moduleserve": "^0.9.0"
}
}

8
nut-score/shell.nix Normal file
View file

@ -0,0 +1,8 @@
let
pkgs = import <nixpkgs> {};
in pkgs.mkShell {
name = "nut-score";
buildInputs = with pkgs; [
yarn
];
}

View file

@ -0,0 +1,9 @@
'use strict';
var React = require("react");
var ReactDOMRe = require("reason-react/src/ReactDOMRe.js");
var ReducerFromReactJSDocs$ReasonReactExamples = require("./ReducerFromReactJSDocs/ReducerFromReactJSDocs.bs.js");
ReactDOMRe.renderToElementWithId(React.createElement(ReducerFromReactJSDocs$ReasonReactExamples.make, { }), "mount");
/* Not a pure module */

1
nut-score/src/Index.re Normal file
View file

@ -0,0 +1 @@
ReactDOMRe.renderToElementWithId(<ReducerFromReactJSDocs />, "mount");

View file

@ -0,0 +1,35 @@
'use strict';
var Curry = require("bs-platform/lib/js/curry.js");
var React = require("react");
var initialState = /* record */[/* count */0];
function reducer(state, action) {
if (action) {
return /* record */[/* count */state[/* count */0] - 1 | 0];
} else {
return /* record */[/* count */state[/* count */0] + 1 | 0];
}
}
function ReducerFromReactJSDocs(Props) {
var match = React.useReducer(reducer, initialState);
var dispatch = match[1];
return React.createElement("div", undefined, React.createElement("div", undefined, "Count: ", String(match[0][/* count */0])), React.createElement("div", undefined, React.createElement("button", {
onClick: (function (_event) {
return Curry._1(dispatch, /* Decrement */1);
})
}, "-"), React.createElement("button", {
onClick: (function (_event) {
return Curry._1(dispatch, /* Increment */0);
})
}, "+")));
}
var make = ReducerFromReactJSDocs;
exports.initialState = initialState;
exports.reducer = reducer;
exports.make = make;
/* react Not a pure module */

View file

@ -0,0 +1,39 @@
// This is the ReactJS documentation's useReducer example, directly ported over
// https://reactjs.org/docs/hooks-reference.html#usereducer
// Record and variant need explicit declarations.
type state = {count: int};
type action =
| Increment
| Decrement;
let initialState = {count: 0};
let reducer = (state, action) => {
switch (action) {
| Increment => {count: state.count + 1}
| Decrement => {count: state.count - 1}
};
};
[@react.component]
let make = () => {
let (state, dispatch) = React.useReducer(reducer, initialState);
// We can use a fragment here, but we don't, because we want to style the counter
<div>
<div>
{React.string("Count: ")}
{React.string(string_of_int(state.count))}
</div>
<div>
<button onClick={_event => dispatch(Decrement)}>
{React.string("-")}
</button>
<button onClick={_event => dispatch(Increment)}>
{React.string("+")}
</button>
</div>
</div>;
};

39
nut-score/watcher.js Normal file
View file

@ -0,0 +1,39 @@
// This is our simple, robust watcher. It hooks into the BuckleScript build
// system to listen for build events.
// See package.json's `start` script and `./node_modules/.bin/bsb --help`
// Btw, if you change this file and reload the page, your browser cache
// _might_ not pick up the new version. If you're in Chrome, do Force Reload.
var websocketReloader;
var LAST_SUCCESS_BUILD_STAMP = localStorage.getItem('LAST_SUCCESS_BUILD_STAMP') || 0;
// package.json's `start` script's `bsb -ws _` means it'll pipe build events
// through a websocket connection to a default port of 9999. This is
// configurable, e.g. `-ws 5000`
var webSocketPort = 9999;
function setUpWebSocket() {
if (websocketReloader == null || websocketReloader.readyState !== 1) {
try {
websocketReloader = new WebSocket(`ws://${window.location.hostname}:${webSocketPort}`);
websocketReloader.onmessage = (message) => {
var newData = JSON.parse(message.data).LAST_SUCCESS_BUILD_STAMP;
if (newData > LAST_SUCCESS_BUILD_STAMP) {
LAST_SUCCESS_BUILD_STAMP = newData;
localStorage.setItem('LAST_SUCCESS_BUILD_STAMP', LAST_SUCCESS_BUILD_STAMP);
// Refresh the page! This will naturally re-run everything,
// including our moduleserve which will re-resolve all the modules.
// No stable build!
location.reload(true);
}
}
} catch (exn) {
console.error("The watcher tried to connect to web socket, but failed. Here's the message:");
console.error(exn);
}
}
};
setUpWebSocket();
setInterval(setUpWebSocket, 2000);

216
nut-score/yarn.lock Normal file
View file

@ -0,0 +1,216 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"bs-platform@^${bsb:bs-version}":
version "6.2.1"
resolved "https://registry.yarnpkg.com/bs-platform/-/bs-platform-6.2.1.tgz#30266c7f23a3b323e1fc9596a9a6eb9f053981b4"
integrity sha512-FmQ8kYV52A0Y302qh6o0/J9TO+kHzsjGQnsjrg/ONUYIY/jWzBnt9dCBO6EBnaEKfFJLqk5JrUDCxuihqtTcnw==
debug@2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
destroy@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
encodeurl@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
http-errors@~1.7.2:
version "1.7.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
dependencies:
depd "~1.1.2"
inherits "2.0.4"
setprototypeof "1.1.1"
statuses ">= 1.5.0 < 2"
toidentifier "1.0.0"
inherits@2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
"js-tokens@^3.0.0 || ^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
mime@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
moduleserve@^0.9.0:
version "0.9.1"
resolved "https://registry.yarnpkg.com/moduleserve/-/moduleserve-0.9.1.tgz#11bad4337ea248d7eaf10d2c7f8649a8c3b9c1f8"
integrity sha512-WF2BeGnM2Ko7bdICgJO+Ibu+ZD33ExJHzOzTDsCUzfZnvnFfheEIYBTWyIqSRU0tXh4UTQ1krDOCglFTJPBMow==
dependencies:
send "^0.17.1"
serve-static "^1.14.1"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
ms@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
dependencies:
ee-first "1.1.1"
parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
prop-types@^15.6.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
dependencies:
loose-envify "^1.4.0"
object-assign "^4.1.1"
react-is "^16.8.1"
range-parser@~1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
react-dom@>=16.8.1, react-dom@^16.8.1:
version "16.13.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.0.tgz#cdde54b48eb9e8a0ca1b3dc9943d9bb409b81866"
integrity sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.19.0"
react-is@^16.8.1:
version "16.13.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527"
integrity sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA==
react@>=16.8.1, react@^16.8.1:
version "16.13.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.13.0.tgz#d046eabcdf64e457bbeed1e792e235e1b9934cf7"
integrity sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
reason-react@>=0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/reason-react/-/reason-react-0.7.0.tgz#46a975c321e81cd51310d7b1a02418ca7667b0d6"
integrity sha512-czR/f0lY5iyLCki9gwftOFF5Zs40l7ZSFmpGK/Z6hx2jBVeFDmIiXB8bAQW/cO6IvtuEt97OmsYueiuOYG9XjQ==
dependencies:
react ">=16.8.1"
react-dom ">=16.8.1"
scheduler@^0.19.0:
version "0.19.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.0.tgz#a715d56302de403df742f4a9be11975b32f5698d"
integrity sha512-xowbVaTPe9r7y7RUejcK73/j8tt2jfiyTednOvHbA8JoClvMYCp+r8QegLwK/n8zWQAtZb1fFnER4XLBZXrCxA==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
send@0.17.1, send@^0.17.1:
version "0.17.1"
resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==
dependencies:
debug "2.6.9"
depd "~1.1.2"
destroy "~1.0.4"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
fresh "0.5.2"
http-errors "~1.7.2"
mime "1.6.0"
ms "2.1.1"
on-finished "~2.3.0"
range-parser "~1.2.1"
statuses "~1.5.0"
serve-static@^1.14.1:
version "1.14.1"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9"
integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==
dependencies:
encodeurl "~1.0.2"
escape-html "~1.0.3"
parseurl "~1.3.3"
send "0.17.1"
setprototypeof@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
"statuses@>= 1.5.0 < 2", statuses@~1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
toidentifier@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==