AWS Lambda的打包代码 [英] Packaging code for AWS Lambda

查看:188
本文介绍了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生成针对nodecommonjs库:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆