Enigmatic-Smile / serverless-plugin-optimize

⛔️ DEPRECATED ⛔️ Bundle with Browserify, transpile and minify with Babel automatically to your NodeJS runtime compatible JavaScript

Home Page:https://www.npmjs.com/package/serverless-plugin-optimize

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

darbio opened this issue · comments

commented

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
commented

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 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.

commented

@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 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.

commented

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).

commented

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

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

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

This one works fine in the Linux environment

commented

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']