Skip to content

Commit 764a299

Browse files
authored
Add rescript example (#442) (#552)
* Add rescript example (#442) * Add rescript build configurations * Create rescript page components * Add rescript deps * Solve render comments issue * Refactor css transaction components React Hooks shouldn't be used in loops or if statement. * Ignore the rescript output js files from lint The rescript output js files from lint because it doesn't follow the lint rules. * Apply review requested changes * Remove unused tag * Add ROR binding * Apply review requested changes * remove action js file * Remove .mjs files * Compile rescript files before running js tests * Build recript files before test * minor change * remove react-on-rails binding * migrate to tailwind * remove bs.mjs files * remove unused scss files * fix rescript spec tests * build rescript before test * refactor rescript src * fix add commit fail bug * refactor the types * format rescript files * remove the types files * update error rescript page state design * refactor switch statements * move store comment state to the form component * format rescript * rename the saving state * empty commit
1 parent 5762d08 commit 764a299

31 files changed

Lines changed: 740 additions & 4 deletions

File tree

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ public/
44
client/app/libs/i18n/translations.js
55
client/app/libs/i18n/default.js
66
postcss.config.js
7+
client/app/bundles/comments/rescript/

.github/workflows/rspec_test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ jobs:
7373
- name: Build i18n libraries
7474
run: bundle exec rake react_on_rails:locale
7575

76+
- name: Build Rescript components
77+
run: yarn res:build
78+
7679
- name: Build shakapacker chunks
7780
run: NODE_ENV=development bundle exec bin/shakapacker
7881

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,8 @@ client/app/libs/i18n/default.js
4747
/yarn-error.log
4848
yarn-debug.log*
4949
.yarn-integrity
50+
51+
lib/bs
52+
/lib/ocaml
53+
54+
client/app/bundles/comments/rescript/**/*.bs.js

Procfile.dev

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Procfile for development using HMR
22
# You can run these commands in separate shells
3+
rescript: yarn res:dev
34
redis: redis-server
45
rails: bundle exec rails s -p 3000
56
wp-client: HMR=true RAILS_ENV=development NODE_ENV=development bin/shakapacker-dev-server

app/controllers/pages_controller.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ def no_router
3636

3737
def simple; end
3838

39+
def rescript; end
40+
3941
private
4042

4143
def set_comments

app/views/pages/rescript.html.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<%= react_component "RescriptShow", prerender: true %>

bsconfig.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "react-webpack-rails-tutorial",
3+
"sources": [
4+
{
5+
"dir": "client/app/bundles/comments/rescript",
6+
"subdirs": true
7+
}
8+
],
9+
"package-specs": [
10+
{
11+
"module": "es6",
12+
"in-source": true
13+
}
14+
],
15+
"bsc-flags": ["-open JsonCombinators", "-open Belt"],
16+
"suffix": ".bs.js",
17+
"bs-dependencies": [
18+
"@rescript/react",
19+
"@rescript/core",
20+
"@glennsl/rescript-fetch",
21+
"@glennsl/rescript-json-combinators",
22+
"rescript-react-on-rails"
23+
],
24+
"jsx": {
25+
"version": 4,
26+
"mode": "automatic"
27+
}
28+
}

client/app/bundles/comments/components/NavigationBar/NavigationBar.jsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ function NavigationBar(props) {
9797
Classic Rails
9898
</a>
9999
</li>
100+
<li className={classNames({ 'bg-yellow-100': pathname === paths.RESCRIPT_PATH })}>
101+
<a
102+
className="px-2 py-4 w-full inline-block text-gray-500 hover:text-gray-700"
103+
href={paths.RESCRIPT_PATH}
104+
>
105+
Rescript
106+
</a>
107+
</li>
100108
<li>
101109
<a
102110
className="px-2 py-4 w-full inline-block text-gray-500 hover:text-gray-700"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export const ROUTER_PATH = '/';
22
export const REACT_ROUTER_PATH = '/react-router';
33
export const NO_ROUTER_PATH = '/no-router';
4+
export const RESCRIPT_PATH = '/rescript';
45
export const SIMPLE_REACT_PATH = '/simple';
56
export const STIMULUS_PATH = '/stimulus';
67
export const RAILS_PATH = '/comments';
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// TODO : use only one way to make http requests either Axios or Fetch
2+
module Create = {
3+
type t = {
4+
author: string,
5+
text: string,
6+
}
7+
8+
let storeComment = async (comment: t) => {
9+
let _ = await Axios.post(
10+
"comments.json",
11+
{
12+
"author": comment.author,
13+
"text": comment.text,
14+
},
15+
{
16+
"responseType": "json",
17+
"headers": {
18+
// see https://github.com/shakacode/react_on_rails/blob/249c69812474e0f532df432581bf5e618df0e1ec/node_package/src/Authenticity.ts#L13C1-L18C1
19+
"X-CSRF-Token": ReactOnRails.authenticityToken(),
20+
"X-Requested-With": "XMLHttpRequest",
21+
},
22+
},
23+
)
24+
}
25+
}
26+
27+
module Fetch = {
28+
type t = {
29+
author: string,
30+
text: string,
31+
id: int,
32+
}
33+
34+
type comments = array<t>
35+
36+
type commentsRes = {comments: comments}
37+
38+
let fetchComments = async (): result<comments, string> => {
39+
open Json.Decode
40+
41+
let response = await Fetch.get("comments.json")
42+
let jsonRes = await response->Fetch.Response.json
43+
44+
let jsonComment = Json.Decode.object(field => {
45+
author: field.required(. "author", string),
46+
text: field.required(. "text", string),
47+
id: field.required(. "id", int),
48+
})
49+
50+
let jsonComments = Json.Decode.object(field => {
51+
comments: field.required(. "comments", array(jsonComment)),
52+
})
53+
54+
switch jsonRes->Json.decode(jsonComments) {
55+
| Ok(decodedRes) => Ok(decodedRes.comments)
56+
| Error(e) => Error(e)
57+
}
58+
}
59+
}

0 commit comments

Comments
 (0)