Skip to content

Commit

Permalink
Merge pull request #17 from serverless-stack/alpha
Browse files Browse the repository at this point in the history
Adding `sst start`, a local dev environment for Lambda
  • Loading branch information
jayair committed Jan 12, 2021
2 parents 0f03451 + 8d44665 commit 0907b18
Show file tree
Hide file tree
Showing 180 changed files with 7,591 additions and 12,606 deletions.
13 changes: 12 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
# Don't ever lint node_modules
node_modules

# Don't lint build output (make sure it's set to your correct build folder name)
dist

# Don't lint nyc coverage output
coverage

# Don't lint cdk.out
cdk.out

# Don't lint build outputs in test
/packages/cli/test/*/build/**
/packages/cli/test/*/.build/**
/packages/cli/test/*/cdk.out/**

# Don't lint templates
/packages/create-serverless-stack/templates/**

# Don't lint eslint tests that need to fail
/packages/cli/test/eslint-ignore/**
/packages/cli/test/eslint-ts/**
/packages/cli/test/eslint/**
/packages/cli/test/lambda-override-tsconfig/**
/packages/cli/test/lambda-override-eslintrc/**
/packages/cli/test/start/src/**
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name: CI

on:
push:
branches: [ master ]
branches: [ master, alpha ]
pull_request:
branches: [ master ]

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,8 @@ dist
# TernJS port file
.tern-port

# CDK
cdk.out

# Vim
.*.sw*
5 changes: 4 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Ignore CDK outputs
cdk.out
# Ignore SST outputs
.build
# Ignore templates
/packages/create-serverless-stack/templates/**

178 changes: 128 additions & 50 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"packages": ["packages/*"],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.4.5"
"version": "1.0.0-alpha.12"
}
21 changes: 15 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,32 @@
"license": "MIT",
"private": true,
"workspaces": [
"packages/*"
"packages/*",
"packages/cli/test/*"
],
"scripts": {
"lint": "eslint . --fix --ext .js,.ts",
"npm-publish": "lerna publish --force-publish",
"prettier": "prettier --write **/*.{js,ts,json,md}",
"changelog": "lerna-changelog",
"release": "lerna publish --force-publish",
"release-alpha": "lerna publish --force-publish --dist-tag alpha",
"clean": "lerna run clean",
"postinstall": "lerna run prepare --scope='{@serverless-stack/resources,@serverless-stack/cli,create-serverless-stack}'",
"test": "lerna run test --stream --scope=@serverless-stack/cli"
},
"repository": {
"type": "git",
"url": "https://github.com/serverless-stack/serverless-stack.git"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^3.9.1",
"@typescript-eslint/parser": "^3.9.1",
"eslint": "^7.6.0",
"husky": "^4.2.5",
"eslint": "^7.16.0",
"husky": "^4.3.6",
"lerna": "^3.22.1",
"lint-staged": "^10.2.11",
"prettier": "^2.0.5",
"lerna-changelog": "^1.0.1",
"lint-staged": "^10.5.3",
"prettier": "^2.2.1",
"typescript": "^3.9.7"
},
"husky": {
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Build outputs in test
/test/*/build/**
/test/*/cdk.out/**
/test/**/.build/**
/test/**/cdk.out/**
1 change: 1 addition & 0 deletions packages/cli/.npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
cdk.out
node_modules
test
*.test.js
Expand Down
20 changes: 19 additions & 1 deletion packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@ $ yarn sst <command>

## Commands

### `start`

Starts up a local development environment for your Lambda functions. It allows you to make changes and test your functions without having to deploy them. Here is how it works:

1. Before deploying your app, SST first deploys a stack with a Lambda powered WebSocket API.
2. While deploying your app, it replaces all the `sst.Function` constructs with a _stub_ Lambda function.
3. SST starts up a local client that connects to the WebSocket API.
4. When your Lambda functions are invoked, the stub Lambdas send the request to the WebSocket API.
5. This in turn sends the request to your local SST client.
6. The client then invokes the local version of your Lambda function and sends back the results to the WebSocket API.
7. The WebSocket API responds to the stub Lambda with the results and the original request continues.

This means that for any new requests, the local version of your Lambdas will be invoked. Without having to deploy them.

Note that all this is deployed to your AWS account. There are no 3rd party services involved and your data never leaves your account. And since the WebSocket API is completely serverless, it's basically free for most use cases.

`sst start` also starts up a watcher to transpile (using [esbuild](https://esbuild.github.io)), lint (with [ESLint](http://eslint.org)), and type check (using [TypeScript](https://www.typescriptlang.org)) your Lambda functions. So you can use ES or TypeScript directly.

### `build`

Build your app and synthesize your stacks.
Expand All @@ -38,7 +56,7 @@ Deploy all your stacks to AWS. Or optionally deploy a specific stack.

### `remove [stack]`

Remove all your stacks and all of their resources from AWS. Or optionally remove a specific stack.
Remove all your stacks and all of their resources from AWS. Or optionally remove a specific stack. Also removes the debug stack that might've been deployed along with `sst start`.

### `add-cdk [packages..]`

Expand Down
29 changes: 29 additions & 0 deletions packages/cli/assets/cdk-wrapper/.eslintrc.internal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module.exports = {
root: true,
parser: "@babel/eslint-parser",
parserOptions: {
requireConfigFile: false,
babelOptions: {
presets: [
[
"@babel/preset-env",
{
targets: {
node: "10",
},
},
],
],
plugins: ["@babel/plugin-proposal-class-properties"],
},
},
plugins: ["@babel"],
overrides: [
{
files: ["*.ts", "*.tsx"],
plugins: ["@typescript-eslint"],
parser: "@typescript-eslint/parser",
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
},
],
};
69 changes: 69 additions & 0 deletions packages/cli/assets/cdk-wrapper/run.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env node

"use strict";

require("source-map-support").install();

process.on("uncaughtException", function (err) {
console.error("\n" + (err.stack || err) + "\n");
process.exit(1);
});

const fs = require("fs");
const path = require("path");
const chalk = require("chalk");
const sst = require("@serverless-stack/resources");

const config = require("./sst-merged.json");

const appPath = process.cwd();

// Disable color
if (process.env.NO_COLOR === 'true') {
chalk.level = 0;
}

// Check first and throw an error
if (!fs.existsSync(path.join(__dirname, "lib", "index.js"))) {
handlerNotFound(true);
}

const handler = require("./lib");

if (!handler.default) {
handlerNotFound(false);
}

// When run inside `sst start`, we need to store a list of handlers to file for `sst start` to use
let synthCallback;
if (config.debugEndpoint) {
synthCallback = (lambdaHandlers) => {
fs.writeFileSync(
path.join(appPath, app.buildDir, "lambda-handlers.json"),
JSON.stringify(lambdaHandlers)
);
};
}

const app = new sst.App({
synthCallback,
name: config.name,
stage: config.stage,
region: config.region,
debugEndpoint: config.debugEndpoint,
});

// Run the handler
handler.default(app);

function handlerNotFound(importFailed) {
const extCopy = fs.existsSync(path.join(appPath, "tsconfig.json"))
? "ts"
: "js";
console.error(
importFailed
? `\nCannot find app handler. Make sure to add a "lib/index.${extCopy}" file.\n`
: `\nCannot find app handler. Make sure "lib/index.${extCopy}" has a default export.\n`
);
process.exit(1);
}
15 changes: 15 additions & 0 deletions packages/cli/assets/debug-stack/bin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env node

const cdk = require("@aws-cdk/core");
const { DebugStack } = require("../lib/DebugStack");

const stage = process.argv[3];
const region = process.argv[4];
const stackName = process.argv[2];

// Override default region
const env = { account: process.env.CDK_DEFAULT_ACCOUNT, region };

const app = new cdk.App();

new DebugStack(app, stackName, { env, stage, stackName, region });
7 changes: 7 additions & 0 deletions packages/cli/assets/debug-stack/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"app": "node bin/index.js",
"context": {
"@aws-cdk/core:enableStackNameDuplicates": "true",
"aws-cdk:enableDiffNoFail": "true"
}
}
3 changes: 3 additions & 0 deletions packages/cli/assets/debug-stack/lambda/wsConnect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.main = async function () {
return { statusCode: 200, body: "Connected." };
};

0 comments on commit 0907b18

Please sign in to comment.