Node.js: Difference between revisions
imported>Milahu m typo: wiki -> manual |
Malteneuss (talk | contribs) m Add nextjs project example |
||
(9 intermediate revisions by 6 users not shown) | |||
Line 13: | Line 13: | ||
=== Packaging with <code>buildNpmPackage</code> === | === Packaging with <code>buildNpmPackage</code> === | ||
From the [https://nixos.org/manual/nixpkgs/stable/#javascript-tool-specific Nixpkgs manual]: "<code>buildNpmPackage</code> allows you to package npm-based projects in Nixpkgs without the use of an auto-generated dependencies file (as used in node2nix). It works by utilizing npm’s cache functionality – creating a reproducible cache that contains the dependencies of a project, and pointing npm to it." | From the [https://nixos.org/manual/nixpkgs/stable/#javascript-tool-specific Nixpkgs manual]: "<code>buildNpmPackage</code> allows you to package npm-based projects in Nixpkgs without the use of an auto-generated dependencies file (as used in node2nix). It works by utilizing npm’s cache functionality – creating a reproducible cache that contains the dependencies of a project, and pointing npm to it." | ||
'''To better understand what happens under the hood and see the latest features see''' | |||
https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/node/build-npm-package/default.nix | |||
==== Packaging electron applications ==== | ==== Packaging electron applications ==== | ||
Line 139: | Line 143: | ||
</pre> | </pre> | ||
One quick workaround for this is [ | 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> | <pre> | ||
Line 150: | Line 154: | ||
(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]) | ||
'''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"> | |||
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"> | |||
... | |||
Running phase: buildPhase | |||
Executing npmBuildHook | |||
> nextjs-ollama-local-ai@0.1.0 build | |||
> next build | |||
▲ Next.js 14.1.0 | |||
Creating an optimized production build ... | |||
request to https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap failed, reason: getaddrinfo EAI_AGAIN fonts.googleapis.com | |||
at ClientRequest.<anonymous> (/build/source/node_modules/next/dist/compiled/node-fetch/index.js:1:66160) | |||
at ClientRequest.emit (node:events:518:28) | |||
at TLSSocket.socketErrorListener (node:_http_client:500:9) | |||
at TLSSocket.emit (node:events:518:28) | |||
at emitErrorNT (node:internal/streams/destroy:169:8) | |||
at emitErrorCloseNT (node:internal/streams/destroy:128:3) | |||
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) { | |||
type: 'system', | |||
errno: 'EAI_AGAIN', | |||
code: 'EAI_AGAIN' | |||
} | |||
Failed to compile. | |||
src/app/layout.tsx | |||
`next/font` error: | |||
Failed to fetch `Inter` from Google Fonts. | |||
> Build failed because of webpack errors | |||
ERROR: `npm build` failed | |||
</syntaxhighlight>You have to patch the Javascript code <syntaxhighlight lang="javascript"> | |||
# In layout.tsx file replace | |||
# | |||
# import {Inter} from "next/font/google"; #or any other Google font like Inter | |||
# const inter = Inter({ subsets: ["latin"] }); | |||
# | |||
# with ("src:" must be relative to the src/app/layout.tsx file): | |||
import localFont from "next/font/local"; | |||
const inter = localFont({ src: './Inter.ttf' }); | |||
</syntaxhighlight>and place the Google fonts from Nixpkgs into the project, e.g. in a <code>preBuild</code> phase:<syntaxhighlight lang="nix"> | |||
buildNpmPackage { | |||
pname = "myproject"; | |||
version = "1.0.0"; | |||
... | |||
# see https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/cr/crabfit-frontend/package.nix | |||
preBuild = '' | |||
cp "${ | |||
google-fonts.override { fonts = [ "Inter" ]; } | |||
}/share/fonts/truetype/Inter[slnt,wght].ttf" src/app/Inter.ttf | |||
''; | |||
... | |||
} | |||
</syntaxhighlight>You can take a look at what fonts are available in the Nix <code>google-fonts</code> package by calling:<syntaxhighlight lang="shell"> | |||
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/master/pkgs/servers/homepage-dashboard/default.nix for further workarounds for Nextjs in Nix. | |||
== Example nix shell for Node.js development == | == Example nix shell for Node.js development == | ||
Line 159: | Line 227: | ||
let | let | ||
lib = import <nixpkgs/lib>; | lib = import <nixpkgs/lib>; | ||
buildNodeJs = pkgs.callPackage <nixpkgs/pkgs/development/web/nodejs/nodejs.nix | buildNodeJs = pkgs.callPackage "${<nixpkgs>}/pkgs/development/web/nodejs/nodejs.nix" { | ||
python = pkgs.python3; | |||
}; | |||
nodejsVersion = lib.fileContents ./.nvmrc; | nodejsVersion = lib.fileContents ./.nvmrc; | ||
Line 182: | Line 252: | ||
export PATH="${NPM_CONFIG_PREFIX}/bin:$PATH" | export PATH="${NPM_CONFIG_PREFIX}/bin:$PATH" | ||
''; | ''; | ||
} | |||
</syntaxhighlight> | |||
== Example nix flake shell for Node.js development == | |||
`flake.nix` example: | |||
<syntaxhighlight lang="nix> | |||
{ | |||
description = "example-node-js-flake"; | |||
inputs = { | |||
flake-utils.url = "github:numtide/flake-utils"; | |||
}; | |||
outputs = { self, nixpkgs, flake-utils }: | |||
flake-utils.lib.eachDefaultSystem (system: | |||
let | |||
pkgs = import nixpkgs { | |||
inherit system; | |||
}; | |||
buildNodeJs = pkgs.callPackage "${<nixpkgs>}/pkgs/development/web/nodejs/nodejs.nix" { | |||
python = pkgs.python3; | |||
}; | |||
nodejs = buildNodeJs { | |||
enableNpm = true; | |||
version = "20.5.1"; | |||
sha256 = "sha256-Q5xxqi84woYWV7+lOOmRkaVxJYBmy/1FSFhgScgTQZA="; | |||
}; | |||
in rec { | |||
flakedPkgs = pkgs; | |||
# enables use of `nix shell` | |||
devShell = pkgs.mkShell { | |||
# add things you want in your shell here | |||
buildInputs = with pkgs; [ | |||
nodejs | |||
]; | |||
}; | |||
} | |||
); | |||
} | } | ||