node2nix icon indicating copy to clipboard operation
node2nix copied to clipboard

Is it possible to install dev dependencies as well?

Open CMCDragonkai opened this issue 6 years ago • 10 comments

I am developing JS project that involves webpack, typescript... etc.

Anyway, the resulting build from webpack is about 400 KiB. I wanted to avoid leaving this in the actual Git repository.

So normally with npm based dev workflow. I would use npm install, npm run build and then I have something production oriented.

I wanted to see if something possible with node2nix and nix-build.

I found the problem is that node2nix only installs the dependencies, not the devDependencies. So using postInstall script with npm run build doesn't work.

Is there a way to make node2nix generated expressions install all dependencies first, run npm run build, and then only push up the built output along with only the node modules relevant for production into the nix-store?

Because at the moment, it seems that I need to have the production build in the current directory and (thus committed to my git repo) for me to properly nix-build it and have the actual built output in nix-store.

CMCDragonkai avatar Jul 19 '19 01:07 CMCDragonkai

There is -d option that you can provide as command-line parameter. This option says that it should install development dependencies. However, this will only work for deployments that are package.json driven. Is this of any use?

svanderburg avatar Aug 06 '19 14:08 svanderburg

The main issue, is that the dev dependencies should only be installed during the "build phase". And then discarded to produce the final $out. So whatever is in $out should only be things from dependencies not devDependencies. But during build time, you need the devDependencies to actually build the output. I guess this is similar to the whole buildInputs vs propagatedBuildInputs distinction but in package.json terms?

CMCDragonkai avatar Aug 19 '19 04:08 CMCDragonkai

@svanderburg It would be useful to at least be able to enable dev dependencies for one package. Right now I'm trying to build something for nixpkgs that requires devDependencies for some build operations and the fact that -d applies to the json globally is making it hard to do.

rileyinman avatar Sep 21 '19 03:09 rileyinman

What if... node2nix took all the deps specified in package.json and put it into node-packages.nix. However the ones that are dev dependencies are marked as so, or even under a specific attribute path. Then our default.nix can then decide to bring in all the dev dependencies, but only as buildInputs and thus do not exist in the final output, they are only build time dependencies.

CMCDragonkai avatar Sep 21 '19 11:09 CMCDragonkai

This might be the ideal workflow:

  1. Generate node-packages.nix with dev dependencies as well as prod dependencies
  2. In the default.nix install both the dev and prod dependencies during build time, by using symlinks in the tmp directory that nix-build uses
  3. Allow the usage of any relevant build commands like npm run build usually, which outputs whatever that is needed into the tmp directory, this might produce things in a dist directory
  4. Finally produce a node package similar to npm publish that recognizes .npmignore... etc, there is a command that does this called npm pack, see below, this distribution does not include the final node modules
  5. Then copy this packed output and extract it into the nix-store path
  6. Then symlink the production node modules into the same nix store path as well
  7. The result should then be the npm packed output plus the prod dependencies accessible via node_modules
[nix-shell:~/Projects/js-pagination]$ npm pack --dry-run
npm notice 
npm notice 📦  @matrixai/[email protected]
npm notice === Tarball Contents === 
npm notice 789B   package.json              
npm notice 11.4kB LICENSE                   
npm notice 1.2kB  README.md                 
npm notice 2.4kB  dist/browser/Cursor.js    
npm notice 12.0kB dist/browser/Cursor.js.map
npm notice 5.4kB  dist/browser/index.js     
npm notice 25.1kB dist/browser/index.js.map 
npm notice 4.0kB  dist/browser/Offset.js    
npm notice 18.4kB dist/browser/Offset.js.map
npm notice 2.6kB  dist/Cursor.d.ts          
npm notice 6.9kB  dist/Cursor.js            
npm notice 11.4kB dist/Cursor.js.map        
npm notice 99B    dist/index.d.ts           
npm notice 15.3kB dist/index.js             
npm notice 27.4kB dist/index.js.map         
npm notice 5.1kB  dist/Offset.d.ts          
npm notice 11.5kB dist/Offset.js            
npm notice 19.4kB dist/Offset.js.map        
npm notice === Tarball Details === 
npm notice name:          @matrixai/pagination                    
npm notice version:       0.0.9                                   
npm notice filename:      matrixai-pagination-0.0.9.tgz           
npm notice package size:  22.8 kB                                 
npm notice unpacked size: 180.4 kB                                
npm notice shasum:        d9b3c6530c107d3a47bb9e3ec57fee3dea4d2855
npm notice integrity:     sha512-RCyTYmj958vV1[...]dX4MZSH3iaqMg==
npm notice total files:   18                                      
npm notice 
matrixai-pagination-0.0.9.tgz

CMCDragonkai avatar Sep 25 '19 03:09 CMCDragonkai

I'm definitely also wanting this behaviour, and am keen to have a go at implementing it if someone else isn't already

JJJollyjim avatar Mar 21 '20 04:03 JJJollyjim

Has anyone made any progress on this? I see this as a major issue for any package requiring devDependencies as part of a build step.

kira-bruneau avatar Jul 04 '20 17:07 kira-bruneau

I've made some progress on this with https://github.com/MatrixAI/TypeScript-Demo-Lib/pull/13. In particular making use of IFD.

However I've hit a problem. The node2nix uses npm install. So if I have a bin config in the package.json, it will complain that the target js file doesn't exist in the dist because the dist hasn't been built yet.

If I add "preinstall": "npm run build", then I can get the dist prior. However this breaks npm install since, that should really run as part of "prepare". However I believe node2nix is doing some symlinking magic with the bin configuration as soon as install finishes, perhaps in the postinstall, this then creates a chicken or egg conflict.

This could be fixed by tweaking how node2nix actually does the bin stuff. And in fact I think it needs a redesign due to #201 .

At the end of the day, I think node2nix could use some IFD magic so it could have a 2 stage build, one to build from dev dependencies, another to produce the final needed package, without the dev dependencies. Then it is possible to have the entire npm build process be nixified.

CMCDragonkai avatar Sep 30 '20 14:09 CMCDragonkai

Hi!

Is there any progress on this issue?

ShamrockLee avatar Aug 02 '22 23:08 ShamrockLee

Same here, I was trying to package an react app but npm run build needs devDependencies and node2nix -l -d will run into an error

/nix/store/81y29x74r9ssp7na4xidjsyayfi5z5sw-node2nix-1.11.0/lib/node_modules/node2nix/node_modules/optparse/lib/optparse.js:247
                                throw OptError('Expected switch argument.');
                                ^
{ msg: 'Expected switch argument.', toString: [Function (anonymous)] }

Edit: The bug is triggered when both -d and -l are used, use -d alone is fine.

BillHuang2001 avatar Sep 28 '22 15:09 BillHuang2001