Skip to content

Commit e5d2377

Browse files
committed
Pick playground changes from branch 10.0_release
1 parent c09f852 commit e5d2377

File tree

4 files changed

+110
-32
lines changed

4 files changed

+110
-32
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,5 @@ playground/packages/
154154
playground/stdlib/
155155
playground/*.cmj
156156
playground/*.cmi
157+
playground/.netrc
157158
playground/compiler.js

CONTRIBUTING.md

+55-31
Original file line numberDiff line numberDiff line change
@@ -99,81 +99,93 @@ dune build -w
9999

100100
> Please note that `dune` will not build the final `rescript` binaries. Use the aforementioned `ninja` workflow if you want to build, test and distribute the final product.
101101
102-
## Adding new Files to the Npm Package
102+
## Adding new Files
103103

104104
To make sure that no files are added to or removed from the npm package inadvertently, an artifact list is kept at `packages/artifacts.txt`. During CI build, it is verified that only the files that are listed there are actually included in the npm package.
105105

106-
When adding a new file to the repository that should go into the npm package - e.g., a new stdlib module -, first compile and test everything locally. Then
106+
When adding a new file to the repository that should go into the npm package - e.g., a new stdlib module -, first compile and test everything locally. Next, run `./scripts/makeArtifactList.js` to update the artifact list and include the updated artifact list in your commit.
107107

108-
- `node scripts/install -force-lib-rebuild` to copy library files into `lib/ocaml`
109-
- `./scripts/makeArtifactList.js` to update the artifact list and include the updated artifact list in your commit.
108+
## Running tests for independent ReScript files
110109

111-
## Test the compiler
110+
The simplest way for running tests is to run your locally built compiler on separate ReScript files:
112111

113-
Make sure to build the compiler first following the instructions above.
112+
```sh
113+
# Make sure to rebuild the compiler before running any tests (./scripts/ninja.js config / build etc)
114+
./darwinarm64/bsc.exe myTestFile.res
115+
```
116+
117+
**Different architectures:**
118+
119+
- `darwinarm64/bsc.exe`: M1 Macs
120+
- `darwin/bsc.exe`: Intel Macs
121+
- `linux/bsc.exe`: Linux computers
122+
123+
### Testing the whole ReScript Package
114124

115-
### Single file
125+
If you'd like to bundle up and use your modified ReScript like an end-user, try:
116126

117127
```sh
118-
./bsc myTestFile.res
128+
node scripts/install -force-lib-rebuild # make sure lib/ocaml is populated
129+
130+
npm uninstall -g rescript # a cache-busting uninstall is needed, but only for npm >=7
131+
132+
# This will globally install your local build via npm
133+
RESCRIPT_FORCE_REBUILD=1 npm install -g .
119134
```
120135

121-
### Project
136+
Then you may initialize and build your ReScript project as usual:
122137

123138
```sh
124-
node scripts/install -force-lib-rebuild ## populate lib/ocaml
125-
cd myProject
126-
npm install __path_to_this_repository__
139+
rescript init my-project
140+
cd my-project
141+
npm run build
127142
```
128143

129144
### Running Automatic Tests
130145

131146
We provide different test suites for different levels of the compiler and build system infrastructure. Always make sure to locally build your compiler before running any tests.
132147

133-
To run all tests:
134-
135-
```sh
136-
npm test
137-
```
138-
139-
**Run Mocha tests only (for our runtime code):**
148+
**Run Mocha tests for our runtime code:**
140149

141150
This will run our `mocha` unit test suite defined in `jscomp/test`.
142151

143152
```
144-
node scripts/ciTest.js -mocha
153+
npx node scripts/ciTest.js -mocha
145154
```
146155

147156
**Run build system test (integration tests):**
148157

149158
This will run the whole build system test suite defined in `jscomp/build_tests`.
150159

151160
```
152-
node scripts/ciTest.js -bsb
161+
# Make sure to globally install rescript via npm first
162+
npm install -g .
163+
164+
npx node scripts/ciTest.js -bsb
153165
```
154166

155167
**Run ounit tests:**
156168

157169
This will run unit tests for compiler related modules. The tests can be found in `jscomp/ounit_tests`.
158170

159171
```
160-
node scripts/ciTest.js -ounit
172+
npx node scripts/ciTest.js -ounit
161173
```
162174

163-
## Contributing to the Runtime
175+
## Contributing to the ReScript Runtime
164176

165-
The runtime implementation is written in OCaml with some raw JS code embedded (`jscomp/runtime` directory).
177+
Our runtime implementation is written in pure OCaml with some raw JS code embedded (`jscomp/runtime` directory).
166178

167-
The goal is to implement the runtime **purely in OCaml**. This includes removing all existing occurrences of embedded raw JS code as well whenever possible, and you can help!
179+
The goal is to implement the runtime **purely in OCaml**. This includes removing all existing occurrences of embedded raw JS code as well, and you can help!
168180

169181
Each new PR should include appropriate testing.
170182

171183
Currently all tests are located in the `jscomp/test` directory and you should either add / update test files according to your changes to the compiler.
172184

173185
There are currently two formats for test files:
174186

175-
1. Mocha test files that run javascript test code
176-
2. Plain `.ml` files to check the result of compilation to JS (expectation tests)
187+
1. Proper mocha test files with executed javascript test code
188+
2. Plain `.ml` files which are only supposed to be compiled to JS (without any logic validation)
177189

178190
Below we will discuss on how to write, build and run these test files.
179191

@@ -284,7 +296,7 @@ Whenever you are modifying any files in the ReScript compiler, or in the `jsoo_p
284296

285297
```sh
286298
node scripts/ninja.js config && node scripts/ninja.js build
287-
PLAYGROUND=../playground node scripts/repl.js
299+
node scripts/repl.js
288300
```
289301

290302
**.cmj files in the Web**
@@ -295,11 +307,23 @@ A `.cmi` file is an [OCaml originated file extension](https://waleedkhan.name/bl
295307

296308
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.
297309

298-
`.cmj` files are required for making ReScript compile modules (this includes modules like ReasonReact). 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?
310+
`.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?
311+
312+
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.
313+
314+
### Publishing the Playground Bundle on our KeyCDN
299315

300-
`repl.js` calls an executable called `cmjbrowser.exe` on every build, which is a compile artifact from `jscomp/main/jscmj_main.ml`. It is used to serialize `cmj` / `cmi` artifacts into two files called `jscomp/core/js_cmj_datasets.ml`. These files are only linked for the browser target, where ReScript doesn't have access to the filesystem. When working on BS, you'll see diffs on those files whenever there are changes on core modules, e.g. stdlib modules or when the ocaml version was changed. We usually check in these files to keep it in sync with the most recent compiler implementation. JSOO will pick up those files to encode them into the `compiler.js` bundle.
316+
> 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.
317+
318+
Our `compiler.js` and third-party packages bundles are hosted on [KeyCDN](https://www.keycdn.com) and uploaded via FTPS.
319+
320+
After a successful bundle build, run our upload script to publish the build artifacts to our server:
321+
322+
```
323+
playground/upload_bundle.sh
324+
```
301325

302-
For any other dependency needed in the playground, such as `ReasonReact`, you will be required to serialize your `.cmi` / `.cmt` files accordingly from binary to hex encoded strings so that BS Playground's `ocaml.load` function can load the data. Right now we don't provide any instructions inside here yet, but [here's how the official ReasonML playground did it](https://github.com/reasonml/reasonml.github.io/blob/source/website/setupSomeArtifacts.js#L65).
326+
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.
303327

304328
## Contribute to the API Reference
305329

playground/playground_test.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
require("./compiler.js")
2-
require("./@rescript/react/cmij.js")
2+
require("./packages/@rescript/react/cmij.js")
33

44
let compiler = rescript_compiler.make()
55

@@ -9,6 +9,8 @@ let result = compiler.rescript.compile(`
99

1010
if(result.js_code != "") {
1111
console.log('-- Playground test output --');
12+
console.log(`ReScript version: ${compiler.rescript.version}`);
13+
console.log('----');
1214
console.log(result.js_code);
1315
console.log('-- Playground test complete --');
1416
}

playground/upload_bundle.sh

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#/usr/bin/sh
2+
3+
# This script will publish the compiler.js bundle / packages cmij.js files to our KeyCDN server.
4+
# The target folder on KeyCDN will be the compiler.js' version number.
5+
# This script requires `curl` / `openssl` to be installed.
6+
7+
SCRIPT_DIR=$(cd "$(dirname "$0")"; pwd -P)
8+
9+
# Get the actual version from the compiled playground bundle
10+
VERSION=$(cd $SCRIPT_DIR; node -e 'require("./compiler.js"); console.log(rescript_compiler.make().rescript.version)')
11+
12+
if [ -z "${KEYCDN_USER}" ]; then
13+
echo "KEYCDN_USER environment variable not set. Make sure to set the environment accordingly."
14+
exit 1
15+
fi
16+
17+
if [ -z "${KEYCDN_PASSWORD}" ]; then
18+
echo "KEYCDN_PASSWORD environment variable not set. Make sure to set the environment accordingly."
19+
exit 1
20+
fi
21+
22+
KEYCDN_SRV="ftp.keycdn.com"
23+
NETRC_FILE="${SCRIPT_DIR}/.netrc"
24+
25+
# To make sure to not leak any secrets in the bash history, we create a NETRC_FILE
26+
# with the credentials provided via ENV variables.
27+
if [ ! -f "${NETRC_FILE}" ]; then
28+
echo "No .netrc file found. Creating file '${NETRC_FILE}'"
29+
echo "machine ${KEYCDN_SRV} login $KEYCDN_USER password $KEYCDN_PASSWORD" > "${NETRC_FILE}"
30+
fi
31+
32+
PACKAGES=( "@rescript/react")
33+
34+
echo "Uploading compiler.js file..."
35+
curl --ftp-create-dirs -T "${SCRIPT_DIR}/compiler.js" --ssl --netrc-file $NETRC_FILE ftp://${KEYCDN_SRV}/v${VERSION}/compiler.js
36+
37+
echo "---"
38+
echo "Uploading packages cmij files..."
39+
for dir in ${PACKAGES[@]};
40+
do
41+
SOURCE="${SCRIPT_DIR}/packages/${dir}"
42+
TARGET="ftp://${KEYCDN_SRV}/v${VERSION}/${dir}"
43+
44+
echo "Uploading '$SOURCE/cmij.js' to '$TARGET/cmij.js'..."
45+
46+
curl --ftp-create-dirs -T "${SOURCE}/cmij.js" --ssl --netrc-file $NETRC_FILE "${TARGET}/cmij.js"
47+
done
48+
49+
50+
51+

0 commit comments

Comments
 (0)