cachix / devenv

Fast, Declarative, Reproducible, and Composable Developer Environments
https://devenv.sh
Apache License 2.0
3.56k stars 259 forks source link

Override default language packages in nixpkgs #637

Open tennox opened 11 months ago

tennox commented 11 months ago

Thanks for this great project! :heart: It's what I dreamt numtide/devshell could be & more :heart_eyes:

I'm looking for a devenv-native, streamlined way to change nodejs version and also have the package managers use that version, for which the best solution I found (see discussion in discourse) was to use an overlay:

{
  overlays = [
    (final: prev: {
      nodejs = cfg.package;
    })
  ];
}

And then all added packages use that, too:

{
  packages = with pkgs; [
    yarn
    nodePackages.pnpm
  ];
}

pnpm node --version && yarn node --version is the selected package

For supporting this in e.g. languages/javascript.nix all we'd need is a way to add an overlay in the language module - is there a way?

A possible option (but less great & flexible):

{
  languages = {
    javascript = {
      package-manager = "pnpm";
    };
  };
}

And then in the languages/javascript.nix if packageManager is yarn add (yarn.override { nodejs = pkgs.nodejs-16_x; })

Coming from #475 Vaguely related to #16

shyim commented 11 months ago

I really like the idea of having an package-manager option in the javascript module and on non npm we could use nodejs slim to remove npm.

soundofspace commented 2 weeks ago

@tennox were you able to get these overlays working in devenv? I'm having a similar problem were even some package json dependencies fail because yarn is using the wrong node version. I'm currently still to novice at nix sadly to get it working myself.

tennox commented 2 weeks ago

@tennox were you able to get these overlays working in devenv?

Yes, you can check out this merge request on my javascript devenv template to see which changes are needed: https://gitlab.com/txlab/dx/templates/js/-/merge_requests/4

soundofspace commented 2 weeks ago

Thanks will give that a go. Does this also work without flakes? Just like you I came here since this is an amazing project (first tried devbox which is also an amazing project but sadly too basic for our needs). But I'm also worry about the extra complexity this introduces everywhere, as long as it works not really that big of a deal, but things like this make it tougher to sell.

tennox commented 2 weeks ago

Thanks will give that a go. Does this also work without flakes?

I don't see a way without integrating this into devenv (which I meant to initiate with this issue, maybe I'll craft a PR 🧐)

I'm also [worried] about the extra complexity this introduces everywhere, as long as it works not really that big of a deal, but things like this make it tougher to sell.

Exactly.

If it helps you, I can say that I have used devenv for many projects and almost never had to fiddle with/update the flake.nix in any 'difficult way' (only e.g. change nixpkgs channel/branch when a new stable nixos release came out) Exceptions are nodejs version (see this issue) - and of course when building software via nix. (but that's just out of scope for devenv)

shyim commented 2 weeks ago

You just want to specify the package manager to use together with nodejs version?

domenkozar commented 2 weeks ago

It seems there are two requests here:

a) supporting other package managers than npm, which we support now as per examples in https://github.com/cachix/devenv/tree/main/examples

b) supporting local overlays which we already have an issue for https://github.com/cachix/devenv/issues/478

soundofspace commented 2 weeks ago

@domenkozar Problem is not really other package managers, problem is that package managers are using different nodejs version. Overlays are a way to fix this, but ideally it doesn't happen in the first place.

    package = pkgs.nodejs_21;
    enable = true;
    # corepack.enable = true;
    yarn = {
      enable = true;
      install.enable = true;
    };
  };
 node --version
v21.7.2
yarn node --version
v20.11.1
soundofspace commented 2 weeks ago

This results in problems with packages such as better-sqlite3 when building dependencies:

yarn node -e 'console.log(process.config)'
-> node_module_version: 115,
node -e 'console.log(process.config)'
-> node_module_version: 120,

Error:

node_modules/better-sqlite3/build/Release/better_sqlite3.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 115. This version of Node.js requires
NODE_MODULE_VERSION 120. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`). {
domenkozar commented 2 weeks ago

Then we should always override that they use the canonical package of nodejs

soundofspace commented 2 weeks ago

Yes indeed. Seeing this comment, would it be possible to do something similar for this snippet?

{
  overlays = [
    (final: prev: {
      nodejs = pkgs.nodejs_21;
    })
  ];
}
soundofspace commented 3 days ago

Current workarounds to make it work, not using nodejs-slim pkg, or overlay in flake:

{ pkgs, lib, config, inputs, ... }:
{

  languages.javascript = rec {
    package = pkgs.nodejs_21;
    enable = true;
    yarn = {
      enable = true;
      # package = pkgs.yarn.override { nodejs = package; };
      package = package.pkgs.yarn;
    };
    pnpm.enable = true;
    pnpm.package = package.pkgs.pnpm;
  };
}

fyi @tennox