question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

(@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 includes entry 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:closed
  • Created 2 years ago
  • Reactions:9
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

5reactions
jogoldcommented, May 22, 2021

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.

0reactions
bodokaisercommented, Jan 9, 2022

@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 if cwd is the cdk directory:

this.lambda = new NodejsFunction(this, 'Lambda', {
      handler: 'handler',
      entry: path.join(__dirname, '../../lambda/main.ts'),
      bundling: {
        commandHooks: {
          beforeBundling(inputDir: string, outputDir: string) {
            return [
              `cd ${inputDir}`,
              'yarn install --frozen-lockfile',
            ]
          },
          beforeInstall() {
            return []
          },
          afterBundling() {
            return []
          }
        }
      },
      memorySize: 256,
      timeout: Duration.seconds(10),
      depsLockFilePath: path.join(__dirname, '../../lambda/yarn.lock'),
    })

If you pull in the codebase into the cdk directory, you need to exclude it via tsconfig.json. Otherwise, yarn run build in the SynthStep fails as it tries to compile the other codebase without having the dependencies available.

Read more comments on GitHub >

github_iconTop Results From Across the Web

aws-cdk/aws-lambda-nodejs
The NodejsFunction construct creates a Lambda function with automatic ... must be present in the package.json 's dependencies or installed.
Read more >
Amazon Lambda Node.js Library
The NodejsFunction allows you to define your CDK and runtime dependencies in a ... the esbuild dependency needs to be installed in the...
Read more >
Why does "npm install" rewrite package-lock.json?
json can override package-lock.json whenever a newer version is found for a dependency in package.json . If you want to pin your dependencies...
Read more >
Package.json Vs Package-lock.json Vs Npm-shrinkwrap.json
will simply avoid this general behavior of installing updated minor version so when someone clones your repo and run npm install in their ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found