async / await打破了我对AWS Lambda的Webpack构建;如何迁移到节点8.10?

时间:2018-04-20 10:20:20

标签: node.js amazon-web-services webpack aws-lambda

注意:这是关于将AWS Lambda Webpack版本从v6.10迁移到v8.10的Q& A - 不需要任何帮助,但当然总是鼓励更好的答案!

有一段时间了,在阅读了James Long的优秀系列文章“Webpack后端应用程序”part 1,{{}后,我已成为使用Webpack构建我的后端Lambdas的门徒{3}}和part2)。

直到最近,part3提供的唯一版本的Node.js是6.10;你必须以“回调”的方式写你的Lambda fn。但是在2018年4月2日Amazon Web Services,并且随之建议的模式是async / await,这太棒了!直到它立即打破了我的Webpack构建。经过一些调试后,我可以通过向Lambda处理程序添加一个async fn来打破我的构建(我甚至不需要调用它):

async function firstAsync() {
  return true;
}

exports.handler = async (event) => {
    // TODO implement
    return 'Hello from Lambda!'
};

要明确的是,在AWS Lambda控制台中执行此操作非常精细,运行良好。 Webpack甚至可以成功构建它,但在上传到AWS Lambda后,我收到以下错误消息:regeneratorRuntime is not defined。我的代码如下。我需要做什么?

webpack.config.js

const nodeExternals = require('webpack-node-externals');
const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const webpack = require('webpack');

const config = {
  entry: './src/index.js',

  output: {
    path: path.resolve(__dirname, 'dist'),
    library: 'index',
    libraryTarget: 'commonjs2',
    filename: 'index.js'
  },
  target: 'node', // building for a Node environment
  externals: [nodeExternals()], // in order to ignore all modules in node_modules folder 
  module: {
    rules: [{
      test: /\.(js|jsx)$/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['env']
        }
      }
    }]
  },
  plugins: [
    new UglifyJsPlugin()
  ]
};

module.exports = config;

的package.json

{
  "name": "lambda-webpack",
  "version": "1.0.0",
  "description": "An empty project scaffold to enable webpack builds in AWS Lambda",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "upload": "upload.bat"
  },
  "author": "Geek Stocks®",
  "license": "MIT",
  "devDependencies": {
    "aws-sdk": "^2.179.0",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "uglifyjs-webpack-plugin": "^1.1.6",
    "webpack": "^3.10.0",
    "webpack-node-externals": "^1.6.0"
  }
}

3 个答案:

答案 0 :(得分:3)

Geek Stock的answer above仅在使用Node v6.10运行时时才需要。它允许您使用async/await语法和babel-runtime/regenerator将异步函数转换为Node v4.3.2和更新运行时支持的ES6生成器。

在Node v8.10中,它是不同的。已经支持async/await,因此您不需要Babel将async函数转换为生成器。你只需正确使用它就可以了。

至于您的具体情况,我假设您只是更改了您的Javascript代码以使用async/await代码,但您没有告诉Babel Not将您的async/await代码转换为生成器。这就是为什么babel-runtime抱怨缺少插件的原因。

如果是这种情况,您只需将Babel配置为简单地定位到Node v8.10即可。您可以在.babelrc ...

中执行此操作
{
  "presets": [
    [
      "env",
      {
        "targets": {
          "node": "8.10"
        }
      }
    ]
  ]
}

babel将停止转换这些async功能。由于它没有进行转换,因此不再需要regenerator-runtime

答案 1 :(得分:2)

在我的情况下,我将其与nodejs12.x一起使用。我收到错误 regeneratorRuntime未定义

我正在使用带有es2015代码的预设stage-0node12.x。另外,我使用的是babel的旧版本。

我所做的安装:

"@babel/cli": "^7.10.1",
"@babel/core": "^7.10.2",
"@babel/preset-env": "^7.10.2"

然后设置此babel预设:

"presets": [
    ["@babel/preset-env", {"targets": { "node": "current" }}]
]

谢谢

答案 2 :(得分:0)

要在Webpack构建的代码中开始使用async / await,您需要Babel的一些帮助,特别是babel-runtimebabel-plugin-transform-runtime。幸运的是,AWS announced that 8.10 was now supported的安装和使用都有很好的写作。您需要Babel为您执行以下操作:

  

使用时自动要求babel-runtime / regenerator   发电机/异步功能。

我不会重复那里写的内容,然而,尤其值得注意的是你需要安装这些内容,因为虽然他们的写作肯定适用于大多数人,但有些需要调整AWS Lambda开发人员之前不需要运行时dependencies

第一部分很正常,你需要新的devDependencies:

npm install --save-dev babel-plugin-transform-runtime

您还需要像他们描述的那样调整您的.babelrc文件:

{
  "plugins": [
    ["transform-runtime", {
      "helpers": false,
      "polyfill": false,
      "regenerator": true,
      "moduleName": "babel-runtime"
    }]
  ]
}

但这是踢球者,这对上面的代码来说是新的:babel-runtime是常规dependencies,而不是devDependencies

npm install --save babel-runtime

这两个安装和.babelrc调整确实解决了上面描述的异步/等待问题,但它为上面的构建引入了一个新问题:Cannot find module 'babel-runtime/regenerator'

如果您完全担心将Webpack构建的代码保持较小,那么您可能也像上面的代码一样使用here on the Babel website。例如,webpack-node-externals非常大,并且已经在Lambda环境中可用,因此再次捆绑它是多余的。上面的webpack-node-externals配置默认情况下将Webpack配置为忽略node-modules中的所有模块,而那里是新问题的根。新安装的babel-runtime是一个需要捆绑在构建中的模块,以便Lambda正确运行。

然后理解问题,答案变得简单:不要使用默认配置。不要将任何内容传递给webpack-node-externals,而是像这样配置:

externals: [nodeExternals({
  whitelist: [
    'babel-runtime/regenerator',
    'regenerator-runtime'
  ]
})], // ignore all modules in node_modules folder EXCEPT the whitelist

解决了原始异步/等待问题以及您可能遇到的(可能的)新问题,如果您的构建中没有dependencies。希望有所帮助 - 快乐的Lambda await ing!