24

In NixOS, I installed the package yarn as usual by running $ nix-env -i yarn. Now I am attempting to run yarn via $ yarn start. But this leads me to the following error.

$ yarn start
    yarn start v0.20.3
    $ webpack-dev-server --env dev 
    sh: webpack-dev-server: command not found
    error Command failed with exit code 127.

When I try to install webpack-dev-server in my usual NixOS way I get a 'matches no derivations' error.

$ nix-env -i webpack-dev-server
error: selector ‘webpack-dev-server’ matches no derivations

I read that webpack-dev-server is an npm package, and am unsure of a couple questions regarding the relevance of that in this case.

  1. Does it make sense to use npm, a different package manager than nix, under Nix?
  2. If answer to (1) is yes, then how to install npm on NixOS? I do not see npm available when searching via nix-env, as $ nix-env -qa npm also matches no derivations.

What is the correct way to install webpack-dev-server on NixOS?


EDIT

I attempted to install webpack-dev-server following the commented link and was able to install node2nix, but am not able to follow through on step 2 listed in the readme there.

I located the file referenced in step 2 in /nix/store at

/nix/store/sgk7sxgqxrv2axkxjwc3y15apcqbrv1z-nixos-17.03.1482.1b57bf274a/nixos/pkgs/development/node-packages/node-packages.json

I can open that file to view the npm packages listed, but the permissions are read-only, even running with sudo -- so I would need to edit it's permissions in order to alter it.

It seems that I should not be editing this /nix/store file directly and should instead be manipulating it indirectly via nix. Am I correct that I should not be editing this file directly? If so, how else can I complete step 2 by using nix or something to add webpack-dev-server to it?

mherzl
  • 1,409
  • 2
  • 18
  • 31
  • 1
    https://github.com/NixOS/nixpkgs/tree/master/pkgs/development/node-packages – Emmanuel Rosa Jul 20 '17 at 23:37
  • @EmmanuelRosa thank you for the link; I attempted to follow the instructions there and updated this question according to the results of that attempt. – mherzl Jul 21 '17 at 03:33
  • `/nix/store` is read-only. You need to clone git repo and use `-I nixpkgs=/path/to/repo` for `nix-*` command – wizzup Jul 21 '17 at 04:21
  • [This](https://stackoverflow.com/a/59606924/4009538) was the most elegant solution in my case (courtesy of @trusktr). – Adam Lee Jul 27 '21 at 18:01

3 Answers3

22

There are multiple ways to use npm packages through nix:

For my personal projects, I use nix-shell then within the shell I use npm scripts to prevent the need for npm global packages (like with gulp). The process looks something like this (and is probably very similar for yarn):

$ nix-shell -p nodejs-8_x
[nix-shell:yourproject]$ npm install # installs npm deps to project-local node_modules
[nix-shell:yourproject]$ npm exec (...) # using scripts configured in package.json

This works well for me since none of my packages have binary dependencies. This post describes the creation of a default.nix for your project so you won't have to specify dependencies for every invocation of nix-shell, but it's optional.

Another way is using npm2nix:

node2nix -i node-packages.json # creates ./default.nix
nix-shell # nix-shell will look for a default.nix, which above will have generated

Which will cause Nix to manage all npm packages in the project.

It may be a good idea to become familiar with nix-shell, since trying to install node packages / any dependency in your nix profile (through nix-env or nox) defeats the purpose of nix by polluting the "global" namespace.

Rui F Ribeiro
  • 55,929
  • 26
  • 146
  • 227
Luke Adams
  • 336
  • 1
  • 3
  • Could you expand on this with regards to packages using binding.gyp for example: https://github.com/mateogianolio/nblas – CMCDragonkai Dec 15 '17 at 07:36
  • 1
    I found out how to do it for binary packages. You need the `nodePackages_6_x.node-gyp`, and any other libraries like `blas`, then when it's all together, you can use `npm install ....` packages that use node-gyp. – CMCDragonkai Dec 15 '17 at 07:52
  • 1
    Regarding the first method, as an alternative to the `npm scripts` solution, I find adding global npm packages to the `nix-shell` effective, e.g. `nix-shell -p nodejs-8_x nodePackages.grunt-cli`. (Warning: nixos and node noob here.) – Ryne Everett Jan 28 '18 at 18:29
  • The one thing I don't understand about the first method is how to actually install the package itself, i.e. where does the binary for the project's package.json `bin` end up? – Ryne Everett Jan 28 '18 at 20:00
  • @ryne-everett If you run `npm install`, executables would be linked into `node_modules/.bin`. See [here](https://docs.npmjs.com/files/folders#more-information). – Luke Adams Feb 03 '18 at 19:21
  • how does one install "npm i node-fetch --save" in nix after this? all I need is fetch to be available. – uber Feb 16 '21 at 16:50
16

For some reason, nodePackages is not in root namespace and can't be found by using nix-env -qa

use nix-env -qaPA nixos.nodePackages to list for available packages.

$ nix-env -qaPA nixos.nodePackages | grep -i web
nixos.nodePackages.webdrvr                     node-webdrvr-2.43.0-1
nixos.nodePackages.webpack                     node-webpack-2.6.1

If the package you want is not there, and you don't know how to write Nix packages, make a packaging request on NixOS github.

wizzup
  • 585
  • 1
  • 5
  • 12
  • 1
    I am using just nix package manager and was able to make it work with: `nix-env -f '' -qaPA nodePackages | grep tern` – zaynetro Nov 14 '18 at 12:52
  • Most of these are not in the root namespace because it would make the normal search slow. It's the same with Haskell packages. Their namespace is too big. – user239558 Nov 19 '19 at 16:50
7

As an alternative, I also found CMCDragonkai's comment on the Nixpkgs issue #3393:

I just found out that you can change NPM's prefix directory. Something like:

npm config set prefix '~/mutable_node_modules'

This allows you to use NPM's global installation.

So it's possible to work around the purely functional model, by redirecting its outputs to somewhere that's not managed by Nix. But I guess it defeats the purpose of using Nix. And not every single software will support these types of configuration changes.

Still I feel it's very clunky having to switch between using nix-env for normal global Node packages, and npm for development packages. I guess that's why there's all those porting layers such as "npm2nix".

toraritte
  • 1,018
  • 13
  • 22