Package excludes do not seem to work

We are using the following configuration for the package:

package:
  exclude:
    - 'node_modules/**'

This is similar to the example in the docs, but it seems, it does not work: the node_modules directory is always included. The problem has already been reported a few times

I think, I have checked everything, but I cannot find the problem. Is it possible that something has changed and this is a bug in the current version?

For now, we do the following during deployment (Node project):

npm install
mv node_modules ../node_modules.tmp
# ignore-scripts: avoid running 'build' again, we only need dependencies
npm install -s --prod --ignore-scripts 

sls deploy $* # pass through script arguments

# restore node_modules directory
rm -rf node_modules
mv ../node_modules_service.tmp node_modules

A similar approach was also suggested by smkamranqadri on a previous question.

Are we doing something wrong, or how can we debug this?

No update from anyone here. However, I just tested a different set up. With the script from the original question, we make sure that only the node modules from ‘production’ are used (remove the --ignore scripts, if this is required by some packages).

Now, we just exclude the original source and test folders:

package:
  exclude:
    - src/**
    - test/**
    - '*_sample*'

This seems to work, however

package:
  include:
    - dist/**
    - node_modules/**

Does not work. Both snippets adapted from the docs

I’m having the same problem. The way excludes/includes and individual packaging work don’t seem to line up with the documentation. I’m currently trying to exclude all node modules from an individually packaged function. However, the only way it will work is if I use the global package individually setting. If the global setting is not used the function package settings are ignored and everything is included in the package.

My problem ended up being the serverless-plugin-include-dependencies plugin interaction with packaging.

Don’t you need to exclude everything first than begin to include? This is what worked for me (I manage functions individually but it may not matter):

package:
  individually: true
  exclude:
    - ./**

functions:
  InviteSlack:
    package:
      include:
        - invite_slack/**
1 Like

Serverless changed the way it handled dependencies a few releases ago. Previously it uploaded everything from node_modules which included development dependencies. There were a number of solutions around this but they’re all redundant now. Serverless will automatically exclude the development dependencies (and their dependencies) from the zip file. It looks like this change means you can no longer exclude packages from the node_modules directory manually.

2 Likes

Good to know. I did not see this at all. Just checked with the documentation … it says this in the end (Development Dependencies)

Serverless will auto-detect and exclude development dependencies based on the runtime your service is using.

This ensures that only the production relevant packages and modules are included in your zip file. Doing this drastically reduces the overall size of the deployment package which will be uploaded to the cloud provider.

It might be good to update the first example which still uses include/exclude on node_modules.

Sounds good. I did not understand it this way. For me, the include-only should work like a whitelist. However, it seems I just misunderstood the documentation. Thank you for clarifying this!

Make sure it’s not a webpack issue. If you’re using serverless-webpack in your serverless.yml to transpile code, it will be bundled into a .webpack dir (or some other temporary/intermediary dir) and it’s from there that serverless will try to create a CloudFormation package. So if you’re trying to include/exclude stuff from the root of your project dir, then you’re prone to get confused/frustrated. I solved my particular problem by specifying what files/dir I wanted to copy over in the webpack.config.js to .webpack using a webpack plugin called copy-webpack-plugin. Syntax:

const CopyWebpackPlugin = require(‘copy-webpack-plugin’);
const path = require(‘path’);
…
plugins: [
new CopyWebpackPlugin([
{
from: path.join(__dirname, “pic.png”)
}
])
]
…

1 Like

Just want to say for future searchers that exclude did work for me… this syntax in serverless.yml:

package:
exclude:
- config/local.json

verified did not send over

A complete exclude let’s include act as a white list:

package:
  exclude:
     - ./**
     - '!node_modules/**'
  include:
    - app/**
    - handler.js
    - package.json

The !node_modules must be quoted. I don’t add it in the includes so that the framework can exclude development dependencies.

1 Like

I also had

package:
  exclude:
    - ./**
  include:
    - src/**

But node_modules are still included no matter what but it’s probably good practice to include ‘!node_modules/**’ in case the code changes in the future.

Same problem here. The “package” command works in general but not in function scope. Or to be more precise it does, because the “artifact” child element is recognized and evaluaed only “include” and “exclude” are just skipped.

Are there any news on that topic? In theory it does not sound like a big problem, more like a minor bug.

This is the only solution worked for me, first exclude all then include only required packages:

package:
exclude:
- ./**
include:
- dist/**
- node_modules/**
- packakge.json

The docs are still wrong, you have to use “exclude” not “patterns”