Node.js Lambda Tracing and Bundlers Compatibility
Overview
Datadog’s tracing libraries (dd-trace
) are known to be not compatible with bundlers, like Webpack or esbuild, due to the use of conditional imports and other issues. While bundlers cannot build dd-trace
, your application can still use the dd-trace
and datadog-lambda-js
libraries provided by the prebuilt Datadog Lambda layer. Follow the instructions below.
Webpack
Follow the installation instructions for Node.js and ensure the Datadog Lambda layer for Node.js is added to your Lambda function.
Exclude datadog-lambda-js
and dd-trace
, either by removing them from your package.json
or by setting an exclude rule. Excluding them tells the bundler to skip building them as dependencies, since they are already available in the Lambda runtime provided by the Datadog Lambda layer.
Mark your dependencies as externals. This tells the bundler to exclude them from the output bundle; instead, they are packaged in node_modules
.
webpack.config.js
const nodeExternals = require("webpack-node-externals");
module.exports = {
// Use webpack-node-externals to exclude all node dependencies.
// You can manually set the externals too.
externals: [nodeExternals()],
module: {
rules: [
{
// Provided by the Datadog Lambda layer and the Lambda Runtime.
exclude: ['/aws-sdk/', '/datadog-lambda-js/', '/dd-trace/'],
}
]
},
}
If you are using the serverless-webpack
plugin and have the option includeModules
set to any value other than false
, the plugin automatically packs external modules under node_modules
. Therefore, you must force exclude datadog-lambda-js
and dd-trace
. Skip this step if you don’t use serverless-webpack
or you don’t have the includeModules
option in your serverless.yml
.
serverless.yml
custom:
webpack:
# You only need the following if you already have the includeModules option configured.
includeModules:
# ... your existing configuration for includeModules
forceExclude:
- aws-sdk
- datadog-lambda-js
- dd-trace
packagerOptions:
scripts:
# Optional, only needed when they are included as transitive dependencies
- rm -rf node_modules/datadog-lambda-js node_modules/dd-trace
To have more control around what dependencies are included, you could also include your webpack.config.js
in your serverless-webpack
configuration:
custom:
webpack:
forceExclude:
- aws-sdk
- datadog-lambda-js
- dd-trace
webpackConfig: 'webpack.config.js'
esbuild
Follow the installation instructions for Node.js and ensure the Datadog Lambda layer for Node.js is added to your Lambda function.
Remove datadog-lambda-js
and dd-trace
from your package.json
and the build process, since they are already available in the Lambda runtime provided by the Datadog Lambda layer.
Mark your dependencies as externals. This tells the bundler to exclude them from the output bundle; instead, they are packaged in node_modules
.
esbuild.config.js
const esbuild = require('esbuild');
esbuild.build({
// ... your existing esbuild configuration
// Same effect as manually passing each dependency to `external`
packages: 'external'
})
If you are using the serverless-esbuild
plugin, you can externalize all dependencies with the esbuild-node-externals
as an esbuild plugin. Automatically packs external modules under node_modules
.
serverless.yml
custom:
esbuild:
exclude:
# aws-sdk is needed because it is the default value for `exclude`
- aws-sdk
- datadog-lambda-js
- dd-trace
plugins: plugins.js
# You can also set the specific dependencies to externalize instead of using `plugins`
external: [...]
// plugins.js
const { nodeExternalsPlugin } = require('esbuild-node-externals')
module.exports = [nodeExternalsPlugin()]
Further Reading
Additional helpful documentation, links, and articles: