The AWS JavaScript SDK is a fantastic tool to leverage the power of the AWS services. All the features provided by the cloud giant are accesible through it. And now, after version 2.6.1 it supports webpack, which makes creating bundles of it a breeze. With webpack, we can only include the bits and pieces we need for our application. Want to add a way to upload files to S3? Ineract directly with DynamoDB? Push notification to other clients through SNS? Just add the client you need and start coding. Webpack will trim away all the unnecessary code, leaving our bundle JavaScript as slim as possible.
The best source to undestand the capabilities of the SDK is through it main documentation site. All the information for all AWS serices are listed on it. As the documentation states:
All requests made through the SDK are asynchronous and use a callback interface.
So we need a way to handle this asynchronous behaviour of the SDK. That is why AWS provides us with the AWS.Request class.
Each service method that kicks off a request returns an AWS.Request object that you can use to register callbacks.
This class offers a lot of ways to handle the responses from each AWS services. So we can use the one which makes more sense for us or the project.
In this article, I want to explore through some examples the different ways the AWS.Request class can help us command AWS services. First we'll setup a simple project using hjs-webpack
to simplify the creation of webpack's configuration file. We'll then import the AWS SDK and configure it with our credentials. After that is done, we'll create a simple html page from where we'll interact with some AWS services. If you want to follow along you can clone each step from the project repo.
Let's init a new npm
project to keep track of all our dependencies. We'll also use npm
scripts to run and build our app.
npm init
As I mentioned on the introduction, we'll be using hjs-webpack
to simplify webpack's configuration. This package was created by Henrik Joreteg as an opinionated way to build apps with webpack. I sugges you give it a try if you don't know it. It is not needed to work with the AWS SDK, you can just use webpack as you normally do if you want.
So, let's install through npm the hjs-webpack
module and some other necessary dependencies.
npm install --save-dev hjs-webpack css-loader postcss-loader style-loader autoprefixer babel-core babel-loader json-loader webpack-visualizer-plugin babel-preset-es2015 babel-preset-react babel-preset-react-hmre
To handle the visual layer of the project we'll use React. Since this is not meant to be a React article I'll try to add all the code necessary to run the app without issues and try to explain some of the implementation details when needed. If you have any question just ask me directly, or check React's documentation. Add react
and react-dom
to the project through npm and save the dependencies to our package.json
file:
npm install --save react react-dom
Let's configure babel to use es2015
and react
presets and to handle Hot Module Replacement. Create a file on your project's root called .babelrc
and include the following code:
{
"presets": ["es2015", "react"],
"env": {
"development": {
"presets": ["react-hmre"]
}
}
}
We are ready to build our webpack configuration using hjs-webpack
. Let's create a file called webpack.config.js
and add the following configuration:
https://gist.github.com/guzmonne/9767a7ee81edff27630adef5e7f88833
Note that we are adding the Visualizer
plugin to see how each dependency influence the final size of our bundle. You can see the results by checking the stats.html
file on the public
folder after every build.
To run our dev server and build our project we'll add a couple of entries to the scripts section of our package.json
config.
{
...
"scripts": {
...
"start": "hjs-dev-server",
"build": "webpack"
}
...
}
We also have to create the src/index.js
and src/app.js
files to have something to render on the page. Add these files to the a new src
folder:
https://gist.github.com/guzmonne/73fd197ddec3bace834772e173767ded
https://gist.github.com/guzmonne/1bec8905f2ec609c4dd68a5b279021dc
The dev server can be run using our start
npm script. Use the command npm start
on your console to start the development server. If you now go to http://localhost:3000 you'll be greeted to a typical "Hello, World" page. Try modifing the content of the h1
inside the App
component. You should see how webpack takes the changes and updates the page accordingly without doing a full page reload.
We can also build this project using the npm run build
command from the console, to see the initial size of our bundle and to check that everything is working fine. After running the command you should see a similar output to the following:
Hash: f5a6e184bfaed9e0ec25
Version: webpack 1.13.3
Time: 4386ms
Asset Size Chunks Chunk Names
app.js 189 kB 0 [emitted] main
index.html 203 bytes [emitted]
stats.html 547 kB [emitted]
[0] multi main 28 bytes {0} [built]
+ 324 hidden modules
The initial size of our file is 189 KB. Which is quite a lot since we have bundled React along our components. It is beyond the scope of this article to explore the different tools provided by webpack to decrease the bundle final size. Nonetheless we'll use this initial filesize to see how the different ways of adding the AWS SDK impact the size of our bundle.
AWS JavaScript SDK is available through npm. So we can add it to the project as we did before:
npm install --save aws-sdk
The AWS JavaScript can be added to our project by to means:
- import the entire
aws-sdk
and then instantiate the necessary clients from it. - import the necessary sdk clients for our app.
Let's say that for this particular project we are going to use AWS SNS, S3, and DynamoDB services. So let's check hoy both ways affect our final bundle. We'll create two modules with the needed config. Then we'll add one to our index.js
before building our app. After the build process finishes, we'll do the same with the other module and finnaly we'll compare the results.
https://gist.github.com/guzmonne/ed90b45b190452dc99a44c14c99eb8ed
https://gist.github.com/guzmonne/d898cc131f0a4870d65cfee032ed0a6b
Here is the output for both builds:
# With the first method
Hash: f2080b91e2e72fbca5f4
Version: webpack 1.13.3
Time: 10957ms
Asset Size Chunks Chunk Names
app.js 1.39 MB 0 [emitted] main
index.html 203 bytes [emitted]
stats.html 805 kB [emitted]
[0] multi main 28 bytes {0} [built]
+ 667 hidden modules
---
# With the second method
Hash: dd28606fc47261526ac5
Version: webpack 1.13.3
Time: 7715ms
Asset Size Chunks Chunk Names
app.js 512 kB 0 [emitted] main
index.html 203 bytes [emitted]
stats.html 669 kB [emitted]
[0] multi main 28 bytes {0} [built]
+ 489 hidden modules
I think it is pretty clear that the second method is way better to handle our bundle size. It is still quite large compared to our starting bundle but more than half of what you get using with the first method.