Non-typescript imports not working on the latest version of Serverless + Webpack + Node - Stack Overflow

admin2025-04-22  1

After upgrading

  • NodeJS to v20.18.0
  • Serverless to v4.4.7
  • Webpack to v5.97.1
  • Typescript to v5.5.4

I realised that the upgrade affected some (maybe all?) imports from libraries that are not developed in typescript.

When doing an import like this

import * as sanitizeHtml from 'sanitize-html';

after packaging the lambda function in serverless, at runtime I get an error saying "sanitizeHtml is not a function".

If I replace the import with something like this, instead, it works

import sanitizeHtml from 'sanitize-html';

The problem in my case is that I am working in a monorepo that supports a lot of environments, not only serverless: the same piece of code can be shared and packaged as part of a lambda function, or an Express server, or an Angular frontend, etc.

For this reason, I cannot change all the imports like described above, because they work on serverless but they don't work on all the other platforms.

For the moment, I managed to come out with the following workaround

import * as sanitizeHtml from 'sanitize-html';

// ...

if (typeof sanitizeHtml === 'object') {
  return (sanitizeHtml as any).default(html);
}

return sanitizeHtml(html);

but ideally I would like a permanent solution.

Anybody has an idea of what the problem is? I suspect there must be something wrong with my serverless configuration

Here is my webpack config

import * as path from 'path';
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';

export const webpackConfig = {
  context: __dirname,
  mode: 'production',
  devtool: 'inline-cheap-module-source-map',
  optimization: {
    minimize: true,
    minimizer: [
      () => {
        return () => {
          return {
            terserOptions: {
              format: {
                comments: false,
              },
            },
            extractComments: false,
          };
        };
      },
    ],
  },
  resolve: {
    extensions: ['.mjs', '.json', '.ts', '.js'],
    symlinks: false,
    cacheWithContext: false,
    plugins: [
      new TsconfigPathsPlugin({ configFile: 'tsconfig.app.json' }),
    ],
  },
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
  },
  target: 'node',
  module: {
    rules: [
      // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
      {
        test: /\.(tsx?)$/,
        loader: 'ts-loader',
        exclude: [
          [
            path.resolve(__dirname, 'node_modules'),
            path.resolve(__dirname, '.serverless'),
            path.resolve(__dirname, '.webpack'),
          ],
        ],
        options: {
          transpileOnly: true,
          experimentalWatchApi: true,
        },
      },
    ],
  },
  plugins: [],
  node: {
    __dirname: true,
  },
};

and this is my serverless config

export const serverlessConfig = {
  frameworkVersion: '4',
  package: {
    individually: true,
    excludeDevDependencies: true,
  },
  plugins: [ 'serverless-offline' ],
  custom: {
    webpack: {
      webpackConfig: './webpack.config.ts',
      includeModules: false,
      excludeFiles: '**/src/**/*.spec.ts',
    },
  },
  provider: {
    name: 'aws',
    runtime: 'nodejs20.x',
    region: 'eu-west-1',
  },
  service: 'my-lambda-function-name',
  functions: {
    execute: {
      handler: 'src/index.execute',
      environment: { ... },
      events: [ ... ],
      timeout: 600,
    },
  },
};
转载请注明原文地址:http://anycun.com/QandA/1745299785a90555.html