Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Npm on Nix.
- This is an example of how to install and debug an npm package on nix.
- We'll install `serve` from `npm`. This package was chosen because it currently
- breaks, so we'll have figure out how to debug and correct it.
- In general, JS ecosystem leaves more to be desired when it comes to deterministic
- builds. `npm` moves in the direction of handling packages in a more and more
- imperative way, which makes it harder to achieve reliable and reproduciable packaging.
- [Even Facebook wrote about it](https://code.facebook.com/posts/1840075619545360).
- There are still [discussions](http://lists.science.uu.nl/pipermail/nix-dev/2016-June/020837.html) about how to approach JS packages in Nix. Tools to handle JS packages are
- being actively developed and reengineered (e.g., `npm2nix` is being replaced by
- `node2nix`). This is one of the reasons why you won't find most JS libraries
- in Nixpkgs.
- However, you can easily install them yourself and not wait until the moment
- they might land in Nixpkgs.
- ## Packaging `serve` for Nix
- First, we want to specify packages that we want available in our environment.
- We'll put them in `node-packages.json`. It will be later parsed by `node2nix`
- that is going to generate a nix expression containing those packages. It
- will not install ALL those packages at the same time; instead, you'll be able
- to choose which ones you want to be installed.
- ```
- >>> cat node-packages.json
- [
- "serve"
- ]
- ```
- Then, we need to generate the nix expression for those packages:
- `node2nix -i node-packages.json`
- This will generate a bunch of `.nix` files. Specific information about each package
- and its dependencies will be stored in `node-packages.nix`. But, as always, by convention
- `default.nix` is the "entry point" file that we'll pass to `nix-env`:
- `nix-env -f default.nix -iA serve`
- The package was installed successfully, but it will break at runtime when we try to run it:
- ```
- /nix/store/clq0pzzjvp9blr2vknj1jy8hk4nn940c-node-serve-2.0.0/lib/node_modules/serve/dist/bin/serve:163
- const directoryPath = [...pathParts];
- ^^^
- SyntaxError: Unexpected token ...
- ```
- Okay, this looks like it tries to use the spread syntax that was introduced in ES6. So, it probably uses an old version of NodeJS.
- On [`node2nix`'s Github page](https://github.com/svanderburg/node2nix/blob/14819200b2de849850ccb98c5b03bf48634421b4/README.md#generating-packages-for-nodejs-5x) we can find that passing `-5` arg will make it use NodeJS 5:
- ```
- >>> node2nix -5 -i node-packages.json
- >>> nix-env -f default.nix -iA serve
- installing ‘node-serve-2.0.0’
- error: attribute ‘nodejs-5_x’ missing, at /home/cyr/packages/serve/default.nix:5:48
- ```
- Hm, it can't find NodeJS 5. We can look inside `default.nix` and check where it looks for it. On line 5
- we can see that it tries to find it in `pkgs."nodejs-5_x" `
- ```
- }, system ? builtins.currentSystem, nodejs ? pkgs."nodejs-5_x"}:
- ```
- Let's jump into `nix-repl` and figure out what's going on:
- ```
- >>> nix-repl "<nixpkgs>"
- Welcome to Nix version 1.11.4. Type :? for help.
- Loading ‘<nixpkgs>’...
- Added 6642 variables.
- nix-repl> pkgs.nodejs<TAB>
- pkgs.nodejs pkgs.nodejs-4_x pkgs.nodejs-6_x
- nix-repl> pkgs.nodejs.version
- "4.6.0"
- ```
- Tab completion tells us that there is only Node.js 4 and 6.
- There is also `nodejs`, but checking its version tells us that
- it points to `nodejs-4_x`.
- We can either add Node.js 5 or try the 6th one, which already
- exists in nixpkgs. The latter approach will be simpler,
- so this is what we are going to do by opening `default.nix`
- and changing `nodejs-5_x` to `nodejs-6_x`. This gives us the
- following:
- ```
- >>> cat default.nix | head -5
- # This file has been generated by node2nix 1.1.0. Do not edit!
- {pkgs ? import <nixpkgs> {
- inherit system;
- }, system ? builtins.currentSystem, nodejs ? pkgs."nodejs-6_x"}:
- ```
- Let's try to install it again:
- ```
- >>> nix-env -f default.nix -iA serve
- ```
- This time it installs successfully. Let's try running it:
- ```
- >>> serve ⏎
- Running on http://localhost:3000
- ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement