aws / aws-sam-cli

CLI tool to build, test, debug, and deploy Serverless applications using AWS SAM
https://aws.amazon.com/serverless/sam/
Apache License 2.0
6.5k stars 1.17k forks source link

esbuild (and TypeScript) Beta Support Feedback #3700

Closed mildaniel closed 1 year ago

mildaniel commented 2 years ago

esbuild Support Beta

Recently, we added support for building Node.js and TypeScript lambda functions with esbuild. This allows for bundling and minification of Node.js functions and eases the process of writing TypeScript-based lambdas.

We now want to hear your feedback on the experience.

What feedback are we looking for?

  1. How is the new TypeScript development experience? Is there any way that we can make it better for building and testing TypeScript?
  2. How is the general user experience of configuring and using esbuild?
collindutter commented 2 years ago

This is a very exciting feature, great work!

Can we use the full esbuild API under BuildProperties? I'm trying to provide aws-sdk as an external, but it doesn't seem to have any effect:

    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        External: 
          - 'aws-sdk'

Error after sam build:

✘ [ERROR] Could not resolve "aws-sdk"

    app.ts:11:20:
      11 │ const AWS = require('aws-sdk');
         ╵                     ~~~~~~~~~

  You can mark the path "aws-sdk" as external to exclude it from the bundle, which will remove this error. You can also surround this "require" call with a try/catch block to handle this failure at run-time instead of bundle-time.
mildaniel commented 2 years ago

Can we use the full esbuild API under BuildProperties?

Unfortunately we don't have support for the entire esbuild API, but having an option to set the aws-sdk as external definitely makes sense.

Thanks for the feedback!

LuizPelegrini commented 2 years ago

Hi @mildaniel the feature certainly brings some handful build shortcuts when developing my lambdas in Typescript

I also have the same question as @collindutter's. I would not like to have my dependencies bundled with my lambda function, I would like to use AWS Layers instead, how can I achieve this?

iRoachie commented 2 years ago

Hey folks, just tried this out. Couple of pain points I found:

mildaniel commented 2 years ago

Thanks everyone, this is all great feedback.

Just wanted to quickly address some of it:

mildaniel commented 2 years ago

@iRoachie

esbuild is required in the dependencies for each function which seems a bit noisy. Most js projects will have a top-level pacakge.json. Would make sense to have it as a dev dependency there. Same thing for eslint, prettier, etc

Could you expand on this a little bit? The way it currently works is by installing the dependencies in the package.json at the CodeURI level. If esbuild is there as a dev dependency, Lambda Builders should find and use the corresponding executable.

iRoachie commented 2 years ago

@mildaniel Yes what you said is correct but that would mean if I have 10 functions, I have to install esbuild as a dependency for each one.

This is kinda backwards from how a normal JS project would be set up. Usually, there would be a top-level package.json that includes all your dev dependencies like esbuild, prettier, eslint etc.

For example, this is how esbuild works in CDK atm - https://docs.aws.amazon.com/cdk/api/v1/docs/aws-lambda-nodejs-readme.html#local-bundling. One install of esbuild at the root package.json that is used for all functions.

nocquidant commented 2 years ago

As a user, this is also one of my concerns...

For me, one package.json and one node_modules folder per function was needed to avoid zipping all the dependencies and deploying the full zip with every function, even the one with no dependencies.

But it seems to me that it's not really necessary anymore because bundling with esbuild involves tree shaking (size is no longer an issue).

That said, changing a "shared" dependency will impact all functions that were using that dependency and cause a new redeployment.

chris-armstrong commented 2 years ago
  1. The new esbuild functionality is great, but because sam build isn't integrated with sam local start-api or sam local invoke, I need to either run 'sam build' before I use these. It would be great to have it integrated with esbuild's watch mode, which is really fast for rebuilding assets (I know this might be difficult given the way esbuild has been integrated, running a separate build for each file instead of one integrated build).
  2. It's very easy, but as mentioned, redeclaring the Metadata section is tedious. Also, by switching the CodeUri to point to the typescript file, I can no longer run a separate esbuild in watch mode pointing to a dist folder - I'm forced to generate the JS files in the same directory, which then interferes with my tests (which I run with jest).
mildaniel commented 2 years ago

@nocquidant

That said, changing a "shared" dependency will impact all functions that were using that dependency and cause a new redeployment.

Would being able to mark that shared dependency as external and including it in a layer resolve this issue?

nocquidant commented 2 years ago

@mildaniel I think so. But this behavior is not an issue for me, I just wanted to mention it. Personally, I try to use layers only for heavy dependencies or system dependencies, but not as a package manager.

collindutter commented 2 years ago

Does sam esbuild use the tsconfig for a project? I'm trying to set the baseDir to avoid using relative paths, but sam esbuild doesn't seem to be picking it up. When I run esbuild manually, it works fine.

My problem is very similar to this issue: https://github.com/evanw/esbuild/issues/2044

fbn-roussel commented 2 years ago

With the recent support of ESM in Lambda, it could be nice to support the format option from esbuild to allow esm instead of forcing the use of cjs.

https://esbuild.github.io/api/#format-esm

chris-armstrong commented 2 years ago

Another thing - with sam sync running on a large project, it is incredibly slow (minutes) to get to a state where I can start modifying functions (and difficult to recognise when, because when you think it is ready its just spinning for a minute or two)

Cephyric-gh commented 2 years ago

Support for esbuild plugins would be very helpful as currently this will only really work for pretty basic lambda functions. Being able to specify plugins for esbuild to use will allow compilation of certain typescript features that Evan has said that esbuild will never support, like decorators.

As an example (pulled right from the issue linked above) - any project that uses TypeORM to access a database (or most of their alternatives, e.g. Sequelize in my use-case) cannot currently use native compilation and must stick to any current build process that exists. I'd love to switch to this as I have been looking to replace my webpack build process with esbuild for quite a while, since webpack is notoriously slow to build

jelder commented 2 years ago

Adding to @collindutter, support for esbuild --external has broad application beyond just omitting aws-sdk. In my particular case I need to use a Node module that is not compatible with esbuild (Knex). It would be ideal if the schema allowed for a list of exclusions.

chris-armstrong commented 2 years ago

Adding to @collindutter, support for esbuild --external has broad application beyond just omitting aws-sdk. In my particular case I need to use a Node module that is not compatible with esbuild (Knex). It would be ideal if the schema allowed for a list of exclusions.

I’ve started submitting patches for —external and others - what esbuild options do you think are also useful?

maryborgwat commented 2 years ago

Am I reading correctly (from above) that you cannot use typeORM with SAM (build) ? I get an error saying "aws_lambda_builders.actions.ActionFailedError: Esbuild Failed: ✘ [ERROR] Could not resolve "pg-native". exclude pg-native to resolve the issue. It is unclear to me where you would exclude it (in the SAM Build process) and if you exclude it would that resolve the problem?

Cephyric-gh commented 2 years ago

Am I reading correctly (from above) that you cannot use typeORM with SAM (build) ? I get an error saying "aws_lambda_builders.actions.ActionFailedError: Esbuild Failed: ✘ [ERROR] Could not resolve "pg-native". exclude pg-native to resolve the issue. It is unclear to me where you would exclude it (in the SAM Build process) and if you exclude it would that resolve the problem?

Until SAM supports both the --external flag and the ability to specify esbuild plugins/config for them it can't build packages like TypeORM. You need --external as that is where you'd specify pg-native as excluded from the build, and you need plugins to be able to compile the TypeORM decorators

zdorow commented 2 years ago

This is a great feature and makes building for typescript super easy. Excluding external would solve our main issues with using it as well. Putting everything into one file makes you responsible for all the code in your dependencies, deprecation warnings and all so it can make things problematic when you have to use a dependency that cannot be updated as they get logged in the lambda and trigger alarms.

mildaniel commented 2 years ago

The external flag option is definitely an important feature that we plan on adding. We're also looking into improvements of esbuild with accelerate to make that a smoother experience.

Thank you for the feedback!

gnowakpoloniex commented 2 years ago

Having watch mode would be incredibly helpful

mildaniel commented 2 years ago

Having watch mode would be incredibly helpful

This is already part of accelerate which is usable with esbuild! Is there a reason for not using accelerate for iterating and testing?

praneetap commented 2 years ago

Another thing - with sam sync running on a large project, it is incredibly slow (minutes) to get to a state where I can start modifying functions (and difficult to recognise when, because when you think it is ready its just spinning for a minute or two)

Hi @chris-armstrong! Thanks for all the great feedback. We were unable to reproduce what you talk about here ^ and I was wonderng if we can get on a call to get more specific repro steps? We would also love to get feedback from you as we are working towards the full GA launch of this feature. Please DM me here, and we can set something up.

yskkin commented 2 years ago

Is deduped build not working when setting Metadata? Migrating to esbuild disables deduped build for me.

erashdan commented 2 years ago

I have an issue to include custom layer


Running NodejsNpmBuilder:CopyNpmrcAndLockfile
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc
Running NodejsNpmBuilder:LockfileCleanUp
Running NodejsNpmEsbuildBuilder:EsbuildBundle
Error: NodejsNpmEsbuildBuilder:EsbuildBundle - Esbuild Failed: ✘ [ERROR] Could not resolve "/opt/nodejs/database"

    latest-posts.ts:4:24:
      4 │ const sayName = require('/opt/nodejs/database')
        ╵                         ~~~~~~~~~~~~~~~~~~~~~~
ryanhaticus commented 2 years ago

Documentation lacking, in my opinion. I can't seem to locate in-depth descriptions of any of the options for the template.yaml file.

Also, I have been experiencing this strange issue:

"errorMessage": "Error: Cannot find module 'app'\nRequire stack:\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js"

coupled within a Runtime.ImportModuleError.

Personally, I don't think the beta is anywhere close to where it needs to be. I think having TypeScript options bundled into Sam CLI as templates is a bad idea while everything is still being ironed out.

gins0023 commented 2 years ago

I've been using esbuild w/ sam sync locally w/ external dependencies and it's worked nicely. However, when running inside of codebuild, I get an error and it seems to not respect the External definition. I'm using the latest runtime version of nodejs in buildspec, but is it possible that the container it's running is lacking some sam-cli features?

This works locally, but not in codebuild.

BuildProperties:
        External:
          - 'pg-native'

Update: I was able to upgrade sam-cli in buildspec

commands:
      - pip install --upgrade pip aws-sam-cli
nubpro commented 2 years ago

Documentation lacking, in my opinion. I can't seem to locate in-depth descriptions of any of the options for the template.yaml file.

Also, I have been experiencing this strange issue:

"errorMessage": "Error: Cannot find module 'app'\nRequire stack:\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js"

coupled within a Runtime.ImportModuleError.

Personally, I don't think the beta is anywhere close to where it needs to be. I think having TypeScript options bundled into Sam CLI as templates is a bad idea while everything is still being ironed out.

I get this error alot Runtime.ImportModuleError. I simply delete .aws-sam from the root folder and re-run the sync command again. Painful, but it does the job.

SAM CLI Team, please thoroughly test this functionality and apply the tool on other aws projects please. Dogfooding, you need it. This tool is great but it's reliability is still something less to be desired.

mildaniel commented 2 years ago

Thanks everyone for the continued feedback, we really appreciate it. We understand the dependency bug is a real pain point for this feature and are looking into it.

@erashdan this issue seems to be that esbuild is searching for the dependency on your machine but can't find it. Try setting those dependencies as External and trying again.

ptejada commented 2 years ago

Was the support for the External option added already?

mildaniel commented 2 years ago

Yes, support for External and Loader were added in 1.49.0.

lightpriest commented 2 years ago

The last esbuild features are awesome and really help us reduce some of the in-house tooling we wrote to support our projects. A couple of issues remain, and they might have an answer in the the current form but I'd appreciate any help here.

  1. How are we expected to deal with dynamic references? For example, sequelize depends on mysql2 at runtime, but dynamically loaded.
  2. Other static files which are not directly referenced (for example, config/ for node-config).

In standard backend project, you can have a giant node_modules directory which includes the "External" dependencies or some other static files. Is there a way you recommend doing this now?

terrywarwar commented 2 years ago

@praneetap I'm also experiencing very slow sam sync of many minutes for a large project.

praneetap commented 2 years ago

@praneetap I'm also experiencing very slow sam sync of many minutes for a large project.

Hey @terrywarwar ! Thanks for reporting this. We are aware of the issue and working on a fix.

jacobduba commented 2 years ago

Here's some feedback: getting unexpected configuration of sourcemaps in the build folder. Debugging with Typescript is not working because the source maps seem to be incorrectly configured. This is the file app.js.map from the build of the hello-world example.

{
  "version": 3,
  "sources": ["../../../../../../../tmp/tmptvm1fyck/app.ts"],
  "sourcesContent": ["import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';\n\n/**\n *\n * Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format\n * @param {Object} event - API Gateway Lambda Proxy Input Format\n *\n * Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html\n * @returns {Object} object - API Gateway Lambda Proxy Output Format\n *\n */\n\nexport const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {\n    let response: APIGatewayProxyResult;\n    try {\n        response = {\n            statusCode: 200,\n            body: JSON.stringify({\n                message: 'hello world',\n            }),\n        };\n    } catch (err) {\n        console.log(err);\n        response = {\n            statusCode: 500,\n            body: JSON.stringify({\n                message: 'some error happened',\n            }),\n        };\n    }\n\n    return response;\n};\n"],
  "mappings": "yaAAA,wDAYO,GAAM,GAAgB,KAAO,IAAgE,CAChG,GAAI,GACJ,GAAI,CACA,EAAW,CACP,WAAY,IACZ,KAAM,KAAK,UAAU,CACjB,QAAS,aACb,CAAC,CACL,CACJ,OAAS,EAAP,CACE,QAAQ,IAAI,CAAG,EACf,EAAW,CACP,WAAY,IACZ,KAAM,KAAK,UAAU,CACjB,QAAS,qBACb,CAAC,CACL,CACJ,CAEA,MAAO,EACX",
  "names": []
}

As you can see the sources point at /tmp and not the source code. This causes line by line debugging to break.

You can reproduce this by using the hello-world example with sam init, and then attaching to the node process with this launch.json.

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Attach to SAM CLI",
      "type": "node",
      "request": "attach",
      "address": "localhost",
      "port": 9999,
      "localRoot": "${workspaceRoot}/.aws-sam/build/HelloWorldFunction",
      "remoteRoot": "/var/task",
      "protocol": "inspector",
      "stopOnEntry": false,
    }
  ]
}
chris-fryer commented 2 years ago

Unable to set breakpoints in TypeScript code via VSCode

I'm also experiencing the same problem as @jacobduba above in being unable to set debug breakpoints within the TypeScript code in the Hello World sample produced by sam init. In VSCode I see the error/warning:

"Some of your breakpoints could not be set. If you're having an issue, you can troubleshoot you launch configuration"

Having done some troubleshooting I can see that when running sam build the app.js and app.js.map get produced in the .aws-sam/build/HelloWorldFunction/ directory, but like @jacobduba in the app.js.map file I see the sources path set to a relative path in a temp folder:

"sources": ["../../../../../../Users/[**removed**]/AppData/Local/Temp/tmpfruu62fk/app.ts"],

Browsing to that path shows the temp folder no longer exists.

I'm running the latest Windows 10, I've tried the latest sam version (1.53.0) and the latest sam nightly (1.53.0.dev202208090902) but have the same issue with both.

The troubleshooting in VSCode suggests that esbuild is producing the app.js.map with the wrong relative path. I've been unable to find the options we can pass into esbuild. Are there any esbuild options I can specify to adjust the relative path to allow me to set TypeScript breakpoints in VSCode? (e.g. in the template.yaml BuildProperties section or via command line for sam build?)

jacobduba commented 2 years ago

@chris-fryer I submitted a PR that fixes the issue.

JamieClayton7 commented 2 years ago

One issue I have just encountered is again tied to the inability to access the entire esbuild API I think. I'm attempting to use uglifyjs and (as intended) esbuild does not resolve "require.resolve()" calls without a plugin to prompt it do so. My Lambda is now throwing:

Runtime.ImportModuleError: Error: Cannot find module '../lib/utils.js'"

from the following uglifyjs code (post esbuild bundling):


var require_node2 = __commonJS({
  "node_modules/uglify-js/tools/node.js"(exports) {
    var fs = require("fs");
    exports.FILES = [
      require.resolve("../lib/utils.js"),
      require.resolve("../lib/ast.js"),
      require.resolve("../lib/transform.js"),
      require.resolve("../lib/parse.js"),
      require.resolve("../lib/scope.js"),
      require.resolve("../lib/compress.js"),
      require.resolve("../lib/output.js"),
      require.resolve("../lib/sourcemap.js"),
      require.resolve("../lib/mozilla-ast.js"),
      require.resolve("../lib/propmangle.js"),
      require.resolve("../lib/minify.js"),
      require.resolve("./exports.js")
    ];```
samesfahani-tuplehealth commented 2 years ago

I'm finding it very hard to configure esbuild as I need it. As others have mentioned, the lack of plugin support is very limiting due to the decoratorMetadata problem that is prevalent when you use esbuild with NestJS, typeorm, etc.

Is there any way I can just tell sam build to run and use a custom build script instead where I call out to esbuild.build() myself directly? Any workarounds would be appreciated.

mildaniel commented 2 years ago

Hey @samesfahani-tuplehealth. I understand where you're coming from with wanting to use the plugins API. There currently isn't a way to use it today, but I'll try to come up with a solution for this.

Thank you for the continued feedback.

samesfahani-tuplehealth commented 2 years ago

Thanks for the quick response @mildaniel.

As a workaround, in case this helps anyone, I just figured I could write my own script build.ts that will call out to esbuild.build() directly and output to an intermediary folder dist/. I then set my CodeUri in my template.yml to dist/ and ran sam build without the new esbuild BuildMethod.

This workaround of course is completely side-stepping the feature at hand here, but it does 1) build and bundle your Javascript as you need it with plugins, exclusions, etc, 2) builds your artifact as sam expects (with proper template.yaml and build.toml files).

Quick dirty example:

build.ts

import { esbuildDecorators } from '@anatine/esbuild-decorators';
import { build } from 'esbuild';

build({
  bundle: true,
  entryPoints: ['src/app.ts'],
  outdir: 'dist',
  external: [
    'pg-native',
  ],
  format: 'cjs',
  platform: 'node',
  plugins: [
    esbuildDecorators({ tsx: false, tsconfig: '../../tsconfig.json' }), // this feature is missing from current set of features!
  ],
  sourcemap: true,
});

Again the only caveat is you set your CodeUri: dist/.

@mildaniel In case this is useful, the serverless framework supports esbuild plugins through the following API: https://www.serverless.com/plugins/serverless-esbuild#esbuild-plugins

Even in our codebase there are nuances with certain libraries needing static files copied over and as mentioned the decorator issue. While I do see the appeal in providing an abstraction over esbuild by exposing only the minimum required flags, inevitably someone is going to need some flag exposed or want some specific nuance. I fear that by the end of it, all of esbuild.BuildOptions will be exposed in a clunky yaml format. Perhaps what might be best is to just provide the basic minimum set of fields as they currently are, but support a backchannel format to run a build script for advanced cases where users need more granular control over their build. Just food for thought, of course!

mildaniel commented 2 years ago

Thanks for providing a workaround @samesfahani-tuplehealth.

Perhaps what might be best is to just provide the basic minimum set of fields as they currently are, but support a backchannel format to run a build script for advanced cases where users need more granular control over their build.

This is my thinking too. I will need to put some more thought into how exactly to support plugins through the SAM-CLI, bu ultimately would like to have support for something like this as well.

tunesmith commented 2 years ago

I'm having trouble figuring out how to attach the IntelliJ debugger and breakpoints when using typescript. Using sam local start-api, I can invoke api requests using curl/Insomnia/whatever, but currently I have to sam build whenever I make changes (rather than have it auto-reload) since it requires reading from .aws-sam. And I'm needing to use console.log for debugging since I can't attach the debugger.

As for the debugger, so far I've tried:

1) using tsc to compile to a build folder and pointing template.yml to that build folder, but the problem there is the /opt import path which lambda requires for layers paths. (I otherwise have this working using the tsconfig.json paths config.)

2) Using .aws-sam and turning on Sourcemap: true in Metadata:BuildProperties, but I'm not sure how to link it to my actual typescript source file breakpoints when developing. I've tried --debug-port. (Tangent: If this is on the right path, can we get "intrinsic functions" support in the Metadata section? I'd like Sourcemap to be an env-specific parameter.)

lucashfreitas commented 1 year ago

@tunesmith yeah I also had a hard time getting the debug function to work as we have very little content/tutorials on that, but I managed to get that working - ofc there is a lot that can be done to improve the developer experience, but basically, you should be able to get the debug working on typescript by following this tutorial:

  1. Add this launch.json file (You need to modify some files as I highlight)
{
    "configurations": [
        {
            "type": "node",
            "request": "attach",
            "name": "Attach to SAM Local Invoke",
            "address": "localhost",
            "port": 8066, //the port used when you trigger the function in debug mode
            //Modify this to match the .aws-sam output from your function
            "localRoot": "${workspaceRoot}/.aws-sam/build/DemoFunction",
            "remoteRoot": "/var/task",
            "skipFiles": [
                "<node_internals>/**",
                "/var/runtime/**/*.js",
                "/var/runtime/node_modules/**",
            ],
            "protocol": "inspector",
            "stopOnEntry": false,      
            //Modify this to match the .aws-sam output from your function
            "outFiles": ["${workspaceRoot}/.aws-sam/build/DemoFunction/**/*.js"]
        },

    ]
}
  1. Run the lambda into debug mode:

sam local invoke DemoFunction --env-vars env.json -d 8066 -e event.local.json: Note the DEBUG port must match the port defined in the launch.json

  1. Once the debug start you need to attach the debugger to get the function running on debug mode. Then you should be able to debug it.

Note: For every change you need to "rebuild" your lambda function, so you can use nodemon to watch file changes and run sam build in paralel.

Please let me know if you need any extra help.

sebelga commented 1 year ago

I am testing esbuild with typescript and I get a strange behaviour when using layers. I have the node_modules layer referenced in my function. When I want to use a dependency, import does not work but require does...

import uuid from 'uuid'; // This will be undefined and thus does not work

const uuid = require('uuid'); // This will work

The problem is that using require returns any which defeats the purpose of using Typescript. Any idea why this is happening and if it is expected to use require?

[EDIT]: Answering my own question: I needed to change my import to make it work

import * as uuid from 'uuid';
sebelga commented 1 year ago

I have been now debugging the following error for a while ...

2022-10-26T08:44:10.921Z    undefined   ERROR   Uncaught Exception  {"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'app'\nRequire stack:\n- /var/runtime/index.mjs","stack":["Runtime.ImportModuleError: Error: Cannot find module 'app'","Require stack:","- /var/runtime/index.mjs","    at _loadUserApp (file:///var/runtime/index.mjs:1000:17)","    at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1035:21)","    at async start (file:///var/runtime/index.mjs:1200:23)","    at async file:///var/runtime/index.mjs:1206:1"]}
26 Oct 2022 08:44:10,933 [ERROR] (rapid) Init failed error=Runtime exited with error: exit status 129 InvokeID=
2022-10-26T08:44:10.981Z    undefined   ERROR   Uncaught Exception  {"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'app'\nRequire stack:\n- /var/runtime/index.mjs","stack":["Runtime.ImportModuleError: Error: Cannot find module 'app'","Require stack:","- /var/runtime/index.mjs","    at _loadUserApp (file:///var/runtime/index.mjs:1000:17)","    at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1035:21)","    at async start (file:///var/runtime/index.mjs:1200:23)","    at async file:///var/runtime/index.mjs:1206:1"]}
END RequestId: 790ce6af-fac8-4dd8-9433-f3a7ebee7876
REPORT RequestId: 790ce6af-fac8-4dd8-9433-f3a7ebee7876  Init Duration: 0.14 ms  Duration: 123.99 ms Billed Duration: 124 ms Memory Size: 128 MB Max Memory Used: 128 MB
{"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'app'\nRequire stack:\n- /var/runtime/index.mjs","trace":["Runtime.ImportModuleError: Error: Cannot find module 'app'","Require stack:","- /var/runtime/index.mjs","    at _loadUserApp (file:///var/runtime/index.mjs:1000:17)","    at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1035:21)","    at async start (file:///var/runtime/index.mjs:1200:23)","    at async file:///var/runtime/index.mjs:1206:1"]}%

I could not find the reason why suddenly it was not finding my module app.. I tried everything... until I finally see at async Object.UserFunction.js.module.exports.load. Not sure what the UserFunction refers to (maybe some old trials) ??

I rename my initial LoadFooFunction in my template.yaml to UserFunction and run

sam local invoke UserFunction

It works!

I changed back the name to LoadFooFunction

sam local invoke LoadFooFunction

It throws the above error... I then changed the name to something completely different TestFunction: it works Back to LoadFooFunction: it throws

It seems like there is a caching issue somewhere.

sriram-mv commented 1 year ago

This issue will be closed after collecting the separate feedback requests into individual issues. esBuild support is now GA.

serkan-ozal commented 1 year ago

Hi all,

In Thundra, we are also suffering from the same problem. Currently only workaround I see is that manually editing source map file to point to the workspace path ("../../../hello-world/app.ts") instead of "scratch dir".

Is there any other workaround and/or how we can automate this manual editing as part of sam build?

mildaniel commented 1 year ago

@serkan-ozal, there aren't any automated ways of doing that today withing sam build. However, this is an issue we're tracking and are looking to resolve.