serverless-heaven / serverless-webpack

Serverless plugin to bundle your lambdas with Webpack
MIT License
1.72k stars 414 forks source link

Trouble accessing external data file while integrating maxmind geoip library #371

Closed janthonyeconomist closed 6 years ago

janthonyeconomist commented 6 years ago

This is a Bug Report

Description

I get the following error when trying to integrate Maxmind's GeoIP library:

Error: ENOENT: no such file or directory, open '//data/GeoLite2-City.mmdb'

The top of my serverless.yml:

service:
  name: aws-nodejs-typescript
# Add the serverless-webpack plugin
plugins:
  - serverless-webpack

I have the data file in <project root>/data

$ tree data
data
├── GeoLite2-ASN.mmdb
├── GeoLite2-City.mmdb
└── GeoLite2-Country.mmdb

And the handlers file is <project root>/handler.ts. The code that is erroring out is:

const geoipDB = maxmind.openSync(__dirname + '/data/GeoLite2-City.mmdb');

I have even tried using the geolite2 package, and loading it like const geoipDB = maxmind.openSync(geolite2.paths.city); thinking that perhaps if the file was in an NPM package it will be bundled correctly; however, it has the same problem.

The interesting part is, it works if I use const geoipDB = maxmind.openSync('../../data/GeoLite2-City.mmdb'); because it happens to be relative to the build file <project root>/.webpack/service/handler.js; however, this seems dubious at best, and I'm not sure this will work once it goes live.

Am I missing some configuration that tells serverless to include this data file? How can I access accurate paths seeing as the build moves the execution directory?

Similar or dependent issue(s):

Additional Data

janthonyeconomist commented 6 years ago

I also attempted to use the geoip2 https://github.com/davidtsai/node-geoip2 module, but it failed to load the compiled C module var mmdb = require('./lib/node_mmdb.node');. It said I might be missing a loader.

HyperBrain commented 6 years ago

Hi @janthonyeconomist . The reason why your deployed code does not find the mmdb file is, because it is most likely not included in your deployed package. You have to use the copy webpack plugin and configure it in your webpack.config.js to copy the data folder or the mmdb file to your compiled output, so that it gets packaged by webpack.

Additionally, you should update your tools:

Serverless-Webpack Version you're using: ^3.0.0
Webpack version you're using: ^3.6.0

Update serverless-webpack to 5.1.1 to use the latest features and bugfixes. Optionally I'd recommend to upgrade webpack to 4.x.x too.

janthonyeconomist commented 6 years ago

Thanks much! Worked like a charm.