我们正在用AWS
编写node.js 4.3
lambda函数,但是我们遇到了一个奇怪的behaviour
并抛出错误。
首先:
'use strict';
exports.handler = function(event, context, callback) {
throw new Error();
};
这就像预期的那样:
at exports.handler (/var/task/TestCode.js:4:11)
但是如果我们添加一个函数(甚至是未调用的),它调用一个不同类/ obj的函数,其中包含带有obj的lambda表达式,我们得到一个神秘的抛出信息。 为了使事情更容易理解,这里有一些代码:
'use strict';
function aRandomFunction() {
something.foo((obj) => {});
}
exports.handler = function(event, context, callback) {
throw new Error();
};
现在我们得到一个日志,我们不明白为什么:
at something.foo.exports.handler (/var/task/TestCode.js:8:11)
有人可以解释一下为什么会这样吗?这似乎是我不理解的一些JS
魔法:)
由于
答案 0 :(得分:1)
您的问题是Node版本4.3。升级到6.1将解决问题。
我重新创建了您提供的代码段,并在两个环境中运行它。两种情况分别给出以下错误。
4.3
at something.foo.module.exports.test (/var/task/handler.js:56:10)
6.1
at module.exports.test (/var/task/handler.js:56:10)
您的问题是错误消息中引用的行上的箭头函数...
'use strict';
function aRandomFunction() {
something.foo((obj) => {}); // illegal arrow function (ES6 not supported in Lambda environment by default)
}
exports.handler = function(event, context, callback) {
throw new Error();
};

没有polyfill的Lambda节点环境不支持ES6 - 即使在传统Node环境中的^ 4.0中也支持ES6。这是因为AWS Lambda不使用完整且最新的Node引擎代码库。它最初是为较小的用例(例如Alexa技能集和单个函数调用)设计的,因此"额外的"特征被削减 - 大部分ES6都是受害者之一。
对于polyfill,我推荐babel。
解决方案:
安装相关的babel包。 (参见package.json以供参考)
将以下行添加到handler.js
的顶部 - 应该执行此操作
特技。
'use strict';
if (!global._babelPolyfill) require('babel-polyfill'); // insert polyfill assignment
function aRandomFunction() {
something.foo((obj) => {});
}
exports.handler = function(event, context, callback) {
throw new Error();
};

// package.json (not a valid comment)
"dependencies": {
"babel-polyfill": "^6.23.0",
"babel-runtime": "^6.23.0",
},
"devDependencies": {
"babel-core": "^6.24.1",
"babel-loader": "^7.0.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-es2016": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"json-loader": "^0.5.4",
"serverless-webpack": "^1.0.0-rc.4",
"webpack": "^2.4.1",
"webpack-node-externals": "^1.6.0"
}

如果你使用无服务器这样的框架,那么这里webpack.config.js
和serverless.yml
// webpack.config.js
const nodeExternals = require('webpack-node-externals');
module.exports = {
entry: './handler.js',
target: 'node',
module: {
loaders: [{
test: /\.jsx?$/,
loader: 'babel-loader', // add babel-loader
include: __dirname,
exclude: /node_modules/,
}, {
test: /\.json$/,
loader: 'json-loader',
}],
},
externals: [nodeExternals()],
};

# serverless.yml
service: myApp
package:
exclude:
provider:
name: aws
runtime: nodejs4.3
stage: development
region: ap-northeast-1
plugins:
- serverless-webpack
custom:
webpackIncludeModules: true
main:
babelOptions: # include babel options
presets: [es2015, es2016, stage-0]
plugins: [transform-runtime]
functions:
main:
handler: handler.main
memorySize: 1024
timeout: 10
events:
- http: