digitalmaas / serverless-plugin-browserifier

Reduce the size and speed up your Node.js based lambda's using browserify.
Other
27 stars 3 forks source link

How to handle multiple entries #13

Closed kvarela closed 4 years ago

kvarela commented 5 years ago

As soon as I added multiple entry points to my custom.browserify options, AWS is no longer able to find my handlers.

For example, I see AWS errors like: Handler 'webhook' missing on module 'src/handlers/graphql'

Even though when I inspect the bundle and looks at the .js, I see exports.handler defined. image

Interestingly though, a different function does work and AWS is able to find the handler.

And when I only include 1 entry in entries, the function for which I add the entry works, but the others do not.

None of my handlers have the same name.

Please let me know if you have any ideas.

Here's a stripped version of my serverless.yml:

package:
    individually: true
    excludeDevDependencies: true
    include:
        - node_modules/dotenv/**/*
        - node_modules/envkey/*
        - node_modules/envkey/ext/envkey-fetch_1.2.4_linux*/*
        - node_modules/glob/**/*
        - node_modules/fs.realpath/**/*
        - node_modules/minimatch/**/*
        - node_modules/brace-expansion/**/*
        - node_modules/concat-map/**/*
        - node_modules/balanced-match/**/*
        - node_modules/inherits/**/*
        - node_modules/path-is-absolute/**/*
        - node_modules/inflight/**/*
        - node_modules/wrappy/**/*
        - node_modules/once/**/*

functions:
    expedia-update:
        handler: src/handlers/expedia.update

    graphql:
        handler: src/handlers/graphql.handler
        events:
            - http:
                  path: graphql
                  method: post
                  cors: true

    membership-check:
        handler: src/handlers/membership.check

    stripe:
        handler: src/handlers/stripe.webhook
        events:
            - http:
                  path: stripe
                  method: post
                  cors: true

plugins:
    - serverless-plugin-browserifier
    - serverless-offline

custom:
    browserify:
        basedir: ./
        entries:
            [
                'src/handlers/graphql.ts',
                'src/handlers/stripe.ts',
                'src/handlers/membership.ts',
                'src/handlers/expedia.ts',
            ]
        exclude:
            - envkey
            - dotenv
            - glob
            - fs.realpath
            - minimatch
            - brace-expansion
            - concat-map
            - balanced-match
            - inherits
            - path-is-absolute
            - inflight
            - wrappy
            - once
        require:
            - node_modules/envkey
            - node_modules/dotenv
            - node_modules/glob
            - node_modules/fs.realpath
            - node_modules/minimatch
            - node_modules/brace-expansion
            - node_modules/concat-map
            - node_modules/balanced-match
            - node_modules/inherits
            - node_modules/path-is-absolute
            - node_modules/inflight
            - node_modules/wrappy
            - node_modules/once
        node: true
        debug: false
        extensions: ['.ts']
        plugin:
            - tsify
nolde commented 5 years ago

Hello @kvarela !

You seem to be trying to work around a limitation that I have just noticed by looking into your config: the file extension.

The plugin gets the file used in the handler option of each function and tries to find a .js file -- notice that there is no extension there. As you are using .ts files, the plugin is unable to find your entrypoint.

I will add a new property to allow manual override of the extension being used.

In the meantime, you should be able to work around the issue by changing the extension of your entrypoint file to .js or, if that fails, to create a dummy entrypoint .js file that just requests your .ts file straight away, and then tsify should be able to pick up from there.

That should allow you to remove all that unneeded configuration you have in your custom.browserify entry, leaving just the plugin option.

kvarela commented 5 years ago

Thanks @nolde. Not sure I understand. For each function, a .zip file is created and inside the .zip file is a file like graphql.js, stripe.js, expedia.js, or membership.js image

So it seems like the correct .js files are being created. Or am I misunderstanding something?

nolde commented 5 years ago

Hi @kvarela !

The way the plugin works is to invoke a new browserify instance for each function, using the handler lambda function file as the entrypoint. This will generate a .zip file for each function, with only the code needed for each specific function to run.

If you manually add additional entrypoints to the global browserify options, you will be adding more code than needed to every function, which defeats the purpose of the plugin, and might confuse AWS when trying to invoke the correct handler function.

Also, browserify verifies your require invocations in code, so there is usually no needed to manually determine requires in browserify; let it handle it.

The plugin code is really simple, I encourage you to take a look at it, it might make things a little clearer. I am kind of swamped with work at the moment, but I'll try to flexibilise the extensions as mentioned in my previous answer. I would be willing to accept pull-requests as well, if you feel so inclined =) .

kvarela commented 5 years ago

Ok, looks like it's working after removing all the entries.