Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excluding node modules from Webpack on Serverless

I'm reading this Medium article, https://medium.com/@awesome1888/how-to-use-serverless-locally-with-webpack-and-docker-5e268f71715, in which a project is set up with these dependencies,

$ npm install serverless serverless-offline serverless-webpack webpack webpack-node-externals babel-loader @babel/core @babel/preset-env @babel/plugin-proposal-object-rest-spread --save-dev

this serverless.yml file,

service: my-first-lambda

# enable required plugins, in order to make what we want
plugins:
  - serverless-webpack
  - serverless-offline

# serverless supports different cloud environments to run at.
# we will be deploying and running this project at AWS cloud with Node v8.10 environment
provider:
  name: aws
  runtime: nodejs8.10
  region: eu-central-1
  stage: dev

# here we describe our lambda function
functions:
  hello: # function name
    handler: src/handler.main # where the actual code is located
    # to call our function from outside, we need to expose it to the outer world
    # in order to do so, we create a REST endpoint
    events:
      - http:
          path: hello # path for the endpoint
          method: any # HTTP method for the endpoint

custom:
  webpack:
    webpackConfig: 'webpack.config.js' # name of webpack configuration file
    includeModules: true # add excluded modules to the bundle
    packager: 'npm' # package manager we use

and this webpack.config.js:

const path = require('path');
const nodeExternals = require('webpack-node-externals');
const slsw = require('serverless-webpack');

module.exports = {
  entry: slsw.lib.entries,
  target: 'node',
  mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
  externals: [nodeExternals()],
  output: {
    libraryTarget: 'commonjs',
    // pay attention to this
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              // ... and this
              presets: [['@babel/env', { targets: { node: '8.10' } }]],
              plugins: [
                '@babel/plugin-proposal-object-rest-spread',
              ]
            },
          },
        ],
      },
    ],
  },
};

This seems to follow the pattern documented at https://github.com/serverless-heaven/serverless-webpack#node-modules--externals. What I don't quite understand though, is why this is not equivalent to just leaving includeModules at its default value of false? It seems from https://www.npmjs.com/package/webpack-node-externals that both would exclude the node_modules dependencies.

like image 623
Kurt Peek Avatar asked Jul 10 '26 10:07

Kurt Peek


1 Answers

includeModules: false means all the dependencies will be a part of the bundle, thus generating one JavaScript file (with no external dependencies).

externals: [nodeExternals()] tells Webpack not to bundle external dependencies, thus the generated JavaScript file will only contain your code.

Since your code probably needs these external dependencies, includeModules: true tells the serverless webpack plugin to include these dependencies in the generated zip package under the node_modules directory.

You can try looking at the generated zip file under .serverless to see the difference between the modes.

The comment includeModules: true # add excluded modules to the bundle in the yaml file is misleading.

It should say includeModules: true # add excluded modules to the generated zip package

The main thing is to distinguish between bundling (done by Webpack) and packaging (done by the plugin).

like image 173
Erez Avatar answered Jul 13 '26 15:07

Erez



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!