Advertisement
Guest User

Untitled

a guest
Aug 29th, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.17 KB | None | 0 0
  1. # Npm on Nix.
  2.  
  3. This is an example of how to install and debug an npm package on nix.
  4. We'll install `serve` from `npm`. This package was chosen because it currently
  5. breaks, so we'll have figure out how to debug and correct it.
  6.  
  7. In general, JS ecosystem leaves more to be desired when it comes to deterministic
  8. builds. `npm` moves in the direction of handling packages in a more and more
  9. imperative way, which makes it harder to achieve reliable and reproduciable packaging.
  10. [Even Facebook wrote about it](https://code.facebook.com/posts/1840075619545360).
  11.  
  12. 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
  13. being actively developed and reengineered (e.g., `npm2nix` is being replaced by
  14. `node2nix`). This is one of the reasons why you won't find most JS libraries
  15. in Nixpkgs.
  16.  
  17. However, you can easily install them yourself and not wait until the moment
  18. they might land in Nixpkgs.
  19.  
  20.  
  21. ## Packaging `serve` for Nix
  22.  
  23. First, we want to specify packages that we want available in our environment.
  24. We'll put them in `node-packages.json`. It will be later parsed by `node2nix`
  25. that is going to generate a nix expression containing those packages. It
  26. will not install ALL those packages at the same time; instead, you'll be able
  27. to choose which ones you want to be installed.
  28.  
  29. ```
  30. >>> cat node-packages.json
  31. [
  32. "serve"
  33. ]
  34. ```
  35.  
  36. Then, we need to generate the nix expression for those packages:
  37.  
  38. `node2nix -i node-packages.json`
  39.  
  40. This will generate a bunch of `.nix` files. Specific information about each package
  41. and its dependencies will be stored in `node-packages.nix`. But, as always, by convention
  42. `default.nix` is the "entry point" file that we'll pass to `nix-env`:
  43.  
  44. `nix-env -f default.nix -iA serve`
  45.  
  46. The package was installed successfully, but it will break at runtime when we try to run it:
  47.  
  48. ```
  49. /nix/store/clq0pzzjvp9blr2vknj1jy8hk4nn940c-node-serve-2.0.0/lib/node_modules/serve/dist/bin/serve:163
  50. const directoryPath = [...pathParts];
  51. ^^^
  52.  
  53. SyntaxError: Unexpected token ...
  54. ```
  55.  
  56. 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.
  57.  
  58. 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:
  59.  
  60. ```
  61. >>> node2nix -5 -i node-packages.json
  62. >>> nix-env -f default.nix -iA serve
  63. installing ‘node-serve-2.0.0’
  64. error: attribute ‘nodejs-5_x’ missing, at /home/cyr/packages/serve/default.nix:5:48
  65. ```
  66.  
  67. Hm, it can't find NodeJS 5. We can look inside `default.nix` and check where it looks for it. On line 5
  68. we can see that it tries to find it in `pkgs."nodejs-5_x" `
  69.  
  70. ```
  71. }, system ? builtins.currentSystem, nodejs ? pkgs."nodejs-5_x"}:
  72. ```
  73.  
  74. Let's jump into `nix-repl` and figure out what's going on:
  75.  
  76. ```
  77. >>> nix-repl "<nixpkgs>"
  78. Welcome to Nix version 1.11.4. Type :? for help.
  79.  
  80. Loading ‘<nixpkgs>’...
  81. Added 6642 variables.
  82.  
  83. nix-repl> pkgs.nodejs<TAB>
  84. pkgs.nodejs pkgs.nodejs-4_x pkgs.nodejs-6_x
  85. nix-repl> pkgs.nodejs.version
  86. "4.6.0"
  87. ```
  88.  
  89. Tab completion tells us that there is only Node.js 4 and 6.
  90. There is also `nodejs`, but checking its version tells us that
  91. it points to `nodejs-4_x`.
  92.  
  93. We can either add Node.js 5 or try the 6th one, which already
  94. exists in nixpkgs. The latter approach will be simpler,
  95. so this is what we are going to do by opening `default.nix`
  96. and changing `nodejs-5_x` to `nodejs-6_x`. This gives us the
  97. following:
  98.  
  99. ```
  100. >>> cat default.nix | head -5
  101. # This file has been generated by node2nix 1.1.0. Do not edit!
  102.  
  103. {pkgs ? import <nixpkgs> {
  104. inherit system;
  105. }, system ? builtins.currentSystem, nodejs ? pkgs."nodejs-6_x"}:
  106. ```
  107.  
  108. Let's try to install it again:
  109.  
  110. ```
  111. >>> nix-env -f default.nix -iA serve
  112. ```
  113.  
  114. This time it installs successfully. Let's try running it:
  115.  
  116. ```
  117. >>> serve ⏎
  118. Running on http://localhost:3000
  119.  
  120. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement