├── .gitignore ├── src ├── index.ts ├── module │ └── health │ │ ├── health.controller.ts │ │ └── health.route.ts ├── app.ts └── route │ └── app.route.ts ├── nodemon.json ├── tsup.config.ts ├── tsconfig.json ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import "./app"; 2 | -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["src"], 3 | "ignore": ["node_modules"], 4 | "ext": "ts,js,json", 5 | "exec": "tsup && node -r tsconfig-paths/register dist/index.js", 6 | "legacyWatch": true 7 | } -------------------------------------------------------------------------------- /src/module/health/health.controller.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express"; 2 | 3 | class HealthCheckController { 4 | public getHealth = (req: Request, res: Response): void => { 5 | res.status(200).json({ status: "healthy" }); 6 | }; 7 | } 8 | 9 | export default HealthCheckController; 10 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup' 2 | 3 | export default defineConfig({ 4 | platform: "node", 5 | target: 'es2022', 6 | entry: ['src/**/*.ts'], 7 | format: ['cjs'], 8 | skipNodeModulesBundle:true, 9 | bundle:true, 10 | minify: true, 11 | minifyWhitespace: true, 12 | minifyIdentifiers: true, 13 | minifySyntax: true, 14 | sourcemap: 'inline', 15 | treeshake: true, 16 | metafile:true 17 | }); -------------------------------------------------------------------------------- /src/module/health/health.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | 3 | import HealthCheckController from '@module/health/health.controller'; 4 | 5 | class HealthCheckRoute { 6 | public path = "/health"; 7 | public router = Router(); 8 | public controller: any; 9 | 10 | constructor() { 11 | this.controller = new HealthCheckController(); 12 | this.initRoute(); 13 | } 14 | 15 | public initRoute(): void { 16 | this.router.get(this.path, this.controller.getHealth); 17 | } 18 | 19 | } 20 | export default HealthCheckRoute; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "target": "es2022", 5 | "outDir": "./dist", 6 | "baseUrl": "./", 7 | "alwaysStrict": true, 8 | "noImplicitAny": true, 9 | "esModuleInterop": true, 10 | "moduleResolution": "Node", 11 | "paths": { 12 | "@module/*": [ 13 | "src/module/*" 14 | ], 15 | "@route/*": [ 16 | "src/route/*" 17 | ] 18 | }, 19 | }, 20 | "include": [ 21 | "src/**/*.ts" 22 | ], 23 | "exclude": [ 24 | "node_modules" 25 | ] 26 | } -------------------------------------------------------------------------------- /src/app.ts: -------------------------------------------------------------------------------- 1 | import http from "http"; 2 | import express, { Application } from "express"; 3 | import { createHttpTerminator } from "http-terminator"; 4 | 5 | import AppRoute from "@route/app.route"; 6 | 7 | const app: Application = express(); 8 | 9 | app.use(express.json()); 10 | app.use(express.urlencoded({ extended: true })); 11 | 12 | AppRoute(app); 13 | 14 | export const server = http.createServer(app); 15 | export const httpTerminator = createHttpTerminator({ server }); 16 | 17 | server.listen(5000, () => { 18 | console.log(`App listening on port 5000`); 19 | }); 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-tsup", 3 | "version": "1.0.0", 4 | "description": "express + tsup", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "dev": "nodemon", 8 | "dev:build": "tsup", 9 | "dev:start": "node dist/index.js" 10 | }, 11 | "keywords": [], 12 | "author": "Sudhakar Jonnakuti", 13 | "license": "ISC", 14 | "dependencies": { 15 | "express": "^4.18.2", 16 | "http-terminator": "^3.2.0" 17 | }, 18 | "devDependencies": { 19 | "@types/express": "^4.17.17", 20 | "@types/node": "^20.4.0", 21 | "module-alias": "^2.2.3", 22 | "nodemon": "^2.0.22", 23 | "tsconfig-paths": "^4.2.0", 24 | "tsup": "^7.1.0", 25 | "typescript": "^5.1.6" 26 | }, 27 | "_moduleAliases": { 28 | "@module": "dist/module", 29 | "@route": "dist/route" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/route/app.route.ts: -------------------------------------------------------------------------------- 1 | import { Application, NextFunction, Request, Response } from "express"; 2 | 3 | import HealthCheckRoute from '@module/health/health.route'; 4 | 5 | const appModuleRoute = (app: Application) => { 6 | const moduleRoute = () => [ 7 | new HealthCheckRoute() 8 | ]; 9 | 10 | moduleRoute().forEach((appRoute) => { 11 | app.use("/api", appRoute.router); 12 | }); 13 | } 14 | 15 | const appDefaultRoute = (app: Application) => { 16 | app.use("*", (req: Request, res: Response, next: NextFunction) => { 17 | res.status(404).json({ 18 | 'errorName': 'NOT FOUND', 19 | 'errorMessage': 'The requested resource not found.' 20 | }) 21 | }); 22 | } 23 | 24 | const AppRoute = (app: Application) => { 25 | appModuleRoute(app); 26 | appDefaultRoute(app); 27 | } 28 | 29 | export default AppRoute; 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # express-tsup 2 | ``` 3 | Output: 4 | 5 | C:\git-repo\express-tsup> npm run dev 6 | 7 | > express-tsup@1.0.0 dev 8 | > nodemon 9 | 10 | [nodemon] 2.0.22 11 | [nodemon] to restart at any time, enter `rs` 12 | [nodemon] watching path(s): src\**\* 13 | [nodemon] watching extensions: ts,js,json 14 | [nodemon] starting `tsup && node -r tsconfig-paths/register dist/index.js` 15 | CLI Building entry: src/app.ts, src/index.ts, src/route/app.route.ts, src/module/health/health.controller.ts, src/module/health/health.route.ts 16 | CLI Using tsconfig: tsconfig.json 17 | CLI tsup v7.1.0 18 | CLI Using tsup config: C:\git-repo\express-tsup\tsup.config.ts 19 | CLI Target: es2022 20 | CJS Build start 21 | CJS dist\app.js 5.81 KB 22 | CJS dist\index.js 5.76 KB 23 | CJS dist\route\app.route.js 4.04 KB 24 | CJS dist\module\health\health.controller.js 963.00 B 25 | CJS dist\module\health\health.route.js 2.21 KB 26 | CJS ⚡️ Build success in 228ms 27 | App listening on port 5000 28 | 29 | Reference: 30 | 31 | TSUP WIKI 32 | https://tsup.egoist.dev/#bundle-files 33 | 34 | Build Better and Faster Bundles with TypeScript and Express using tsup 35 | https://plusreturn.com/blog/build-better-and-faster-bundles-with-typescript-and-express-using-tsup/ 36 | 37 | Bundle Buddy 38 | https://www.bundle-buddy.com/esbuild 39 | 40 | Additional 41 | 42 | How to configure and resolve path alias with a Typescript Project 43 | https://plusreturn.com/blog/how-to-configure-and-resolve-path-alias-with-a-typescript-project/ 44 | 45 | A Comprehensive Guide to Building Node APIs with esbuild 46 | https://dev.to/franciscomendes10866/how-to-build-a-node-api-with-esbuild-8di 47 | 48 | ``` --------------------------------------------------------------------------------