This project demonstrates using the following technologies:
- 
AWS Lambda: AWS Lambda allows developers to deploy packages of executable JavaScript code to the AWS infrastructure and make it executable without having to worry about managing servers. 
- 
webpack: webpackis used to create optimized bundles from JavaScript code that leverage ES6 modules.
- 
babel: babeltranspiles JavaScript code to JavaScript code that is compatible with various runtimes.
- 
TypeScript: TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. 
- 
bunyan: bunyanprovides structured JSON logging.
- 
ava: avais a test runner.
- 
tslint: tslintis a TypeScript linter.
- 
yarn: yarnis a dependency manager that is an alternative tonpm.
- 
nyc: nycprovides a command-line interface for calculating test code coverage with istanbul.
- 
chalk: chalkis used to add color to console output.
- 
proxyquire: proxyquireis used to substitute mock modules at runtime when running tests.
Clone this repo and make changes as you see fit. Push your changes to your own repo.
- 
Allow developers to use TypeScript for lambda functions, tests, and other source code. 
- 
Also allow JavaScript files to be used (hopefully sparingly). 
- 
Automatically compile JavaScript code related to AWS Lambda functions down to level supported by node6.10(which is currently the latest Node.js runtime that AWS lambda supports).
- 
Calculate test code coverage using nycwhen running tests usingava.
- 
Create a bundle using webpackfor each AWS Lambda function located atsrc/lambdas/*.
- 
Create a server and relaunch when file changes (this is not necessary due to the nature of testing and deploying lambda functions). 
- 
Provide a starter project that works for everyone. 
- 
Provide deployment scripts (use something like terraform, CloudFormation, or aws-cli if you need to deploy lambda functions). 
- 
yarn test: Use this command to lint, compiletest/**/*files with TypeScript, and run tests withavaandnyc. We use the following glob pattern for unit tests:test/**/*.test.js.
- 
yarn build: Use this command to compile the lambda functions.
- 
yarn bundle: Use this command to build the lambda functions and then create zip files atwork/dist/*.zip.
- 
yarn lint: Use this command to lint thesrc/**/*andtest/**/*files withtslint(does not require compilation).
This starter project uses require-self-ref
to make it possible to require/import relative to the root of the project.
For example, import { sleep } from '~/src/util' will always import
the sleep function from src/util/index.ts no matter which file
the import file is found in.
In the webpack configuration we provide an resolve.alias property
that automatically resolves ~/* paths relative to the root of the project.
In the tsc (TypeScript compiler) configuration, we use a combination of
the compilerOptions.baseUrl and compilerOptions.paths properties to
configure how ~/* paths are resolved.
At runtime, all test files include import 'require-self-ref' which
loads the require-self-ref module which tweaks the Node.js module
loader so that ~/* paths are properly resolved at runtime. It's
not necessary to use require-self-ref for lambda functions because
the webpack bundling job will automatically inline all modules into
a single bundle.
TypeScript was chosen because it helps developers write code with more compile-time safety checks via it's flexible and powerful static typing.
This project provides multiple TypeScript configuration files and their usage is explained below.
- 
tsconfig.json: This TypeScript configuration file is used by IDEs such as Visual Studio Code and Atom Editor. Theincludesfor this configuration includesrc/**/*andtest/**/*.The compilation scripts in this project do not use this configuration when compiling files because the output settings for testandsrcare different.
- 
tsconfig-test.json: This TypeScript configuration file is used to compile files intest/directory and themoduleoutput setting iscommonjsso that they can be executed directly by Node.js runtime without having to be bundled or transpiled withwebpackandbabel.
- 
tsconfig-src.json: This TypeScript configuration file is used to compile files insrc/directory and themoduleoutput setting isES6and the output files cannot be executed directly by Node.js. It is assumed thatwebpackandbabelwill be used to create a JavaScript bundle that targets the Node.js runtime supported by AWS Lambda.
The webpack tool is used to create an
optimized bundle for each lambda function located at src/lambdas/.
The webpack tool is invoked via yarn webpack which cause webpack to
use the default configuration located at webpack.config.json.
This project does not use webpack to process code in the test/*
directory when running tests. The test code is only compiled by
the TypeScript compiler (tsc). The source files in test/* are
compiled from TypeScript down to commonjs modules so that they can be
loaded directly by the Node.js runtime.
NOTE: In earlier versions of this starter project, we tried to use
rollup but rollup poorly handled transforming JavaScript files
that had both ES6 import/export statements and CommonJS require(...)
statements in the same file.
In our use case, we wanted to be able to require(...) normal JavaScript files
and use import/export for ES6 modules created from TypeScript compiler.
That is, in our use case a single JavaScript file compiled from TypeScript
file might have a mix of import/export and require(...) statements.
When the rollup-plugin-commonjs
plugin saw import/export in a file then it didn't bother traversing
the require(...) statements (because it assumed that you don't mix
both in the same file). This caused code referenced in these require(...)
statements to not be bundled properly.
The webpack configuration for each lambda function is dynamically produced
inside webpack.config.js. webpack will automatically create a bundle as
described by the entry property. The entry property value is an object in
which each key is a bundle name and each associated value is the entry point
file.
The babel transpiler is integrated with webpack via babel-loader plugin.
This project is only configured to use babel when creating the AWS lambda
bundle files because we need to transpile all JavaScript files so that they
are compatible with the Node.js runtime supported by AWS Lambda. Currently,
the highest Node.js version supported bye AWS Lambda is node 6.10.
The babel configuration is embedded inside the webpack configuration which
allows flexibility in the future for having multiple babel configurations
for the various output targets.
The babel-preset-env package provides presets for babel that can be
used to target specific runtime environments (for example, node 6.10).
The babel configuration is provided via the options property of the
babel-loader plugin in webpack.config.js and it looks like the following:
{
  presets: [
    [
      'env',
      {
        // Latest Node.js runtime for AWS Lambda functions is currently 6.10
        targets: {
          node: '6.10'
        },
        modules: false
      }
    ]
  ],
  plugins: [
    'external-helpers'
  ]
}This project uses bunyan because it uses structured JSON logging.
Bunyan loggers are created and configured when they are created via
the createLogger function of src/logging/index.ts.
This project provides a yarn.lock file and uses yarn as its package manager.
If you prefer npm then delete the yarn.lock file and run npm install
which will create a package-lock.json file.
All source code for this project is provided under the MIT License.
See LICENSE file.
If you see ways to improve this project then please create a Pull Request or an Issue.