From f5f38afad4254eb763238376903f65e7e1009273 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 6 Oct 2023 14:07:49 +0200 Subject: [PATCH 1/3] add 3-vite example --- examples/3-vite/.gitignore | 5 + examples/3-vite/3-vite.opam | 34 ++ examples/3-vite/Makefile | 67 +++ examples/3-vite/README.md | 35 ++ examples/3-vite/dune | 13 + examples/3-vite/dune-project | 34 ++ examples/3-vite/index.html | 12 + examples/3-vite/package-lock.json | 802 +++++++++++++++++++++++++++++ examples/3-vite/package.json | 15 + examples/3-vite/src/ReactApp.re | 20 + examples/3-vite/src/dune | 29 ++ examples/3-vite/src/world/dune | 4 + examples/3-vite/src/world/world.ml | 1 + examples/3-vite/vite.config.js | 20 + 14 files changed, 1091 insertions(+) create mode 100644 examples/3-vite/.gitignore create mode 100644 examples/3-vite/3-vite.opam create mode 100644 examples/3-vite/Makefile create mode 100644 examples/3-vite/README.md create mode 100644 examples/3-vite/dune create mode 100644 examples/3-vite/dune-project create mode 100644 examples/3-vite/index.html create mode 100644 examples/3-vite/package-lock.json create mode 100644 examples/3-vite/package.json create mode 100644 examples/3-vite/src/ReactApp.re create mode 100644 examples/3-vite/src/dune create mode 100644 examples/3-vite/src/world/dune create mode 100644 examples/3-vite/src/world/world.ml create mode 100644 examples/3-vite/vite.config.js diff --git a/examples/3-vite/.gitignore b/examples/3-vite/.gitignore new file mode 100644 index 0000000..4b06df1 --- /dev/null +++ b/examples/3-vite/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +node_modules +_build +_opam +dist/ diff --git a/examples/3-vite/3-vite.opam b/examples/3-vite/3-vite.opam new file mode 100644 index 0000000..ae6f620 --- /dev/null +++ b/examples/3-vite/3-vite.opam @@ -0,0 +1,34 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: "Melange React example with Vite" +description: "Minimal React example with Melange and Vite" +maintainer: [""] +authors: [""] +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" + "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} + ] +] diff --git a/examples/3-vite/Makefile b/examples/3-vite/Makefile new file mode 100644 index 0000000..9e7be64 --- /dev/null +++ b/examples/3-vite/Makefile @@ -0,0 +1,67 @@ +project_name = 2-react + +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 @2-react # @2-react 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 @2-react + +.PHONY: serve +serve: ## Serve the application with a local HTTP server + npm run serve + +.PHONY: dev +dev: ## Dev the application with a local HTTP server + npm run dev + +.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 @2-react diff --git a/examples/3-vite/README.md b/examples/3-vite/README.md new file mode 100644 index 0000000..64a93b0 --- /dev/null +++ b/examples/3-vite/README.md @@ -0,0 +1,35 @@ +# `3-vite` + +
+ +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". + +
+ +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 + +
$ cd example/3-vite
+$ make init
+$ make dev
+
+ +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 dev`: Run the application locally with vite and melange simultaneously +- `make bundle`: creates a full bundle with the generated `js` files and `html` page diff --git a/examples/3-vite/dune b/examples/3-vite/dune new file mode 100644 index 0000000..94d93f4 --- /dev/null +++ b/examples/3-vite/dune @@ -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) diff --git a/examples/3-vite/dune-project b/examples/3-vite/dune-project new file mode 100644 index 0000000..dc9f152 --- /dev/null +++ b/examples/3-vite/dune-project @@ -0,0 +1,34 @@ +(lang dune 3.8) + +(using melange 0.1) + +(generate_opam_files true) + +(name 3-vite) + +(license "MIT") + +(maintainers ) + +(authors ) + +(homepage https://github.com/your/project) + +(bug_reports https://github.com/your/project/issues) + +(package + (name 3-vite) + (synopsis "Melange React example with Vite") + (description "Minimal React example with Melange and Vite") + (depends + (melange + (>= "2.0.0")) + (reason + (>= "3.10.0")) + (reason-react + (>= "0.13.0")) + reason-react-ppx + (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 + )) diff --git a/examples/3-vite/index.html b/examples/3-vite/index.html new file mode 100644 index 0000000..fd84e5c --- /dev/null +++ b/examples/3-vite/index.html @@ -0,0 +1,12 @@ + + + + + + Melange app with Vite + + +
+ + + diff --git a/examples/3-vite/package-lock.json b/examples/3-vite/package-lock.json new file mode 100644 index 0000000..beb1371 --- /dev/null +++ b/examples/3-vite/package-lock.json @@ -0,0 +1,802 @@ +{ + "name": "3-vite", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "react": "^17.0.0", + "react-dom": "^17.0.0" + }, + "devDependencies": { + "vite": "^4.4.0", + "vite-plugin-melange": "^2.2.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@types/node": { + "version": "20.8.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", + "integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + }, + "peerDependencies": { + "react": "17.0.2" + } + }, + "node_modules/rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/terser": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", + "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/vite": { + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz", + "integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==", + "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-melange": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-melange/-/vite-plugin-melange-2.2.0.tgz", + "integrity": "sha512-2OE9XXU2FW02fTRXCwMKGHGT3p18bNubpVkipjlEOV3lHuvS94bmktZaPBwavSxJRCxT1Gu5Hmv3+mhUAyeVOA==", + "dev": true, + "dependencies": { + "etag": "^1.8.1", + "picocolors": "^1.0.0", + "strip-ansi": "^6.0.1" + } + } + } +} diff --git a/examples/3-vite/package.json b/examples/3-vite/package.json new file mode 100644 index 0000000..3f2e4a2 --- /dev/null +++ b/examples/3-vite/package.json @@ -0,0 +1,15 @@ +{ + "scripts": { + "bundle": "vite build", + "serve": "vite preview", + "dev": "vite" + }, + "dependencies": { + "react": "^17.0.0", + "react-dom": "^17.0.0" + }, + "devDependencies": { + "vite": "^4.4.0", + "vite-plugin-melange": "^2.2.0" + } +} diff --git a/examples/3-vite/src/ReactApp.re b/examples/3-vite/src/ReactApp.re new file mode 100644 index 0000000..abd1169 --- /dev/null +++ b/examples/3-vite/src/ReactApp.re @@ -0,0 +1,20 @@ +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 = () => + ["Hello " ++ World.name ++ "!", "This is React with Vite!"] + ->Belt.List.map(greeting =>

greeting->React.string

) + ->Belt.List.toArray + ->React.array; +}; + +ReactDOM.querySelector("#root") +->( + fun + | Some(root) => ReactDOM.render(, root) + | None => + Js.Console.error( + "Failed to start React: couldn't find the #root element", + ) + ); diff --git a/examples/3-vite/src/dune b/examples/3-vite/src/dune new file mode 100644 index 0000000..c0be7ff --- /dev/null +++ b/examples/3-vite/src/dune @@ -0,0 +1,29 @@ +; `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 + +(melange.emit + (package 3-vite) + ; 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 3-vite) + ; 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 world) + ; 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)) diff --git a/examples/3-vite/src/world/dune b/examples/3-vite/src/world/dune new file mode 100644 index 0000000..16ff9de --- /dev/null +++ b/examples/3-vite/src/world/dune @@ -0,0 +1,4 @@ +(library + (name world) + (public_name 3-vite.world) + (modes melange)) diff --git a/examples/3-vite/src/world/world.ml b/examples/3-vite/src/world/world.ml new file mode 100644 index 0000000..16ef55f --- /dev/null +++ b/examples/3-vite/src/world/world.ml @@ -0,0 +1 @@ +let name = "world" diff --git a/examples/3-vite/vite.config.js b/examples/3-vite/vite.config.js new file mode 100644 index 0000000..7643ec2 --- /dev/null +++ b/examples/3-vite/vite.config.js @@ -0,0 +1,20 @@ +import { defineConfig } from "vite"; +import melangePlugin from "vite-plugin-melange"; + +export default defineConfig({ + plugins: [ + melangePlugin({ + emitDir: "src", + buildCommand: "opam exec -- dune build @3-vite", + watchCommand: "opam exec -- dune build --watch @3-vite", + }), + ], + server: { + watch: { + awaitWriteFinish: { + stabilityThreshold: 500, + pollInterval: 20, + }, + }, + }, +}); From 14633de3157faca80415592a7d0e03ed9bfd02cc Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 6 Oct 2023 14:09:58 +0200 Subject: [PATCH 2/3] add 3-vite example to main README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0980c22..a6060eb 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ Each example includes a `README.md` with instructions on how to get started. application, prints a "hello world" message when it runs. - [**`2-react`**](examples/2-react)  —  a simple Reason React app with Webpack. +- [**`3-vite`**](examples/3-vite)  —  a simple Reason React + app with Vite. ## Contributing From 7736c77b2c13b8268bd09afbc1fc8a9202f90e8b Mon Sep 17 00:00:00 2001 From: Javier Chavarri Date: Tue, 17 Oct 2023 16:44:15 +0000 Subject: [PATCH 3/3] 3-vite: add it to makefile+opam, fix some cmds --- Makefile | 4 ++++ examples/3-vite/Makefile | 8 ++++---- melange-examples.opam | 2 ++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index c9ba275..eb51148 100644 --- a/Makefile +++ b/Makefile @@ -27,21 +27,25 @@ init: create-switch install ## Configure everything to develop this repository i install: ## Install development dependencies make -C examples/1-node install make -C examples/2-react install + make -C examples/3-vite install .PHONY: build build: ## Build all examples make -C examples/1-node build make -C examples/2-react build + make -C examples/3-vite build .PHONY: test test: ## Test all examples make -C examples/1-node test make -C examples/2-react test + make -C examples/3-vite test .PHONY: clean clean: ## Clean all examples make -C examples/1-node clean make -C examples/2-react clean + make -C examples/3-vite clean .PHONY: format format: ## Format the codebase with ocamlformat diff --git a/examples/3-vite/Makefile b/examples/3-vite/Makefile index 9e7be64..cb14767 100644 --- a/examples/3-vite/Makefile +++ b/examples/3-vite/Makefile @@ -1,4 +1,4 @@ -project_name = 2-react +project_name = 3-vite DUNE = opam exec -- dune @@ -27,7 +27,7 @@ install: ## Install development dependencies .PHONY: build build: ## Build the project - $(DUNE) build @2-react # @2-react is a dune alias: https://dune.readthedocs.io/en/stable/overview.html#term-alias + $(DUNE) build @3-vite # @3-vite 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 @@ -36,7 +36,7 @@ test: build ## Test the project .PHONY: build_verbose build_verbose: ## Build the project - $(DUNE) build --verbose @2-react + $(DUNE) build --verbose @3-vite .PHONY: serve serve: ## Serve the application with a local HTTP server @@ -64,4 +64,4 @@ format-check: ## Checks if format is correct .PHONY: watch watch: ## Watch for the filesystem and rebuild on every change - $(DUNE) build --watch @2-react + $(DUNE) build --watch @3-vite diff --git a/melange-examples.opam b/melange-examples.opam index 66a599e..c61f2cb 100644 --- a/melange-examples.opam +++ b/melange-examples.opam @@ -9,9 +9,11 @@ bug-reports: "https://github.com/your/project/issues" depends: [ "1-node" "2-react" + "3-vite" ] dev-repo: "git+https://github.com/your/project.git" pin-depends: [ "1-node.dev" "./examples/1-node" "2-react.dev" "./examples/2-react" + "3-vite.dev" "./examples/3-vite" ]