Add Support for ES6/ES7 JavaScript

From @jayair on Sat Oct 14 2017 22:30:32 GMT+0000 (UTC)

@lbybill I haven’t come across this error before but on local the AWS SDK is being used to make calls to DynamoDB. So technically if the AWS CLI works then this sls invoke local should work as well. At least I think it should.

From @kaiyes on Thu Nov 16 2017 05:58:19 GMT+0000 (UTC)

webpack is only needed locally isn’t it ? The babel runtime transpiles normal js into es6/7 syntax in lambda right ? I have babel-preset-2015 and it seems that I can use import working locally. However, app breaks in lambda when deployed. So I was wondering if adding babel-runtime in the dependency will solve issues for me ?

From @jayair on Thu Nov 16 2017 20:00:38 GMT+0000 (UTC)

@kaiyes Aside from transpiling, Babel also has a a runtime portion that is needed. It’s in our package.json here - https://github.com/AnomalyInnovations/serverless-stack-demo-api/blob/master/package.json#L32

From @kaiyes on Sat Nov 18 2017 02:00:06 GMT+0000 (UTC)

@jayair thanks. I was trying to get some answers in the forum about how webpack and bable runtime works in lambda. And I got this answer which clears it up for me.

Serverless uses the serverless-webpack plugin to run Webpack which builds the files that are uploaded to Lambda. Webpack uses TypeScript (or Babel) to compile ES7/8 code back to ES6 that’s supported by Node 6. It’s the compiled ES6 version that is being sent to Lambda and not your ES 7/8 source versions.

From what I’ve read the bable-runtime package add polyfills for missing objects and functions but it won’t help with missing syntax. That’s what the babel compiler run by Webpack handles.

Basically I am trying to get async-await and imports working in my current app and failing.

From @rogerschlachter on Tue Nov 21 2017 04:05:41 GMT+0000 (UTC)

Can this step now be simplified with the ability to create a service from a ecma template via:

serverless create --template aws-nodejs-ecma-script --path myService

From @jayair on Wed Nov 22 2017 18:30:55 GMT+0000 (UTC)

@rogerschlachter Yeah we have a similar service that we show later in the tutorial - https://serverless-stack.com/chapters/serverless-es7-service.html. The services themselves don’t do a whole lot and for now it makes sense to show folks what they are doing. But at some point we’ll switch over to this.

From @fcostarodrigo on Sat Dec 02 2017 17:38:56 GMT+0000 (UTC)

> Since ‘aws-sdk’ is not compatible with webpack, we exclude all node dependencies

This justification does not follow the description of webpack-node-externals library, which is:

When bundling with Webpack for the backend - you usually don’t want to bundle its node_modules dependencies. This library creates an externals function that ignores node_modules when bundling in Webpack.

Meaning, we don’t have to bundle the dependencies because they will be available in node_modules.

From @jayair on Sat Dec 02 2017 19:23:17 GMT+0000 (UTC)

@fcostarodrigo Replied to this here - https://github.com/AnomalyInnovations/serverless-stack-com/issues/21#issuecomment-348713844

From @SpencerGreene on Tue Dec 12 2017 02:32:23 GMT+0000 (UTC)

```
npm install --save-dev babel-preset-es2015

now yields the following:

npm WARN deprecated babel-preset-es2015@6.24.1:
:raised_hands: Thanks for using Babel: we recommend using babel-preset-env now:
please read babeljs.io/env to update!

From @jayair on Tue Dec 12 2017 17:52:28 GMT+0000 (UTC)

@SpencerGreene Thanks for letting us know I’ll switch over to it.

From @appernetic on Fri Jan 05 2018 14:23:31 GMT+0000 (UTC)

Why not use SimpleDB instead of DynamoDB? Then you have two services that only run when you have a request.

How complicated would it be to use SimpleDB for this tutorial instead?

From @jayair on Fri Jan 05 2018 21:06:52 GMT+0000 (UTC)

@appernetic We had looked into SimpleDB but it has some big limitations when you grow. Support for SimpleDB has also fallen behind for the SDK. So it isn’t a very good option to invest in, if you are just starting off.

From @appernetic on Mon Jan 08 2018 18:28:07 GMT+0000 (UTC)

@jayair Ok, thanks for the heads up. What are the big limitations when you grow?

From @appernetic on Mon Jan 08 2018 18:59:22 GMT+0000 (UTC)

I intend to use it for user data and each user has only 347 B of data. It will be read each time user signs in and written one time each month when subscription date is updated. Sounds like a perfect use case for SimpleDB.

From @appernetic on Mon Jan 08 2018 21:52:35 GMT+0000 (UTC)

I have researched both SimpleDB, DynamoDB and Aurora Serverless and DynamoDB seems to be the best option.

From @takeuchie on Thu Jan 25 2018 06:53:36 GMT+0000 (UTC)

@jayair hey man…if i want to add ‘src’ directory to store all my codes, what do i need to add or change in the webpack.config.js file …? thanks.

From @jayair on Thu Jan 25 2018 20:28:57 GMT+0000 (UTC)

@takeuchie You just need to change the line in serverless.yml where the handler is referenced with the new path. So handler: create.main changes to handler: src/create.main.

From @takeuchie on Fri Jan 26 2018 09:18:27 GMT+0000 (UTC)

@jayair thanks mate…

From @rudyhadoux on Sun Feb 25 2018 14:39:22 GMT+0000 (UTC)

I do prefer a Typescript AWS Lambda function like here :

From @Malouda on Sun Apr 01 2018 14:59:40 GMT+0000 (UTC)

Error running “serverless invoke local --function create --path mocks/create-event.json”
i get the following error

ERROR in Entry module not found: Error: Can’t resolve ‘./src’ in ‘/var/www/html/learning/notes-app-api’
here is my webpack.config.js

const slsw=require("serverless-webpack");
const nodeExternals=require("webpack-node-externals");


module.export={
    entry:slsw.lib.entries,
    target:'node',
    externals:[nodeExternals()],
    mode:slsw.lib.webpack.islocal?"development":"production",
    optimization:{
        minimize:false
    },
    performance:{
        hints:false
    },
    module:{
        rules:[
            {
                test:/\.js$/,
                loaders:['babel-loader'],
                include:__dirname,
                exclude:/node_modules/
            }
        ]
    }
};

Here is my serverless.yml

service: notes-app-api

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

# serverless-webpack configuration
# 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

  # 'iamRoleStatement' defines the permission policy for the Lambda function.
  # In this case Lambda functions are granted with permissions to access DynamoDB.
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:DescribeTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: "arn:aws:dynamodb:us-east-1:*:*"

functions:
  # Defines an HTTP API endpoint that calls the main function in create.js
  # - path: url path is /notes
  # - method: POST request
  # - cors: enabled CORS (Cross-Origin Resource Sharing) for browser cross
  #     domain api call
  # - authorizer: authenticate using the AWS IAM role
  create:
    handler: create.main
    events:
      - http:
          path: notes
          method: post
          cors: true
          authorizer: aws_iam

here is mys package.json

{
  "name": "notes-app-api",
  "version": "1.0.0",
  "description": "",
  "main": "handler.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "aws-sdk": "^2.218.1",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.4",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-stage-3": "^6.24.1",
    "serverless-webpack": "^5.1.1",
    "webpack": "^4.4.1",
    "webpack-cli": "^2.0.13",
    "webpack-node-externals": "^1.6.0"
  },
  "dependencies": {
    "babel-runtime": "^6.26.0",
    "uuid": "^3.2.1"
  }
}

here is my create.js

import uuid from "uuid";
import AWS from "aws-sdk";


AWS.config.update({region:"us-east-1"});
const dynamoDB=new AWS.DynamoDB.DocumentClient();


export function main(event,contenxt,callback){

    const data=JSON.parse(event.body);


    const params={
        TableName:"noted",
        Item:{
            userId:event.requestContext.identity.cognitoIdentityId,
            noteId:uuid.content,
            attachment:data.attachment,
            createdAt:new Date().getTime()
        }
    };


dynamoDB.put(params,(error,data)=>{
    const headers={
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Credentials": true
    };

    if(error){
        const response={
            statusCode:500,
            headers:headers,
            body:JSON.stringify({status:false})
        };

        callback(null,response);

        return;
    }

    const response={
        statusCode:200,
        headers:headers,
        body:JSON.stringify(params.Item)
    };
    callback(null,response);
});
   
}