-
Notifications
You must be signed in to change notification settings - Fork 4k
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
(aws-lambda-nodejs): .mjs
file extension and import.meta
not supported
#13274
Comments
Hi @blake-regalia, does Lambda support |
Yes in node.js >= v14.13 environment you can use esmodules. |
I understand that you want to use But regarding the output of |
I don't know where you are getting this assumption about Lambda not knowing how to deal with And more important than the file extension is getting away from transpilation entirely since this breaks the use of |
Tried in the Lambda console and I was not able to do this. If you manage to successfully run files in module mode in the Lambda environment, let me know how you did it. |
I am also getting errors on a new lambda with node 14.x. Could someone publish a working example of using .mjs? |
I believe the problem is that the lambda engine is using CommonJS require to load the handler method. This won't work if the lambda handler is an ES6 module or a .mjs file as it will fall in the error quadrant on the table below. So the question is: how do we use nodejs 14.x out-of-the-box ES6 modules on AWS Lambdas? https://pencilflip.medium.com/using-es-modules-with-commonjs-modules-in-node-js-1015786dab03 |
This is what I get when using "type": "module" on package.json. As you can see on the error: The lambda engine is using require() to load the code on index.js.
|
I would like to load a
My motivation is to use esbuild's tree-shaking. Right now my function is very large and appears to contain all of @aws-cdk and typeorm and others, so I am very sure tree shaking is not working correctly.
But I can see that
I believe if esbuild was configured to support ES-modules then we could get much much smaller function bundles. As it is now it appears to bundle entire packages: |
This is really strange... can you share a repro? Are those dependencies imported in your handler? If yes, why? If not, they shouldn't be bundled. |
My handler includes |
Can you show your handler? Is it a |
Yes, https://github.com/jetbridge/jetkit-cdk/blob/implement-view-routing/src/test/sampleApp.ts is the handler file. It's the export const handler = apiViewHandler(__filename, AlbumApi)
I'm trying to make some decorators that a CDK construct can make use of to generate NodeJsLambda functions and APIGW routes automatically |
According to this SO question, the Node on Lambda doesn't support ecmascript modules yet. I would love to see this happen ASAP. All of Sindre Sorhus' packages are currently moving to ESM only! https://blog.sindresorhus.com/hello-modules-d1010b4e777b |
Any updates on this? I'm on a mayor refactor on a curtial step of a pure JS project ( I wanted to switch to TS but was too agressive to suggest all changes at once). So if I use nodejs 14.x runtime, then |
Here's a possible approach to running ES modules in lambda today (without the benefit of NodejsFunction) The following stackoverflow answer claims success running ES modules with a shim using dynamic From https://stackoverflow.com/a/69136438/91927
|
The following code in aws/aws-lambda-nodejs-runtime-interface-client looks like it could be adapted to use /**
* Attempt to load the user's module.
* Attempts to directly resolve the module relative to the application root,
* then falls back to the more general require().
*/
function _tryRequire(appRoot: string, moduleRoot: string, module: string): any {
const lambdaStylePath = path.resolve(appRoot, moduleRoot, module);
if (_canLoadAsFile(lambdaStylePath)) {
return require(lambdaStylePath);
} else {
// Why not just require(module)?
// Because require() is relative to __dirname, not process.cwd()
const nodeStylePath = require.resolve(module, {
paths: [appRoot, moduleRoot],
});
return require(nodeStylePath);
}
}
/**
* Load the user's application or throw a descriptive error.
* @throws Runtime errors in two cases
* 1 - UserCodeSyntaxError if there's a syntax error while loading the module
* 2 - ImportModuleError if the module cannot be found
*/
function _loadUserApp(
appRoot: string,
moduleRoot: string,
module: string
): any {
try {
return _tryRequire(appRoot, moduleRoot, module);
} catch (e) {
if (e instanceof SyntaxError) {
throw new UserCodeSyntaxError(<any>e);
} else if (e.code !== undefined && e.code === "MODULE_NOT_FOUND") {
throw new ImportModuleError(e);
} else {
throw e;
}
}
} |
Since there seems to be no progress, I will give my personal opinion. 1. .mjs is not supported.It should be legitimate for esbuild to output *.mjs and *.cjs as format=cjs.
2. import.meta is not supportedThe CDK is not concerned about the AWS Lambda runtime fully supporting ES2020 features (e.g. import.meta). |
Came here to see if this was in the works; @jogold are you planning to add support for native esm? |
I will try to have a look at it this week or next week. |
Add a `format` option to choose the output format (CommonJS or ECMAScript module). Generate a `index.mjs` file when the ECMAScript module output format is chosen so that AWS Lambda treats it correctly. Closes aws#13274
See #18346 |
Add a `format` option to choose the output format (CommonJS or ECMAScript module). Generate a `index.mjs` file when the ECMAScript module output format is chosen so that AWS Lambda treats it correctly. See https://aws.amazon.com/about-aws/whats-new/2022/01/aws-lambda-es-modules-top-level-await-node-js-14/ See https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/ Closes #13274 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
|
Not an aws-cdk Issue, but for everyone who ends up here: Using modules form layers is currently not supported in lambda when using ESM |
Add a `format` option to choose the output format (CommonJS or ECMAScript module). Generate a `index.mjs` file when the ECMAScript module output format is chosen so that AWS Lambda treats it correctly. See https://aws.amazon.com/about-aws/whats-new/2022/01/aws-lambda-es-modules-top-level-await-node-js-14/ See https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/ Closes aws#13274 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@pfried damn, thats exactly the issue I hit. aws/aws-sdk-js-v3#3386 |
Although Lambda now supports Node v14:
.mjs
entry files are rejected by a regex pattern in aws-lambda-nodejsesbuild
is transpiling the scripts tocjs
format (commonjs) but BundlingOptions provides no means to specifyformat: "esm"
, and consequently esbuild polyfillsimport.meta
which breaks all of its uses in the scriptsReproduction Steps
lib/my-stack.mjs
:src/entry-file.mjs
:What did you expect to happen?
entry-file.mjs
to be allowed to be used as an entry file.import.meta
to be defined andExample()
to return a string.What actually happened?
Error: Only JavaScript or TypeScript entry files are supported.
Example()
returns undefined sinceimport.meta
is polyfilled with an empty plain object.Environment
Other
For the
.mjs
extension:aws-cdk/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts
Line 140 in 5d71d8e
Allow passing in the
format
option toesbuild
:aws-cdk/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
Lines 141 to 158 in 5d71d8e
This is 🐛 Bug Report
The text was updated successfully, but these errors were encountered: