Skip to content

Commit 0aff3a6

Browse files
authored
Merge pull request #6201 from rescript-lang/ryyppy/playground-dune-integration
Fix playground build infra w/ ReScript 11
2 parents 065defe + ed711f8 commit 0aff3a6

15 files changed

+227
-564
lines changed

CONTRIBUTING.md

+18-55
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,6 @@ This is usually the file you want to create to test certain compile behavior wit
196196

197197
## Contribute to the ReScript Playground Bundle
198198

199-
> Note: These instructions are designed for building the 4.06 based version of ReScript (ReScript v6).
200-
201199
The "Playground bundle" is a JS version of the ReScript compiler; including all necessary dependency files (stdlib / belt etc). It is useful for building tools where you want to compile and execute arbitrary ReScript code in the browser.
202200

203201
The ReScript source code is compiled with a tool called [JSOO (js_of_ocaml)](https://ocsigen.org/js_of_ocaml/4.0.0/manual/overview), which uses OCaml bytecode to compile to JavaScript and is part of the bigger OCaml ecosystem.
@@ -210,99 +208,64 @@ opam install js_of_ocaml.4.0.0
210208

211209
### Building the Bundle
212210

213-
The entry point of the JSOO bundle is located in `jscomp/main/jsoo_playground_main.ml`, the code for packing the compiler into a single compiler file is located in `jscomp/snapshot.ninja`, and the script for running JSOO can be found in `scripts/repl.js`. A full clean build can be done like this:
214-
215-
```
216-
# We create a target directory for storing the bundle / stdlib files
217-
mkdir playground && mkdir playground/stdlib
218-
219-
# We build the ReScript source code and also the bytecode for the JSOO entrypoint
220-
node scripts/ninja.js config && node scripts/ninja.js build
221-
222-
# Now we run the repl.js script which will create all the required artifacts in the `./playground` directory
223-
node scripts/repl.js
224-
```
225-
226-
In case you want to build the project with our default third party packages (like `@rescript/react`), prepare the `playground-bundling` project and then run `repl.js` with `BUILD_THIRD_PARTY` enabled:
211+
The entry point of the JSOO bundle is located in `jscomp/jsoo/jsoo_playground_main.ml`, the compiler and its relevant runtime cmij files can be built via make:
227212

228-
```
229-
# Prepare the `playground-bundling` project to allow building of the third party cmij packages
230-
npm link
231-
cd packages/playground-bundling
232-
npm install
233-
npm link rescript
234-
235-
BUILD_THIRD_PARTY=true node scripts/repl.js
213+
```sh
214+
make playground
215+
make playground-cmijs
236216
```
237217

238-
_Troubleshooting: if ninja build step failed with `Error: cannot find file '+runtime.js'`, make sure `ocamlfind` is installed with `opam install ocamlfind`._
218+
Note that building the cmijs is based on the dependencies defined in `packages/playground-bundling/package.json`. In case you want to build some different version of e.g. `@rescript/react` or just want to add a new package, change the definition within the `package.json` file and run `make playground-cmijs` again.
239219

240220
After a successful compilation, you will find following files in your project:
241221

242222
- `playground/compiler.js` -> This is the ReScript compiler, which binds the ReScript API to the `window` object.
243-
- `playground/stdlib/*.js` -> All the ReScript runtime files.
244223
- `playground/packages` -> Contains third party deps with cmij.js files (as defined in `packages/playground-bundling/bsconfig.json`)
224+
- `playground/compilerCmij.js` -> The compiler base cmij containing all the relevant core modules (`Js`, `Belt`, `Pervasives`, etc.)
245225

246-
You can now use the `compiler.js` file either directly by using a `<script src="/path/to/compiler.js"/>` inside a html file, use a browser bundler infrastructure to optimize it, or you can even use it with `nodejs`:
226+
You can now use the `compiler.js` file either directly by using a `<script src="/path/to/compiler.js"/>` and `<script src="/path/to/packages/compilerCmij.js"/>` inside a html file, use a browser bundler infrastructure to optimize it, or use `nodejs` to run it on a command line:
247227

248228
```
249229
$ node
250230
> require("./compiler.js");
231+
> require("./packages/compilerCmij.js")
251232
> let compiler = rescript_compiler.make()
252233
> let result = compiler.rescript.compile(`Js.log(Sys.ocaml_version)`);
253234
> eval(result.js_code);
254235
4.06.2+BS
255236
```
256237

257-
You can also run `node playground/playground_test.js` for a quick sanity check to see if all the build artifacts are working together correctly.
258-
259-
### Playground JS bundle API
238+
### Testing the Playground bundle
260239

261-
As soon as the bundle is loaded, you will get access to the functions exposed in [`jsoo_playground_main.ml`](jscomp/main/jsoo_playground_main.ml). Best way to check out the API is by inspecting a compiler instance it either in node, or in the browser:
262-
263-
```
264-
$ node
265-
require('./compiler.js')
266-
267-
> let compiler = rescript_compiler.make()
268-
> console.log(compiler)
269-
```
240+
Run `node playground/playground_test.js` for a quick sanity check to see if all the build artifacts are working together correctly. When releasing the playground bundle, the test will always be executed before publishing to catch regressions.
270241

271242
### Working on the Playground JS API
272243

273244
Whenever you are modifying any files in the ReScript compiler, or in the `jsoo_playground_main.ml` file, you'll need to rebuild the source and recreate the JS bundle.
274245

275-
```sh
276-
node scripts/ninja.js config && node scripts/ninja.js build
277-
node scripts/repl.js
278246
```
247+
make playground
279248
280-
**.cmj files in the Web**
281-
282-
A `.cmj` file contains compile information and JS package information of ReScript build artifacts (your `.res / .ml` modules) and are generated on build (`scripts/ninja.js build`).
283-
284-
A `.cmi` file is an [OCaml originated file extension](https://waleedkhan.name/blog/ocaml-file-extensions/) and contains all interface information of a certain module without any implementation.
285-
286-
In this repo, these files usually sit right next to each compiled `.ml` / `.res` file. The structure of a `.cmj` file is defined in [js_cmj_format.ml](jscomp/core/js_cmj_format.ml). You can run a tool called `./jscomp/bin/cmjdump.exe [some-file.cmj]` to inspect the contents of given `.cmj` file.
287-
288-
`.cmj` files are required to compile modules (this includes modules like RescriptReact). ReScript includes a subset of modules by default, which can be found in `jscomp/stdlib-406` and `jscomp/others`. You can also find those modules listed in the JSOO call in `scripts/repl.js`. As you probably noticed, the generated `playground` files are all plain `.js`, so how are the `cmj` / `cmi` files embedded?
289-
290-
JSOO offers an `build-fs` subcommand that takes a list of `.cmi` and `.cmj` files and creates a `cmij.js` file that can be loaded by the JS runtime **after** the `compiler.js` bundle has been loaded (either via a `require()` call in Node, or via `<link/>` directive in an HTML file). Since we are shipping our playground with third party modules like `RescriptReact`, we created a utility directory `packages/playground-bundling` that comes with a utility script to do the `cmij.js` file creation for us. Check out `packages/playground-bundling/scripts/generate_cmijs.js` for details.
249+
# optionally run your test / arbitrary node script to verify your changes
250+
node playground/playground_test.js
251+
```
291252

292253
### Publishing the Playground Bundle on our KeyCDN
293254

294255
> Note: If you want to publish from your local machine, make sure to set the `KEYCDN_USER` and `KEYCDN_PASSWORD` environment variables accordingly (credentials currently managed by @ryyppy). Our CI servers / GH Action servers are already pre-configured with the right env variable values.
295256
296257
Our `compiler.js` and third-party packages bundles are hosted on [KeyCDN](https://www.keycdn.com) and uploaded via FTPS.
297258

298-
After a successful bundle build, run our upload script to publish the build artifacts to our server:
259+
The full release can be executed with the following make script:
299260

300261
```
301-
playground/upload_bundle.sh
262+
make playground-release
302263
```
303264

304265
The script will automatically detect the ReScript version from the `compiler.js` bundle and automatically create the correct directory structure on our CDN ftp server.
305266

267+
Note that there's currently still a manual step involved on [rescript-lang.org](https://rescript-lang.org) to make the uploaded playground version publicly available.
268+
306269
## Contribute to the API Reference
307270

308271
The API reference is generated from doc comments in the source code. [Here](https://github.com/rescript-lang/rescript-compiler/blob/99650/jscomp/others/js_re.mli#L146-L161)'s a good example.

Makefile

+16-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,21 @@ lib: build node_modules/.bin/semver
5252
artifacts: lib
5353
./scripts/makeArtifactList.js
5454

55+
# Builds the core playground bundle (without the relevant cmijs files for the runtime)
56+
playground:
57+
dune build --profile browser
58+
cp ./_build/default/jscomp/jsoo/jsoo_playground_main.bc.js playground/compiler.js
59+
60+
# Creates all the relevant core and third party cmij files to side-load together with the playground bundle
61+
playground-cmijs: artifacts
62+
node packages/playground-bundling/scripts/generate_cmijs.js
63+
64+
# Builds the playground, runs some e2e tests and releases the playground to the
65+
# CDN (requires KEYCDN_USER and KEYCDN_PASSWORD set in the env variables)
66+
playground-release: playground playground-cmijs
67+
node playground/playground_test.js
68+
sh playground/upload_bundle.sh
69+
5570
format:
5671
dune build @fmt --auto-promote
5772

@@ -69,4 +84,4 @@ clean-all: clean clean-gentype
6984

7085
.DEFAULT_GOAL := build
7186

72-
.PHONY: build watch ninja bench dce test test-syntax test-syntax-roundtrip test-gentype test-all lib artifacts format checkformat clean-gentype clean clean-all
87+
.PHONY: build watch ninja bench dce test test-syntax test-syntax-roundtrip test-gentype test-all lib playground playground-cmijs playground-release artifacts format checkformat clean-gentype clean clean-all

jscomp/jsoo/dune

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
; Don't build the JS compiler by default as it slows down CI considerably.
22

33
(executables
4-
(names jsoo_main jsoo_playground_main)
4+
(names jsoo_playground_main)
55
(modes js)
66
(enabled_if
77
(= %{profile} browser))
88
(flags
99
(:standard -w +a-4-9-40-42-44-45))
10-
(libraries core ml super_errors))
10+
(libraries core syntax ml js_of_ocaml))

jscomp/jsoo/jsoo_common.ml

-69
This file was deleted.

jscomp/jsoo/jsoo_common.mli

-59
This file was deleted.

0 commit comments

Comments
 (0)