when trying to run the lambda function I get the error "out/get-user-messages.handler is undefined or not exported". downloading the zip I see the "out" folder in the root and get-user-messages.js inside though. and I am exporting the handler
get-user-messages.ts
import "reflect-metadata";
import { APIGatewayEvent, APIGatewayEventRequestContext, APIGatewayProxyEvent } from "aws-lambda";
export const handler = async (event: APIGatewayProxyEvent, context: APIGatewayEventRequestContext) => {
/** Code **/
}
tsconfig.json
{
"compilerOptions": {
"experimentalDecorators": true,
"module": "es2015",
"target": "esnext",
"noImplicitAny": false,
"outDir": "./out",
"strict": false,
"resolveJsonModule": true,
"strictNullChecks": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"esModuleInterop": true,
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts", "**/*.test.ts"],
"paths": {
"#/*": ["src/*"]
}
}
webpack.config.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
var path = require('path');
/** #type {import('webpack').Configuration} */
module.exports = {
mode: "production",
module: {
mode: "production",
rules: [
{
test: /\.js|.ts|.tsx/,
exclude: /node_modules/,
use: 'babel-loader'
},
],
},
resolve: {
extensions: ['*', '.js', '.jsx', '.tsx', '.ts', '.json'],
},
module: {
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: ["babel-loader"]
}
]
},
plugins: [new ForkTsCheckerWebpackPlugin()],
externals: ['aws-sdk'], //avoid un-needed modules since aws-sdk exists in aws lambdas already
entry: {
//list of compiled files
"get-user-messages": path.join(__dirname, "./src/lambda/get-user-messages.ts"),
"insert-user-message": path.join(__dirname, "./src/lambda/insert-user-message.ts"),
"mark-read-user-message": path.join(__dirname, "./src/lambda/mark-read-user-message.ts"),
"get-application-release-notes": path.join(__dirname, "./src/lambda/get-application-release-notes.ts"),
"insert-application-release-note": path.join(__dirname, "./src/lambda/insert-application-release-note.ts")
},
target: 'node',
output: {
path: path.join(__dirname, "./out"),
filename: "[name].js",
library: "[name]",
libraryTarget: 'commonjs'
}
};
.babelrc
{
"presets": [
["#babel/preset-env",{"targets":{"node":"14"}, "modules":false}],
"#babel/preset-typescript"
],
"sourceType": "unambiguous",
"plugins": [
"babel-plugin-transform-typescript-metadata",
["#babel/plugin-proposal-decorators", { "legacy": true }],
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-runtime"
]
}
the issue was the "library" option in the output section of webpack.config.js, removing that allowed me to successfully run the lambda function
Related
The AWS compilation errors from within node_modules are occurring the build
ERROR in ../../../node_modules/#aws-sdk/client-dynamodb/models/models_0.ts 6321:51-59
TS2339: Property '$unknown' does not exist on type 'never'.
6319 | if (obj.NULL !== undefined) return { NULL: obj.NULL };
6320 | if (obj.BOOL !== undefined) return { BOOL: obj.BOOL };
> 6321 | if (obj.$unknown !== undefined) return { [obj.$unknown[0]]: "UNKNOWN" };
| ^^^^^^^^
6322 | };
6323 | }
6324 |
webpack compiled with 9 errors in 6844 ms
I have just updated AWS
"#aws-sdk/client-dynamodb": "^3.51.0",
"#aws-sdk/lib-dynamodb": "^3.51.0",
"#aws-sdk/util-dynamodb": "^3.51.0",
With webpack
const path = require('path');
const slsw = require('serverless-webpack');
const nodeExternals = require('webpack-node-externals');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
/*
This line is only required if you are specifying `TS_NODE_PROJECT` for whatever
reason.
*/
// delete process.env.TS_NODE_PROJECT;
module.exports = {
context: __dirname,
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
entry: slsw.lib.entries,
devtool: slsw.lib.webpack.isLocal ? 'eval-cheap-module-source-map' : 'source-map',
resolve: {
extensions: ['.mjs', '.json', '.ts'],
symlinks: false,
cacheWithContext: false,
plugins: [
new TsconfigPathsPlugin({
configFile: './tsconfig.paths.json',
}),
],
},
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, '.webpack'),
filename: '[name].js',
},
target: 'node',
externals: [nodeExternals()],
module: {
rules: [
{
// Include ts, tsx, js, and jsx files.
test: /\.(ts|js)x?$/,
exclude: [
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, '.serverless'),
path.resolve(__dirname, '.webpack'),
],
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true,
}
},
'babel-loader'
]
}
]
},
plugins: [new ForkTsCheckerWebpackPlugin()],
};
And ts-config
{
"extends": "./tsconfig.paths.json",
"compilerOptions": {
"lib": ["ESNext"],
"moduleResolution": "node",
"esModuleInterop": true,
"noUnusedParameters": false,
"noUnusedLocals": false,
"resolveJsonModule": true,
"removeComments": true,
"sourceMap": true,
"target": "ES2020",
"outDir": "lib",
"paths": {
"#functions/*": ["src/functions/*"],
"#libs/*": ["src/libs/*"],
"#api/*": ["src/api/*"],
"~/*": [
"./*"
]
},
"types": [
"#types/node",
"#types/jest"
]
},
"include": ["src/**/*.ts", "serverless.ts"],
"exclude": [
"util/**/*",
"node_modules/**/*",
".serverless/**/*",
".webpack/**/*",
"_warmup/**/*",
".vscode/**/*" ],
"ts-node": {
"require": ["tsconfig-paths/register"]
}
}
Webpack looks to be still compiling node_modules regardless of it being in the excluded list.
Stop typescript type lookup traversing parent nodes
Incompatible types found by going up directories
Alter tsconfig.json to include typeRoots as a parameter as per Prevent require(...) from looking up modules in the parent directory
{
"extends": "./tsconfig.paths.json",
"compilerOptions": {
"lib": ["ESNext"],
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"module": "commonjs",
"esModuleInterop": true,
"noUnusedParameters": false,
"noUnusedLocals": false,
"resolveJsonModule": true,
"removeComments": true,
"sourceMap": true,
"target": "ES2020",
"outDir": "lib",
"paths": {
"#functions/*": ["src/functions/*"],
"#libs/*": ["src/libs/*"],
"#api/*": ["src/api/*"],
"~/*": [
"./*"
]
},
"typeRoots": [
"./"
],
"types": [
"#types/node",
"#types/jest"
]
},
"include": ["src/**/*.ts", "serverless.ts"],
"exclude": [
"util/**/*",
"node_modules",
"node_modules/**/*",
".serverless/**/*",
".webpack/**/*",
"_warmup/**/*",
".vscode/**/*"
],
"ts-node": {
"require": ["tsconfig-paths/register"]
}
}
I am trying to use imagemin node package in my project. It is a es6 module and I am getting error while using it.
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module. with "type" as "module" in package.json
ReferenceError: require is not defined with "type" as "commonjs" in package.json
My webpack config:
export default env => {
return {
mode: env.production ? 'production' : 'development',
entry: {
main: './src/main.ts',
worker: './src/worker.ts'
},
target: ['node', 'es2019'],
devtool: env.production ? false : 'inline-source-map',
watch: !env.production,
resolve: {
extensions: ['.ts', '.js'],
alias: {
src: _resolve(process.cwd(), './src')
}
},
module: {
rules: [{
test: /\.ts$/,
include: _resolve(process.cwd(), "src"),
use: 'ts-loader',
exclude: [/node_modules/, /\.spec\.ts/, /\.e2e-spec\.ts/]
}],
},
externalsPresets: { node: true },
externals: [nodeExternals()],
output: {
filename: '[name].js',
path: OUTPUT_DIR,
clean: !!env.production,
devtoolModuleFilenameTemplate: 'file:///[absolute-resource-path]',
library: {
type: 'module'
}
},
optimization: {
minimize: false, //!!env.production
mangleExports: true,
minimizer: [new terserPlugin({
terserOptions: {
output: {
comments: false
},
keep_classnames: true,
},
extractComments: false,
})]
},
experiments: {
outputModule: true
}
};
};
My tsconfig:
{
"compilerOptions": {
"module": "ES2020",
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2019",
"sourceMap": true,
"strict": true,
"baseUrl": ".",
"esModuleInterop": true,
"noImplicitAny": true,
"moduleResolution": "node",
"outDir": "../bin/server",
"typeRoots": [
"node_module/#types",
"./typings"
],
"types": [
"node",
"#types/jest"
]
},
"exclude": [
"node_modules"
]
}
When I try to "import" imagemin in one of my .ts file, webpack convert it to "require". I have also tried using import() but it doesn't work either.
I have made a repo on github
Is there a way to get es6 bundle (preferred) or use imagemin with commonjs bundle?
I couldn't found a way to bundle es6 format through webpack but i was able to use es6 module in commonjs system while bundling through webpack.
externals: [
nodeExternals({
allowlist: ['imagemin', 'imagemin-mozjpeg']
}),
async function ({ request }) {
if (request === 'imagemin' || request === 'imagemin-mozjpeg')
return `import ${request}`;
},
]
This is how i got imagemin to work.
Change your start script
"start": "node --experimental-modules src/index.mjs "
and In package.json Add
{
...
"type": "module",
...
}
I have a problem with Typescript not reading my return type correctly.
I am defining a function with a return type of something | null. And what typescript does is to read only the something type ignoring the null, which can be returned, when I call the function.
function nullornot(): null | string { // here is says it returns null | string
return null
}
const response = nullornot() // but here is says it returns string
My tsconfig.json file
{
"extends": "./tsconfig.paths.json",
"compilerOptions": {
"typeRoots": ["node_modules/#types", "src/#types"],
"allowSyntheticDefaultImports": true,
"lib": ["ESNext"],
"moduleResolution": "node",
"noUnusedLocals": true,
"noUnusedParameters": true,
"removeComments": true,
"sourceMap": true,
"target": "ESNext",
"outDir": "lib"
},
"files": ["src/#types/graphql.d.ts"],
"include": ["src/**/*.ts"],
"exclude": [
"node_modules/**/*",
".serverless/**/*",
".webpack/**/*",
"_warmup/**/*",
".vscode/**/*"
]
}
My webpack.config.js file
module.exports = {
context: __dirname,
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
entry: slsw.lib.entries,
devtool: slsw.lib.webpack.isLocal ? 'eval-cheap-module-source-map' : 'source-map',
resolve: {
extensions: ['.mjs', '.json', '.ts'],
symlinks: false,
cacheWithContext: false,
plugins: [
new TsconfigPathsPlugin({
configFile: './tsconfig.paths.json',
}),
],
},
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, '.webpack'),
filename: '[name].js',
},
optimization: {
concatenateModules: false,
},
target: 'node',
externals: [nodeExternals()],
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,
},
},
{
test: /\.graphql?$/,
use: [
{
loader: 'webpack-graphql-loader',
options: {
// validate: true,
// schema: "./src/schema.graphql",
// removeUnusedFragments: true
// etc. See "Loader Options" below
}
}
]
}
],
},
plugins: [],
};
Thanks for all help!
To type the result as string | null, you need to enable strictNullChecks in compilerOptions like this:
"compilerOptions": {
"strictNullChecks": true
}
See the TypeScript docs for more details.
It's because you don't have the strictNullChecks flag set to true in the tsconfig. Therefore TS won't enforce null checks, so for all intents and purposes it's just a string.
See how in this playground link where strict null checks are off it behaves the same as you're seeing, but once you turn it on the type of response is string | null
If this is a new project I'd recommend activating the strictest settings for the best type safety.
I have a (node) server folder located in the root of my project, it is a Gatsby app written in Typescript
Here is one of the errors:
#27 27.94 ERROR in ./server/modules/version/index.ts
#27 27.94 Module not found: Error: Can't resolve '../../common/api/cache' in '/build/server/modules/version'
#27 27.94 # ./server/modules/version/index.ts 7:16-49
#27 27.94 # ./server/index.ts
The module it is referring to is this:
export class StatusCache {
private _cache: Record<string, CacheObject> = {};
private options: CacheOptions = {
expiresMinutes: 3
};
...
and the import in the other file is import { StatusCache } from "../../common/api/cache";
the folder structure of the area of interest:
server
- common
- api
- cache (StatusCache class location)
- modules
- <version>
- index.ts
and lastly my webpack.server.js
const path = require("path");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");
const OUTPUT_FOLDER = "dist";
module.exports = env => ({
entry: "./server/index.ts",
mode: "production",
target: "node",
module: {
rules: [
{
test: /\.(tsx|ts)?$/,
use: [
{
loader: "ts-loader",
options: {
logInfoToStdOut: true,
logLevel: "info",
allowTsInNodeModules: false,
transpileOnly: true
}
}
],
exclude: /node_modules/
}
]
},
plugins: [
new CleanWebpackPlugin(),
new webpack.IgnorePlugin(/\.(test|spec)\./)
],
externals: {
bufferutil: "bufferutil",
"utf-8-validate": "utf-8-validate",
"mongodb-client-encryption": "mongodb-client-encryption"
},
resolve: {
extensions: [".tsx", ".ts", ".js"]
},
output: {
filename: "server.js",
chunkFilename: "[name].bundle.js",
path: path.resolve(__dirname, OUTPUT_FOLDER),
publicPath: "/"
}
});
I found a solution that worked for me and might be useful for others.
I added and edited my tsconfig-server.json to this:
{
"compilerOptions": {
"baseUrl": "./server",
"module": "commonjs",
"esModuleInterop": true,
"target": "esnext",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"noEmit": false
},
"lib": ["es2015"]
}
particularly the baseUrl, target, and moduleResolution
I had a similar Error , the problem was in gatsby-config,I had to add ignore property like so :
{
resolve: `gatsby-source-filesystem`,
options: {
name: `data`,
path: `${__dirname}/src/data/`,
ignore: [`**/\.*`], // ignore files starting with a dot
},
},
I am trying to write both frontend (React) and backend (Express) in TypeScript. At the moment, my webpack.config.js in the root folder encounters an error even though I have ts-loader for it.
This is webpack.config.js
const webpack = require('webpack');
const path = require('path');
const config = {
cache: true,
mode: 'development',
entry: {
'user': ['./src/client/User/index.tsx', 'webpack-hot-middleware/client']
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/static'
},
devServer: {
contentBase: './dist',
hot: true
},
plugins: [new webpack.HotModuleReplacementPlugin()],
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
include: path.join(__dirname, 'client')
}
]
},
node: { fs: 'empty' }
};
module.exports = config;
And this is my tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"jsx": "react",
"esModuleInterop": true,
"outDir": "dist",
"sourceMap": true,
"baseUrl": "."
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}
I got the error like this:
ERROR in ./src/client/User/index.tsx 10:1
Module parse failed: Unexpected token (10:1)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|
| const rootComponent = (
> <Provider store={store}>
| <BrowserRouter>
| <div id="page-container" className="sidebar-o sidebar-dark enable-page-overlay side-scroll page-header-fixed side-trans-enabled">
# multi ./src/client/User/index.tsx webpack-hot-middleware/client user[0]
Thanks to FunkeyFlo answer, I found out the answer myself. I have to change both:
tsconfig.json: include also src/**/*.tsx
webpack.config.js: entry to ./dist/src/client/User/index
change include section in tsconfig to the following
{
...
"include": [
"src/**/*.ts",
"src/**/*.tsx"
],
...
}