async/await中断了我用于AWS Lambda的Webpack构建;如何迁移到Node 8.10? [英] async / await breaks my Webpack build for AWS Lambda; how can I migrate to Node 8.10?

查看:110
本文介绍了async/await中断了我用于AWS Lambda的Webpack构建;如何迁移到Node 8.10?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


一段时间以来,在阅读James Long的出色著作《 带Webpack的后端应用程序》 (第3部分).

直到最近, Amazon Web Services 提供的唯一Node.js版本是6.10;您必须以回调"样式编写Lambda fn.但是在2018年4月2日

要开始在Webpack构建的代码中使用异步/等待,您需要Babel的帮助,尤其是babel-runtimebabel-plugin-transform-runtime.幸运的是,在Babel网站上的>这两者的安装和使用方面确实写得很好.一个>.您需要Babel为您执行以下操作:

使用时自动需要babel-runtime/regenerator 生成器/异步函数.

我不会重复这里写的内容,但是,特别要注意的是,您需要如何安装它们,因为尽管它们的写法确实适用于大多数情况,但仍需要对某些内容进行一些调整以前不需要运行时dependencies的AWS Lambda开发人员.

第一部分很正常,您需要新的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

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

如果您完全关心使Webpack内置的代码保持较小的大小,则可能还会使用 webpack-node-externals 就像上面的代码一样.例如,Node中的JavaScript的 aws-sdk非常大,并且在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开心!

Note: this is a Q&A on migrating AWS Lambda Webpack builds from v6.10 to v8.10 — no help is needed, but even better answers are of course always encouraged!


For a while now I have been a disciple of using Webpack to build my back-end Lambdas after reading James Long's excellent series entitled "Backend Apps with Webpack" (part 1, part2, and part3).

Up until recently, the only version of Node.js that Amazon Web Services offered was 6.10; you had to write your Lambda fn in the "callback" style. But on April 2, 2018 AWS announced that 8.10 was now supported, and with it the suggested pattern is async / await which is great! Until it immediately broke my Webpack build. After a bit of debugging, I can break my build just by adding one async fn to the Lambda handler (I don't even need to call it):

async function firstAsync() {
  return true;
}

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

To be clear, doing this in the AWS Lambda console is perfectly fine, runs great. Webpack even builds it successfully, but upon uploading to AWS Lambda, I get the following error message: regeneratorRuntime is not defined. My code is below. What am I needing to do?

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"
  }
}

解决方案

To begin using async / await in your Webpack-built code, you need a little help from Babel, specfically the babel-runtime and the babel-plugin-transform-runtime. Fortunately there is a really good writeup on the installation and use of both here on the Babel website. You need Babel to do the following for you:

Automatically requires babel-runtime/regenerator when you use generators/async functions.

I won't repeat what has been written there, however, of particular note is HOW you need to install these, because while their writeup certainly works for most, there is a needed tweak for some AWS Lambda devs who have not needed runtime dependencies before now.

The first part is pretty normal, you need new devDependencies:

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

And also you need to tweak your .babelrc file like they describe:

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

But here is the kicker, and this is new to the code above: the babel-runtime is a regular dependencies, not a devDependencies:

npm install --save babel-runtime

These 2 installs and the .babelrc tweaks do SOLVE the async / await problem described above, but it introduces a new problem to the build above: Cannot find module 'babel-runtime/regenerator'.

If you are at all concerned with keeping your Webpack built code small, you are likely also using webpack-node-externals like the above code does. For example, the aws-sdk for JavaScript in Node is very large and is already available in the Lambda environment, so its superfluous to bundle it again. The webpack-node-externals configuration above configures Webpack to ignore ALL the modules in node-modules by default, and there is the root of the new problem. The newly installed babel-runtime is a module that needs to be bundled in the build in order for Lambda to run correctly.

Understanding the problem then, the answer becomes simple: don't use the default configuration. Instead of passing in nothing to webpack-node-externals, configure it like this:

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

And that solves both the original async / await problem, and the (possible) new problem you may be encountering if you had no previous dependencies in your build. Hope that helps — happy Lambda awaiting!

这篇关于async/await中断了我用于AWS Lambda的Webpack构建;如何迁移到Node 8.10?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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