├── .gitignore ├── README.md ├── app.ts ├── bin └── www.ts ├── config └── webpack.config.js ├── package.json ├── server ├── routes.ts └── views │ ├── error.ejs │ └── index.ejs ├── tsconfig.json └── typings.json /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | build/ 3 | typings/ 4 | node_modules/ 5 | .DS* 6 | ._.* 7 | .idea/ 8 | yarn.lock -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Modern Express | Easy starter project for writing modern Express Applications using TypeScript and Webpack 2 | 3 | This project is used to quickly get started with Webpack using Express and TypeScript. The intention of this project is to learn to use Webpack with out getting bogged down in the details of configuring Webpack. Below is a list of the outcomes of this project. 4 | 5 | 1. Automates the task of setting up Webpack 6 | 2. Cleanly installs and setups Webpack with out polluting the global system scope 7 | 3. Creates basic Express project to write TypeScript 8 | 4. Cleanly builds TypeScript code into a build directory 9 | 5. Stores and Saves Typings for VSCode 10 | 6. Uses `ejs` as the templating engine 11 | 12 | **Setup** 13 | --- 14 | **[Clone this Repository](https://github.com/jsecademy/webpack-express-typescript/archive/master.zip)** 15 | 16 | ``` 17 | npm install 18 | ``` 19 | 20 | **Run Builds** 21 | --- 22 | ``` 23 | npm run build 24 | ``` 25 | 26 | **Run Application** 27 | --- 28 | ``` 29 | npm start 30 | ``` 31 | 32 | **Getting started with this module** 33 | --- 34 | Simply start with writing your TypeScript code in the `server` directory 35 | 36 | ``` 37 | ├── app.ts 38 | ├── bin 39 | │ └── www.ts 40 | ├── build 41 | │ └── compiled 42 | ├── config 43 | │ └── webpack.config.js 44 | ├── package.json 45 | ├── README.md 46 | ├── server 47 | │ ├── routes.ts 48 | │ └── views 49 | │ ├── error.ejs 50 | │ └── index.ejs 51 | ├── tsconfig.json 52 | └── typings.json 53 | ``` 54 | 55 | *This module was made possible thanks to [LearnMEAN.com](https://www.learnmean.com/)* 56 | -------------------------------------------------------------------------------- /app.ts: -------------------------------------------------------------------------------- 1 | import * as express from 'express'; 2 | import * as path from 'path'; 3 | import * as logger from 'morgan'; 4 | import * as bodyParser from 'body-parser'; 5 | import * as root from 'app-root-path'; 6 | import * as cookieParser from 'cookie-parser'; 7 | import * as routes from './server/routes'; 8 | 9 | const app = express(); 10 | 11 | // view engine setup 12 | app.set('views', `${root}/server/views/`); 13 | app.set('view engine', 'ejs'); 14 | 15 | app.use(logger('dev')); 16 | app.use(bodyParser.json()); 17 | app.use(bodyParser.urlencoded({ 18 | extended: false 19 | })); 20 | 21 | app.use(cookieParser()); 22 | 23 | app.use('/', routes); 24 | 25 | // catch 404 and forward to error handler 26 | app.use((req: express.Request, res: express.Response, next: express.NextFunction) => { 27 | let err: any = new Error('Not Found'); 28 | err.status = 404; 29 | next(err); 30 | }); 31 | 32 | // error handlers 33 | // development error handler 34 | // will print stacktrace 35 | if (app.get('env') === 'development') { 36 | app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => { 37 | res.status(err.status || 500); 38 | res.render('error', { 39 | message: err.message, 40 | error: err 41 | }); 42 | }); 43 | } 44 | 45 | app.use(function(err: any, req: express.Request, res: express.Response, next: Function) { 46 | res.status(err.status || 500); 47 | res.render('error', { 48 | message: err.message, 49 | error: {} 50 | }); 51 | }); 52 | 53 | export = app; -------------------------------------------------------------------------------- /bin/www.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies. 3 | */ 4 | import * as app from '../app'; 5 | import * as http from 'http'; 6 | import * as debug from 'debug'; 7 | 8 | // binding to console 9 | let log = debug('modern-express:server'); 10 | log.log = console.log.bind(console); 11 | 12 | /** 13 | * Get port from environment and store in Express. 14 | */ 15 | let PORT = process.env.PORT || '3000'; 16 | 17 | function getPort(val) { 18 | /** 19 | * Normalize a port into a number, string, or false. 20 | */ 21 | const port = parseInt(val, 10); 22 | if (isNaN(port)) { 23 | // named pipe 24 | return val; 25 | } 26 | if (port >= 0) { 27 | // port number 28 | return port; 29 | } 30 | return false; 31 | } 32 | 33 | app.set('port', PORT); 34 | 35 | /** 36 | * Create HTTP server. 37 | */ 38 | const server = http.createServer(app); 39 | 40 | /** 41 | * Listen on provided port, on all network interfaces. 42 | */ 43 | server.listen(PORT); 44 | 45 | server.on('error', (error) => { 46 | /** 47 | * Event listener for HTTP server "error" event. 48 | */ 49 | if (error.syscall !== 'listen') { 50 | throw error; 51 | } 52 | const bind = typeof PORT === 'string' ? `Pipe ${PORT}` : `Port ${PORT}`; 53 | // handle specific listen errors with friendly messages 54 | switch (error.code) { 55 | case 'EACCES': 56 | console.error(bind + ' requires elevated privileges'); 57 | process.exit(1); 58 | break; 59 | case 'EADDRINUSE': 60 | console.error(bind + ' is already in use'); 61 | process.exit(1); 62 | break; 63 | default: 64 | throw error; 65 | } 66 | }); 67 | 68 | server.on('listening', () => { 69 | /** 70 | * Event listener for HTTP server "listening" event. 71 | */ 72 | const addr = server.address(); 73 | const bind = (typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`); 74 | log(`Listening on ${bind}`); 75 | }); -------------------------------------------------------------------------------- /config/webpack.config.js: -------------------------------------------------------------------------------- 1 | const root = require('app-root-path').path; 2 | module.exports = { 3 | entry: `${root}/bin/www.ts`, 4 | target: 'node', 5 | externals: [ 6 | /^[a-z\-0-9]+$/ // Ignore node_modules folder 7 | ], 8 | output: { 9 | filename: 'compiled', // output file 10 | path: `${root}/build`, 11 | libraryTarget: "commonjs" 12 | }, 13 | resolve: { 14 | // Add in `.ts` and `.tsx` as a resolvable extension. 15 | extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js'], 16 | modules: [ 17 | `${root}/node_modules`, 18 | 'node_modules' 19 | ] 20 | }, 21 | resolveLoader: { 22 | //root: [`${root}/node_modules`], 23 | 24 | 25 | }, 26 | module: { 27 | rules: [{ 28 | // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader` 29 | test: /\.tsx?$/, 30 | use: [ 31 | { 32 | loader: 'ts-loader', 33 | } 34 | ] 35 | }] 36 | } 37 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-express-typescript", 3 | "version": "1.0.0", 4 | "description": "Easy starter project for writing modern Express Applications using TypeScript, and Webpack", 5 | "private": true, 6 | "directories": { 7 | "test": "tests" 8 | }, 9 | "scripts": { 10 | "build": "node node_modules/webpack/bin/webpack.js --config config/webpack.config.js", 11 | "postinstall": "node node_modules/typings/dist/bin.js install --overwrite", 12 | "start": "node build/compiled" 13 | }, 14 | "main": "", 15 | "keywords": [ 16 | "Easy", 17 | "TypeScript", 18 | "Starter", 19 | "Template" 20 | ], 21 | "author": "Rick Hernandez", 22 | "license": "MIT", 23 | "devDependencies": { 24 | "ts-loader": "^4.4.2", 25 | "typescript": "^2.9.2", 26 | "typings": "^2.1.1", 27 | "webpack": "^4.14.0" 28 | }, 29 | "repository": { 30 | "type": "git", 31 | "url": "" 32 | }, 33 | "dependencies": { 34 | "app-root-path": "^2.0.1", 35 | "body-parser": "^1.17.1", 36 | "cookie-parser": "^1.4.3", 37 | "ejs": "^2.5.1", 38 | "express": "^4.15.2", 39 | "morgan": "^1.7.0" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /server/routes.ts: -------------------------------------------------------------------------------- 1 | import * as express from 'express'; 2 | const router = express.Router(); 3 | 4 | router.get('/', (req: express.Request, res: express.Response, next: express.NextFunction) => { 5 | res.render('index', { 6 | title: 'Express' 7 | }); 8 | }); 9 | 10 | export = router; -------------------------------------------------------------------------------- /server/views/error.ejs: -------------------------------------------------------------------------------- 1 |
<%= error.stack %>4 | -------------------------------------------------------------------------------- /server/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
Welcome to 13 | <%= title %> 14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "noImplicitAny": false, 6 | "sourceMap": false, 7 | "outDir": "build" 8 | }, 9 | "exclude": [ 10 | "node_modules", 11 | "build", 12 | "config", 13 | "release" 14 | ] 15 | } -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": { 3 | "main": "typings/" 4 | }, 5 | "globalDependencies": { 6 | "app-root-path": "registry:dt/app-root-path#1.2.1+20160719232327", 7 | "body-parser": "registry:dt/body-parser#0.0.0+20160619023215", 8 | "cookie-parser": "registry:dt/cookie-parser#1.3.4+20160316155526", 9 | "core-js": "registry:dt/core-js#0.0.0+20160725163759", 10 | "debug": "registry:dt/debug#0.0.0+20160317120654", 11 | "express": "registry:dt/express#4.0.0+20160708185218", 12 | "express-serve-static-core": "registry:dt/express-serve-static-core#4.0.0+20160829034835", 13 | "mime": "registry:dt/mime#0.0.0+20160316155526", 14 | "morgan": "registry:dt/morgan#1.7.0+20160524142355", 15 | "node": "registry:dt/node#6.0.0+20160830141956", 16 | "serve-static": "registry:dt/serve-static#0.0.0+20160606155157" 17 | } 18 | } 19 | --------------------------------------------------------------------------------