AWS Developer Tools Blog

Using webpack and the AWS SDK for JavaScript to Create and Bundle an Application – Part 2

In the previous post in this series, we introduced how to use webpack and the AWS SDK for JavaScript to create and bundle an application.

In this post, we’re going to dig a little bit into other features, such as creating bundles with only the AWS services you need, and generating bundles that will also run in Node.js.

Importing Individual Services

One of the benefits of using webpack is that it can parse your dependencies and include only the code your application needs. You might have noticed that in our previous project, webpack generated a bundle that was 2.38 MB. That’s because webpack is currently importing the entire AWS SDK for JavaScript based on the following statement in s3.js.

var AWS = require('aws-sdk');

We can help webpack include only the Amazon S3 service if we update our require statement to the following:

var S3 = require('aws-sdk/clients/s3');

All the AWS SDK configuration options that are available using AWS.config can also be set when instantiating a service. We can still access the AWS namespace to set global configuration across all services with the following:

var AWS = require('aws-sdk/global');

Here’s an example of what our s3.js file would look like with these changes.

s3.js

// Import the Amazon S3 service client
var S3 = require('aws-sdk/clients/s3');

// Set credentials and region
var s3 = new S3({
    apiVersion: '2006-03-01',
    region: 'REGION', 
    credentials: {/* */}
  });

/**
 * This function retrieves a list of objects
 * in a bucket, then triggers the supplied callback
 * with the received error or data
 */
function listObjects(bucket, callback) {
  s3.listObjects({
    Bucket: bucket
  }, callback);
}

// Export the handler function
module.exports = listObjects;

Now when we run npm run build, webpack reports the following:

    Version: webpack 1.13.2
    Time: 720ms
      Asset    Size  Chunks             Chunk Names
    bundle.js  797 kB     0  [emitted]  main
      [0] multi main 28 bytes {0} [built]
      [1] ./browser.js 653 bytes {0} [built]
      [2] ./s3.js 803 bytes {0} [built]
       + 155 hidden modules

Now, our generated bundle has dropped from 2.38 MB to 797 KB.

You can configure webpack to minify the generated code to reduce the final size even more!

Generating Node.js Bundles

You can use webpack to generate bundles that run in Node.js by specifying target: 'node' in the configuration. This can be useful when you’re running a Node.js application in an environment where your disk space is limited.

Let’s update our project to build a Node.js bundle by creating a file called node.js. This file will be nearly identical to browser.js, however, instead of listing S3 objects in the DOM, it will output them to the console.

node.js

// Import the listObjects function
var listObjects = require('./s3');
var bucket = 'BUCKET';
// Call listObjects on the specified bucket
listObjects(bucket, function(err, data) {
  if (err) {
    console.log(err);
  } else {
    console.log('S3 Objects in ' + bucket + ':');
    // Print the Key for each returned Object
    data.Contents.forEach(function(metadata) {
      console.log('Key: ' + metadata.Key);
    });
  }
});

Next, we’ll update our webpack.config.js to use node.js as the entry point, and add a new field, target: "node" to let webpack know it should generate a Node.js bundle.

webpack.config.js

// Import path for resolving file paths
var path = require('path');
module.exports = {
  // Specify the entry point for our app
  entry: [
    path.join(__dirname, 'node.js')
  ],
  // Specify the output file containing our bundled code
  output: {
    path: __dirname,
    filename: 'bundle.js'
  },
  // Let webpack know to generate a Node.js bundle
  target: "node",
  module: {
    /**
      * Tell webpack how to load JSON files
      * By default, webpack only knows how to handle
      * JavaScript files
      * When webpack encounters a 'require()' statement
      * where a JSON file is being imported, it will use
      * the json-loader
      */
    loaders: [
      {
        test: /.json$/, 
        loaders: ['json']
      }
    ]
  }
}

Run npm run build to generate the new bundle. You can test this code on the command line by running node bundle.js. This should output a list of S3 objects in the console!

Give It a Try!

We look forward to hearing what you think of this new support for webpack in the AWS SDK for JavaScript v2.6.1! Try it out and leave your feedback in the comments or on GitHub!