dhall-haskell
dhall-haskell copied to clipboard
Publish GHC.js output to npm?
Trying out dhall using toolchains web developers are already familiar with, could make dhall even more approachable to other communities/audiences.
E.g. npx dhall <command>
would install the package, run the command and then uninstall the package. Most JS devs have npx on their machine (even if they don't realise it) and https://www.npmjs.com/package/dhall is not taken (at the time of writing).
I'm not sure if this is inadvisable for other reasons, (e.g. maybe the JS build is limited in some way).
In that case, maybe it makes sense to publish the binaries to the npm registry instead - to get the exact same affect without involving ghc.js.
@JAForbes: I don't have any objections to doing this; I just need help with the NPM-specific parts because I have never used NPM before.
We should probably reserve the name dhall
for a native JavaScript implementation, but we could call the package derived from the Haskell implementation dhall-haskell
or something similar.
For reference, here is what the directory tree looks like for the output of the GHCJS build (slightly truncated for clarity):
$ tree result
result
├── bin
│ ├── dhall
│ └── dhall.jsexe
│ ├── all.js
│ ├── all.js.externs
│ ├── index.html
│ ├── lib.js
│ ├── manifest.webapp
│ ├── out.frefs.js
│ ├── out.frefs.json
│ ├── out.js
│ ├── out.stats
│ ├── rts.js
│ └── runmain.js
├── lib
│ ├── ghcjs-8.4.0.1
│ │ ├── dhall-1.32.0
│ │ │ ├── Dhall
│ │ │ │ ├── Binary.js_dyn_hi
│ │ │ │ ├── Binary.js_hi
│ │ │ │ ├── …
│ │ │ │ ├── Version.js_hi
│ │ │ │ └── Version.js_p_hi
│ │ │ ├── Dhall.js_dyn_hi
│ │ │ ├── Dhall.js_hi
│ │ │ ├── Dhall.js_p_hi
│ │ │ ├── Paths_dhall.js_dyn_hi
│ │ │ ├── Paths_dhall.js_hi
│ │ │ ├── Paths_dhall.js_p_hi
│ │ │ ├── libHSdhall-1.32.0-CshM77PedRE5DNyCkSSjoI.js_a
│ │ │ └── libHSdhall-1.32.0-CshM77PedRE5DNyCkSSjoI_p.js_a
│ │ ├── package.conf.d
│ │ │ └── dhall-1.32.0-CshM77PedRE5DNyCkSSjoI.conf
│ │ └── x86_64-linux-ghcjs-8.4.0.1-ghc8_4_2_20180420
│ │ └── libHSdhall-1.32.0-CshM77PedRE5DNyCkSSjoI-ghcjs8.4.0.1.js_so
│ └── links
└── nix-support
└── propagated-build-inputs
If all we need is JavaScript code that can be executed by NPM, that is essentially what the ./bin/dhall
and ./bin/dhall.jsexe
provide.
For example, the ./bin/dhall
script is a runnable node
script:
$ cat ./result/bin/dhall
#!/nix/store/p0r56cns3ibjlwkh052mpczsrrs25wlh-nodejs-slim-6.14.3/bin/node
var h$currentThread = null;
var h$stack = null;
var h$sp = 0;
var h$initStatic = [];
var h$staticThunks = {};
var h$staticThunksArr = [];
var h$regs = [];
var h$r1 = 0;
var h$r2 = 0;
…
$ ./result/bin/dhall <<< '2 + 2'
4
... and the build also includes the same code without the initial shebang line in ./result/bin/dhall.jsexe/all.js
:
$ cat ./result/bin/dhall.jsexe/all.js
var h$currentThread = null;
var h$stack = null;
var h$sp = 0;
var h$initStatic = [];
var h$staticThunks = {};
var h$staticThunksArr = [];
var h$regs = [];
var h$r1 = 0;
var h$r2 = 0;
var h$r3 = 0;
…
... in case you want to insert your own custom shebang line (e.g. without the dependency on Nix).
I also put up a pull request to make it easier for others who have Nix installed to inspect the GHCJS build product for themselves:
https://github.com/dhall-lang/dhall-haskell/pull/1861
If you would like to know more about the various files in that directory tree I can do my best to answer, although I'm still a bit of a GHCJS novice myself.
Ok great! Yeah that looks to be all we need 👍
In order to be compatible with npx/npm we just need to generate a package.json with a few entries
{ "name": "dhall-haskell"
, "version": "<dhall-version>"
, "bin": "./result/bin/dhall.jsexe/all.js"
, "files": "./result/bin/dhall.jsexe/all.js"
}
We'd probably want to add licence
, repository
, author
, homepage
to the JSON as well, and possible keywords
as well.
I'm not sure how dhall's CI is configured but I imagine this is the basic process:
- Set up CI to be authenticated to publish npm packages docs
- Obtain the version number for the release somehow (a variable, a server call?)
- Generate the package.json with the included version number
- Run
npm publish
@JAForbes: Is there a way to do a test publication to verify that the package is runnable via npx
? I can always release a test 0.1 version if necessary, but I wasn't sure if there was a more idiomatic solution
npx
will check your $PATH first. So you can do something like
-
npm pack
from the directory containing your package.json to create a tarball of your package - make a directory to test it out,
/tmp/foo
or what have you - cd in there and run
npm install /absolute/path/to/tarball/from-step-1
- this should install the package you created in step 1 in
/tmp/foo/node_modules
- it should also create
/tmp/foo/node_modules/.bin
, where your executable specified by thebin
field in your package.json should be - add
/tmp/foo/node_modules/.bin
to your PATH -
npx name-of-your-command
Note you can name your command by giving an object to bin
in package.json, eg bin: { "dhall-haskell": "./result/bin/dhall.jsexe/all.js" }
. I don't use npx
much myself, I'm not sure how much magic it does or how much running a locally pack
ed package will do to verify it would work with npx. I would guess just running the first 3 steps and then trying to execute your installed "binary" would be enough?
You can also publish a prerelease with a tag:
npm version 0.0.0-alpha-1
npm publish --tag alpha
This will prevent this release from being installed without specifically opting into that tag or release.
Then you can run npx dhall-haskell@alpha
or npx [email protected]
to test.
You can also unpublish within 72 hours of publishing, even if it isn't an alpha. This is generally seen as bad practice, but I think in this case a valid option as no-one should be depending on this package yet.