serverless-webpack: loading native library failing with "Can't resolve" error

This is a Bug Report

I created an stackoverflow question for the same, i’m pasting the full content from there.

The stackoverflow link: https://stackoverflow.com/questions/50188865/load-native-npm-x509-package-using-webpack-in-serverless

I’m testing the aws iot features using serverless framework. So for one usecase I wasn’t to analyse the x509 certificates iot devices register with aws from aws lambdas, I saw npm package named x509 to do it easily. It’s a native package, so I’m building it in Ubuntu 64 bit box to make it compatible with aws environment.

Issues is the webpack is not identifying this npm package even after my package importing it.

The error it saying is,

$ sls package

Serverless: Bundling with Webpack... Time: 245ms Built at: 05/05/2018 11:04:55 AM
                       Asset      Size  Chunks             Chunk Names
               jitr/index.js  11.9 KiB       0  [emitted]  jitr/index jitr/build/Release/x509.node  44.2 KiB          [emitted] Entrypoint jitr/index = jitr/index.js [0] ./jitr/index.js 7.39 KiB {0} [built] [1] external "aws-sdk" 42 bytes {0} [built] [2] ./jitr/node_modules/x509/index.js 1.29 KiB {0} [built] [3] external "fs" 42 bytes {0} [built]

ERROR in ./jitr/node_modules/x509/index.js Module not found: Error: Can't resolve './build/Release/x509' in '/home/serverless/jitr/node_modules/x509'  @ ./jitr/node_modules/x509/index.js 1:11-42  @ ./jitr/index.js

  Error --------------------------------------------------

  Webpack compilation error, see above

     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Forums:        forum.serverless.com
     Chat:          gitter.im/serverless/serverless

  Your Environment Information -----------------------------
     OS:                     linux
     Node Version:           8.10.0
     Serverless Version:     1.26.1

My package dir structure is,

- myproject
-- webpack.config.js
-- serverless.yml
-- jitr
--- index.js <- Here I'm importing x509
--- node_modules
---- x509
----- index.js <- First line: var x509 = require('./build/Release/x509')
----- build/Release/x509.node

My webpack config file

const path = require("path");
const slsw = require("serverless-webpack");
const nodeExternals = require("webpack-node-externals");
const CopyWebpackPlugin = require("copy-webpack-plugin");

module.exports = {
    entry: slsw.lib.entries,
    target: "node",
    output: {
        libraryTarget: "commonjs2",
        path: path.resolve(__dirname, ".webpack"),
        filename: "[name].js"
    },
    module: {
        rules: [
            {
                test: /\.json$/,
                loader: "json-loader"
            },
            {
                test: /\.node$/,
                loader: "node-loader"
            }
        ]
    },
    mode: "none",
    externals: [
        nodeExternals({
            whitelist: ["x509"]
        })
    ],
    plugins: [
        new CopyWebpackPlugin([
            {
                from: "jitr/node_modules/x509/build/Release/x509.node",
                to: "jitr/build/Release/x509.node",
                toType: "file"
            }
        ])
    ]
};

What might be going wrong here ?. I was looking for more debugging steps when doing webpack command, but here i’m using a serverless plugin named serverless-webpack to package and deploy the lambdas.

Aws lambda have access to raw openssl command, if nothing works I have to use that command from nodejs to do the things.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 15 (9 by maintainers)

Most upvoted comments

Yes, you have to uncomment the copy plugin to get the binary library packaged. You have to check if the node file is sufficient or if you need to copy the whole Release folder to get all compiled binaries.

webpack-386-native-modules.zip

I also did some changes to the serverless.yml where I removed unnecessary stuff and enabled includeModules, so that in case the project uses more externals besides x509 it will automatically package them and the correct order of the 2 plugins.

The webpack config also includes the correct “mode” setting to enable debugging when run locally, but using production mode otherwise.

You can ignore the package.json changes. I only added serverless and sls-offline locally so that I could test better with specific versions.

Hi @haridas , good to hear that you found a feasible solution. Using node-forge sounds good, because it internally relies on OpenSSL, which is available in the lambda environments (independent of which version) natively. From this experience the best solution might be, to completely separate lambdas that use native libraries into a single project (as long as they must be done with native libraries).

UPDATE:

Serverless: Bundling with Webpack...
Time: 778ms
Built at: 05/10/2018 12:49:01 AM
            Asset      Size  Chunks             Chunk Names
    jitr/index.js  1.83 KiB       0  [emitted]  jitr/index
jitr/index.js.map     7 KiB       0  [emitted]  jitr/index
Entrypoint jitr/index = jitr/index.js jitr/index.js.map
[0] external "fs" 42 bytes {0} [built]
[1] (webpack)/buildin/module.js 519 bytes {0} [built]
[2] ./jitr/node_modules/x509/build/Release/x509.node 209 bytes {0} [built]
[3] ./jitr/node_modules/x509/index.js 1.17 KiB {0} [built]
[4] ./jitr/index.js 141 bytes {0} [built]
Serverless: No external modules needed
Serverless: Packaging service...

The main reason was that the file name resolver was not configured in webpack.conf.js. It has to be configured to use .node as additional file extension to be able to resolve unqualified requires. However there are some small other things that should be changed… I’ll re-post the zip file with the working/changed configuration as soon as I did some final tests.