npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

serverless-build-modules

v1.0.22

Published

A cli that build a single serverless file from different modular sls files

Downloads

4

Readme

serverless-build-modules

- Design your serverless in small readable files

This cli package was created to turn able the modularization of your serverless files with high amount of configurations like functions and resoruces in small files, in other words, modularize your project structure to keep it legible. So, this cli can build all these modules in a single sls file to be deployed by serverless.

# the problematic:

In the most cases when we are designing our service architecture in serverless, it got a lot of configurations that can easily grow up for each new function added to the serverless file, and at a certain point that files becomes unreadable.

Of course, we can make use of serverless-compose to break our entire architecture in multiple services, but even so, more specific services can end up growing a lot depending on the amount of functions and associated resources at this context.

Then we introduce the serverless-build-module, that allows you to break theses service in modules, where your can define a single function and only the specific resources associated to this function, but that still belongs to the same service, keeping smaller and legible files. When you're done, this cli will merge all modules in a single sls file to be deployed by serverless.


# getting started:

This CLI is designed to run in your CI/CD pipeline with simplicity in mind, with no changes to your existing architecture required.

With this in mind, you just need to:

1 - Install the library

npm install -g serverless-build-modules

2 - Run the cli command before run serverless deploy

$ serverless-build-modules --file serverless.yml

3 - !!! IMPORTANT !!! - To test library in development you must to use the --dev flag, it will create a serverless.build.yml file to check if is everything ok instead of override your original serverless.yml file

$ serverless-build-modules --file serverless.yml --dev
When this command runs, it will merge all serverless.m.yml files into existent serverless.yml files, so keep in mind to just run this command on your CI/CD pipeline, otherelse it will override your original serverless files in development if you not provide the --dev flag.

# how it works?

Firstly the lib will search for the serverless.yml file on directory, if not founded, then it will search for serverless-compose.yml file at the same directory, or if you have a file with a different name, you can provide the arg --file your-sls-filename.yml.

Once the main serverless file is founded, it will identify if is a single service, or a serverless-compose pointing to another directory services and create a map for these paths.

Then for each service path, the library will work in scopped builds, searching for subfolder files called serverless.m.yml, reading its content, resolving relative paths and merging the module on original serverless service file.

On the end, you will get build service files containing all module contents and ready to be deployed by serverless.

keep in mind that your serverless files can co-exists in the same folder structure and the serverless modules will only be merged to its directly parent.

# can you help me with examples? yes!

Imagine you have a serverless file with 3 functions and for each function, attached resources needed to fire the function's trigger.

complex-serverless.yml
service: complex-service

provider:
  name: aws
  stage: ${opt:stage, 'development'}

functions:
  function-module-a:
    handler: modules/module-a/index.handler   
    events:
      - sqs:
          arn: !GetAtt ModuleAQueue.Arn
          batchSize: 1
  function-module-b:
    handler: modules/module-b/index.handler   
    events:
      - sqs:
          arn: !GetAtt ModuleBQueue.Arn
          batchSize: 1
  function-module-c:
    handler: modules/module-c/index.handler   
    events:
      - sqs:
          arn: !GetAtt ModuleCQueue.Arn
          batchSize: 1

resources:
  Resources:
    ModuleAQueue:
      Type: "AWS::SQS::Queue"
      Properties:
        QueueName: module-a-queue
        VisibilityTimeout: 360
        RedrivePolicy:
          deadLetterTargetArn: !GetAtt ModuleADeatLetterQueue.Arn
          maxReceiveCount: 10
    ModuleADeatLetterQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: module-a-dlq
    ModuleBQueue:
      Type: "AWS::SQS::Queue"
      Properties:
        QueueName: module-b-queue
        VisibilityTimeout: 360
        RedrivePolicy:
          deadLetterTargetArn: !GetAtt ModuleBDeatLetterQueue.Arn
          maxReceiveCount: 10
    ModuleBDeatLetterQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: module-b-dlq
    ModuleCQueue:
      Type: "AWS::SQS::Queue"
      Properties:
        QueueName: module-c-queue
        VisibilityTimeout: 360
        RedrivePolicy:
          deadLetterTargetArn: !GetAtt ModuleCDeatLetterQueue.Arn
          maxReceiveCount: 10
    ModuleCDeatLetterQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: module-c-dlq

It is not hard to see that how much more implementations you have on the service, more complex and unreadable it becomes. Then with this library we can split it on modules to keep more simple and readable.

src/serverless.yml
service: simple-service

provider:
  name: aws
  stage: ${opt:stage, 'development'}
src/modules/module-a/serverless.m.yml
functions:
  function-module-a:
    handler: index.handler   
    events:
      - sqs:
          arn: !GetAtt ModuleAQueue.Arn
          batchSize: 1
resources:
  Resources:
    ModuleAQueue:
      Type: "AWS::SQS::Queue"
      Properties:
        QueueName: module-a-queue
        VisibilityTimeout: 360
        RedrivePolicy:
          deadLetterTargetArn: !GetAtt ModuleADeatLetterQueue.Arn
          maxReceiveCount: 10
    ModuleADeatLetterQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: module-a-dlq
src/modules/module-b/serverless.m.yml
functions:
  function-module-b:
    handler: index.handler   
    events:
      - sqs:
          arn: !GetAtt ModuleAQueue.Arn
          batchSize: 1
resources:
  Resources:
    ModuleBQueue:
      Type: "AWS::SQS::Queue"
      Properties:
        QueueName: module-b-queue
        VisibilityTimeout: 360
        RedrivePolicy:
          deadLetterTargetArn: !GetAtt ModuleBDeatLetterQueue.Arn
          maxReceiveCount: 10
    ModuleBDeatLetterQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: module-b-dlq
src/modules/module-c/serverless.m.yml
functions:
  function-module-c:
    handler: index.handler   
    events:
      - sqs:
          arn: !GetAtt ModuleCQueue.Arn
          batchSize: 1
resources:
  Resources:
    ModuleCQueue:
      Type: "AWS::SQS::Queue"
      Properties:
        QueueName: module-c-queue
        VisibilityTimeout: 360
        RedrivePolicy:
          deadLetterTargetArn: !GetAtt ModuleCDeatLetterQueue.Arn
          maxReceiveCount: 10
    ModuleCDeatLetterQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: module-c-dlq

For this scenario, the module becomes readable and maintainable, and on the build moment, after run serverless-build-module we got the same result as complex-serverless.yml ready to be deployed.

On this project example directory, you can find a complex implementation scenario making use of serverless-compose, a shared resources service and another service with two separated modules.


# the relative path resolver

Relative path resolver is used to adjust relative paths from module to its serverless.yml parent, it grants that built serverless.yml keep looking to the right file paths.

Example:

src/modules/module_a/serverless.m.yml
functions:
  module-fn-name:
    handler: index.handler   

Then after built, it will look like:

src/serverless.yml
functions:
  module-fn-name:
    handler: modules/module_a/index.handler   

For while, this library support resolver for the following relative paths:

- functions.*.handler # all function handle paths
- provider.ecr.images.*.path # docker ecr image path on provider

!!! if you find and need to implement more relative path mappings, contact me via github repo.