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
DX: Zip only production relevant node_modules to decrease bundle size #2709
Comments
I wrote a plugin for this, called serverless-plugin-include-dependencies - give it a try? |
Awesome @dougmoscrop! 🎉 BTW here's the link https://github.com/dougmoscrop/serverless-plugin-include-dependencies |
@dougmoscrop cool, I guess you'll want to add it to the list of plugins. |
If you're using later versions of npm (I've only tested this with 4.5.0) then it's pretty easy to reduce the size of your deployment pages. Create a This keeps all of your development dependencies and the packages they depend on out of the zip file as only the |
That's neat! (sad that it only works with newer Thanks for posting @buggy 👍 |
There are a number of ways we can include only prod dependancies and exclude dev dependancies See http://stackoverflow.com/questions/36447801/grunt-and-npm-package-all-production-dependencies This works. /**
* Returns an array of the node dependencies needed for production.
* See https://docs.npmjs.com/cli/ls for info on the 'npm ls' command.
*/
var getProdDependencies = function(callback) {
require('child_process').exec('npm ls --prod=true --parseable=true', undefined,
function(err, stdout, stderr) {
var array = stdout.split('\n');
var nodeModuleNames = [];
array.forEach(function(line) {
var index = line.indexOf('node_modules');
if (index > -1) {
nodeModuleNames.push(line.substr(index + 13));
}
});
callback(nodeModuleNames);
});
}; Are there any potential risks/downsides to implementing something like this? |
@DavidWells great research! we should only keep in mind to support both |
@pmuens I believe The alternative solution would be recursively parsing the package.json prod deps ourselves and zipped up only the prod deps. Or potentially leveraging @dougmoscrop handy work =) https://github.com/dougmoscrop/serverless-plugin-include-dependencies/blob/master/get-dependency-list.js |
@DavidWells yes, I'm also not 100% sure if supporting both ( I came up with that because of this LOC where require('child_process').exec('npm ls --prod=true --parseable=true', undefined, function(err, stdout, stderr) AFAIK we have some people relying on yarn. Another question we've should discuss is a way how we can extend this later on to support other runtimes such as Python or JVM. Maybe we can define an interface for this so that it can be easily extended for other runtimes later down the road. Something to keep in my although this might be out of the scope for now. |
I think we can do this for |
@DavidWells for what it's worth, this can be accomplished with |
Also note, there was some discussion around an equivalent command for |
Thanks for the tip @marshall007 👍 That sounds good. I'm still in favor of the more general solution without Can't we just read the |
@pmuens yeah we can start with root I believe this is how npm is actually doing it with that https://github.com/npm/npm/blob/6f09d6d2d915cdccfee6f423d7f14135be89e9f9/lib/ls.js |
Quick update: We just started the implementation in #3737. Feel free to test it and provide feedback 👍 |
@pmuens very useful work, however there is a bug in the code which prevents functions to be packaged individually. I added a comment in your PR to describe the issue. Thx! |
@marshall007 This was my solution. Copy package.json and node_modules into the build dir, run prune, . |
As commented in #3737, there is an issue if functions are packaged individually, and if functions are developed as separate nodejs packages, with each of these packages having its own
where function1 and function2 are developed as 2 separate nodejs packages. In case |
Doesn't this approach in general break the concept of microservices propagated by the Serverless framework? In my understanding a Serverless service represents a microsoervice, that is self-contained. There are plugins that solve the issue that you try to solve here already. E.g. the serverless-webpack plugin, which only deploys the used dependencies per function, if you enable packaging per function. |
@HyperBrain Yes right you have a point, maybe our development model doesn't really fit with some (implicit?) assumptions, but except for this issue with |
@HyperBrain - Pragmatically, I don't think it violates anything, since the term "microservice" is a buzzword that has a lot of interpretation to it ;) We regularly have separate functions that use different libraries even within a 'self contained system' since those functions usually do very different things. Wanting to minimize size seems reasonable. |
Hey everyone! Thanks for the discussion here. 👍 I just pushed some changes to the PR (#3737) so that nested directories with dependencies are now supported out of the box. Feel free to give it a try. |
This is a Feature Proposal
Description
At the moment everything inside
node_modules
is being zipped and uploaded to s3.If we would create a plugin for zipping the service (to not only be dependent on node.js), we could leverage npm (or at least their
ls
algorithm) to find a list of only the production dependencies (even with npm@3 and their flat directory structure).npm ls --production --parseable
creates exactly this - a list of all dependencies and their transient dependencies, that are declared through the package.json's dependencies (excluding devDependencies).The text was updated successfully, but these errors were encountered: