Node.js: Difference between revisions
imported>Mightyiam Example nix shell for Node.js development |
imported>Tennox Add example how to build nodePackages with different nodejs version - see https://discourse.nixos.org/t/how-to-use-pnpm-with-recent-nodejs/21867/4?u=tennox |
||
Line 177: | Line 177: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Using nodePackages with a different node version == | |||
Packages in {{ic|nixpkgs.nodePackages}} are built using {{ic|nixpkgs.nodejs}}, so if you [[Overlays|overlay that package]] to a different version, the {{ic|nodePackages}} will be built using that: | |||
<syntaxhighlight lang="nix> | |||
final: prev: { | |||
nodejs = prev.nodejs-16_x; | |||
} | |||
</syntaxhighlight> | |||
<pre> | |||
$ pnpm node --version | |||
v16.17.1 | |||
</pre> | |||
== External Links == | == External Links == |
Revision as of 22:25, 22 October 2022
Install
environment.systemPackages = with pkgs; [ nodejs ];
See nix search nodejs
for additional versions like nodejs-12_x
, etc.
Packaging
Package with yarn2nix
yarn2nix uses the yarn nodejs tool to create a file called yarn.lock, which in return can be used by yarn2nix to generate a usable yarn expression. This is what was needed to convert a small application server shackspace muellshack:
$ nix-shell -p yarn yarn2nix
$ yarn install
# creates yarn.lock
$ yarn2nix > yarn.nix
$ vim package.json
# add: "bin": "app.js",
$ cat > default.nix <<EOF
with (import <nixpkgs> {});
rec {
muellshack = mkYarnPackage {
name = "muellshack";
src = ./.;
packageJSON = ./package.json;
yarnLock = ./yarn.lock;
yarnNix = ./yarn.nix;
};
}
EOF
$ sed -i '1i#!/usr/bin/env node' app.js
$ chmod +x app.js
$ nix-build
$ result/bin/muellshack
The complete diff can be found at the respective diff
FAQ
Using npm install -g
fails
The following errors are to be expected.
npm ERR! Error: EACCES: permission denied, access '/nix/store/00000000000000000000000000000000-nodejs-6.14.3/lib/node_modules' npm ERR! at Error (native) npm ERR! { Error: EACCES: permission denied, access '/nix/store/00000000000000000000000000000000-nodejs-6.14.3/lib/node_modules' npm ERR! at Error (native) npm ERR! errno: -13, npm ERR! code: 'EACCES', npm ERR! syscall: 'access', npm ERR! path: '/nix/store/00000000000000000000000000000000-nodejs-6.14.3/lib/node_modules' } npm ERR! npm ERR! Please try running this command again as root/Administrator.
The store is read-only as it should be. Purity in Nix and NixOS makes it right not to allow installation using -g
.
There are a couple solutions, none of them are strictly wrong. You can either configure npm
so it installs globally to your home, or avoid using -g
entirely. It is also possible, for node versions 8 and greater, to use npx
.
Install to your home
This is done through configuring npm and amending your PATH.[1]
$ npm set prefix ~/.npm-global
Then, amend your PATH so it looks into $HOME/.npm-global.
Avoid using -g
This is a bit harder to implement, but creates a bit more strictness in your environment; it will be impossible accidentally make use of what would have been a globally installed package. The idea is to install it to either a temporary transitory folder or to the project folder, then run the locally installed instance of the package, the binaries are found under node_packages/.bin/.[2]
$ npm install uglify-es [ ... ] $ ls -l node_modules/.bin/ total 0 lrwxrwxrwx 1 user users 25 Jul 17 15:34 uglifyjs -> ../uglify-es/bin/uglifyjs $ node_modules/.bin/uglifyjs --help Usage: uglifyjs [options] [files...]
direnv
If calling the executables with full path is too cumbersome, another elegant solution is to leverage direnv. Direnv is a shell-hook that can set directory-specific environment-variables. You basically add a file ".envrc" next to your "package.json" with the following content:
layout node
direnv then adds your "node_modules/.bin" to your path whenever you enter the directory. Please follow direnv's setup instructions on how to activate setup direnv in general.
Using npx
$ nix-shell -p nodejs-8_x $ npx create-react-app --help npx: installed 67 in 1.671s Usage: create-react-app <project-directory> [options] [...]
Using npx
with binaries
Some binaries obtained via npm will not work out of the box with NixOS, as they're dynamically linked to things that don't exist in NixOS (for good reason!)
They'll typically give some kind of ENOENT
error.
For example, npx cypress open
might give an error like:
$ npx cypress open Cypress failed to start. This is usually caused by a missing library or dependency. The error below should indicate which dependency is missing. https://on.cypress.io/required-dependencies If you are using Docker, we provide containers with all required dependencies installed. ---------- spawn /home/rkb/.cache/Cypress/4.10.0/Cypress/Cypress ENOENT
One quick workaround for this is to use steam-run
to provide a placeholder FHS environment that *should* work; e.g. for the Cypress example above:
$ nix-env -iA nixos.steam-run $ steam-run npx cypress open -- Cypress opens successfully!
(Inspired by this discussion on discourse.nixos.org)
Example nix shell for Node.js development
`shell.nix` example:
{ pkgs ? import <nixpkgs> {} }:
let
lib = import <nixpkgs/lib>;
buildNodeJs = pkgs.callPackage <nixpkgs/pkgs/development/web/nodejs/nodejs.nix> {};
nodejsVersion = lib.fileContents ./.nvmrc;
nodejs = buildNodeJs {
enableNpm = false;
version = nodejsVersion;
sha256 = "1a0zj505nhpfcj19qvjy2hvc5a7gadykv51y0rc6032qhzzsgca2";
};
NPM_CONFIG_PREFIX = toString ./npm_config_prefix;
in pkgs.mkShell {
packages = with pkgs; [
nodejs
nodePackages.npm
];
inherit NPM_CONFIG_PREFIX;
shellHook = ''
export PATH="${NPM_CONFIG_PREFIX}/bin:$PATH"
'';
}
Using nodePackages with a different node version
Packages in nixpkgs.nodePackages
are built using nixpkgs.nodejs
, so if you overlay that package to a different version, the nodePackages
will be built using that:
final: prev: {
nodejs = prev.nodejs-16_x;
}
$ pnpm node --version v16.17.1