(@aws-cdk/aws-lambda-nodejs): NodejsFunction dependency installation behavior (`package-lock.json`, npm install)
See original GitHub issue❓ General Issue
The Question
I’m having trouble following the NodejsFunction documentation about dependency management. It says that a dependencies lock file is required and that dependencies will be installed, but with CDK v1.105.0 I’m not seeing that behavior with esbuild in the environment or using Docker.
With a tree like:
component/
└── function-a/
├── index.js
├── package-lock.json
└── package.json
And a construct like:
const functionA = new NodejsFunction(this, "function-a", {
entry: path.join(baseDirectory, "component", "function-a", "index.js"),
runtime: lambda.Runtime.NODEJS_14_X,
})
// or
const functionA = new NodejsFunction(this, "function-a", {
depsLockFilePath: path.join(baseDirectory, "component", "function-a", "package-lock.json"),
entry: path.join(baseDirectory, "component", "function-a", "index.js"),
runtime: lambda.Runtime.NODEJS_14_X,
})
My expectation is that component/function-a/package-lock.json
would be required and would be used to install the dependencies prior to bundling.
What I’m observing is that package-lock.json
isn’t required (there’s no complaint if it’s omitted), dependencies aren’t installed, and synth fails if there wasn’t already a node_modules/
populated with dependencies.
Here is a minimal repro.
I get the same result if I set bundling.forceDockerBundling
to true
.
And in both cases if I define bundling.commandHooks.beforeInstall
it doesn’t get executed (and before I get to that point I get errors about the other hooks not being defined, which I’ll open a separate issue about if there isn’t one already).
Where the documentation says…
Alternatively, you can specify the
depsLockFilePath
prop manually. In this case you need to ensure that this path includesentry
and any module/dependencies used by your function. Otherwise bundling will fail.
…does…
you need to ensure that this path includes
entry
…mean that the file specified as entry
has to be in the directory that the file specified as depsLockFilePath
is in? And if so, why?
What does it mean by:
you need to ensure that this path includes […] any module/dependencies used by your function.
Is it referring to the lock file or a node_modules/
directory?
Environment
- CDK CLI Version: 1.105.0 (build 4813992)
- Module Version: 1.105.0
- Node.js Version: v14.16.0
- OS: macOS
- Language (Version):
Other information
Issue Analytics
- State:
- Created 2 years ago
- Reactions:9
- Comments:13 (6 by maintainers)
You don’t need a separate package.json per function.
You can put all your dependencies (= cdk deps and runtime deps) at the root of your project and let the construct find your lock file. The construct bundles only what is required by each function.
Will update the README to explain this better.
@pfried as you both have pointed out it seems sufficient to insert an install command through the
commandHooks
.For reference, the following worked for me when you pull a separate repo with independent dependencies next to the cdk directory, i.e.,
../lambda
ifcwd
is the cdk directory:If you pull in the codebase into the cdk directory, you need to exclude it via
tsconfig.json
. Otherwise,yarn run build
in theSynthStep
fails as it tries to compile the other codebase without having the dependencies available.