svanderburg / node2nix

Generate Nix expressions to build NPM packages
MIT License
524 stars 100 forks source link

Guidance: how to reproducibly build a global package with plugins (e.g. serverless + couple plugins) #197

Open takeda opened 4 years ago

takeda commented 4 years ago

I believe this is mostly due to my lack of understanding serverless (and in fact whole node ecosystem), but despite multiple experiments I can't package serverless together with plugins (in my case these are serverless-step-functions and serverless-python-requirements).

I'm trying to have a shell (in the future I will want to create a docker container as well) where serverless is available as a command, but the serverless also sees the extra plugins. At best I can get serverless command to be available, but it doesn't have any plugins.

Any guidance how this can be done?

takeda commented 4 years ago

After studying more about nodejs I think the grunt example is what supposed to target my use case, so I created:

package.json

{
  "name": "testapp",
  "version": "0.1.0",
  "private": "true",
  "devDependencies": {
    "serverless": "*",
    "serverless-python-requirements": "*",
    "serverless-step-functions": "*"
  }
}

I run npm install which generated package-lock.json. I checked and it worked with plugins. I removed node_packages directory.

Created supplement.json

[
    "serverless-cli"
]

then I called

$ node2nix -l package-lock.json -d --supplement-input supplement.json

When trying to use the shell, I get working serverless but it still is complaining that the plugins referenced in serverless.yml are missing.

What am I doing wrong?

svanderburg commented 4 years ago

That's weird. I have repeated your instructions, and for me it works.

Two questions:

I used:

$ nix-shell -A shell

This is what I'm seeing in my shell session:

$ serverless

Serverless: No project detected. Do you want to create a new one? (Y/n) 

[nix-shell:~/teststuff/node2nix-test]$ which serverless
/nix/store/bm68hxpfwgrpljir451s2mhx0waqk2yr-node-dependencies-testapp-0.1.0/bin/serverless
takeda commented 4 years ago

serverless was working for me, but it didn't see the plugins (serverless-python-requirements and serverless-step-functions)

takeda commented 4 years ago

Looks like the issue I was having was not because of node2nix, but because how serverless works, so I'm guessing this ticket can be closed.

svanderburg commented 4 years ago

@takeda I looked at this again, and can you try something else? Maybe your problem can be fixed if you carry out the instructions here: https://github.com/svanderburg/node2nix#creating-a-symlink-to-the-node_modules-folder-in-a-shell-session

If serverless is a package that is a plugin system, e.g. similar to gulp, grunt or eslint, that relies on plugins installed in the node_modules/ folder, then it is very likely that it hits the same limitation.

The solution described in the README.md is not very elegant, but it should work.

takeda commented 4 years ago

@svanderburg sorry, I actually somehow overlooked your response. This is something that I actually tried (although I put the ln -s ... inside of a wrapper, my goal was to make serverless available as a command without having the user to know anything about node or npm, kind of like we can use awscli without having to know about python) and it worked, but I didn't like that it was modifying the current working directory.

I actually manged to get a PR merged to serverless that would make serverless also look for plugins in the folder that it was started from, so I'm hoping this will resolve my issue. I had some other things to work on, so I'm trying it now :)

takeda commented 4 years ago

@svanderburg actually I still have a problem, basically I'm trying to figure out what's the best way to package an application with few plugins in such way that the binaries from that application are exposed under /bin directory.

In other words, I want to pack serverless, serverless-python-requirements and serverless-step-functions into one single node_modules directory, and expose sls command from serverless in /bin. So when I do:

nix build -f default.nix package I can run result/bin/sls and serverless-python-requirements and serverless-step-functions are included.