typescript - 在 VS Code 中对 AWS SAM 无服务器应用程序进行 TypeScript 调试
问题描述
我在 Visual Studio Code 中使用 AWS SAM 构建了一个无服务器功能。我使用的运行时是 nodejs12.x 但我在 TypeScript 中编写所有内容,然后将其编译为 JS 到一个/dist
目录中。这是我将所有 CloudFormation 模板指向的目录,以便找到处理程序。比如右边是TS,左边是我编译的JS。
在侧边栏中,您可以看到/dist
我运行后放置我的 JS 文件的目录,tsc
而再往下一点是我的模板和 TypeScript 源代码。
然后我的模板如下所示:
LibraryAddMangaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: dist/src/handlers.LibraryAddMangaHandler
FunctionName: Foobar
Runtime: nodejs12.x
MemorySize: 256
Timeout: 300
我按照亚马逊的文档在 VS Code 中执行本地调试并让它适用于 JS 文件。我可以毫无问题地设置断点并逐步执行编译的 JS 代码。
我想知道是否可以在单步执行 TypeScript 代码时进行调试,类似于我在 Chrome 中使用 Angular/React 中的客户端应用程序执行的操作。我知道框架处理 JS 到 TS 的映射作为构建过程的一部分,以支持 Chrome 调试工具的需求。如果没有 SAM/AWS 的支持,我不确定我想做的事情是否可行。
此外,当我的 HTTP 请求完成时,调试会话结束,而不是继续运行并监听下一个请求 - 类似于sam local start-api
. 有没有办法配置调试运行器以保持应用程序运行?我看到有人推荐使用Thundra,但这需要将 Lambda 部署到 AWS 中,我真的很喜欢本地调试、调整、调试的快速循环。我真的不希望sam deploy
每 15 秒执行一次并等待堆栈部署。
谢谢!
解决方案
是的,可以做到:您需要的是源地图
就我而言,我将我的 lambda 表达式编译并捆绑到index.js
dist 文件夹下的 1 个单个文件中。.map
我使用 webpack 作为捆绑器将其与单个文件一起提供。
const path = require('path');
const glob = require('glob');
const webpack = require('webpack');
const CreateFileWebpack = require('create-file-webpack');
const nodeExternals = require('webpack-node-externals');
// Credits: https://hackernoon.com/webpack-creating-dynamically-named-outputs-for-wildcarded-entry-files-9241f596b065
const entryArray = glob.sync('./src/lambda/**/handler.ts');
const entryObject = entryArray.reduce((acc, item) => {
let name = path.dirname(item.replace('./src/lambda', ''));
// conforms with Webpack entry API
// Example: { ingest: './src/ingest/index.ts' }
acc[name] = item;
return acc;
}, {});
/** @type {import('webpack').Configuration} */
module.exports = {
cache: {
type: 'memory',
},
entry: entryObject,
devtool: false,
target: 'node',
// externals: [nodeExternals()], // use if dependencies should not be bundled (like when using layers)
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
transpileOnly: true,
},
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
plugins: [
new webpack.IgnorePlugin({ resourceRegExp: /^pg-native$/ }),
new webpack.IgnorePlugin({ resourceRegExp: /^hiredis$/ }),
...Object.keys(entryObject).map(lambda => {
return new CreateFileWebpack({
path: path.resolve(__dirname, 'build'),
fileName: `${lambda}/package.json`,
content: JSON.stringify({
name: 'dummy_dependencies',
dependencies: {},
version: '1.0.0',
}),
});
}),
new webpack.SourceMapDevToolPlugin({
columns: false,
module: true,
filename: '[file].map',
}),
],
// Output directive will generate build/<function-name>/index.js
output: {
filename: '[name]/index.js',
path: path.resolve(__dirname, 'build'),
devtoolModuleFilenameTemplate: '[absolute-resource-path]',
// Credit to Richard Buggy!!
libraryTarget: 'commonjs2',
},
};
我不知道在您的情况下拥有多个编译文件会如何,但我认为这是与 webpack 或任何其他“编译”工具类似的场景(我最近一直在研究esbuild)。
即使是激活了源映射的普通 tsc 也应该足够了。
完成此操作后,您还应该使用正确的 .vscode 启动配置,以便 vs code 可以将容器的远程文件与本地文件映射,同时还可以通过源映射连接其相应的 typescript 文件。
{
"name": "[Serverless] <lambda-name> attach",
"type": "node",
"request": "attach",
"address": "localhost",
"port": 5678,
"localRoot": "${workspaceRoot}/.serverless/build/<lambda-folder>",
"remoteRoot": "/var/task",
"protocol": "inspector",
"stopOnEntry": false,
"outFiles": ["${workspaceRoot}/.serverless/build/<lambda-folder>"],
"sourceMaps": true
}
有没有办法配置调试运行器以保持应用程序运行?
如果我理解正确,您正在寻找的是保持调试器在请求之间连接,这样您就不必每次在本地调用 lambda 时手动连接它。
如果是这种情况,您可以通过运行sam local start-lambda
using --shutdown
and --warm-containers LAZY
flags ( reference ) 来实现:
sam local start-lambda -d 5678 --host 0.0.0.0 --shutdown --debug --warm-containers LAZY
这将创建一个类似于 AWS 在云上使用的 API,因此您可以使用aws-sdk
或aws cli
aws lambda invoke --function-name \"<sam-template-lambda-id>\" --payload <stringified-json-input> --endpoint-url \"http://127.0.0.1:3001\" lambda_invoke_output.log
aws sam 将使容器保持温暖,直到 lambda 代码更改,并且调试器将在您触发的所有 INVOKE 事件中保持激活状态,有效地停止您每次调用 lambda 时设置的打字稿断点
TL;博士
使用源地图,并在整个互联网上搜索如何将所有东西粘合在一起
个人笔记:我第一次处理这个问题时,我在互联网上经历了漫长而痛苦的航行来完成它。
生活不应该是这样的:')
推荐阅读
- parsing - Parsec 简单解析器导致错误“约束中的非类型变量参数:Stream sm Char”
- algorithm - 分析具有未知结构和容错的表
- d3.js - D3 - 在鼠标悬停时获取 x 位置
- python - django覆盖删除级联一次
- c# - 无法将字符串列表排序为数字?
- nginx - uwsg_cache的不同配置取决于url路径
- python - 如何在 osmnx 中下载和构建图形?
- javascript - ASP 会话在 Java 1.8 但不是 1.6 中超时。造成巨大的用户影响
- c# - C#:让编译器在从 IEnumerable 读取多态对象时调用正确的方法重载
- php - 使用 file_get_contents() 获取对本地 IP URL 的请求不起作用