After upgrading
v20.18.0
v4.4.7
v5.97.1
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,
},
},
};