Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add dream, webpack and atd example #4

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions examples/4-dream-atd/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.DS_Store
node_modules
_build
_opam
dist/
36 changes: 36 additions & 0 deletions examples/4-dream-atd/4-dream-atd.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: "Melange React example"
description: "Minimal React example with Melange"
maintainer: ["<your_name>"]
authors: ["<your_name>"]
license: "MIT"
homepage: "https://github.com/your/project"
bug-reports: "https://github.com/your/project/issues"
depends: [
"dune" {>= "3.8"}
"melange" {>= "2.0.0"}
"reason" {>= "3.10.0"}
"reason-react" {>= "0.13.0"}
"reason-react-ppx"
"dream"
"atdgen"
"ocaml-lsp-server" {with-test}
"opam-check-npm-deps" {with-test}
"ocamlformat" {with-test}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
69 changes: 69 additions & 0 deletions examples/4-dream-atd/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
project_name = 4-dream-atd

DUNE = opam exec -- dune

.DEFAULT_GOAL := help

.PHONY: help
help: ## Print this help message
@echo "List of available make commands";
@echo "";
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}';
@echo "";

.PHONY: create-switch
create-switch: ## Create opam switch
opam switch create . 5.1.0 -y --deps-only

.PHONY: init
init: create-switch install ## Configure everything to develop this repository in local

.PHONY: install
install: ## Install development dependencies
npm install # install JavaScript packages that the project might depend on, like `react` or `react-dom`
opam update # make sure that opam has the latest information about published libraries in the opam repository https://opam.ocaml.org/packages/
opam install -y . --deps-only --with-test # install the Melange and OCaml dependencies
opam exec opam-check-npm-deps # check that the versions of the JavaScript packages installed match the requirements defined by Melange libraries

.PHONY: build
build: ## Build the project
$(DUNE) build @4-dream-atd # @4-dream-atd is a dune alias: https://dune.readthedocs.io/en/stable/overview.html#term-alias
# Another way to build the project would be just calling `dune build`, which will build the `@@default` alias: https://dune.readthedocs.io/en/stable/reference/aliases.html#default

.PHONY: test
test: build ## Test the project
npm run bundle

.PHONY: build_verbose
build_verbose: ## Build the project
$(DUNE) build --verbose @4-dream-atd

.PHONY: serve
serve: ## Serve the application with a local HTTP server
npm run serve

.PHONY: start
start: ## start the application with a local HTTP server
# dune build --watch @4-dream-atd
# dune exec --root . server/server.exe
$(DUNE) build --watch @server @dream-atd @common

.PHONY: bundle
bundle: ## Bundle the JavaScript application
npm run bundle

.PHONY: clean
clean: ## Clean build artifacts and other generated files
$(DUNE) clean

.PHONY: format
format: ## Format the codebase with ocamlformat
$(DUNE) build @fmt --auto-promote

.PHONY: format-check
format-check: ## Checks if format is correct
$(DUNE) build @fmt

.PHONY: watch
watch: ## Watch for the filesystem and rebuild on every change
$(DUNE) build --watch @4-dream-atd
37 changes: 37 additions & 0 deletions examples/4-dream-atd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# `4-dream-atd`

<br>

This project shows how to create a simple React app with Melange and
[ReasonReact](https://reasonml.github.io/reason-react/).

The app just renders a component with "Hello world".

<br>

To set up the environment to work with it, you will need to install
[opam](https://opam.ocaml.org/) and [Node.js](https://nodejs.org/).

## Get started

<pre><code><b>$ cd example/4-dream-atd</b>
<b>$ make init</b>
<b>$ make watch</b>
# in another tab
<b>$ make serve</b>
</code></pre>

Then open the browser to see the rendered app.

## Commands

You can see all available commands by running `make help` or just `make`. Here
are a few of the most useful ones:

- `make init`: set up opam local switch and download OCaml, Melange and
JavaScript dependencies
- `make install`: install OCaml, Melange and JavaScript dependencies
- `make watch`: watch for the filesystem and have Melange rebuild on every
change
- `make serve`: serve the application with a local HTTP server
- `make bundle`: creates a full bundle with the generated `js` files and `html` page
33 changes: 33 additions & 0 deletions examples/4-dream-atd/client/ReactApp.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module App = {
// This sample forces an import of Belt.*, so that CI builds can ensure that
// Melange has been installed correctly for JS bundlers to be able to find it.
[@react.component]
let make = () => {
React.useEffect0(() => {
(
Fetch.get("http://localhost:3001/")
|> Js.Promise.then_(res => {
Js.log2(res, "es");
Js.Promise.resolve(res);
})
)
->ignore;

None;
});
["Hello " ++ "!", "This is React!"]
->Belt.List.map(greeting => <h1> greeting->React.string </h1>)
->Belt.List.toArray
->React.array;
};
};

ReactDOM.querySelector("#root")
->(
fun
| Some(root) => ReactDOM.render(<App />, root)
| None =>
Js.Console.error(
"Failed to start React: couldn't find the #root element",
)
);
11 changes: 11 additions & 0 deletions examples/4-dream-atd/client/bindings/Fetch.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
type nonrec response;

[@send] external json: response => Js.Promise.t(Js.Json.t) = "json";

[@val]
external fetch: (string, Js.t({..})) => Js.Promise.t(response) = "fetch";

let get = url =>
Js.Promise.(
fetch(url, {"method": "GET"}) |> then_(json) |> catch(Js.log)
);
31 changes: 31 additions & 0 deletions examples/4-dream-atd/client/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
; `melange.emit` is a Dune stanza that will produce build rules to generate
; JavaScript files from sources using the Melange compiler
; https://dune.readthedocs.io/en/stable/melange.html#melange-emit

(include_subdirs unqualified)

(melange.emit
(package 4-dream-atd)
; The `target` field is used by Dune to put all JavaScript artifacts in a specific folder inside `_build/default`
; This field `target` allows to have multiple `melange.emit` stanzas in the `dune` file
; if, for example, we want to produce ES6 and CommonJS output from the same sources.
(target output)
; The `alias` field can be used later on to build just the artifacts from this `melange.emit`
; by calling `dune build @react`.
; Note that if no `alias` field is defined, a default `melange` alias will be used instead.
(alias 4-dream-atd)
; Here's the list of dependencies of the stanza. In this case (being `melange.emit`),
; Dune will look into those dependencies and generate rules with JavaScript targets
; for the modules in those libraries as well.
; Caveat: the libraries need to be specified with `(modes melange)`.
(libraries reason-react )
; By default, Dune will include all modules in the folder to the targets. With `modules` field
; we can tweak this default behavior by including or excluding modules from the list of targets of this stanza.
; See https://dune.readthedocs.io/en/stable/reference/predicate-language.html#predicate-language
; (modules :standard \ hello) ; include all modules except `hello`
; (modules hello) ; include `hello`
; Uncomment the following to copy the generated JavaScript files inside the source tree
; (promote (until-clean))
(preprocess
(pps melange.ppx reason-react-ppx))
(module_systems es6))
6 changes: 6 additions & 0 deletions examples/4-dream-atd/common/article.atd
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type t = {
title: string;
body: string;
}

type articles = t list
8 changes: 8 additions & 0 deletions examples/4-dream-atd/common/common.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
let example1: Article_t.t = {title: "first", body: "foo"};
let example2: Article_t.t = {title: "second", body: "bar"};

let article_list = [example1, example2];

let sendArticles = _request => {
article_list |> Article_j.string_of_articles |> Dream.json;
};
17 changes: 17 additions & 0 deletions examples/4-dream-atd/common/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
(library
(name common)
(libraries dream atdgen-runtime)
(preprocess (pps lwt_ppx)))

(rule
(targets article_j.ml article_j.mli)
(deps article.atd)
(action
(run atdgen -j -j-std %{deps})))

(rule
(targets article_t.ml article_t.mli)
(deps article.atd)
(action
(run atdgen -t %{deps})))

Empty file.
13 changes: 13 additions & 0 deletions examples/4-dream-atd/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
;; `dirs` is a stanza to tell dune which subfolders from the current folder
;; (where the `dune` file is) it should process.
;; `:standard` is part of Dune's predicate language: https://dune.readthedocs.io/en/stable/reference/predicate-language.html#predicate-language
;; In the case of `dirs` stanza, `:standard` means "Process all subdirs, except those starting with underscore"
;; `\` operator will exclude the next value defined set.

;; With that in mind, we start by ignoring `node_modules`, because in most cases
;; there should be no `dune` files to be processed there by Dune.
;; If you need to consume an OCaml project from `node_modules`, this should work:
;; - remove the `dirs` stanza below
;; - add a `(subdir node_modules (dirs only_your_package))`

(dirs :standard \ node_modules)
36 changes: 36 additions & 0 deletions examples/4-dream-atd/dune-project
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
(lang dune 3.8)

(using melange 0.1)

(generate_opam_files true)

(name 4-dream-atd)

(license "MIT")

(maintainers <your_name>)

(authors <your_name>)

(homepage https://github.com/your/project)

(bug_reports https://github.com/your/project/issues)

(package
(name 4-dream-atd)
(synopsis "Melange React example")
(description "Minimal React example with Melange")
(depends
(melange
(>= "2.0.0"))
(reason
(>= "3.10.0"))
(reason-react
(>= "0.13.0"))
reason-react-ppx
dream
atdgen
(ocaml-lsp-server :with-test) ; todo: use with-dev-setup once opam 2.2 is out
(opam-check-npm-deps :with-test) ; todo: use with-dev-setup once opam 2.2 is out
(ocamlformat :with-test) ; todo: use with-dev-setup once opam 2.2 is out
))
Loading
Loading