Keeping Dev Dependencies Out Of Your Serverless Package

Keeping Dev Dependencies Out Of Your Serverless Package

NOTE: This has been tested using Node 6.10, NPM 4.5 and Serverless 1.11. I don't know the first version of those packages that this works with.

Most developers will find themselves with a number of dependencies in their package.json that are only required for development. In the serverless world it's not uncommon to require a compiler/transpiler (TypeScript/Flow/Babel), type definitions, a unit testing framework, additional plugins, etc.

Even though they're included in your package.json as devDependencies they're put into the same node_modules folder as your regular runtime dependencies. This means that when Serverless creates your deployment package you often end up shipping a large number of packages that are only required for development. Obviously this is less than ideal for a number of reasons.

While you could try to using the package include/exclude directives in your serverless.yml it quickly gets out of control.

For a long time I lived with this problem but it appears a solution is now available.

With NPM 4.5 you can now put a package.json/node_modules in the projects root folder with your development dependencies and a package.json/node_modules in the service folder with runtime dependencies. When you run sls from the service folder it has access to both sets of packages, allowing you to use plugins from the root folder, but when it creates the deployment package (the .zip file that is uploaded) it will only includes the node_modules from the service folder. This excludes all of the development dependencies.

Still lost?

  1. Start by creating a root folder for your project. If you're using git then this is probably going to be the root folder for your repository.

  2. Create a package.json using npm init. You're going to install all of your development dependencies here using npm install PACKAGE --save-dev from this folder.

  3. Now create a new folder for each service. You can do that by using sls create -t aws-nodejs -p service-name.

  4. In each service create another package.json using npm init. Your runtime dependencies are installed here by using npm install PACKAGE --save from this folder.

If you managed to following this correctly you'll probably have something that looks like:

root
  + package.json
  + node_modules
  + service-name
      + package.json
      + serverless.yml
      + node_modules

When you run sls deploy from the service folder only the packages from the root/service-name/node_modules folder are included.