Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SAM deploying TypeScript source code instead of the transpiled JavaScript #86

Open
seansica opened this issue May 27, 2023 · 2 comments
Labels
question Further information is requested

Comments

@seansica
Copy link

seansica commented May 27, 2023

My build process successfully outputs webpack .js artifacts. However, when I deploy to AWS, only the original TypeScript files get uploaded, not the transpiled .js and .map.js files shown below. I cannot for the life of me figure out why this is happening.

Running webpack-cli produces:

.aws-sam
└── build
    ├── ConfigFunction
    │   ├── index.js
    │   └── index.js.map
    ├── DiscordNotifierFunction
    │   ├── index.js
    │   └── index.js.map
    ├── QueuePublisherFunction
    │   ├── index.js
    │   └── index.js.map
    ├── ShopifySyncFunction
    │   ├── index.js
    │   └── index.js.map
    └── template.yaml

But when I deploy the stack, the deployed lambda packages only include the orginal TypeScript files, not the webpack bundles.

Example:
image

Ignore the fact that the file is named app instead of index -- this is because I've been trying different things and happened to grab a screenshot before I switched to using index. The important part is that the .ts source code is getting deployed instead of the .js files that are generated in the .aws-sam/build directory.

Here is my webpack config. Note that I added an --env flag to webpack to more easily switch between template.prod.yaml and template.dev.yaml.

webpack.config.cjs:

const path = require("path");
const AwsSamPlugin = require("aws-sam-webpack-plugin");

const getEnvironment = (env) => {
    if (env.prod) {
        return 'prod';
    }
    if (env.dev) {
        return 'dev';
    }
    throw new Error('No valid Webpack environment set');
};

module.exports = (env) => {
    const environment = getEnvironment(env);
    const awsSamPlugin = new AwsSamPlugin({
        projects: {
            [environment]: `./template.${environment}.yaml`,
        },
        outFile: "index"
    });
    return {
        entry: () => awsSamPlugin.entry(),
        output: {
            filename: (chunkData) => awsSamPlugin.filename(chunkData),
            libraryTarget: "commonjs2",
            path: path.resolve("."),
        },
        devtool: "source-map",
        resolve: {
            extensions: [".ts", ".js"],
        },
        target: "node",
        externals: process.env.NODE_ENV === "development" ? [] : ["aws-sdk"],
        mode: process.env.NODE_ENV || "production",
        module: {
            rules: [{ test: /\.tsx?$/, loader: "ts-loader" }],
        },
        plugins: [awsSamPlugin],
    };
};

To deploy, I run sam deploy --config-env dev or sam deploy --config-env default.

samconfig.toml:

version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "shopify-bot"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1n1zoqn89o0dg"
s3_prefix = "shopify-bot"
region = "us-east-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
image_repositories = []
profile = "AdministratorAccess-328571739532"
template_file = "template.prod.yaml"

[dev]
[dev.deploy]
[dev.deploy.parameters]
stack_name = "shopify-bot-dev"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-csuag1qx37c0"
s3_prefix = "shopify-bot-dev"
region = "us-east-2"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
image_repositories = []
profile = "AdministratorAccess-328571739532"
template_file = "template.dev.yaml"

Here is how my lambda files are organized:

├── lambdas
│   ├── checkAllInventory
│   │   └── index.ts
│   ├── config
│   │   └── index.ts
│   ├── discordNotifier
│   │   └── index.ts
│   ├── queuePublisher
│   │   └── index.ts
│   └── shopifySync
│       └── index.ts
├── package-lock.json
├── package.json

Here are the CodeUri and Handler properties declared in my SAM templates:

Resources:

  ConfigFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: ConfigFunction
      CodeUri: lambdas/config
      Handler: index.handler

  ShopifySyncFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: ShopifySyncFunction
      CodeUri: lambdas/shopifySync
      Handler: index.handler

  QueuePublisherFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: QueuePublisherFunction
      CodeUri: lambdas/queuePublisher
      Handler: index.handler

  DiscordNotifierFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: DiscordNotifierFunction
      CodeUri: lambdas/discordNotifier
      Handler: index.handler

Any help in understanding why SAM is deploying TypeScript files despite webpack correctly outputting ECMAScript files to .aws-sam/build/ would be appreciated!

@seansica
Copy link
Author

seansica commented May 28, 2023

So I found an interesting workaround:

sam deploy --template-file .aws-sam/build/template.yaml --config-file ~/dev/shopify-monitor/samconfig.toml --config-env dev --guided

For some reason, specifying the relative path to the template and the absolute path to samconfig.toml resolved the issue. SAM is deploying the transpiled .js code from .aws-sam/build/ now.

I tried passing a relative path to samconfig.toml but that did not work:

> sam deploy --template-file .aws-sam/build/template.yaml --config-file ./samconfig.toml --config-env dev --guided                    

Error: Config file ./samconfig.toml does not exist or could not be read!

This leaves some outstanding questions:

  1. Why is samconfig.toml not in the relative path of the SAM CLI when I execute sam deploy ... from the
    same directory? I've never had to set the absolute path to the samconfig.toml file before.
  2. Same question. Why do I need to explicitly specify the path to .aws-sam/build/template.yaml? I've never had to set the path to .aws-sam/build/template.yaml before.

To clarify, here is the process I am following to deploy my code:

  1. Build the stack webpack-cli --env prod
  2. Deploy the stack: sam deploy --config-env dev

Step 1 definitively builds the intended stack. We can verify this by looking at the contents of .aws-sam/builld/ after Step 1 and checking that only bundled JS files are present. This is the case.

Step 2 seems to lack harmony with Step 1. While Step 2 technically works in that AWS SAM successfully deploys the defined resources to AWS, it somehow deploys the original TypeScript files instead of the JS bundles that were generated in Step 1.

@buggy
Copy link
Collaborator

buggy commented May 29, 2023

Originally SAM CLI had separate steps for build, package and deploy. The plugin replaces the build step in that original 3 step process. My best guess is that it's incompatible with the newer guided deployment that sam deploy offers. That would make sense because SAM is going to use it's own build step instead of this plugin.

@buggy buggy added the question Further information is requested label May 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants