DataDog / serverless-plugin-datadog

Serverless plugin to automagically instrument your Lambda functions with Datadog
Apache License 2.0
96 stars 49 forks source link

Using webpack and nodeExternals() include dependencies in each function #393

Closed nserbass closed 1 year ago

nserbass commented 1 year ago

Expected Behavior

I'm using webpack to build our service to push it to lambdas. There's a rule to exclude node_modules from final function package so I've included nodeExternals() to exclude them. When I add serverless-plugin-datadog, dependecies should be excluded following configuration in serverless.yml and webpack.config.js

Actual Behavior

When I add serverless-plugin-datadog, dependecies are included in each function package.

Packaging test for stage dev (us-east-1)
Auto instrumenting functions with Datadog
Adding Lambda Library Layers to functions
Adding Datadog Lambda Extension Layer to functions
Adding Datadog Env Vars
Package lock found - Using locked versions
Packing external modules: @nestjs/common@^8.0.0, @nestjs/config@^2.0.0, @nestjs/core@^8.0.0, @nestjs/cqrs@^8.0.3, @nestjs/jwt@^8.0.0, @nestjs/passport@^8.2.1, @nestjs/typeorm@^9.0.1, @vendia/serverless-express@^4.5.4, amqplib@^0.9.0, argon2@^0.28.7, axios@^0.27.2, cache-manager-redis-store@^2.0.0, cache-manager@^4.0.0, express@4.18.1, google-auth-library@^7.14.1, js-yaml@^4.1.0, lodash@4.17.21, luxon@^3.0.4, maxmind@^4.3.6, passport-jwt@^4.0.0, passport@^0.5.2, reflect-metadata@^0.1.13, rxjs@^7.2.0, typeorm-naming-strategies@^4.1.0, typeorm@0.3.11, ua-parser-js@^1.0.33, uuid@8.3.2
...

Specifications

Code

Serverless

service: test

custom:
    layerConfig:
      packager: 'npm'
      webpack:
        configPath: ./webpack.config.js
        includeModules: false
        externals: [ nodeExternals(), 'dd-trace', 'datadog-lambda-js' ]
    serverless-offline:
      useChildProcesses: true
    datadog:
      site: datadoghq.eu
      apiKeySecretArn: xxxx
    customDomains:
      - rest:
          domainName: xxxx
          basePath: ''
          stage: ${self:provider.stage}
          endPointType: regional
          certificateArn: xxxx
          createRoute53Record: true
          enabled: true
          securityPolicy: tls_1_2
          apiType: rest
          autoDomain: true
    subscriberDir: src
    vhost: ${param:prefix}

plugins:
  - serverless-plugin-datadog
  - serverless-webpack
  - serverless-domain-manager
  - serverless-plugin-resource-tagging

provider:
    name: aws
    deploymentMethod: direct
    stage: ${opt:stage, 'dev'}
    runtime: nodejs18.x
    region: us-east-1
    stackTags:
       branch: ${param:branch}
       user: ${param:user}
    layers:
      - { Ref: DependenciesLambdaLayer }
    functions:
    - ${file(external/deploy/shared/serverless/endpoints.yml)}
package:
    individually: true
    excludeDevDependencies: true
layers:
    dependencies:
      path: .deps-layer
      description: 'Dependencies layer'

webpack.config.js

// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const serverlessWebpack = require('serverless-webpack');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const nodeExternals = require('webpack-node-externals');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
  context: __dirname,
  mode: serverlessWebpack.lib.webpack.isLocal ? 'development' : 'production',
  entry: serverlessWebpack.lib.entries,
  devtool: 'inline-cheap-module-source-map',
  resolve: {
    extensions: ['.mjs', '.json', '.ts'],
    symlinks: false,
    cacheWithContext: false,
    plugins: [
      new TsconfigPathsPlugin({
        configFile: './tsconfig.json'
      })
    ]
  },
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js'
  },
  optimization: {
    minimize: false
  },
  externals: [nodeExternals(), 'dd-trace', 'datadog-lambda-js'],
  target: 'node',
  module: {
    rules: [
      {
        test: /\.(tsx?)$/,
        loader: 'ts-loader',
        exclude: [
          [
            path.resolve(__dirname, 'node_modules'),
            path.resolve(__dirname, '.serverless'),
            path.resolve(__dirname, '.webpack'),
            path.resolve(__dirname, 'test')
          ]
        ],
        options: {
          transpileOnly: true,
          experimentalWatchApi: true
        }
      }
    ]
  },
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: '.env',
          to: '.'
        },
      ]
    })
  ]
};
duncanista commented 1 year ago

Why is webpack from serverless-webpack under layerConfig in custom?

custom:
  layerConfig:
    packager: 'npm'
    webpack: # <--- Shouldn't this be indented one level down?
      configPath: ./webpack.config.js
      includeModules: false
      externals: [ nodeExternals(), 'dd-trace', 'datadog-lambda-js' ]
duncanista commented 1 year ago

We haven't heard from you in a while – I'm going to close this issue for now, but feel free to re-open it if you have any other questions, or concerns, thanks 🐶 !