Skip to content

Commit

Permalink
Upgrading to use starter and Node v8.10 (sst#222)
Browse files Browse the repository at this point in the history
* Updating to use starter

* Editing
  • Loading branch information
jayair committed Apr 11, 2018
1 parent 27bd47b commit dc134bf
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 104 deletions.
9 changes: 5 additions & 4 deletions _chapters/add-a-create-note-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,12 @@ Now let's define the API endpoint for our function.
``` yaml
service: notes-app-api

# Use serverless-webpack plugin to transpile ES6/ES7
# Use the serverless-webpack plugin to transpile ES6
plugins:
- serverless-webpack
- serverless-offline

# Configuration for serverless-webpack
# serverless-webpack configuration
# Enable auto-packing of external modules
custom:
webpack:
Expand All @@ -106,7 +107,7 @@ custom:

provider:
name: aws
runtime: nodejs6.10
runtime: nodejs8.10
stage: prod
region: us-east-1

Expand Down Expand Up @@ -250,7 +251,7 @@ export function call(action, params) {

Here we are using the promise form of the DynamoDB methods. Promises are a method for managing asynchronous code that serve as an alternative to the standard callback function syntax. It will make our code a lot easier to read.

<img class="code-marker" src="/assets/s.png" />Now, we'll go back to our `create.js` and use the helper functions we created. Our `create.js` should now look like the following.
<img class="code-marker" src="/assets/s.png" />Now, we'll go back to our `create.js` and use the helper functions we created. Replace our `create.js` with the following.

``` javascript
import uuid from "uuid";
Expand Down
2 changes: 2 additions & 0 deletions _chapters/add-a-get-note-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ This follows exactly the same structure as our previous `create.js` function. Th
authorizer: aws_iam
```
Make sure that this block is indented exactly the same way as the preceding `create` block.

This defines our get note API. It adds a GET request handler with the endpoint `/notes/{id}`.

### Test
Expand Down
96 changes: 47 additions & 49 deletions _chapters/add-support-for-es6-es7-javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,68 @@ layout: post
title: Add Support for ES6/ES7 JavaScript
date: 2016-12-29 12:00:00
redirect_from: /chapters/add-support-for-es6-javascript.html
description: AWS Lambda supports Node.js 6.10 and so to use async/await and other ES6/ES7 features in our Serverless Framework project we need to use Babel and Webpack 4 to transpile our code. We can do this by adding the serverless-webpack plugin to our project and setting it up to automatically transpile our handler functions.
description: AWS Lambda supports Node.js v8.10 and so to use ES import/exports in our Serverless Framework project we need to use Babel and Webpack 4 to transpile our code. We can do this by using the serverless-webpack plugin to our project. We will use the serverless-nodejs-starter to set this up for us.
context: backend
code: backend
comments_id: 22
---

By default, AWS Lambda only supports a specific version of JavaScript. It doesn't have an up-to-date Node.js engine. And looking a bit further ahead, we'll be using a more advanced flavor of JavaScript with ES6/ES7 features. So it would make sense to follow the same syntax on the backend and have a transpiler convert it to the target syntax. This would mean that we won't need to worry about writing different types of code on the backend or the frontend.
AWS Lambda recently added support for Node.js v8.10. The supported syntax is a little different compared the frontend React app that we'll be working on a little later. It makes sense to use similar ES features. Specifically, we'll be relying on ES import/exports in our handler functions. To do this we will be transpiling our code using [Babel](https://babeljs.io) and [Webpack 4](https://webpack.github.io). Serverless Framework supports plugins to do this automatically. We are going to use the [serverless-webpack](https://github.com/serverless-heaven/serverless-webpack) plugin.

In this chapter, we are going to enable ES6/ES7 for AWS Lambda using the Serverless Framework. We will do this by setting up [Babel](https://babeljs.io) and [Webpack](https://webpack.github.io) 4 to transpile and package our project. If you would like to code with AWS Lambda's default JavaScript version, you can skip this chapter. But you will not be able to directly use the sample code in the later chapters, as they are written in ES6 syntax.
All this has been added in the previous chapter using the [`serverless-nodejs-starter`]({% link _chapters/serverless-nodejs-starter.md %}). We created this starter for a couple of reasons:

### Install Babel and Webpack
- Use a similar version of JavaScript in the frontend and backend
- Ensure transpiled code still has the right line numbers for error messages
- Allow you to run your backend API locally
- And add support for unit tests

<img class="code-marker" src="/assets/s.png" />At the root of the project, run.
If you recall we installed this starter using the `serverless install --url https://github.com/AnomalyInnovations/serverless-nodejs-starter --name my-project` command. This is telling Serverless Framework to use the [starter](https://github.com/AnomalyInnovations/serverless-nodejs-starter) as a template to create our project.

``` bash
$ npm install --save-dev \
babel-core \
babel-loader \
babel-plugin-transform-runtime \
babel-preset-env \
babel-preset-stage-3 \
serverless-webpack \
webpack \
webpack-node-externals
In this chapter, let's quickly go over how it is doing this. So you'll be able to make changes to this in the future if you need to.

$ npm install --save babel-runtime
### Serverless Webpack

The transpiling process of converting our ES code to Node v8.10 JavaScript is done by the serverless-webpack plugin. This plugin was added in our `serverless.yml`. Let's take a look at it in more detail.

<img class="code-marker" src="/assets/s.png" />Open `serverless.yml` and replace the default with the following.

``` yaml
service: notes-app-api

# Use the serverless-webpack plugin to transpile ES6
plugins:
- serverless-webpack
- serverless-offline

# serverless-webpack configuration
# Enable auto-packing of external modules
custom:
webpack:
webpackConfig: ./webpack.config.js
includeModules: true

provider:
name: aws
runtime: nodejs8.10
stage: prod
region: us-east-1
```
Most of the above packages are only needed while we are building our project and they won't be deployed to our Lambda functions. We are using the `serverless-webpack` plugin to help trigger the Webpack build when we run our Serverless commands. The `webpack-node-externals` is necessary because we do not want Webpack to bundle our `aws-sdk` module, since it is not compatible.
The `service` option is pretty important. We are calling our service the `notes-app-api`. Serverless Framework creates your stack on AWS using this as the name. This means that if you change the name and deploy your project, it will create a completely new project.

You'll notice the `serverless-webpack` plugin that is included. We also have a `webpack.config.js` that configures the plugin.

<img class="code-marker" src="/assets/s.png" />Create a file called `webpack.config.js` in the root with the following.
Here is what your `webpack.config.js` should look like. You don't need to make any changes to it. We are just going to take a quick look.

``` javascript
``` js
const slsw = require("serverless-webpack");
const nodeExternals = require("webpack-node-externals");
module.exports = {
entry: slsw.lib.entries,
target: "node",
// Generate sourcemaps for proper error messages
devtool: 'source-map',
// Since 'aws-sdk' is not compatible with webpack,
// we exclude all node dependencies
externals: [nodeExternals()],
Expand All @@ -68,45 +91,20 @@ module.exports = {
};
```

This is the configuration Webpack will use to package our app. The main part of this config is the `entry` attribute that we are automatically generating using the `slsw.lib.entries` that is a part of the `serverless-webpack` plugin. This automatically picks up all our handler functions and packages them.
The main part of this config is the `entry` attribute that we are automatically generating using the `slsw.lib.entries` that is a part of the `serverless-webpack` plugin. This automatically picks up all our handler functions and packages them. We also use the `babel-loader` on each of these to transpile our code. One other thing to note here is that we are using `nodeExternals` because we do not want Webpack to bundle our `aws-sdk` module. Since it is not compatible with Webpack.

Note that, you won't have to do this for your new projects, we created a [starter project]({% link _chapters/serverless-nodejs-starter.md %}) for you to use without any of the configuration.

<img class="code-marker" src="/assets/s.png" />Next create a file called `.babelrc` in the root with the following.
Finally, let's take a quick look at our Babel config. Again you don't need to change it. Just open the `.babelrc` file in your project root. It should look something like this.

``` json
{
"plugins": ["transform-runtime"],
"plugins": ["source-map-support", "transform-runtime"],
"presets": [
["env", { "node": "6.10" }],
["env", { "node": "8.10" }],
"stage-3"
]
}
```

The presets are telling Babel the type of JavaScript we are going to be using.

<img class="code-marker" src="/assets/s.png" />Open `serverless.yml` and replace it with the following.

``` yaml
service: notes-app-api

# Use serverless-webpack plugin to transpile ES6/ES7
plugins:
- serverless-webpack

# Configuration for serverless-webpack
# Enable auto-packing of external modules
custom:
webpack:
webpackConfig: ./webpack.config.js
includeModules: true

provider:
name: aws
runtime: nodejs6.10
stage: prod
region: us-east-1
```
Here we are telling Babel to transpile our code to target Node v8.10.

And now we are ready to build our backend.
16 changes: 3 additions & 13 deletions _chapters/create-a-new-reactjs-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,18 @@ comments_id: 29

Let's get started with our frontend. We are going to create a single page app using [React.js](https://facebook.github.io/react/). We'll use the [Create React App](https://github.com/facebookincubator/create-react-app) project to set everything up. It is officially supported by the React team and conveniently packages all the dependencies for a React.js project.

### Install Create React App

<img class="code-marker" src="/assets/s.png" />Move out of the directory that we were working in for the backend.

``` bash
$ cd ../
```

<img class="code-marker" src="/assets/s.png" />Create a new project in directory separate from the backend. Run the following command.

``` bash
$ npm install -g create-react-app
```

This installs the Create React App NPM package globally.

### Create a New App
### Create a New React App

<img class="code-marker" src="/assets/s.png" />From your working directory, run the following command to create the client for our notes app.
<img class="code-marker" src="/assets/s.png" />Run the following command to create the client for our notes app.

``` bash
$ create-react-app notes-app-client
$ npx create-react-app notes-app-client
```

This should take a second to run, and it will create your new project and your new working directory.
Expand Down
11 changes: 5 additions & 6 deletions _chapters/serverless-nodejs-starter.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ layout: post
title: Serverless Node.js Starter
redirect_from: /chapters/serverless-es7-service.html
date: 2017-05-30 00:00:00
description: A Serverless Node.js starter project that adds support for ES6/ES7 async/await methods and unit tests to your Serverless Framework project.
description: A Serverless Node.js starter project that adds support for ES6/ES7 async/await methods, import/export, and unit tests to your Serverless Framework project.
context: all
comments_id: 72
---

Now that we know how to set our Serverless projects up, it makes sense that we have a good starting point for our future projects. For this we created a couple of Serverless starter projects that you can use called, [Serverless Node.js Starter](https://github.com/AnomalyInnovations/serverless-nodejs-starter). We also have a Python version called [Serverless Python Starter](https://github.com/AnomalyInnovations/serverless-python-starter). Our starter projects also work really well with [Seed](https://seed.run); a fully-configured CI/CD pipeline for Serverless Framework.
Based on what we have gone through in this guide, it makes sense that we have a good starting point for our future projects. For this we created a couple of Serverless starter projects that you can use called, [Serverless Node.js Starter](https://github.com/AnomalyInnovations/serverless-nodejs-starter). We also have a Python version called [Serverless Python Starter](https://github.com/AnomalyInnovations/serverless-python-starter). Our starter projects also work really well with [Seed](https://seed.run); a fully-configured CI/CD pipeline for Serverless Framework.

[Serverless Node.js Starter](https://github.com/AnomalyInnovations/serverless-nodejs-starter) uses the [serverless-webpack](https://github.com/serverless-heaven/serverless-webpack) plugin, the [serverless-offline](https://github.com/dherault/serverless-offline) plugin, [Babel](https://babeljs.io), and [Jest](https://facebook.github.io/jest/). It supports:

- **Use async/await in your handler functions**
- **Use ES7 syntax in your handler functions**
- **Package your functions using Webpack**
- **Run API Gateway locally**
- Use `serverless offline start`
- **Support for unit tests**
Expand Down Expand Up @@ -57,7 +58,7 @@ const message = ({ time, ...rest }) => new Promise((resolve, reject) =>

### Installation

To create a new Serverless project with ES7 support.
To create a new Serverless project.

``` bash
$ serverless install --url https://github.com/AnomalyInnovations/serverless-nodejs-starter --name my-project
Expand Down Expand Up @@ -117,5 +118,3 @@ To add environment variables to your project
4. Make sure to not commit your `env.yml`.

So give it a try and send us an [email](mailto:contact@anoma.ly) if you have any questions or open a [new issue](https://github.com/AnomalyInnovations/serverless-nodejs-starter/issues/new) if you've found a bug.


42 changes: 14 additions & 28 deletions _chapters/setup-the-serverless-framework.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@ In this chapter, we are going to set up the Serverless Framework on our local de

### Install Serverless

<img class="code-marker" src="/assets/s.png" />Create a directory for our API backend.

``` bash
$ mkdir notes-app-api
$ cd notes-app-api
```

<img class="code-marker" src="/assets/s.png" />Install Serverless globally.

``` bash
Expand All @@ -31,33 +24,36 @@ $ npm install serverless -g

The above command needs [NPM](https://www.npmjs.com), a package manager for JavaScript. Follow [this](https://docs.npmjs.com/getting-started/installing-node) if you need help installing NPM.

<img class="code-marker" src="/assets/s.png" />At the root of the project; create an AWS Node.js service.
<img class="code-marker" src="/assets/s.png" />In your working directory; create a project using a Node.js starter. We'll go over some of the details of this starter project in the next chapter.

``` bash
$ serverless create --template aws-nodejs
$ serverless install --url https://github.com/AnomalyInnovations/serverless-nodejs-starter --name notes-app-api
```

Now the directory should contain the two following files, namely **handler.js** and **serverless.yml**.
<img class="code-marker" src="/assets/s.png" />Go into the directory for our backend api project.

``` bash
$ ls
handler.js serverless.yml
$ cd notes-app-api
```

Now the directory should contain a few files including, the **handler.js** and **serverless.yml**.

- **handler.js** file contains actual code for the services/functions that will be deployed to AWS Lambda.
- **serverless.yml** file contains the configuration on what AWS services Serverless will provision and how to configure them.

### Install AWS Related Dependencies
We also have a `tests/` directory where we can add our unit tests.

### Install Node.js packages

The starter project relies on a few dependecies that are listed in the `package.json`.

<img class="code-marker" src="/assets/s.png" />At the root of the project, run.

``` bash
$ npm init -y
$ npm install
```

This creates a new Node.js project for you. This will help us manage any dependencies our project might have.

<img class="code-marker" src="/assets/s.png" />Next, install these two packages.
<img class="code-marker" src="/assets/s.png" />Next, we'll install a couple of other packages specifically for our backend.

``` bash
$ npm install aws-sdk --save-dev
Expand All @@ -67,14 +63,4 @@ $ npm install uuid --save
- **aws-sdk** allows us to talk to the various AWS services.
- **uuid** generates unique ids. We need this for storing things to DynamoDB.

Now the directory should contain three files and one directory.

``` bash
$ ls
handler.js node_modules package.json serverless.yml
```

- **node_modules** contains the Node.js dependencies that we just installed.
- **package.json** contains the Node.js configuration for our project.

Next, we are going to set up a standard JavaScript environment for us by adding support for ES6.
The starter project that we are using allows us to use the version of JavaScript that we'll be using in our frontend app later. Let's look at exactly how it does this.
10 changes: 6 additions & 4 deletions _chapters/test-the-apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ To be able to hit our API endpoints securely, we need to follow these steps.

These steps can be a bit tricky to do by hand. So we created a simple tool called [AWS API Gateway Test CLI](https://github.com/AnomalyInnovations/aws-api-gateway-cli-test).

You can install it by running the following.
You can run it using.

``` bash
$ npm install -g aws-api-gateway-cli-test
$ npx aws-api-gateway-cli-test
```

The `npx` command is just a convenient way of running a NPM module without installing it globally.

We need to pass in quite a bit of our info to complete the above steps.

- Use the username and password of the user created in the [Create a Cognito test user]({% link _chapters/create-a-cognito-test-user.md %}) chapter.
Expand All @@ -34,7 +36,7 @@ We need to pass in quite a bit of our info to complete the above steps.
And run the following.

``` bash
$ apig-test \
$ npx aws-api-gateway-cli-test \
--username='admin@example.com' \
--password='Passw0rd!' \
--user-pool-id='YOUR_COGNITO_USER_POOL_ID' \
Expand All @@ -53,7 +55,7 @@ While this might look intimidating, just keep in mind that behind the scenes all
If you are on Windows, use the command below. The space between each option is very important.

``` bash
$ apig-test --username admin@example.com --password Passw0rd! --user-pool-id YOUR_COGNITO_USER_POOL_ID --app-client-id YOUR_COGNITO_APP_CLIENT_ID --cognito-region YOUR_COGNITO_REGION --identity-pool-id YOUR_IDENTITY_POOL_ID --invoke-url YOUR_API_GATEWAY_URL --api-gateway-region YOUR_API_GATEWAY_REGION --path-template /notes --method POST --body "{\"content\":\"hello world\",\"attachment\":\"hello.jpg\"}"
$ npx aws-api-gateway-cli-test --username admin@example.com --password Passw0rd! --user-pool-id YOUR_COGNITO_USER_POOL_ID --app-client-id YOUR_COGNITO_APP_CLIENT_ID --cognito-region YOUR_COGNITO_REGION --identity-pool-id YOUR_IDENTITY_POOL_ID --invoke-url YOUR_API_GATEWAY_URL --api-gateway-region YOUR_API_GATEWAY_REGION --path-template /notes --method POST --body "{\"content\":\"hello world\",\"attachment\":\"hello.jpg\"}"
```

If the command is successful, the response will look similar to this.
Expand Down
2 changes: 2 additions & 0 deletions _includes/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@

<p class="site-description">Learn to Build Full-Stack Apps with Serverless and React on AWS</p>

<!--
<a class="site-announcement" target="_blank" href="{{ site.github_repo }}{{ site.github_issues_prefix }}193">
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i> We recently updated our guide. Read about it here.
</a>
-->

</div>

Expand Down

0 comments on commit dc134bf

Please sign in to comment.