serverless-heaven / serverless-webpack

Serverless plugin to bundle your lambdas with Webpack

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

5.3.0: Handler 'handler' missing on module

joebernard opened this issue · comments

This is a (Bug Report / Feature Proposal)

Bug Report

Description

For bug reports:

  • What went wrong?
    Upgrading from 5.2.0 to 5.3.0 causes Lambda to not recognize exports.handler within the webpack generated Lambda function. Upon upgrading and running sls deploy, a Lambda function with an import statement will return the following error:

Handler 'handler' missing on module

Upon rolling back to 5.2.0 and another sls deploy, the handler is recognized again.

  • What did you expect should have happened?
    The packager should not obscure exports.handler.

  • What was the config you used?

package.json

{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "private": true,
  "workspaces": [
    "src/lib/*"
  ],
  "sideEffects": false,
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.4.3",
    "@babel/preset-env": "^7.4.3",
    "aws-sdk": "^2.437.0",
    "babel-core": "7.0.0-bridge.0",
    "babel-eslint": "^10.0.1",
    "babel-loader": "^8.0.4",
    "babel-plugin-source-map-support": "^2.0.1",
    "babel-polyfill": "^6.26.0",
    "eslint": "^5.16.0",
    "eslint-config-airbnb": "^17.1.0",
    "eslint-config-prettier": "^4.1.0",
    "eslint-plugin-import": "^2.17.1",
    "eslint-plugin-jsx-a11y": "^6.2.1",
    "eslint-plugin-prettier": "^3.0.1",
    "eslint-plugin-react": "^7.12.4",
    "prettier": "^1.17.0",
    "progress-bar-webpack-plugin": "^1.12.1",
    "serverless-plugin-split-stacks": "^1.7.2",
    "serverless-webpack": "^5.2.0",
    "terser-webpack-plugin": "^1.2.3",
    "webpack": "^4.30.0",
    "webpack-cli": "^3.2.3"
  },
  "dependencies": {
    "crypto-secure-random-digit": "^1.0.7",
    "serverless-appsync-plugin": "^1.1.0",
    "serverless-plugin-aws-alerts": "^1.2.4",
    "source-map-support": "^0.5.12"
  }
}

webpack.config.js

const path = require("path");
const webpack = require("webpack");
const slsw = require("serverless-webpack");
const TerserPlugin = require("terser-webpack-plugin");
const ProgressBarPlugin = require("progress-bar-webpack-plugin");

const handler = (percentage, message, ...args) => {
  // e.g. Output each progress message directly to the console:
  console.info(percentage, message, ...args);
};

module.exports = {
  mode: "development",
  entry: slsw.lib.entries,
  target: "node",
  devtool: "none",
  externals: [
    {
      "aws-sdk": "commonjs aws-sdk",
      bufferutil: "commonjs bufferutil",
      "utf-8-validate": "commonjs utf-8-validate"
    }
  ],
  plugins: [
    new ProgressBarPlugin(),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ],
  optimization: {
    minimizer: [new TerserPlugin({ parallel: true, sourceMap: false })], // sourceMap: true
    minimize: false,
    usedExports: true
  },
  performance: {
    hints: false
  },
  stats: {
    maxModules: Infinity,
    optimizationBailout: false
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        include: path.resolve(__dirname, "src/services"),
        sideEffects: false,
        options: {
          babelrc: false,
          presets: [
            [
              "@babel/preset-env",
              {
                targets: {
                  node: "8.10"
                },
                shippedProposals: true,
                modules: false,
                debug: false
              }
            ]
          ]
        }
      }
    ]
  }
};

from serverless.json

webpack:
    packager: "yarn"
    webpackConfig: "./webpack.config.js"
  • What stacktrace or error message from your provider did you see?

Handler 'handler' missing on module

Additional Data

The problem only seems to arise with lambda functions using import. If the function does not contain an import, it seems to be understood by Lambda (it finds the handler). I created a simple test function and packaged two versions of it using 5.3.0. One has an import, the other does not. The imported file is also very simplistic and just contains a console.log(). Here is a selection of the generated output from each:

without import:

function(module, __webpack_exports__, __webpack_require__) {
        "use strict";
        __webpack_require__.r(__webpack_exports__);
        /* harmony import */ var test__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
          /*! test */ "./src/lib/test/index.js"
        );
        exports.handler = async event => {
          console.log(JSON.stringify(event)); // const { userId } = event;
        };

        /***/
      }

with import

(function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var test__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! test */ "./src/lib/test/index.js");

exports.handler = async event => {
  console.log(JSON.stringify(event)); // const { userId } = event;

};

/***/ })

When the file contains an import, the function containing exports.handler is wrapped in parenthesis. Perhaps this is causing Lambda to not see handler somehow. This was the only difference I could find between the generated files.

  • Serverless-Webpack Version you're using: 5.3.0
  • Webpack version you're using: ^4.30.0
  • Serverless Framework Version you're using: 1.4.3
  • Operating System: MacOS 10.14.5
  • Stack Trace (if available):

@serverless-heaven/serverless-webpack-team @serverless-heaven/serverless-webpack-contributors Any idea what could have caused this regression?

Same problem here, I'm also using import XXX from XXX in my functions.

webpack.config.js

const slsw = require('serverless-webpack');

module.exports = {
  entry: slsw.lib.entries,
  target: 'node',
  devtool: 'source-map',
  mode: 'production',
  optimization: {
    minimize: false
  },
  performance: {
    hints: false
  },
  externals: [
    // Those externals modules are either to heavy or can't be compilated with Webpack. They are in a separate layer
    {
      'aws-sdk': 'aws-sdk', // Included by default in Lambda execution environment
      pg: 'pg',
      'pg-hstore': 'pg-hstore',
      sequelize: 'sequelize'
    }
  ]
};

@Hugoo @joebernard Can anyone of you provide a sample setup that can be used to reproduce (and investigate) the issue?

@HyperBrain , sure, I uploaded a simple repo here :

https://github.com/Hugoo/sls-webpack-bug

I didn't try it on AWS but by using sls offline I can see the error.

Please let me know if you want more details.

@HyperBrain sorry for the delayed response, not had a chance to upgrade production projects to v5.3.0 yet.

@Hugoo thanks for uploading the sample repo

Hi all, I've gone through the commit log using @Hugoo's sample repo and I've narrowed it down to PR #450. I think the quickest fix would be to revert the commit, thoughts?

@Hugoo @joebernard @hassankhan I pushed a revert commit of #450 to master.
Can you please verify with
"serverless-webpack": "github:serverless-heaven/serverless-webpack#master"
and give feedback if it works?
I will then do a bugfix release (5.3.1) tomorrow.
Thanks

Very strange. Would be good if @TheLarkInn could share some insights. Thanks

github:serverless-heaven/serverless-webpack#master

It works for me!

This looks good to me.

Released as 5.3.1

Release 5.3.1 solved this problem for me.

Thank you !