serverless-plugin-optimize icon indicating copy to clipboard operation
serverless-plugin-optimize copied to clipboard

[TypeScript Plugin] ENOENT: no such file or directory 'node_mnode_modules/...'

Open darbio opened this issue 7 years ago • 11 comments

When I set external in the serverless.yml options to be the name of two node modules (which exist) I get the following error:

ENOENT: no such file or directory, lstat '/Users/darbio/Repositories/tsz/tsz-serverless-api/.build/node_mnode_modules/nodemailer'

Function:

  wp-shared-email:
    handler: functions/workers/shared/email/handler.index
    optimize:
      external: [
        'nodemailer',
        'email-templates'
      ]
    events:
      - sns:
          topicName: ${self:custom.sns-topic-shared-email}
          displayName: SNS topic for sending email

Error:

192-168-1-101:tsz-serverless-api$ serverless deploy function -f wp-shared-email --aws-profile tsz-dev --stage dev
Serverless: Configuring serverless offline -> localstack
Serverless: Configuring serverless offline -> kinesis consumer
Serverless: Compiling with Typescript...
Serverless: Using local tsconfig.json
Serverless: Typescript compiled.
Serverless: Optimize: starting engines
Serverless: Optimize: tsz-serverless-api-dev-wp-shared-email

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

  ENOENT: no such file or directory, lstat '/Users/darbio/Repositories/tsz/tsz-serverless-api/.build/node_mnode_modules/nodemailer'

     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:                     darwin
     Node Version:           6.9.4
     Serverless Version:     1.26.0

darbio avatar Feb 26 '18 05:02 darbio

I did some analysis of the source code and found that the issues is the following:

const externalDir = externalEntry.substring(
            this.serverless.config.servicePath.length,
            externalEntry.lastIndexOf('node_modules/' + external)
          ) + 'node_modules/' + external

In my example, this gets evaluated as substring(77, 71) + 'node_modules/' + external which is incorrect (as my functions are built into a .build folder using typescript-plugin) hence the node_mnode_modules string.

This plugin doesn't seem to honour the sub-folder that the functions are built into, instead expecting them to be in the root folder.

Changing this to the following seems to solve the issue:

const externalDir = externalEntry.substring(
            externalEntry.lastIndexOf('node_modules/' + external),
            externalEntry.indexOf(external) + external.length
          )

I had some packaging issues after this fix with regards to external libraries not being able to be found. To fix this, I had to walk through the dependency tree of the external node_modules used by the packages and include any which have symlinks in the folder structure (particularly .bin).

darbio avatar Mar 04 '18 23:03 darbio

@darbio I never used TS with SLS. So this needs to be fixed.

Have you came to a externalDir code that works with TS? I can give it a test without TS.

goncaloneves avatar Apr 09 '18 18:04 goncaloneves

@goncaloneves I got it working with the code above, however I never got around to doing a PR as we ditched the external library. The TS plugin transpiles to a ‘.build’ folder.

darbio avatar Apr 09 '18 22:04 darbio

@darbio are you still using TS plugin with optimize? Want to understand if the issue here is TS compatibility or specific only to those libraries. Thanks for taking the time to explain.

goncaloneves avatar Apr 10 '18 09:04 goncaloneves

Still using the package.

The problem only manifested itself when I used the external config option.

The problem is that the TS gets transpiled to a folder (.build) which changes the substring dry algorithm in this plugin.

Changing the code as per my above post fixes the issue - however I haven't tested with non TS projects. It should work, but it needs to be tested.

The external library that I was using failed because it symlinked to other external packages that no longer existed at that symlink.

Another failed due to not being compatible with the minification process (not a problem with this project).

darbio avatar Apr 10 '18 22:04 darbio

To clarify: With the code change I suggested above, I believe the issue is fixed.

darbio avatar Apr 10 '18 22:04 darbio

Awesome @darbio. I will give it a go in the next few days without TS 👍

goncaloneves avatar Apr 11 '18 09:04 goncaloneves

I'm having the same issue above. Any fix from the library distribution side?

shashikac avatar Feb 24 '22 07:02 shashikac

This one works fine in the Linux environment

shashikac avatar Mar 02 '22 07:03 shashikac

Same for me - is there any progress on this topic

OperationalError: ENOENT: no such file or directory, stat 'XXXX/server/.build/node_mnode_modules/swagger-ui-dist'] {
  cause: [Error: ENOENT: no such file or directory, stat 'XXXX/server/.build/node_mnode_modules/swagger-ui-dist'] {
    errno: -2,
    code: 'ENOENT',
    syscall: 'stat',
    path: 'XXXX/server/.build/node_mnode_modules/swagger-ui-dist'
  },
  isOperational: true,
  errno: -2,
  code: 'ENOENT',
  syscall: 'stat',
  path: 'XXXX/server/.build/node_mnode_modules/swagger-ui-dist'
custom:
  optimize:
    external: ['swagger-ui-dist']

MaLub avatar Apr 01 '22 17:04 MaLub

This might help: https://github.com/serverless/serverless-plugin-typescript/issues/239#issuecomment-1313951913

x71c9 avatar Nov 14 '22 15:11 x71c9