aws-cdk: (aws-lambda-nodejs): `.mjs` file extension and `import.meta` not supported
Although Lambda now supports Node v14:
.mjsentry files are rejected by a regex pattern in aws-lambda-nodejsesbuildis transpiling the scripts tocjsformat (commonjs) but BundlingOptions provides no means to specifyformat: "esm", and consequently esbuild polyfillsimport.metawhich breaks all of its uses in the scripts
Reproduction Steps
lib/my-stack.mjs:
export class MyStack extends Stack {
constructor(scope, id, props) {
super(scope, id, props);
// ...
new NodejsFunction(this, 'Example', {
runtime: Runtime.NODEJS_14_X,
entry: 'src/entry-file.mjs',
bundling: {
target: 'es2020',
// format: 'esm', <-- should be able to pass this option here
},
};
// ...
}
}
src/entry-file.mjs:
export async function Example() {
return import.meta.url;
}
What did you expect to happen?
entry-file.mjsto be allowed to be used as an entry file.import.metato be defined andExample()to return a string.
What actually happened?
Error: Only JavaScript or TypeScript entry files are supported.Example()returns undefined sinceimport.metais polyfilled with an empty plain object.
Environment
- CDK CLI Version : n/a
- Framework Version:
- Node.js Version: 14.13.0
- OS : n/a
- Language (Version):
Other
-
For the
.mjsextension: https://github.com/aws/aws-cdk/blob/5d71d8e815529ccde7ffe13bb72f57ae88e896dc/packages/%40aws-cdk/aws-lambda-nodejs/lib/function.ts#L140 -
Allow passing in the
formatoption toesbuild: https://github.com/aws/aws-cdk/blob/5d71d8e815529ccde7ffe13bb72f57ae88e896dc/packages/%40aws-cdk/aws-lambda-nodejs/lib/bundling.ts#L141-L158
This is š Bug Report
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 6
- Comments: 27 (12 by maintainers)
Commits related to this issue
- feat(lambda-nodejs): ES modules 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 t... — committed to jogold/aws-cdk by jogold 2 years ago
- feat(lambda-nodejs): ES modules (#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 ch... — committed to aws/aws-cdk by jogold 2 years ago
- feat(lambda-nodejs): ES modules (#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 ch... — committed to TikiTDO/aws-cdk by jogold 2 years ago
This is what I get when using ātypeā: āmoduleā on package.json. As you can see on the error: require() of ES modules is not supported. require() of /var/task/index.jsā¦
The lambda engine is using require() to load the code on index.js.
https://aws.amazon.com/about-aws/whats-new/2022/01/aws-lambda-es-modules-top-level-await-node-js-14/
https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/
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
See #18346
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.
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
I am also getting errors on a new lambda with node 14.x.
Could someone publish a working example of using .mjs?
I will try to have a look at it this week or next week.
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
The following code in aws/aws-lambda-nodejs-runtime-interface-client looks like it could be adapted to use
import()andimport.meta.resolve()without much trouble.From https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/blob/f9373b3e7cb153fe2895db446e21f3241eb156c6/src/utils/UserFunction.ts#L70-L111
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
export const handlerwont work?