Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the Dev dependencies after build #96

Open
CMCDragonkai opened this issue Aug 16, 2021 · 3 comments
Open

Remove the Dev dependencies after build #96

CMCDragonkai opened this issue Aug 16, 2021 · 3 comments

Comments

@CMCDragonkai
Copy link

I currently have hacked up node2nix to do this where the final output doesn't have the Dev dependencies lying about. Is it possible to do this with npm2nix?

@andir
Copy link
Collaborator

andir commented Aug 16, 2021

It is possible but requires some special care.

The primary issue is with languages such as typescript that during compilation require tsc (and other libraries) but during runtime doesn't need those anymore. Usually this also means that you run your tests with the full dev dependencies and you can't be sure that the application actually works without them when you substitute the node_modules with the non-dev version but that is a general npm/software engineering issue.

One step of the puzzle is to make the npm install flexible enough to also just install the non-dev dependencies. As a first step we could add an argument to node_modules that allows doing just that. Then you could already do all the plumbing (required for picking up the non-dev dependencies during runtime) as part of the build invocation.

The pseudocode I am thinking of:

let
  runtimeDeps = npmlock2nix.node_modules  { src = ./.; devDependencies = false; };
in
npmlock2nix.build {
  src = ./.;
  buildCommands = [
     "npm run build"
  ];

  installPhase = ''
    mkdir -p $out/{lib,bin}
    mv dist $out/lib/app
    ln -s ${runtimeDeps}/lib/node_modules $out/lib/node_modules
    cat - <<EOF > $out/bin/run
       export NODE_PATH=${placeholder "out"}/lib/node_modules
       exec ${nodejs}/bin/node ${placeholder "out"}/lib/app/index.js "$@"
    '';
}

Does that look anywhere near to what you would require?

@achuie
Copy link

achuie commented Mar 3, 2023

For newbies like me who stumbled upon this issue trying to build a minimal docker image for their project, the following works with current npmlock2nix for an optimized production build (via, say, react-scripts) that doesn't have any runtime dependencies:

let
  npmDeps = npmlock2nix.v2.node_modules  { src = ./.; };
in
npmlock2nix.v2.build {
  src = ./.;
  buildCommands = [
     "npm run build"
  ];

  nativeBuildInputs = [ pkgs.removeReferencesTo ];

  installPhase = ''
    cp -r build $out
    runHook postInstall
  '';
  postInstall = ''
    find "$out" -type f -exec remove-references-to -t ${npmDeps} '{}' +
  '';
}

I would think this method could be used to selectively strip only certain dependencies manually if you know which are runtime and which are build time dependencies.

@bbigras
Copy link

bbigras commented Mar 3, 2023

Some packages in nixpkgs are using npm prune --omit=dev in installPhase. Not sure if it could help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants