11# ReasonProject
22
3- Reason project environment via ` npm ` .
3+ Installation of [ ` Reason ` ] ( http://facebook.github.io/reason/ ) project and
4+ development environments via ` npm ` .
45
5- - Local sandboxed ` Reason ` projects.
6- - Installation of ` Reason ` tools globally.
6+ > Requirements: ` npm ` (currently tested on Mac, Linux, and Windows Linux subsystem).
77
8- Those two features may sound completely different, but the truth is that they
9- are very similar, and therefore it makes sense to have ` ReasonProject ` handle
10- both.
8+ ` ReasonProject ` installs the ` Reason ` toolchain into a local directory using
9+ ` npm ` . ` ReasonProject ` can therefore be used as a template for new projects,
10+ but can also be used to install the toolchain [ into the global
11+ environment] ( #reasonproject-editor-support ) . ` ReasonProject ` includes: the
12+ compiler toolchain, the source formatter, REPL, and IDE support for popular
13+ editors.
1114
1215> A sandboxed environment models dependencies and builds them into a local
1316> directory so that it works reliably for anyone. Installing tools into your
1922
2023[ ![ Build Status] ( https://travis-ci.org/reasonml/ReasonProject.svg?branch=master )] ( https://travis-ci.org/reasonml/ReasonProject )
2124
22- ## Get Started:
25+ ## Install
2326
2427Install by cloning the repo and running ` npm install ` . This installs all
2528dependencies locally into the ` ReasonProject ` directory.
@@ -30,53 +33,70 @@ cd ReasonProject
3033npm install
3134```
3235
36+ ## Project Commands
37+
38+ Once built, ` ReasonProject ` generates an * environment* that you can temporarily
39+ load when executing commands. The environment contains an enhanced ` PATH `
40+ containing binaries built by your dependencies, but this environment isn't
41+ loaded into your global path. Some ` npm run ` commands have been setup to allow
42+ you to run some basic tasks, as well as any custom command, all within the
43+ project environment.
44+
45+
46+
3347### Run, Change, Rebuild
3448
3549There are a couple of built in commands declared in ` package.json ` that you can
3650execute via ` npm run ` . For example: ` "npm run start" ` , ` "npm run reasonBuild" `
3751and ` "npm run clean" ` . You can also [ add your
38- own] ( #reasonproject-get-started-add-your-own-scripts ) commands.
52+ own] ( #reasonproject-developing-your-project-add-your-own-scripts ) named scripts
53+ which give you a nicer alias like ` npm run myScriptName ` .
3954
4055
4156``` sh
42- npm run start # Runs the compiled app
4357npm run reasonBuild # Rebuilds after changing
58+ npm run start # Runs the compiled app
4459npm run clean # Clean if you need to!
4560```
4661
62+ A single test file ` ./src/Test.re ` is included. Make a simple change to it and
63+ then run the commands above to see it effect the output.
64+
4765
4866### REPL
4967
50- The ` rtop ` REPL is built into the sandbox, and the command ` npm run top ` which
51- starts the REPL is predefined in ` package.json ` .
68+ The ` rtop ` REPL is built into the sandbox. The command ` npm run top ` starts the
69+ REPL.
5270
5371``` sh
5472# Opens `rtop` from the sandbox.
5573npm run top
5674```
5775
58- ### Environment Commands
5976
60- Once built, ` ReasonProject ` generates an environment that you can temporarily
61- load to execute commands within. The environment contains an enhanced ` PATH `
62- that contains binaries built by your dependencies, but this environment isn't
63- loaded automatically. To temporarily load this environment, execute the
64- predefined ` npm run env -- ` command. You should pass the * actual* command you
65- want to run after ` -- ` .
77+ ### Custom Commands
78+
79+ To do anything beyond those basic, preconfigured commands, you just prefix your
80+ command with ` npm run env -- ` . You should pass the * actual* command you want to
81+ run after ` -- ` .
6682
6783``` sh
84+ # By default nothing is found!
85+ which refmt
6886
69- npm run env -- which refmt
87+ > Not Found !
7088
71- > ReasonProject/node_modules/reason/_build/ocamlfind/bin/refmt
89+ # Prefix with "npm run env --" and it finds it!
90+ npm run env -- which refmt
7291
92+ > ~ /ReasonProject/node_modules/reason/_build/ocamlfind/bin/refmt
7393```
7494
75- The previous command would likely fail if not prefixed with ` npm run env -- `
76- because the dependencies are the ones that built ` refmt ` in this case. `npm
77- run env` makes all the things from our dependencies available .
95+ If this becomes tedious, you can [ add your
96+ own ] ( #reasonproject-developing-your-project-add-your-own-scripts ) named scripts
97+ so that you can do ` npm run yourScriptName ` instead .
7898
79- ### Editor Support
99+ ## Editor Support
80100
81101#### Prepare Your Editor
82102
@@ -115,16 +135,16 @@ ensures that your editor will find the editor support in your environment
115135variables.
116136
117137> Note: If you use ` atom ` , and already have ` opam ` installed, then there's a
118- known issue where ` atom ` has problems loading, but you can fix it easily
119- by commenting out any part in your ` bashrc ` that sources opam environments.
120- We will come up with a long term solution at some point.
138+ > known issue where ` atom ` has problems loading, but you can fix it easily by
139+ > commenting out any part in your ` bashrc ` that sources opam environments. We
140+ > will come up with a long term solution at some point.
121141
122- ##### Just Using Global Paths
142+ ##### Using Global Paths
123143
124144Pure sandboxed based development doesn't always work for certain workflows.
125- Prefixing * all* commands with ` npm run env ` may not work well. In that case,
126- you can easily inject your successfully built project's environment into the
127- global ` PATH ` , by putting the following in your ` .bashrc ` :
145+ (prefixing * all* commands with ` npm run ` may not work well) . In that case, you
146+ can easily inject your successfully built project's environment into the global
147+ ` PATH ` , by putting the following in your ` .bashrc ` :
128148
129149``` sh
130150# In your .bashrc
@@ -134,15 +154,9 @@ pushd ~/pathTo/ReasonProject/ && \
134154```
135155
136156
137- ### Multiple Projects
138-
139- You can have multiple clones/forks/builds of ` ReasonProject ` for each of your
140- projects. When you make changes, you can share the project easily with anyone
141- else. It's common to have multiple ` ReasonProject ` s simultaneously. If also
142- using global environment variables, it's wise to also have one special
143- ` ReasonProject ` , that is only used for augmenting the global path.
157+ ## Developing Your Project
144158
145- ### Making It Your Project
159+ ### Making It Yours
146160` ReasonProject ` is meant to be the starting point of your own project. You'll want
147161to make use of existing libraries in your app, so
148162browse the growing set of ` opam ` packages ported to ` npm ` under
@@ -162,62 +176,94 @@ npm install --save @opam-alpha/cstruct
162176
163177** Option ` 2 ` :** Edit the ` package.json ` manually to include your new dependency and run ` npm install ` .
164178
165- > Note: Sometimes options ` 1 ` and ` 2 ` above fail because some * other* dependency that is
166- rebuilt as a result of the ` install ` was not designed to build in an idempotent manner.
167- In that case, just add the new dependency to your ` package.json ` ` "dependencies" ` ,
168- ` rm -r node_modules ` , and then run ` npm install ` . This installs from a clean slate.
179+ > Note: Sometimes options ` 1 ` and ` 2 ` above fail because some * other*
180+ > dependency that is rebuilt as a result of the ` install ` was not designed to
181+ > build in an idempotent manner. In that case, just add the new dependency to
182+ > your ` package.json ` ` "dependencies" ` , ` rm -r node_modules ` , and then run `npm
183+ > install`. This installs from a clean slate.
169184
170185
171186> Note: ` opam-alpha ` is "alpha" - we may move to a new namespace ` opam-beta `
172- once we apply the lessons we've learned from ` opam-alpha ` . All the should exist
173- as they are, but a next generation ` opam-beta ` universe on ` npm ` would have
174- everything ` opam-alpha ` has (and then some). The work to upgrade your projects
175- will likely be minimal.
187+ > once we apply the lessons we've learned from ` opam-alpha ` . All the should
188+ > exist as they are, but a next generation ` opam-beta ` universe on ` npm ` would
189+ > have everything ` opam-alpha ` has (and then some). The work to upgrade your
190+ > projects will likely be minimal.
176191
177192
193+ This merely adds and builds the dependency. It doesn't mean your build system
194+ will know to link to it. Accomplishing that is build system dependent, but if
195+ using the example build system (` rebuild ` , which is based on ` ocamlbuild ` ), you
196+ can get an idea for the options by doing ` npm run buildHelp ` . Typically you
197+ need to configure the ` reasonBuild ` entry in ` package.json ` to add the `-pkg
198+ dependencyPackage`. Consult your dependency's docs.
199+
178200### Add Your Own Scripts
179- - ` npm ` allows ` scripts ` to be specified in your project's ` package.json ` .
180- These ` scripts ` are a named set of commands.
181- - A few scripts have special meaning, such as the ` postinstall ` script. The
182- ` postinstall ` script is how your project compiles itself. It is guaranteed
183- that the ` postinstall ` script executes any time you run ` npm install ` in this
184- package, or any time another package installs you as a dependency. You're
185- also guaranteed that your ` postinstall ` script is executed * after* all of
186- your dependencies' ` postinstall ` scripts.
187- - You can add new named scripts in the ` package.json ` ` scripts ` field. Once
188- added, you can then run them via ` npm run scriptName ` from within the project
189- root.
190- - ` eval $(dependencyEnv) ` is commonly used in these ` scripts ` . The ` eval `
191- manages the environment, and ensures that important
192- binaries (such as ` refmt ` ) are in the ` PATH ` . ` dependencyEnv ` ensures that
193- the environment is augmented only for the duration of that ` script ` running,
194- and only in ways that you or your immediate dependencies decide. When
195- the entire purpose of developer tools is to generate a binary (such as a
196- compiler) to be included in your ` PATH ` , or produce a library whose path
197- should be specified in an special environment variable, it's almost like the
198- environment variable is the public API of that package. ` dependencyEnv `
199- allows your script to see the environment variables that your immediate
200- dependencies wanted to publish as their public API. You can learn how
201- packages can publish environment variables in the [ dependency-env
202- repo] ( https://github.com/npm-ml/dependency-env ) .
203-
204-
205- ### Creating Reusable Libraries
206-
207- - To turn this example project into a library that other people can depend on
208- via ` npm ` ... (coming soon).
209-
210-
211- ### Debugging Failed Dependencies
212-
213- When ` npm install ` fails to install one of your dependencies successfully, it's
214- typically because a ` postinstall ` step of a package has failed. Read
215- the logs to determine which one is failing. ` npm ` will delete the directory
216- of the failed package so it won't be in ` node_modules ` , but it's in the cache, so you
217- can usually install it explicitly, and debug the installation. Suppose the
201+
202+ ` npm ` allows ` scripts ` to be specified in your project's ` package.json ` . These
203+ ` scripts ` are a named set of commands. A few scripts have special meaning, such
204+ as the ` postinstall ` script.
205+
206+ > The ` postinstall ` script is how your project compiles itself. It is
207+ > guaranteed that the ` postinstall ` script executes any time you run `npm
208+ > install` in this package, or any time another package installs you as a
209+ > dependency. You're also guaranteed that your ` postinstall ` script is executed
210+ > * after* all of your dependencies' ` postinstall ` scripts.
211+
212+ You can add new named scripts in the ` package.json ` ` scripts ` field. Once
213+ added, you can then run them via ` npm run scriptName ` from within the project
214+ root.
215+
216+ ###### Making Sure Your Scripts See The Environment
217+
218+ ` eval $(dependencyEnv) ` is commonly used in these ` scripts ` . This ` eval `
219+ statement augments the environment for the duration of the named script, which
220+ ensures that important binaries (such as ` refmt ` ) are in the ` PATH ` .
221+
222+ > When the entire purpose of developer tools is to generate a binary (such as a
223+ > compiler) to be included in your ` PATH ` , or produce a library whose path
224+ > should be specified in an special environment variable, it's almost like the
225+ > environment variable is the public API of that package. ` dependencyEnv `
226+ > allows your script to see the environment variables that your immediate
227+ > dependencies wanted to publish as their public API. You can learn how
228+ > packages can publish environment variables in the [ dependency-env
229+ > repo] ( https://github.com/npm-ml/dependency-env ) .
230+
231+ ### Multiple Projects
232+
233+ You can have multiple clones/forks/builds of ` ReasonProject ` - one for each of
234+ your projects. When you make changes, you can share the project easily with
235+ anyone else because you are modelling all dependencies via ` package.json ` . If
236+ also [ using the global
237+ environment] ( #reasonproject-editor-support ) , you may want to
238+ designate one special ` ReasonProject ` , that is only used for augmenting the
239+ global path.
240+
241+
242+ ### Creating Libraries
243+
244+ ` ReasonProject ` sets up your environment for building an application. We
245+ haven't yet mentioned how to then share your work with other people * as* an
246+ ` npm ` dependency itself. More coming soon.
247+
248+
249+ ## Troubleshooting
250+
251+ In general, if something goes wrong, try deleting the local ` node_modules `
252+ directory that was installed, and then try reinstalling using ` npm install -f `
253+ (to avoid using a stale cache). Then if that doesn't work, follow the following
254+ steps to debug your specific failed dependency.
255+
256+ #### Debugging Failed Dependencies
257+
258+ When ` npm install ` fails to install one of your dependencies, it's typically
259+ because a ` postinstall ` step of a package has failed. Read the logs to
260+ determine which one is failing. ` npm ` will delete the directory of the failed
261+ package so the failed install won't be in ` node_modules ` , but you can
262+ usually try to reinstall it explicitly, and debug the installation. Suppose the
218263` @opam-alpha/qcheck ` package failed to install. Let's recreate the failure so
219264we can debug it.
220265
266+ #####Do a dry run:
221267Let's see what an ` npm install ` for this package * would* install. The ` --dry-run `
222268flag avoids actually installing anything.
223269
@@ -229,15 +275,16 @@ In my project, it says it would only need to install the following packages.
229275That's because all of the other ones must have already been installed in
230276` node_modules ` .
231277
232- Output:
233278``` sh
279+ # Output
234280test@1.0.0 /Users/jwalke/Desktop/tmp
235281└─┬ @opam-alpha/qcheck@0.4.0
236- └── qcheck-actual@0.4.0 (git://github.com/npm-opam/qcheck.git
282+ └── qcheck-actual@0.4.0 (git://github.com/npm-opam/qcheck.git)
237283```
238- ( Note: Sometimes it won' t traverse `git` dependencies to find all the potentially installed
239- package. That' s okay) .
284+ > Note: Sometimes it won't traverse ` git ` dependencies to find all the potentially installed
285+ package. That's okay.
240286
287+ ###### Install Source Without Building
241288So we want to install that now, but * without* executing the install scripts so we
242289pass the ` --ignore-scripts ` flag. Without that flag, it would fail when running
243290the scripts again, and then remove the package again!
@@ -248,13 +295,7 @@ npm install --ignore-scripts @opam-alpha/qcheck@0.4.0
248295
249296This will just install the source code, and let us know what it actually installed.
250297
251- Ouput:
252- ` ` `
253- test@1.0.0 /Users/jwalke/Desktop/tmp
254- └─┬ @opam-alpha/qcheck@0.4.0
255- └── qcheck-actual@0.4.0 (git://github.com/npm-opam/qcheck.git
256- ` ` `
257-
298+ ###### Try The Build Manually, In Place
258299Now, make sure ` npm ` didn't do something weird with installing new versions of package
259300that didn't show up in the dry run, and make sure it installed things
260301as flat as possible in ` node_modules ` , as opposed to nesting ` node_modules `
@@ -280,20 +321,6 @@ from the top again. This just makes sure you've got everything
280321nice and clean as if you installed it for the first time.
281322
282323
283- # # Troubleshooting:
284- - Check to make sure everything is installed correctly. There' s a `script`
285- already setup that will help you test the location of where `Reason` has been
286- compiled into.
287-
288- - If something goes wrong, try deleting the local `node_modules` directory that
289- was installed, and then try reinstalling using `npm install -f`.
290-
291324```
292325npm run whereisocamlmerlin
293326```
294-
295- ## TODO:
296-
297- - This also installs sandboxed IDE support for Vim/Atom/Emacs. We need to
298- upgrade all of the plugins to automatically search for IDE plugins inside of
299- the `./node_modules` directory.
0 commit comments