serverless-SAM-typescript-boilerplate
serverless-SAM-typescript-boilerplate copied to clipboard
npm build:prod error
Hi Nick, amazing tutorial so far.
Yet, almost by the end, when I need to build a Api Function (npm run build:prod) with altered webpack.config.ts I'm getting an error
[webpack-cli] webpack.config.ts:42:14 - error TS2304: Cannot find name 'EventSource'.
42 Events?: EventSource;
~~~~~~~~~~~
NOTE: please note that I've picked all the latest devDependencies and here is the list:
"devDependencies": {
"@types/aws-lambda": "^8.10.64",
"@types/jest": "^26.0.15",
"@types/node": "^14.14.2",
"@types/webpack": "^4.41.23",
"@typescript-eslint/eslint-plugin": "^4.5.0",
"@typescript-eslint/parser": "^4.5.0",
"eslint": "^7.11.0",
"eslint-config-prettier": "^6.14.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-prettier": "^3.1.4",
"jest": "^26.6.0",
"prettier": "^2.1.2",
"ts-jest": "^26.4.1",
"ts-loader": "^8.0.6",
"ts-node": "^9.0.0",
"typescript": "^4.0.3",
"webpack": "^5.1.3",
"webpack-cli": "^4.1.0",
"yaml-cfn": "^0.2.3"
}
If I look into ISamFunction interface in that webpack.config.js, all are "primitives" except that Events?: EventSource.
Can it be that it is referenced somewhere? Maybe you have some global npm module installed?
As a temp. solution, I have commented out, as I can see that is not used later in resources in ISamFunction.
So final webpack.config.ts in my case looks like:
import { resolve } from 'path';
import { readFileSync } from 'fs';
import { yamlParse } from 'yaml-cfn';
import { Configuration } from 'webpack';
/* eslint-disable */
const { compilerOptions } = require('./tsconfig.json');
/* eslint-enable */
/** Webpack Config Variables */
const conf = {
prodMode: process.env.NODE_ENV === 'production',
templatePath: '../../template.yaml'
};
/**
* Parsing tsconfig.json paths to resolve aliases
*/
const tsPaths = Object.keys(compilerOptions.paths).reduce(
(paths, path) =>
Object.assign(paths, { [`${path}`]: resolve(__dirname, compilerOptions.paths[path][0]) }),
{}
);
/**
* Parsing template.yaml file for function dir locations
*/
/** Interface for AWS SAM Function */
const { Resources: resources } = yamlParse(readFileSync(conf.templatePath, 'utf-8'));
interface ISamFunction {
Type: string;
Properties: {
AssumeRolePolicyDocument?: JSON;
AutoPublishAlias?: string;
AutoPublishCodeSha256?: string;
CodeUri?: string;
Description?: string;
Environment?: {
Variables: {
[key: string]: string;
};
};
// Events?: EventSource;
FunctionName?: string;
Handler: string;
Layers?: { [Ref: string]: string }[];
Runtime: string;
Timeout?: number;
Tracing?: string;
VersionDescription?: string;
};
}
const entries = Object.values(resources)
.filter((resource: ISamFunction) => resource.Type === 'AWS::Serverless::Function')
.filter(
(resource: ISamFunction) =>
resource.Properties.Runtime && resource.Properties.Runtime.startsWith('nodejs')
)
.map((resource: ISamFunction) => ({
filename: resource.Properties.Handler.split('.')[0],
entryPath: resource.Properties.CodeUri.split('/').splice(3).join('/'),
}))
.reduce(
(resources, resource) =>
Object.assign(resources, {
[`${resource.filename}`]: `./src/${resource.entryPath}${resource.filename}.ts`,
}),
{}
);
/**
* Webpack Config
*/
const webpackConfig: Configuration = {
entry: entries,
target: 'node',
mode: conf.prodMode ? 'production' : 'development',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
alias: tsPaths,
},
output: {
path: resolve(__dirname, 'dist'),
filename: '[name].js',
libraryTarget: 'commonjs2',
},
devtool: 'source-map',
plugins: [],
};
export default webpackConfig;