-
Notifications
You must be signed in to change notification settings - Fork 822
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
Support ES import when amplify mock function #10432
Comments
Hey @bc4253 👋 thanks for taking the time to file this! I've marked this as a feature request for the team to evaluate further 🙂 |
this feature request invalidate the steps mentioned in - https://docs.amplify.aws/cli/function/#graphql-from-lambda these steps won't work without this feature. so link needs to be updated. |
I'm trying to follow steps mentioned here - https://docs.amplify.aws/cli/function/#graphql-from-lambda to call GraphQL API from lambda. stack: 'Error: Could not load lambda handler function due to Error [ERR_REQUIRE_ESM]: Must use import to load ES Module |
The docs should also show how to run the function to try the GraphQL API (with and without amplify mock). |
Hey folks 👋 here is a CommonJS version of the function sample const crypto = require('@aws-crypto/sha256-js');
const { defaultProvider } = require('@aws-sdk/credential-provider-node');
const { SignatureV4 } = require('@aws-sdk/signature-v4');
const { HttpRequest } = require('@aws-sdk/protocol-http');
const fetch = require('node-fetch');
const { Request } = fetch
const { Sha256 } = crypto;
const GRAPHQL_ENDPOINT = process.env.API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT;
const AWS_REGION = process.env.AWS_REGION || 'us-east-1';
const query = /* GraphQL */ `
query LIST_TODOS {
listTodos {
items {
id
name
description
}
}
}
`;
/**
* @type {import('@types/aws-lambda').APIGatewayProxyHandler}
*/
exports.handler = async (event) => {
console.log(`EVENT: ${JSON.stringify(event)}`);
const endpoint = new URL(GRAPHQL_ENDPOINT);
const signer = new SignatureV4({
credentials: defaultProvider(),
region: AWS_REGION,
service: 'appsync',
sha256: Sha256
});
const requestToBeSigned = new HttpRequest({
method: 'POST',
headers: {
'Content-Type': 'application/json',
host: endpoint.host
},
hostname: endpoint.host,
body: JSON.stringify({ query }),
path: endpoint.pathname
});
const signed = await signer.sign(requestToBeSigned);
const request = new Request(endpoint, signed);
let statusCode = 200;
let body;
let response;
try {
response = await fetch(request);
body = await response.json();
if (body.errors) statusCode = 400;
} catch (error) {
statusCode = 500;
body = {
errors: [
{
message: error.message
}
]
};
}
return {
statusCode,
headers: {
"Access-Control-Allow-Headers" : "Content-Type",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET"
},
body: JSON.stringify(body)
};
}; Two notes here:
For testing with mock we can use a dotenv file to manually provide/override environment variables to the function https://docs.amplify.aws/cli/usage/mock/#function-mock-environment-variables |
Using commonjs was causing headaches for me. I have come up with a workaround using Typescript. I am posting my retrospective notes here in hopes it helps others get around this issue if they are willing to use Typescript to solve it or are already using Typescript. Expand this for Typescript setup if you don't already it set up for your function(s)
If you have typescript setup already, you can seemingly just add these 2 lines to
now in index.tsx I can use normal import statements
and in other ts files in that same directory I can use normal module pattern exports
Overall this has made a huge difference for me to be able to use ESM using It would be nice if we could use the cli to create new amplify functions using a typescript template so I don't have to do as much manual package.json updates and copy-pasting the tsconfig from function to function. |
I'm running into some similar issues trying to mock lambda functions using TypeScript. As a minimal example, I can create a function using I add {
"compilerOptions": {
"target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
"sourceMap": false, /* Create source map files for emitted JavaScript files. */
"noEmit": false, /* Disable emitting files from a compilation. */
"preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
"isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
"allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
"strict": true, /* Enable all strict type-checking options. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
} (I have used a Compiling this with /**
* @type {import('@types/aws-lambda').APIGatewayProxyHandler}
*/
export const handler = async (event) => {
console.log(`EVENT: ${JSON.stringify(event)}`);
return {
statusCode: 200,
// Uncomment below to enable CORS requests
// headers: {
// "Access-Control-Allow-Origin": "*",
// "Access-Control-Allow-Headers": "*"
// },
body: JSON.stringify('Hello from Lambda!'),
};
}; When I run
Amplify CLI version: // package.json
{
"name": "testfunc",
"version": "2.0.0",
"description": "Lambda function generated by Amplify",
"main": "index.mjs",
"license": "Apache-2.0",
"type": "module",
"devDependencies": {
"@types/aws-lambda": "^8.10.92"
}
} If I create this function and don't change anything about the generated files (i.e. not converting to TypeScript), mocking the function works fine and I see the response and console output as expected. I also know from experience with some other functions in another project, that running code similar to the example provided by @josefaidt by using ESM instead of CJS will run correctly on AWS, though I have not tried mocking those functions. |
+1 |
Maybe it could help others facing the same issue: |
Hi, needs to be fixed, please |
would be really helpfull... |
I think this is a bug and not a feature request. If you use the "amplify add function" along with the graphQL template it will generate a .js file that uses ES imports. That stock template does not work for amplify mock. |
Agreed, this should be classified as a bug. The template/boilerplate examples cannot be run using the mock functionality. |
plz fix |
Suffering from the same bug. Currently, I need to push any change to AWS to test it. Here is the output from
My
using a Mac M1 with |
@josefaidt I think that the support of AWS JavaScript SDK v3 should be prioritised for Amplify CLI. Right now is really big mess, between: TypeScript configs, CommonsJS and Modules node mode. Running locally the Amplify mock function for example, gives this info message:
I did try to configure SDK for JavaScript(v3) within Amplify context with no success. |
nearly one year later...please fix. |
please fix this bug. It slows development so much. |
wen fix? |
any update ? would be really useful to speed up devs ! |
Yes just starting a new project and getting the exact same error. Having working local mock functionality for generated code should be a mimimum. Might have to take the advice in the thread and do a .ts config etc. But this is a functionality bug as i see it as well. |
For people having the same issue here. Mocking of typescript functions does not seem to work. However they seem to run with amplify push. So the workaround is as mentions above by @erikash is to just test locally with |
+1 |
any updates? AWS Developers, you must to respect your users. say smth! |
nope, they would better rewrite the whole project structure and call it "Next gen dev experience" rather than fix things that developers face once they make one step out from the way the product was advertised |
They always seems to put marketing over everything else. |
Sadly, amplify is good only for todo tasks kind of projects, anything more serious than that is a waste of time and money. Been there, done that, I'd recommend staying away from it under any circumstance if your intention is to use it for business. |
Could anyone from the aws team comment on this? How can you all let issues like this go for so long? |
Still waiting on this bug to be resolved as well. For now, I'm testing by pushing it to cloud and checking it on the lambda online... |
Just to note: using Lambda Layers for Amplify functions will also break the mock functionality. It's clear that this isn't solely an Amplify problem; it's a generic one. But, I don't see how to avoid using Lambda Layers for a larger project. Consequently, mocking becomes obsolete, which presents a significant problem. For the Amplify Team: It would be really helpful to add some documentation and at least mention this limitation. Additionally, having documentation related to testing and debugging Amplify functions would be very beneficial. |
If you use TypeScript you can workaround sharing code without Lambda Layers with the help of multiple root dirs inside your here is the post about it https://www.vorant94.io/posts/aws-amplify-functions-on-steroids#sharing-code-between-lambdas and here is the repo with example https://github.com/vorant94/amplify-functions-on-steroids |
I use Nx libs for code sharing, but it's not what Lambda Layers solves. The problem that Lambda Layers solves is deploying all the dependencies once, so that it doesn't require a separate build or dependency installation for each Lambda. I also remember that Amplify has a size limit per Function, and deploying everything without Lambda dependencies was a problem. |
yeah, that’s why u called it workaround)
Interesting… I remember this limit to be on Lambda side, not Amplify. And this limit is actually pretty high, I played with it and put the whole express service with set of basic libraries there without reaching even half of it… |
The maximum size for a .zip deployment package for Lambda is 250 MB. |
yeah, and if during build process exclude dev dependencies it is more than enough to include fully-fledged express server all more so for some shared typescript code |
It is important to note that the aws-sdk version 2 deprecation has been announced. The recommended fix is to migrate to v3. v3 uses import. import doesn't work with amplify function mock. Can somebody please clarify how one is supposed to use this now? |
Hey folks just wanted to stop by and mention that we have not forgotten about this issue. As others in the thread have mentioned you can use a small harness like an express/hono/polka server to replace @SilverLinings89 for SDK v3 they support CommonJS and ECMAScript Modules -- for the most part you can swap the |
@josefaidt Thanks for the clarification, we have the code working that way in our codebase already. My point was more along the lines that the examples/code excerpts in the AWS SDK docs will no longer be compatible/useable in functions that need to use amplify mock (out of the box). There's afaik no clear indication in the docks that using an import will break mock. Considering this chapter, for example: https://docs.amplify.aws/javascript/tools/cli/usage/mock/#function-mock-limitations there are mentions of limitations but this pretty big limitation isn't referenced but might be relevant for newcomers. |
Is this feature request related to a new or existing Amplify category?
function
Is this related to another service?
No response
Describe the feature you'd like to request
Similar to issue: #5691 support for import when mocking a function locally.
Describe the solution you'd like
Either support ES import by default or support adding "type": "module" to package.json for amplify functions when testing with amplify mock function
Describe alternatives you've considered
currently the only alternative is to require modules
Additional context
No response
Is this something that you'd be interested in working on?
Would this feature include a breaking change?
The text was updated successfully, but these errors were encountered: