serverless-heaven / serverless-webpack

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

Webpack throws ENOENT if there is no dependency #1898

Open HyperDwarf opened 2 months ago

HyperDwarf commented 2 months ago

This is a Bug Report

Description

However, when I tried to deploy a single function, which depends only on aws-api, it throws the error below:

[OperationalError: ENOENT: no such file or directory, lstat '***.webpack\dependencies\node_modules'] {
  cause: [Error: ENOENT: no such file or directory, lstat '***.webpack\dependencies\node_modules'] {
    errno: -4058,
    code: 'ENOENT',
    syscall: 'lstat',
    path: '***.webpack\\dependencies\\node_modules'
  },
  isOperational: true,
  errno: -4058,
  code: 'ENOENT',
  syscall: 'lstat',
  path: '***.webpack\\dependencies\\node_modules'
}

The package.json under .webpack/dependencies:

{
  "name": "test",
  "version": "1.0.0",
  "description": "Packaged externals for test",
  "private": true,
  "scripts": {},
  "dependencies": {
    "": ""
  }
}

It generates a weird "" in dependencies, and the problem still persists even if I exclude "" from serverless.yml or webpack-config.js Making a node_modules manually won't help either, because webpack (or serverless) removes the directory when packing. Could be related to #497.

custom: webpack: webpackConfig: "webpack.config.js" includeModules: forceExclude:

...


`webpack-config.js`:

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

const isLocal = slsw.lib.webpack.isLocal;

module.exports = { mode: isLocal ? 'development' : 'production', entry: slsw.lib.entries, externals: [ nodeExternals(), "@aws-sdk/client-s3", "@aws-sdk/client-dynamodb", "@aws-sdk/client-sqs", "@aws-sdk/util-dynamodb" ], devtool: 'source-map', resolve: { extensions: ['.js', '.jsx', ".mjs", '.json', '.ts', '.tsx'] }, output: { libraryTarget: 'commonjs2', path: path.join(__dirname, '.webpack'), filename: '[name].js' }, target: 'node', cache: { type: 'filesystem', allowCollectingMemory: true, cacheDirectory: path.resolve('.webpackCache') }, module: { rules: [ { // Include ts, tsx, js, and jsx files. test: /.(mjs|ts|js)x?$/, exclude: /node_modules/, use: ['babel-loader'] } ] }, plugins: [] };



* What stacktrace or error message from your provider did you see?
As above.

## Additional Data

* ***Serverless-Webpack Version you're using***:
5.14.1

* ***Webpack version you're using***:
5.92.1

* ***Serverless Framework Version you're using***:
3.39.0

* ***Operating System***:
Windows 11

* ***Stack Trace (if available)***:
As above.
j0k3r commented 2 months ago

Is there any chance you create a minimal repo with a reproduction of the bug? It'll help us investigate.

HyperDwarf commented 2 months ago

Is there any chance you create a minimal repo with a reproduction of the bug? It'll help us investigate.

Sorry for the late reply.

After some investigation, I think I found the cause. The problem is I am trying to import dependency which is installed on efs.

I have to use tensorflow-js on lmabda, which contains some native binaries to accelerate inferences.

According to the guide provided by AWS, I will have to first create an amazon linux2 instance, install the tfjs to somewhere, then let lambda import the module from the install location.

In my case I install tfjs to efs. But this make webpack fails for some reason.

Here is the minimal repo: https://github.com/HyperDwarf/sls-test

So I think I should rather ask, how to exclude imports that does not present in package.json correctly?