Search code examples
javascriptbrowserifywebpackaws-lambdasystemjs

How do I build a single js file for AWS Lambda nodejs runtime


We are working on a project/framework that aids in deploying and maintaining code in AWS Lambda. I want to build/bundle all node.js code for a lambda function into one js file because:

  • Smaller codebases help with lambda cold start issues
  • Lambda has code zip size limit of 50MB

We don't want to create a custom bundler to do this because there are many options already out there (systemjs,browserify,webpack etc). HOWEVER we are concerned with issues with some node modules not playing well with bundlers/builders.

Specifically aws-sdk has known issues with webpack, says it has browserify support but I've talked to people who have had issues with browserify'ing aws-sdk

We want to pick an existing bundler (or 2), but we want to make sure it works for as many modules/code as possible. We are trying to create a plugin ecosystem for JAWS, so getting this right is important (don't want to turn people off because module X they use wont bundle).

Questions:

  1. How would I go about bundling/building to satisfy these constraints?
  2. Is there any guidelines we can give to consumers of our product to ensure the code they write/use will bundle? Ex: Dynamic require()s cause issues AFAIK.

Solution

  • aws-sdk-js now officially supports browserify. You can why this is a great thing on my blog.

    I have created a serverless plugin called serverless-plugin-browserify that will do all the heavy lifting with very minimal configuration.

    To answer the question specifically, I solved the problem with this browserify config:

    {
      disable: false, //Not an official option, used as internal option to skip browserify
      exclude: [],    //Not an option, but will use for setting browserify.exclude() if defined in yml
      ignore:  [],    //Not an option, but will use for setting browserify.ignore() if defined in yml
    
      basedir:          this.serverless.config.servicePath,
      entries:          [],
      standalone:       'lambda',
      browserField:     false,  // Setup for node app (copy logic of --node in bin/args.js)
      builtins:         false,
      commondir:        false,
      ignoreMissing:    true,  // Do not fail on missing optional dependencies
      detectGlobals:    true,  // We don't care if its slower, we want more mods to work
      insertGlobalVars: {      // Handle process https://github.com/substack/node-browserify/issues/1277
        //__filename: insertGlobals.lets.__filename,
        //__dirname: insertGlobals.lets.__dirname,
        process: function() {
        },
      },
      debug:            false,
    }
    

    You can see my full code here with a complete example here