DEV Community

Discussion on: Managing Multiple Functions with AWS SAM and Webpack

Collapse
 
sandinosaso profile image
Sandino • Edited

Thanks for sharing this is a great post!!.

Regarding your concern about your approach "adding a new function means touching both your template.yaml and your webpack.config.ts files." someone else figured out how to keep them in sync:

// Extract the AWS::Serverless::Function Resources as they
// are the entires we need to compile.
const { Resources } = CloudFormation.yamlParse(fs.readFileSync('template.yml'))

const entries = Object.values(Resources)
  .filter(resource => resource.Type == 'AWS::Serverless::Function')
  .filter(resource => resource.Properties.Runtime.startsWith('nodejs'))

  .map(resource => {
    const file = resource.Properties.Handler.split('.')[0]
    const prefix = resource.Properties.CodeUri.substr(9)

    return {
      name: `${prefix}/${file}`,
      entry: `${prefix}/${file}.ts`,
    }
  })

  .reduce((accumulator, resource) => {
    const { name, entry } = resource

    return Object.assign(accumulator, {
      [name]: path.resolve(entry),
    })
  }, {})

module.exports = {
  entry: entries,
  ...
}
Enter fullscreen mode Exit fullscreen mode

Here is the full config: gist.github.com/henrikbjorn/d2eef5...

I think combining both approaches is a great toolchain to have.

Thank you.

Collapse
 
elthrasher profile image
Matt Morgan

Thanks so much for the comment. I'll definitely try this!

Collapse
 
borduhh profile image
Nick Bordeau

Here's the Typescript version as well.

/** Interface for AWS SAM Function */
interface ISamFunction {
  Type: string;
  Properties: {
    AssumeRolePolicyDocument?: JSON;
    AutoPublishAlias?: string;
    AutoPublishCodeSha256?: string;
    CodeUri?: string;
    Description?: string;
    Environment?: {
      Variables: {
        [key: string]: string;
      };
    };
    Events?: EventSource;
    FunctionName?: string;
    Handler: string;
    Layers?: { [Ref: string]: string }[];
    Runtime: string;
    Timeout?: number;
    Tracing?: string;
    VersionDescription?: string;
  };
}

const { resources } = yamlParse(readFileSync(conf.templatePath, 'utf-8'));

const entries = Object.values(resources)

  .filter((resource: ISamFunction) => resource.Type === 'AWS::Serverless::Function')

  .filter(
    (resource: ISamFunction) =>
      resource.Properties.Runtime && resource.Properties.Runtime.startsWith('nodejs')
  )

  .map((resource: ISamFunction) => ({
    filename: resource.Properties.Handler.split('.')[0],
    entryPath: resource.Properties.CodeUri.split('/').splice(3).join('/'),
  }))

  .reduce(
    (resources, resource) =>
      Object.assign(resources, {
        [`${resource.filename}`]: `./src/${resource.entryPath}${resource.filename}.ts`,
      }),
    {}
  );
Enter fullscreen mode Exit fullscreen mode
Collapse
 
elthrasher profile image
Matt Morgan

Nice and thanks for the reminder. Got to get around to trying this!

Thread Thread
 
elthrasher profile image
Matt Morgan

After leaving the same silly comment twice, I finally got around to putting this in and it works great. Thanks so much for the input!