如何为 AWS Lambda nodejs 运行时构建单个 js 文件
How do I build a single js file for AWS Lambda nodejs runtime
我们正在开发 project/framework 来帮助在 AWS Lambda 中部署和维护代码。我想 build/bundle 一个 lambda 函数的所有 node.js 代码到一个 js 文件中,因为:
- 较小的代码库有助于解决 lambda 冷启动问题
- Lambda 的代码 zip 大小限制为 50MB
我们不想创建自定义捆绑器来执行此操作,因为已经有很多选项(systemjs、browserify、webpack 等)。但是,我们担心某些节点模块不能很好地与 bundlers/builders.
配合使用的问题
具体来说 aws-sdk
有 known issues with webpack, says it has browserify support 但我已经与那些对浏览器化 aws-sdk 有问题的人交谈过
我们想选择一个现有的捆绑器(或 2 个),但我们想确保它适用于尽可能多的 modules/code。我们正在尝试为 JAWS 创建一个插件生态系统,因此做好这一点很重要(不想让人们失望,因为他们使用的模块 X 不会捆绑)。
问题:
- 我将如何bundling/building满足这些限制?
- 我们是否可以为我们产品的消费者提供任何指南,以确保他们 write/use 将捆绑代码?例如:动态 require()s 导致问题 AFAIK。
可能的答案可能是使该函数的行为类似于引导加载程序。使函数从 S3 下载打包代码,解压并运行它。
必须按照您提议的方式修改代码似乎是个坏主意,可能会导致无法预测且难以调试的错误。
我不喜欢使用单个文件解决方案,而是上传打包了所有代码的 zip 文件。我为此使用 gulp。下面的代码仅上传生产依赖项,不包括开发依赖项和之前上传的 zip 存档。您还可以使用 gulp.src
.
参数排除您的测试文件夹或任何其他文件
顺便提一下,aws-sdk
库在我的开发依赖项中,因为 AWS Lambda 已经有一个副本 ;)
var gulp = require('gulp');
var lambda = require('gulp-awslambda');
var zip = require('gulp-zip');
var settings = require('./settings');
var argv = require('yargs').argv;
var p = require('./package.json');
gulp.task('default', function () {
var profile = argv.profile;
var src = ['**', '!*.zip', '!node_modules/aws-sdk{,/**}'];
var i;
for (i in p.devDependencies) {
src.push("!node_modules/" + i + "{,/**}");
}
if (!profile) {
profile = settings.aws.defaultProfile;
}
return gulp.src(src)
.pipe(zip('archive.zip'))
.pipe(lambda(settings.aws.lambda, {
region: settings.aws.region,
profile: profile
}))
.pipe(gulp.dest('.'));
});
这并没有直接回答您的问题,但 serverless 项目可能正是处于这种情况的人所需要的。
它允许您在普通的 webpack 风格的多文件架构中构建项目,然后使用 CLI 实用程序将您的项目构建到 Lambda 优化的文件中。
CLI 还处理函数初始化、部署和一连串我什至不需要的其他函数。它甚至会 create/configure 您的触发器(例如,s3 对象创建或通过 AWS API 服务设置新的 REST API)。
我只有几个 Lambda 函数,但在我开始使用 serverless
之前,即使维护这些函数也很痛苦 serverless
。
(这是一个讨好 post,但需要说明的是,我与该项目无关)
aws-sdk-js now officially supports browserify. You can why this is a great thing on my blog.
我创建了一个名为 serverless-plugin-browserify 的无服务器插件,它将以非常少的配置完成所有繁重的工作。
为了具体回答这个问题,我用这个 browserify 配置解决了这个问题:
{
disable: false, //Not an official option, used as internal option to skip browserify
exclude: [], //Not an option, but will use for setting browserify.exclude() if defined in yml
ignore: [], //Not an option, but will use for setting browserify.ignore() if defined in yml
basedir: this.serverless.config.servicePath,
entries: [],
standalone: 'lambda',
browserField: false, // Setup for node app (copy logic of --node in bin/args.js)
builtins: false,
commondir: false,
ignoreMissing: true, // Do not fail on missing optional dependencies
detectGlobals: true, // We don't care if its slower, we want more mods to work
insertGlobalVars: { // Handle process https://github.com/substack/node-browserify/issues/1277
//__filename: insertGlobals.lets.__filename,
//__dirname: insertGlobals.lets.__dirname,
process: function() {
},
},
debug: false,
}
我们正在开发 project/framework 来帮助在 AWS Lambda 中部署和维护代码。我想 build/bundle 一个 lambda 函数的所有 node.js 代码到一个 js 文件中,因为:
- 较小的代码库有助于解决 lambda 冷启动问题
- Lambda 的代码 zip 大小限制为 50MB
我们不想创建自定义捆绑器来执行此操作,因为已经有很多选项(systemjs、browserify、webpack 等)。但是,我们担心某些节点模块不能很好地与 bundlers/builders.
配合使用的问题具体来说 aws-sdk
有 known issues with webpack, says it has browserify support 但我已经与那些对浏览器化 aws-sdk 有问题的人交谈过
我们想选择一个现有的捆绑器(或 2 个),但我们想确保它适用于尽可能多的 modules/code。我们正在尝试为 JAWS 创建一个插件生态系统,因此做好这一点很重要(不想让人们失望,因为他们使用的模块 X 不会捆绑)。
问题:
- 我将如何bundling/building满足这些限制?
- 我们是否可以为我们产品的消费者提供任何指南,以确保他们 write/use 将捆绑代码?例如:动态 require()s 导致问题 AFAIK。
可能的答案可能是使该函数的行为类似于引导加载程序。使函数从 S3 下载打包代码,解压并运行它。
必须按照您提议的方式修改代码似乎是个坏主意,可能会导致无法预测且难以调试的错误。
我不喜欢使用单个文件解决方案,而是上传打包了所有代码的 zip 文件。我为此使用 gulp。下面的代码仅上传生产依赖项,不包括开发依赖项和之前上传的 zip 存档。您还可以使用 gulp.src
.
顺便提一下,aws-sdk
库在我的开发依赖项中,因为 AWS Lambda 已经有一个副本 ;)
var gulp = require('gulp');
var lambda = require('gulp-awslambda');
var zip = require('gulp-zip');
var settings = require('./settings');
var argv = require('yargs').argv;
var p = require('./package.json');
gulp.task('default', function () {
var profile = argv.profile;
var src = ['**', '!*.zip', '!node_modules/aws-sdk{,/**}'];
var i;
for (i in p.devDependencies) {
src.push("!node_modules/" + i + "{,/**}");
}
if (!profile) {
profile = settings.aws.defaultProfile;
}
return gulp.src(src)
.pipe(zip('archive.zip'))
.pipe(lambda(settings.aws.lambda, {
region: settings.aws.region,
profile: profile
}))
.pipe(gulp.dest('.'));
});
这并没有直接回答您的问题,但 serverless 项目可能正是处于这种情况的人所需要的。
它允许您在普通的 webpack 风格的多文件架构中构建项目,然后使用 CLI 实用程序将您的项目构建到 Lambda 优化的文件中。
CLI 还处理函数初始化、部署和一连串我什至不需要的其他函数。它甚至会 create/configure 您的触发器(例如,s3 对象创建或通过 AWS API 服务设置新的 REST API)。
我只有几个 Lambda 函数,但在我开始使用 serverless
之前,即使维护这些函数也很痛苦 serverless
。
(这是一个讨好 post,但需要说明的是,我与该项目无关)
aws-sdk-js now officially supports browserify. You can why this is a great thing on my blog.
我创建了一个名为 serverless-plugin-browserify 的无服务器插件,它将以非常少的配置完成所有繁重的工作。
为了具体回答这个问题,我用这个 browserify 配置解决了这个问题:
{
disable: false, //Not an official option, used as internal option to skip browserify
exclude: [], //Not an option, but will use for setting browserify.exclude() if defined in yml
ignore: [], //Not an option, but will use for setting browserify.ignore() if defined in yml
basedir: this.serverless.config.servicePath,
entries: [],
standalone: 'lambda',
browserField: false, // Setup for node app (copy logic of --node in bin/args.js)
builtins: false,
commondir: false,
ignoreMissing: true, // Do not fail on missing optional dependencies
detectGlobals: true, // We don't care if its slower, we want more mods to work
insertGlobalVars: { // Handle process https://github.com/substack/node-browserify/issues/1277
//__filename: insertGlobals.lets.__filename,
//__dirname: insertGlobals.lets.__dirname,
process: function() {
},
},
debug: false,
}