A demo of a multi-package PureScript project (monorepo) nixified using purs-nix.
Like haskell-multi-nix, this repository has two packages:
./foo: a PureScript library../bar: a PureScript executable, depends on./foo./qux: a PureScript library, depends on./fooandzalgo-jsfrom npm
A "PureScript package" is, alas, a mere copy of the .purs source files. To build the foo PureScript package:
❯ nix build .#fooTo build the bar package:
❯ nix build .#barNOTE: if you are on a Apple silicon processor (such as M1, M2, etc.), you will need to add --option system x86_64-darwin and run binaries through Rosetta 2’s x86 translator until native ARM-compatible binaries are built upstream (see: purs-nix/purs-nix#17).
Unlike PureScript packages, a JavaScript bundle is probably more useful inasmuch as compilation actually happens as part of the build. The PureScript package, above, will succeed in building even if there is a syntax error in the source tree.
To build the bar JS bundle:
❯ nix build .#bar-jsThis produces the compiled JavaScript at ./result.
Once the JS bundle (.#bar-js) of the application package bar is produced using nix build .#bar-js, we can run it directly using NodeJS:
❯ node ./result
Nix, Nix
Nix, Nix
Nix, NixAlternatively: nix run .#bar.
The qux package imports a foreign library from npm. Like the bar package, this application can be produced and ran with Nix.
❯ nix run .#qux
N̳ĩẋ,̦ ̲N͌i͖x̤
N̥i̒x̑,͗ ͈N̎i͔x͎
N̹i͐x̡,͉ ͬṆi͂x̖The dev shell is a work-in-progress.
This repo implements purs-nix/purs-nix#36 but outside of purs-nix (see multi.nix). It also acts as a stepping stone towards actually implementing the aforementioned proposal in purs-nix itself.
- It creates a wrapper bash script to implement the above. Run
purs-nixin devshell, and it will do the right thing depending on your $PWD.- For example,
purs-nix ./foo runwill try to run the foo package. This will, of course fail because there is noMainentry point in the foo package (unless, of course, your "output" directory already compiles compiled assets for ./bar). Trypurs-nix ./bar runinstead, and it will do whatnix rundoes.
- For example,
- A ghost top-level ps command is also created for running
purs-nix . compilefrom project root. This will compile all packages. It may not make sense for non-compile commands, though.
- Non-relevant "output" directory assets can be used. E.g., running
purs-nix ./foo runwill actually succeed by running bar's entrypoint if bar had already been compiled.- When purs-nix implements this properly, its "run" and "test" commands should probably ensure separation somehow.
Run purs-nix ./qux compile to compile your sources, producing an ./output directory. This directory, in turn, will be used by the PureScript language server. This is tested to work with VSCode.
To automatically load and unload the Nix shell environment, when entering the project, an .envrc can be used to invoke the Nix shell (as well as other things you may want in your development environement; see direnv’s docs). A minimal example is provided:
❯ cp .envrc.example .envrc
❯ $EDITOR .envrc
❯ direnv allow