serverless-webpack: Unable to import module 'handler': Error revisited

This is a Bug Report

Description

For bug reports:

  • What went wrong? I get Unable to import module 'handler': Error when visiting my AWS endpoint
  • What did you expect should have happened? Everything works fine locally. Expecting same results.
  • What was the config you used?

serverless.yml:


custom:
  webpackIncludeModules: true;
    
# package:
#  individually: true

provider:
  name: aws
  runtime: nodejs6.10

# you can overwrite defaults here
  stage: dev
  region: us-east-1

functions:
  alerts:
    handler: handler.alerts
    events:
      - http: ANY alerts
      - cors: true    

plugins:
  - serverless-webpack
  - serverless-offline

webpack.config.js

const slsw = require('serverless-webpack');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  entry: slsw.lib.entries,
  externals: [nodeExternals()], // in order to ignore all modules in node_modules folder
  target: 'node',
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/, // in order to ignore built-in modules like path, fs, etc.
        loaders: ['babel-loader'],
        include: __dirname,
      },
    ],
  },
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
  },
};

package.json

  "name": "alerts",
  "version": "1.0.0",
  "description": "",
  "main": "handler.js",
  "scripts": {
    "test": "mocha handler.test.js",
    "debug:offline": "SLS_DEBUG=* sls offline start",
    "debug:deploy": "SLS_DEBUG=* sls deploy --verbose",
    "debug": "SLS_DEBUG=* sls deploy --verbose && nodemon sls offline start",
    "invoke": "serverless invoke local --function alerts",
    "start": "serverless offline start",
    "deploy": "sls deploy -f alerts",
    "curl:local": "curl http://localhost:3000/alerts -i --header 'Content-Type: application/vnd.api+json' --header 'Accept: application/vnd.api+json'",
    "curl:local:paged": "curl http://localhost:3000/alerts -i -G -d page[offset]=2 -d page[limit]=10 --header 'Content-Type: application/vnd.api+json' --header 'Accept: application/vnd.api+json'",
    "git:push": "git push https://git-codecommit.us-east-1.amazonaws.com/v1/repos/alerts --all",
    "mockAPI": "http-server -p 1980",
    "ngrok:start": "nodemon --inspect ./ngrok/request.js --exec babel-node",
    "ngrok:connect": "nodemon ./ngrok/connect.js --exec babel-node",
    "ngrok": "ngrok http 3000"
  },
  "author": "James Fishwick",
  "license": "ISC",
  "engines": {
    "node": "6.10.3"
  },
  "dependencies": {
    "babel-runtime": "6.26.0",
    "bluebird": "3.5.0",
    "dotenv": "4.0.0",
    "elasticsearch": "13.3.1",
    "http-aws-es": "3.1.0",
    "json-api-serializer": "1.9.1",
    "ramda": "0.24.1",
    "request": "2.81.0",
    "request-promise": "4.2.1",
    "uuid": "3.1.0"
  },
  "devDependencies": {
    "aws-sdk": "2.118.0",
    "babel-cli": "6.26.0",
    "babel-core": "6.26.0",
    "babel-eslint": "7.2.3",
    "babel-loader": "7.1.2",
    "babel-plugin-ramda": "1.4.3",
    "babel-plugin-transform-object-rest-spread": "6.26.0",
    "babel-plugin-transform-runtime": "6.23.0",
    "babel-preset-env": "1.6.0",
    "chai": "4.1.2",
    "eslint": "4.7.1",
    "eslint-config-airbnb-base": "12.0.0",
    "eslint-plugin-async-await": "0.0.0",
    "eslint-plugin-babel": "4.1.2",
    "eslint-plugin-chai-expect": "1.1.1",
    "eslint-plugin-import": "2.7.0",
    "eslint-plugin-mocha": "4.11.0",
    "eslint-plugin-node": "5.1.1",
    "eslint-plugin-prefer-object-spread": "1.2.1",
    "http-server": "0.10.0",
    "mocha": "3.5.3",
    "ngrok": "2.2.22",
    "nodemon": "1.12.1",
    "npm-run-script": "0.0.4",
    "pre-commit": "1.2.2",
    "serverless": "1.22.0",
    "serverless-offline": "3.16.0",
    "serverless-webpack": "^3.0.0-rc.1",
    "webpack": "3.6.0",
    "webpack-node-externals": "1.6.0"
  }
}
  • What stacktrace or error message from your provider did you see?
babel-preset-env: `DEBUG` option

Using targets:
{
  "node": "6.10"
}

Modules transform: commonjs

Using plugins:
  transform-exponentiation-operator {"node":"6.10"}
  transform-async-to-generator {"node":"6.10"}
  syntax-trailing-function-commas {"node":"6.10"}
Time: 864ms
     Asset     Size  Chunks             Chunk Names
handler.js  13.3 kB       0  [emitted]  handler
   [0] external "dotenv" 42 bytes {0} [not cacheable]
   [1] ./handler.js 1.43 kB {0} [built]
   [2] ./main.js 6.96 kB {0} [built]
   [3] external "babel-runtime/core-js/json/stringify" 42 bytes {0} [not cacheable]
   [4] external "babel-runtime/helpers/extends" 42 bytes {0} [not cacheable]
   [5] external "babel-runtime/helpers/asyncToGenerator" 42 bytes {0} [not cacheable]
   [6] external "url" 42 bytes {0} [not cacheable]
   [7] external "bluebird" 42 bytes {0} [not cacheable]
   [8] external "request-promise" 42 bytes {0} [not cacheable]
   [9] external "uuid/v5" 42 bytes {0} [not cacheable]
  [10] ./serializer.js 724 bytes {0} [built]
  [11] external "json-api-serializer" 42 bytes {0} [not cacheable]
  [12] ./pplog.js 409 bytes {0} [built]
  [13] external "util" 42 bytes {0} [not cacheable]
Serverless: Fetch dependency graph from /Users/jamesfishwick/Documents/alerts/package.json
Serverless: Packing external modules: dotenv@4.0.0, babel-runtime@6.26.0, bluebird@3.5.0, request-promise@4.2.1, uuid@3.1.0, json-api-serializer@1.9.1
Serverless: Package took [4104 ms]
Serverless: Copy modules: /Users/jamesfishwick/Documents/alerts/.webpack/service [1921 ms]
Serverless: Prune: /Users/jamesfishwick/Documents/alerts/.webpack/service [1725 ms]
Serverless: Zip service: /Users/jamesfishwick/Documents/alerts/.webpack/service [3625 ms]
Serverless: Packaging service...
Serverless: Remove /Users/jamesfishwick/Documents/alerts/.webpack
Serverless: Invoke aws:package:finalize
Serverless: Invoke aws:common:moveArtifactsToPackage
Serverless: Invoke aws:common:validate
Serverless: Invoke aws:deploy:deploy
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - alerts-dev
CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::Function - AlertsLambdaFunction
CloudFormation - UPDATE_COMPLETE - AWS::Lambda::Function - AlertsLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1505851381038
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1505851381038
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1505851381038
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - alerts-dev
CloudFormation - DELETE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1505851297621
CloudFormation - DELETE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1505851297621
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - alerts-dev
Serverless: Stack update finished...
Serverless: Invoke aws:info
Service Information
service: alerts
stage: dev
region: us-east-1
stack: alerts-dev
api keys:
  None
endpoints:
  ANY - https://xxx.execute-api.us-east-1.amazonaws.com/dev/alerts
functions:
  alerts: alerts-dev-alerts

Stack Outputs
AlertsLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:xxx:function:alerts-dev-alerts:6
ServiceEndpoint: https://xxx.execute-api.us-east-1.amazonaws.com/dev
ServerlessDeploymentBucketName: alerts-dev-serverlessdeploymentbucket-18jzstz1xn4qa

Serverless: Publish service to Serverless Platform...
Service successfully published! Your service details are available at:
https://platform.serverless.com/services/two7sclash/alerts
Serverless: Invoke aws:deploy:finalize
Serverless: Removing old service versions...

then:

curl https://xxx.execute-api.us-east-1.amazonaws.com/dev/alerts gives {"message": "Internal server error"}

Stack trace is:

Unable to import module 'handler': Error
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at /var/task/node_modules/request-promise/lib/rp.js:11:16
at module.exports (/var/task/node_modules/stealthy-require/lib/index.js:62:23)
at Object.<anonymous> (/var/task/node_modules/request-promise/lib/rp.js:10:19)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/var/task/handler.js:370:18)
at __webpack_require__ (/var/task/handler.js:20:30)
at Object.<anonymous> (/var/task/handler.js:162:17)
at __webpack_require__ (/var/task/handler.js:20:30)
at Object.<anonymous> (/var/task/handler.js:80:14)
at __webpack_require__ (/var/task/handler.js:20:30)
at /var/task/handler.js:63:18
at Object.<anonymous> (/var/task/handler.js:66:10)

Similar or dependent issue(s): *#43

Additional Data

  • Serverless-Webpack Version you’re using: ^3.0.0-rc.1
  • Webpack version you’re using: 3.6.0
  • Serverless Framework Version you’re using: 1.22.0
  • Operating System: macOS Sierra 10.12.6 16G29 x86_64

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 4
  • Comments: 45 (19 by maintainers)

Most upvoted comments

@jkruse14: Unable to import module 'handler' usually occurs due to missing dependencies. The error is misleading in this case, but you can think of it as Lambda (the Node.js runtime) trying to import your handler. If there are any syntax errors, missing modules or similar, Unable to import module 'handler' gets thrown.

To debug this, do a serverless package and check what is packaged in the zip-archive (in the .serverless directory). Make sure that everything you import or require in your bundle is available in the node_modules directory within the zip-archive.

I suppose you can try extracting the zip-archive and do a node bundle.js where your working directory is where the node_modules directory is. You should then get similar errors to Unable to import module 'handler', but hopefully with more information.

Ok. That helps. There is a dependency missing in the package: /var/task/node_modules/request-promise/lib/rp.js:11:16 that is needed by request-promise. I checked the request-promise package.json and the package has a peer dependency: request@^2.34.

There is currently a bug #223 that you hit here. With the released 3.0.0 you have to do a require('request') as workaround as mentioned in #223.

With version 3.1.0 which is already in master you can do

custom:
  webpackIncludeModules:
    forceInclude:
      - request

Sorry for the inconvenience. I will try to implement a bugfix for #223 as soon as possible.

Hey @btburton42 , even if some issues turn out to be a missing configuration, it is quite helpful to have them documented here in the GitHub issues. This will help others who run into the same to have a variety of possible things to check 👍 .

However a Wiki might be better to collect them and extract them as Problem->Solution pairs from the issues. As I’m not very used in how to setup a good wiki in GitHub, I could need some help there 😄 .

problem was that the url module was choking on const selfApi = url.resolve(process.env.API_URL, 'alerts');. I simply wasn’t doing env variables correctly. Read https://medium.com/@purplecones/serverless-environment-variables-4ec818f67388 and all is well.

Just FWIW… I’ve also been fighting this issues for some hours (which appeared after adding babel to my build chain btw.). Earlier I had the following in my Lambda handler:

module.exports.getVersion = async event => {
    return {
    statusCode: 200,
    body: JSON.stringify({"version":1.2})
  };
};

Adding babel to webpack and the code above stopped working, TypeError: Cannot set property 'getVersion' of undefined

Changing the handler method signature to export const getVersion ... and it works again. Just if someone has the same issue…

No problem 😄 , I think the peer dependency issue is then resolved with the PR as request is added now as it is added automatically.

You could be right, that the issue has something to do with the handling of the native url module. Which Node version do you use locally? Maybe the Node version used locally and on AWS Lambda are different, so that the compiled code breaks online - just a guess.