Node.js: Difference between revisions

Makefu (talk | contribs)
m update link to homepage-dashboard package
DHCP (talk | contribs)
m Setup: suggest search.nixos.org instead of cli nix search
 
(3 intermediate revisions by 2 users not shown)
Line 5: Line 5:
== Setup ==
== Setup ==
Adapt or add following line to your system configuration:<syntaxhighlight lang="nix>
Adapt or add following line to your system configuration:<syntaxhighlight lang="nix>
  environment.systemPackages = with pkgs; [ nodejs ];
environment.systemPackages = with pkgs; [ nodejs ];
</syntaxhighlight>
</syntaxhighlight>


See <code>nix search nixpkgs nodejs</code> for additional versions like <code>nodejs-12_x</code>, etc.
See [https://search.nixos.org/packages?&query=nodejs NixOS Package Search] for additional versions like <code>nodejs_20</code>, etc.
 
== Development environment ==
Also see [[Development environment with nix-shell]] on this wiki.
 
=== Nixpkgs example ===
{{file|shell.nix|nix|3=
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  nativeBuildInputs = with pkgs.buildPackages; [
    nodejs_22
    yarn
  ];
}
}}
 
=== Corepack example ===
To use specific/pinned versions of your runtime & package manager, a combination of corepack & steam-run can be used
{{file|shell.nix|nix|3=
{ pkgs ? import <nixpkgs> {} }:
 
pkgs.mkShell {
  buildInputs = with pkgs; [
    corepack
    steam-run-free
  ];
  shellHook = ''
    alias deno="steam-run pnpm deno"
  '';
}
}}
 
{{file|package.json|json|3=
{
  "packageManager": "pnpm@11.4.0",
  "devEngines": {
    "runtime": {
      "name": "deno",
      "version": "^2.7.14",
      "onFail": "download"
    }
  }
}
}}


== Packaging ==
== Packaging ==
Line 72: Line 115:
<syntaxhighlight lang="console">
<syntaxhighlight lang="console">
$ nix-shell -p yarn yarn2nix
$ nix-shell -p yarn yarn2nix
$ yarn install
$ yarn install # creates yarn.lock
# creates yarn.lock
$ yarn2nix > yarn.nix
$ yarn2nix > yarn.nix
$ vim package.json
$ vim package.json # add: "bin": "app.js",
# add:   "bin": "app.js",
$ cat > default.nix <<EOF
$ cat > default.nix <<EOF
with (import <nixpkgs> {});
with (import <nixpkgs> {});
Line 125: Line 166:
This is done through configuring npm and amending your <tt>PATH</tt>.<ref>[https://logs.nix.samueldr.com/nixos/2018-07-09#1358500 joepie91 on #nixos, 2018-07-09]</ref>
This is done through configuring npm and amending your <tt>PATH</tt>.<ref>[https://logs.nix.samueldr.com/nixos/2018-07-09#1358500 joepie91 on #nixos, 2018-07-09]</ref>


<pre>
<syntaxhighlight lang="console">
$ npm set prefix ~/.npm-global
$ npm set prefix ~/.npm-global
</pre>
</syntaxhighlight>


Then, amend your <tt>PATH</tt> so it looks into <tt>$HOME/.npm-global</tt>.
Then, amend your <tt>PATH</tt> so it looks into <tt>$HOME/.npm-global</tt>.
Line 135: Line 176:
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 <tt>node_packages/.bin/</tt>.<ref>[https://logs.nix.samueldr.com/nixos/2018-07-17#1386090; samueldr on #nixos, 2018-07-17]</ref>
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 <tt>node_packages/.bin/</tt>.<ref>[https://logs.nix.samueldr.com/nixos/2018-07-17#1386090; samueldr on #nixos, 2018-07-17]</ref>


<pre>
<syntaxhighlight lang="console">
$ npm install uglify-es
$ npm install uglify-es
[ ... ]
[ ... ]


$ ls -l node_modules/.bin/
$ ls -l node_modules/.bin/
total 0
total 0
lrwxrwxrwx 1 user users 25 Jul 17 15:34 uglifyjs -> ../uglify-es/bin/uglifyjs
lrwxrwxrwx 1 user users 25 Jul 17 15:34 uglifyjs -> ../uglify-es/bin/uglifyjs


$ node_modules/.bin/uglifyjs --help
$ node_modules/.bin/uglifyjs --help
   Usage: uglifyjs [options] [files...]
   Usage: uglifyjs [options] [files...]
</pre>
</syntaxhighlight>


===== direnv =====
===== direnv =====
Line 159: Line 200:
==== Using <code>npx</code> ====
==== Using <code>npx</code> ====


<pre>
<syntaxhighlight lang="console">
$ nix-shell -p nodejs-8_x
$ nix-shell -p nodejs-8_x


$ npx create-react-app --help
$ npx create-react-app --help
npx: installed 67 in 1.671s
npx: installed 67 in 1.671s
   Usage: create-react-app <project-directory> [options]
   Usage: create-react-app <project-directory> [options]
[...]
[...]
</pre>
</syntaxhighlight>


==== Using <code>npx</code> with binaries ====
==== Using <code>npx</code> with binaries ====
Line 175: Line 216:
For example, <code>npx cypress open</code> might give an error like:
For example, <code>npx cypress open</code> might give an error like:


<pre>
<syntaxhighlight lang="console">
$ npx cypress open
$ npx cypress open


Line 185: Line 226:
----------
----------
spawn /home/rkb/.cache/Cypress/4.10.0/Cypress/Cypress ENOENT
spawn /home/rkb/.cache/Cypress/4.10.0/Cypress/Cypress ENOENT
</pre>
</syntaxhighlight>


One quick workaround for this is [[Steam#FHS environment only| to use <code>steam-run</code>]] to provide a placeholder FHS environment that *should* work; e.g. for the Cypress example above:
One quick workaround for this is [[Steam#FHS environment only| to use <code>steam-run</code>]] to provide a placeholder FHS environment that *should* work; e.g. for the Cypress example above:


<pre>
<syntaxhighlight lang="console">
$ nix-env -iA nixos.steam-run
$ nix-env -iA nixos.steam-run


Line 195: Line 236:


-- Cypress opens successfully!
-- Cypress opens successfully!
</pre>
</syntaxhighlight>


(Inspired by [https://discourse.nixos.org/t/how-to-make-nixos-so-easy-that-people-can-be-productive-up-front-without-having-to-first-learn-the-nix-language/5625 this discussion on discourse.nixos.org])
(Inspired by [https://discourse.nixos.org/t/how-to-make-nixos-so-easy-that-people-can-be-productive-up-front-without-having-to-first-learn-the-nix-language/5625 this discussion on discourse.nixos.org])
Line 201: Line 242:
'''Google-fonts fetch failure with NextJS'''
'''Google-fonts fetch failure with NextJS'''


Nextjs is a popular React framework and comes with built-in support with support for Google fonts. If a NPM project uses it, <syntaxhighlight lang="shell">
Nextjs is a popular React framework and comes with built-in support with support for Google fonts. If a NPM project uses it, <syntaxhighlight lang="console">
npm run build # which calls "next build"
$ npm run build # which calls "next build"
</syntaxhighlight>will try to fetch and optimize the Google fonts during a  nix build run, which will fail in Nix's isolated sandbox without internet:<syntaxhighlight lang="shell">
</syntaxhighlight>will try to fetch and optimize the Google fonts during a  nix build run, which will fail in Nix's isolated sandbox without internet:<syntaxhighlight lang="shell">
...
...
Line 236: Line 277:
ERROR: `npm build` failed
ERROR: `npm build` failed
</syntaxhighlight>You have to patch the Javascript code <syntaxhighlight lang="javascript">
</syntaxhighlight>You have to patch the Javascript code <syntaxhighlight lang="javascript">
# In layout.tsx file replace
// In layout.tsx file replace
#
//
# import {Inter} from "next/font/google"; #or any other Google font like Inter
// import {Inter} from "next/font/google"; // or any other Google font like Inter
# const inter = Inter({ subsets: ["latin"] });
// const inter = Inter({ subsets: ["latin"] });
#
//
# with ("src:" must be relative to the src/app/layout.tsx file):
// with ("src:" must be relative to the src/app/layout.tsx file):
import localFont from "next/font/local";
import localFont from "next/font/local";
const inter = localFont({ src: './Inter.ttf' });
const inter = localFont({ src: './Inter.ttf' });
Line 259: Line 300:
   ...
   ...
}
}
</syntaxhighlight>You can take a look at what fonts are available in the Nix <code>google-fonts</code> package by calling:<syntaxhighlight lang="shell">
</syntaxhighlight>You can take a look at what fonts are available in the Nix <code>google-fonts</code> package by calling:<syntaxhighlight lang="console">
ls -ahl $(nix build --no-link --print-out-paths nixpkgs#google-fonts)/share/fonts/truetype/
$ ls -ahl $(nix build --no-link --print-out-paths nixpkgs#google-fonts)/share/fonts/truetype/
</syntaxhighlight>Take a look at [https://github.com/NixOS/nixpkgs/blob/8358fd43a66594d8b3445d87006185fa76d4be6e/pkgs/by-name/ho/homepage-dashboard/package.nix homepage-dashboard package in nixpkgs] for further workarounds for Nextjs in Nix.
</syntaxhighlight>Take a look at [https://github.com/NixOS/nixpkgs/blob/8358fd43a66594d8b3445d87006185fa76d4be6e/pkgs/by-name/ho/homepage-dashboard/package.nix homepage-dashboard package in nixpkgs] for further workarounds for Nextjs in Nix.


Line 312: Line 353:
<syntaxhighlight lang="nix>
<syntaxhighlight lang="nix>
final: prev: {
final: prev: {
      nodejs = prev.nodejs-16_x;
  nodejs = prev.nodejs-16_x;
}
}
</syntaxhighlight>
</syntaxhighlight>
<pre>
<syntaxhighlight lang="console">
$ pnpm node --version
$ pnpm node --version
v16.17.1
v16.17.1
</pre>
</syntaxhighlight>


=== Override NodeJS package ===
=== Override NodeJS package ===