AWS Lambda的打包代码 [英] Packaging code for AWS Lambda
问题描述
我正在尝试打包AWS Lambda的代码. Lambda具有各种限制,例如使用Node 6.10,并且没有AWS EB这样的构建步骤.我还使用NPM模块,因此这些模块需要与AWS Lambda处理程序捆绑在一起.
这就是我想做的:
- 定义和使用NPM模块(仅限纯JS模块)
- 将所有代码(包括NPM模块)转换为Node 6.10支持的JS版本
- 将所有NPM模块静态链接到一个大JS文件中
- 将该单个文件上传到AWS Lambda
例如,假设我有一个NPM模块foo
(node_modules/foo/index.js
):
export default { x: 1 };
,我有自己的代码('index.js'):
import foo from 'foo';
export const handler = (event, context, callback) => {
console.log(foo); // Will appear in CloudWatch logs
callback(null, 'OK');
};
输出将是这样的('dist/bundle.js'):
var foo = { x: 1 };
exports.handler = function(event, context, callback) {
console.log(foo);
callback(null, 'OK');
};
我应该能够在AWS Lambda上上传并运行bundle.js
,而无需进一步修改.
如何使用现有的JS工具实现这一目标?
事实证明,这是可能的,但是要实现此功能需要一些棘手的配置.我创建了一个样板仓库供其他人使用./p>
以下是重要的位...
首先,您需要一个以Node.js 6.10
为目标的.babelrc
:
{
"presets": [
[
"env", {
"targets": {
"node": "6.10"
},
"loose": false,
"spec": true
}
]
]
}
接下来,您需要配置Webpack生成针对node
的commonjs
库:
const path = require('path');
const webpack = require('webpack');
const debug = process.env.NODE_ENV !== 'production';
module.exports = {
context: __dirname,
entry: [ 'babel-polyfill', './index.js' ],
output: {
path: path.join(__dirname, 'out'),
filename: 'index.js',
libraryTarget: 'commonjs'
},
devtool: debug ? 'source-map' : false,
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
babelrc: true,
compact: !debug
}
}
}
],
},
target: 'node',
plugins: [
new webpack.DefinePlugin({ 'global.GENTLY': false })
]
};
请注意,您不是不想忽略node_modules
文件夹,因为这会阻止静态链接.
如果要使用现代JS功能,babel-polyfill
插件也至关重要.
您的实际处理程序代码应具有一个名为export
,该名称与您在AWS控制台中设置的名称匹配:
export const handler = (event, context, callback) => callback(null, 'OK');
不要不这样做!
// Bad!
export default {
handler: (event, context, callback) => callback(null, 'OK'),
};
打包代码时,请确保将index.js
添加到zip的顶层:
zip -j bundle.zip ./out/index.js
I am trying to package code for AWS Lambda. Lambda has various restrictions, such as using Node 6.10, and not having a build step, like AWS EB does. I also am using NPM modules, so these will need to be bundled with the AWS Lambda handler.
Here is what I would like to do:
- Define and use NPM modules (pure JS modules only)
- Transpile all code (including NPM modules) to a JS version that Node 6.10 supports
- Statically link all NPM modules into one big JS file
- Upload that single file to AWS Lambda
For example, suppose I have an NPM module foo
(node_modules/foo/index.js
):
export default { x: 1 };
and I have my own code ('index.js'):
import foo from 'foo';
export const handler = (event, context, callback) => {
console.log(foo); // Will appear in CloudWatch logs
callback(null, 'OK');
};
The output would be something like this ('dist/bundle.js'):
var foo = { x: 1 };
exports.handler = function(event, context, callback) {
console.log(foo);
callback(null, 'OK');
};
I should be able to upload and run bundle.js
on AWS Lambda without further modification.
How can I achieve this using existing JS tools?
It turns out that this is possible, but it requires some tricky configuration to achieve. I have created a boiler-plate repo for others to use.
Here are the important bits...
First, you need a .babelrc
that targets Node.js 6.10
:
{
"presets": [
[
"env", {
"targets": {
"node": "6.10"
},
"loose": false,
"spec": true
}
]
]
}
Next, you need to configure Webpack to generate a commonjs
library targetting node
:
const path = require('path');
const webpack = require('webpack');
const debug = process.env.NODE_ENV !== 'production';
module.exports = {
context: __dirname,
entry: [ 'babel-polyfill', './index.js' ],
output: {
path: path.join(__dirname, 'out'),
filename: 'index.js',
libraryTarget: 'commonjs'
},
devtool: debug ? 'source-map' : false,
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
babelrc: true,
compact: !debug
}
}
}
],
},
target: 'node',
plugins: [
new webpack.DefinePlugin({ 'global.GENTLY': false })
]
};
Note that you do not want to ignore the node_modules
folder, since that would prevent static-linking.
The babel-polyfill
plugin is also crucial if you want to use modern JS features.
Your actual handler code should have a named export
that matches what you have set in the AWS console:
export const handler = (event, context, callback) => callback(null, 'OK');
Do not do it like this!
// Bad!
export default {
handler: (event, context, callback) => callback(null, 'OK'),
};
When packaging the code, make sure you add index.js
to the top level of the zip:
zip -j bundle.zip ./out/index.js
这篇关于AWS Lambda的打包代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!