How to create an OpenJS Architect serverless app with Babel and Rollup
by Brian Leroux
@brianleroux
on
In this article we’ll set up an OpenJS Architect project that uses Babel and Rollup to take advantage of next-generation and experimental JS syntax features. Future editions will explore TypeScript and JSX.
Other articles in this series you may be interested in:
- How to create a bundler-free Architect app with Babel
- How to create an Architect app with TypeScript
Let’s get started! First:
npm init @architect ./myapp
The Architect init script generated one Lambda function in src/http/get-index/index.js
which we’ll overwrite with code generated by Babel.
For now, define a new JS entry file at src/http/get-index/entry.js
. Here’s a basic handler with some modern syntax:
// src/http/get-index/entry.js
export async function handler(req) {
let response = `
<h1>Test Babel</h1>
<pre>
<b>req?.queryStringParameters?.foo</b> ${req?.queryStringParameters?.foo}
</pre>
<hr>
<pre>${JSON.stringify(req, null, 2)}</pre>
`
return {
headers: {
'content-type': 'text/html; charset=utf8'
},
body: response
}
}
Notice: we’re using ES modules syntax! This is not something the default Node.js runtime for Lambda can do natively… yet!
Install Babel
Babel is extremely configurable and can be extended much farther than the scope of this tutorial; these are the minimal dependencies required.
npm i @babel/core @babel/preset-env core-js
Bonus: add the optional chaining plugin!
npm i @babel/plugin-proposal-optional-chaining
Install Rollup
Rollup creates the smallest possible bundle, which is also nice for cloud function coldstarts. We add it and a few plugins for making module interop less of a headache:
npm i rollup rollup-plugin-babel rollup-plugin-commonjs rollup-plugin-node-resolve
Configure Rollup
The final boss (already)! We need to configure Rollup to transpile entry.js into index.js. This way both local dev and live deployment will work as we’d expect them to.
// rollup.config.js
import babel from 'rollup-plugin-babel'
import resolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs'
export default {
input: 'src/http/get-index/entry.js',
output: {
file: 'src/http/get-index/index.js',
format: 'cjs'
},
plugins: [
resolve(),
babel({
exclude: 'node_modules/**',
presets: [[
'@babel/env', {
modules: 'false',
targets: {node: 10},
useBuiltIns: 'usage',
corejs: 3
}
]],
plugins: ["@babel/plugin-proposal-optional-chaining"]
}),
commonjs()
]
}
We won’t dig into the config too much, but you’re certainly welcome to! Suffice to say, this will generate a CommonJS module that AWS Lambda can run.
Configure npm scripts
Add the classic npm start
and npm run build
commands:
"scripts": {
"build": "npx rollup -c",
"start": "npm run build && npx arc sandbox",
"deploy": "npm run build && npx arc deploy"
},
Work locally, then deploy to AWS when you’re happy with your app
Set up CI/CD
Now that everything is working locally we can set up Begin to deploy our code from GitHub whenever we commit. Login to Begin with your GitHub account, click New app
, and scroll to the big Import app
button. (My first build was completed in 11.474 seconds!)
You can use the GitHub repo brianleroux/arc-example-babel to get started.
That’s it!
Now you’re up and running with some serverless Babel. Here’s another example of enabling optional chaining on a request object’s queryStringParameter
property — something that would normally require nested accessors:
req.queryStringParameters && req.queryStringParameters.foo
no more!
You can find the full source code for this tutorial here.
Stay tuned: we’ll look at combining AWS Lambda with TypeScript and JSX next!
Next steps
- Sign up for Begin.com, score your username, and make an app!
- Star architect/architect on GitHub! 🌟