(aws-lambda-nodejs): `devEngines` field not propagated during nodeModules bundling
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 74
Description
### Describe the bug
When using `aws-lambda-nodejs` with the `nodeModules` option, there is currently no way to control which version of the package manager is used to install dependencies during bundling. The bundler generates a minimal `package.json` in the output directory, but does not forward any package manager constraints from the project's `package.json`.
Two common ways to declare a package manager version in `package.json` are the `packageManager` field and the `devEngines` field:
```json
{
"packageManager": "npm@10.8.0"
}
```
```json
{
"devEngines": {
"packageManager": { "name": "npm", "version": ">=10", "onFail": "error" }
}
}
```
The `devEngines` field is a standard [defined by the OpenJS Foundation](https://github.com/openjs-foundation/package-metadata-interoperability-working-group/blob/main/devengines-field-proposal.md) that allows projects to declare package manager and runtime requirements for development. Package managers such as npm (>= 10.4 with Corepack) and pnpm use this field to enforce or warn when the wrong package manager or version is used. Because neither field is forwarded into the generated `package.json`, these constraints are silently ignored during the `nodeModules` install step, making it impossible to enforce package manager version consistency during Lambda bundling.
### Regression Issue
- [ ] Select this option if this issue appears to be a regression.
### Last Known Working CDK Library Version
_No response_
### Expected Behavior
When a `devEngines` field is present in the project's `package.json`, it should be forwarded into the minimal `package.json` that `aws-lambda-nodejs` writes to the asset output directory during `nodeModules` bundling. Allowing package managers that support `devEngines` to enforce the declared package manager and version during the install step.
### Current Behavior
The generated `package.json` only contains the `dependencies` field. The `devEngines` field is always omitted, even when it is present in the nearest parent `package.json`. As a result, tools like npm with Corepack cannot enforce the declared package manager during bundling.
For example, given a `package.json` like:
```json
{
"devEngines": {
"packageManager": { "name": "npm", "version": ">=10", "onFail": "error" }
},
"dependencies": {
"delay": "5.0.0"
}
}
```
The generated `package.json` in the asset output directory will be:
```json
{ "dependencies": { "delay": "5.0.0" } }
```
The `devEngines` constraint is silently dropped.
### Reproduction Steps
```ts
import * as path from 'path';
import * as cdk from 'aws-cdk-lib';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
// package.json in the project root contains:
// {
// "devEngines": {
// "packageManager": { "name": "npm", "version": ">=10", "onFail": "error" }
// },
// "dependencies": { "delay": "5.0.0" }
// }
const app = new cdk.App();
const stack = new cdk.Stack(app, 'TestStack');
new NodejsFunction(stack, 'MyFunction', {
entry: path.join(__dirname, 'handler.ts'),
runtime: Runtime.NODEJS_20_X,
bundling: {
nodeModules: ['delay'],
},
});
app.synth();
// Inspect the generated package.json in cdk.out//package.json
// Expected: { "devEngines": { "packageManager": { ... } }, "dependencies": { "delay": "5.0.0" } }
// Actual: { "dependencies": { "delay": "5.0.0" } }
```
### Possible Solution
At bundling time, read the `devEngines` field from the nearest `package.json` by walking up the directory tree from the entry file. If the field is present, include it in the generated `package.json` written to the output directory.
### Additional Information/Context
This issue was discovered due to the situation described in https://github.com/aws/aws-cdk/issues/37898 but we haven't migrated to pnpm v11 yet and our version specification is not being respected.
https://github.com/openjs-foundation/package-metadata-interoperability-working-group/blob/main/devengines-field-proposal.md
https://github.com/pnpm/pnpm/issues/8153
### AWS CDK Library version (aws-cdk-lib)
2.252.0
### AWS CDK CLI version
2.1120.0
### Node.js Version
24.x
### OS
macOS
### Language
TypeScript
### Language Version
5.x
### Other information
_No response_
Contributor guide
Research direction
Start with the aws-lambda-nodejs nodeModules bundling path that writes the minimal package.json in the asset output directory, using the entry file handler.ts and its nearest parent package.json as the inputs. Confirm the generated package.json preserves devEngines alongside dependencies, then verify the bundling behavior described in the reproduction steps.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, node.js, typescript
- Domain
- build-system, cloud
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100