Optimise your Lambda functions using Webpack
Tags: serverless, aws, lambda, node
Published: 2020-03-13 13:54:51

---
title: Optimise your Lambda functions using Webpack
canonical_url: https://winterwindsoftware.com/fff-webpacking-lambdas/
tags: [Serverless, AWS, Lambda, Node.js]
description: How you can use Webpack to optimise your Lambda functions.
cover_image: https://winterwindsoftware.com/img/blog-images/treeshaking.jpg
published: true
---
_Every Friday, I will share a small tip with you on something Lambda/FaaS-related. Because Fridays are fun, and so are functions._ 🥳

Today we'll cover why and how to package your Node.js Lambda functions for deployment using Webpack and the Serverless Framework. This is an approach I take for all my Lambda function development.

## What problem does this solve?
The primary goal of using Webpack is to reduce the amount of code contained in the zip artifact that is uploaded when your Lambda function is being deployed. This has the benefit of reducing cold start times whenever your function code is loaded into memory.

It also has some secondary benefits:
- Lower security risk as only the required parts of third party modules are deployed rather than the entire contents of the `node_modules` folder.
- Transpilers such as TypeScript and Babel can be easily hooked into the build process via Webpack loaders.

## How does it work?
If you've used Webpack in the past for front-end development, you might already know that (amongst other things) it's used to bundle multiple client-side JavaScript modules into a single file. You may not know that it can be used to do the same thing with server-side Node.js modules (it's just JavaScript after all).

It works by first configuring an entrypoint function, which in our case will be the Lambda handler function. Starting with this function, it proceeds with a static analysis checking for `require` and `import` statements, following each path to other files as needed. It bundles up each file into its own module within a single file. Webpack uses a technique called [treeshaking](https://bitsofco.de/what-is-tree-shaking/) to eliminate dead code and only import the specific functions from a module that are referenced by your application code.

You might also know that Webpack can be pretty complex to configure! Don't worry though, our configuration will be simple and we'll be using the [`serverless-webpack` plugin](https://github.com/serverless-heaven/serverless-webpack) to help us.

This plugin allows us to create optimised individual bundles for each Lambda function in our service.

## Setting it up
You can follow the detailed instructions on the [`serverless-webpack` plugin README](https://github.com/serverless-heaven/serverless-webpack/), but here's a quick run-through of my standard setup. I'm assuming you already have the [Serverless Framework](https://serverless.com/framework) installed and an existing `serverless.yml` file in place.

Install the plugin:

```sh
npm install serverless-webpack --save-dev
```

Add the following sections to your `serverless.yml` file:

```yml
# serverless.yml

custom:
  webpack:
    includeModules: false

package:
    individually: true

plugins:
  - serverless-webpack
```

This specifies that separate zip files for each individual function should be created rather than one for the whole service. It also tells the plugin to not package the `node_modules` folder in the zip but instead to trust Webpack to discover all the required modules itself and bundle them into a single `.js` file.

Now create a file called `webpack.config.js` in the same folder as your `serverless.yml` file. Here's what mine typically looks like for plain JavaScript projects (Typescript requires a bit more config):

```js
// webpack.config.js
const path = require('path');
const slsw = require('serverless-webpack');

module.exports = {
  entry: slsw.lib.entries,
  target: 'node',
  mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
  stats: 'minimal',
  devtool: 'nosources-source-map',
  performance: {
    hints: false,
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json'],
  },
  output: {
    libraryTarget: 'commonjs2',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
    sourceMapFilename: '[file].map',
  },
};
```

That's all the config done.

To view the results, you can package your service without deploying by running `serverless package` in your terminal. Then open the `./.serverless` folder and look at the zip files that have been created.

## Handling edge cases
You may need to stray from the above configuration if your Lambda function references a module that is required at runtime but Webpack cannot discover it during its analysis. The most common cause of this is when the module contains dynamic requires, whereby the path string passed into the `require` statement is composed at runtime. If this is the case, you can configure `serverless-webpack` to use [forced inclusion](https://github.com/serverless-heaven/serverless-webpack#forced-inclusion) to always include specific modules in its bundle.

💌 _If you enjoyed this article, you can [sign up to my newsletter](https://winterwindsoftware.com/newsletter/). I send emails every weekday where I share my guides and deep dives on building serverless solutions on AWS with hundreds of developers and architects._

_Originally published at **[winterwindsoftware.com](https://winterwindsoftware.com/fff-webpacking-lambdas/)**_.