From 96279b1679557ed3f3b131d6d75489c9079ab668 Mon Sep 17 00:00:00 2001 From: Louis Yuen <15329894+louisyuenll@users.noreply.github.com> Date: Sun, 2 Feb 2020 15:44:12 +0800 Subject: [PATCH 1/7] gen: add typescript support Clone js template to ts template folder --- templates/ts/app.js.ejs | 51 ++++++++++++++++++++ templates/ts/gitignore | 61 ++++++++++++++++++++++++ templates/ts/index.html | 13 ++++++ templates/ts/routes/index.js | 9 ++++ templates/ts/routes/users.js | 9 ++++ templates/ts/www.ejs | 90 ++++++++++++++++++++++++++++++++++++ 6 files changed, 233 insertions(+) create mode 100644 templates/ts/app.js.ejs create mode 100644 templates/ts/gitignore create mode 100644 templates/ts/index.html create mode 100644 templates/ts/routes/index.js create mode 100644 templates/ts/routes/users.js create mode 100644 templates/ts/www.ejs diff --git a/templates/ts/app.js.ejs b/templates/ts/app.js.ejs new file mode 100644 index 00000000..2ef75aec --- /dev/null +++ b/templates/ts/app.js.ejs @@ -0,0 +1,51 @@ +<% if (view) { -%> +var createError = require('http-errors'); +<% } -%> +var express = require('express'); +var path = require('path'); +<% Object.keys(modules).sort().forEach(function (variable) { -%> +var <%- variable %> = require('<%- modules[variable] %>'); +<% }); -%> + +<% Object.keys(localModules).sort().forEach(function (variable) { -%> +var <%- variable %> = require('<%- localModules[variable] %>'); +<% }); -%> + +var app = express(); + +<% if (view) { -%> +// view engine setup +<% if (view.render) { -%> +app.engine('<%- view.engine %>', <%- view.render %>); +<% } -%> +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', '<%- view.engine %>'); + +<% } -%> +<% uses.forEach(function (use) { -%> +app.use(<%- use %>); +<% }); -%> + +<% mounts.forEach(function (mount) { -%> +app.use(<%= mount.path %>, <%- mount.code %>); +<% }); -%> + +<% if (view) { -%> +// catch 404 and forward to error handler +app.use(function(req, res, next) { + next(createError(404)); +}); + +// error handler +app.use(function(err, req, res, next) { + // set locals, only providing error in development + res.locals.message = err.message; + res.locals.error = req.app.get('env') === 'development' ? err : {}; + + // render the error page + res.status(err.status || 500); + res.render('error'); +}); + +<% } -%> +module.exports = app; diff --git a/templates/ts/gitignore b/templates/ts/gitignore new file mode 100644 index 00000000..d1bed128 --- /dev/null +++ b/templates/ts/gitignore @@ -0,0 +1,61 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# next.js build output +.next diff --git a/templates/ts/index.html b/templates/ts/index.html new file mode 100644 index 00000000..ab1ad8a9 --- /dev/null +++ b/templates/ts/index.html @@ -0,0 +1,13 @@ + + +
+Welcome to Express
+ + + diff --git a/templates/ts/routes/index.js b/templates/ts/routes/index.js new file mode 100644 index 00000000..ecca96a5 --- /dev/null +++ b/templates/ts/routes/index.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET home page. */ +router.get('/', function(req, res, next) { + res.render('index', { title: 'Express' }); +}); + +module.exports = router; diff --git a/templates/ts/routes/users.js b/templates/ts/routes/users.js new file mode 100644 index 00000000..623e4302 --- /dev/null +++ b/templates/ts/routes/users.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +router.get('/', function(req, res, next) { + res.send('respond with a resource'); +}); + +module.exports = router; diff --git a/templates/ts/www.ejs b/templates/ts/www.ejs new file mode 100644 index 00000000..690fc488 --- /dev/null +++ b/templates/ts/www.ejs @@ -0,0 +1,90 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var app = require('../app'); +var debug = require('debug')('<%- name %>:server'); +var http = require('http'); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || '3000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + debug('Listening on ' + bind); +} From abecec592626484c171a6c8ec31e15dd767b1337 Mon Sep 17 00:00:00 2001 From: Louis Yuen <15329894+louisyuenll@users.noreply.github.com> Date: Wed, 5 Feb 2020 22:58:13 +0800 Subject: [PATCH 2/7] gen: add typescript support Add TypeScript related dependencies and files --- bin/express-cli.js | 79 +++++++++++++++++++-- templates/ts/{app.js.ejs => app.ts.ejs} | 20 +++--- templates/ts/declarations/node-compass.d.ts | 4 ++ templates/ts/gitignore | 61 ---------------- templates/ts/index.html | 13 ---- templates/ts/routes/index.js | 9 --- templates/ts/routes/index.ts | 9 +++ templates/ts/routes/users.js | 9 --- templates/ts/routes/users.ts | 9 +++ templates/ts/tsconfig.json | 66 +++++++++++++++++ templates/ts/{www.ejs => www.ts.ejs} | 28 ++++---- test/cmd.js | 3 +- 12 files changed, 189 insertions(+), 121 deletions(-) rename templates/ts/{app.js.ejs => app.ts.ejs} (72%) create mode 100644 templates/ts/declarations/node-compass.d.ts delete mode 100644 templates/ts/gitignore delete mode 100644 templates/ts/index.html delete mode 100644 templates/ts/routes/index.js create mode 100644 templates/ts/routes/index.ts delete mode 100644 templates/ts/routes/users.js create mode 100644 templates/ts/routes/users.ts create mode 100644 templates/ts/tsconfig.json rename templates/ts/{www.ejs => www.ts.ejs} (68%) diff --git a/bin/express-cli.js b/bin/express-cli.js index d0c80b7f..3c302378 100755 --- a/bin/express-cli.js +++ b/bin/express-cli.js @@ -57,6 +57,7 @@ program .option('-c, --cssWelcome to Express
- - - diff --git a/templates/ts/routes/index.js b/templates/ts/routes/index.js deleted file mode 100644 index ecca96a5..00000000 --- a/templates/ts/routes/index.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET home page. */ -router.get('/', function(req, res, next) { - res.render('index', { title: 'Express' }); -}); - -module.exports = router; diff --git a/templates/ts/routes/index.ts b/templates/ts/routes/index.ts new file mode 100644 index 00000000..de994eaf --- /dev/null +++ b/templates/ts/routes/index.ts @@ -0,0 +1,9 @@ +import * as express from 'express'; +const router = express.Router(); + +/* GET home page. */ +router.get('/', (req, res, next) => { + res.render('index', { title: 'Express' }); +}); + +export default router; diff --git a/templates/ts/routes/users.js b/templates/ts/routes/users.js deleted file mode 100644 index 623e4302..00000000 --- a/templates/ts/routes/users.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET users listing. */ -router.get('/', function(req, res, next) { - res.send('respond with a resource'); -}); - -module.exports = router; diff --git a/templates/ts/routes/users.ts b/templates/ts/routes/users.ts new file mode 100644 index 00000000..f4166100 --- /dev/null +++ b/templates/ts/routes/users.ts @@ -0,0 +1,9 @@ +import * as express from 'express'; +const router = express.Router(); + +/* GET users listing. */ +router.get('/', (req, res, next) => { + res.send('respond with a resource'); +}); + +export default router; diff --git a/templates/ts/tsconfig.json b/templates/ts/tsconfig.json new file mode 100644 index 00000000..eda460a5 --- /dev/null +++ b/templates/ts/tsconfig.json @@ -0,0 +1,66 @@ +{ + "compilerOptions": { + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } +} diff --git a/templates/ts/www.ejs b/templates/ts/www.ts.ejs similarity index 68% rename from templates/ts/www.ejs rename to templates/ts/www.ts.ejs index 690fc488..97900578 100644 --- a/templates/ts/www.ejs +++ b/templates/ts/www.ts.ejs @@ -4,22 +4,24 @@ * Module dependencies. */ -var app = require('../app'); -var debug = require('debug')('<%- name %>:server'); -var http = require('http'); +import app from '../app'; +import debug from 'debug'; +import * as http from 'http'; + +debug('<%- name %>:server'); /** * Get port from environment and store in Express. */ -var port = normalizePort(process.env.PORT || '3000'); +let port = normalizePort(process.env.PORT || '3000'); app.set('port', port); /** * Create HTTP server. */ -var server = http.createServer(app); +let server = http.createServer(app); /** * Listen on provided port, on all network interfaces. @@ -33,8 +35,8 @@ server.on('listening', onListening); * Normalize a port into a number, string, or false. */ -function normalizePort(val) { - var port = parseInt(val, 10); +function normalizePort(val: string): string | number | boolean { + let port = parseInt(val, 10); if (isNaN(port)) { // named pipe @@ -53,12 +55,12 @@ function normalizePort(val) { * Event listener for HTTP server "error" event. */ -function onError(error) { +function onError(error: NodeJS.ErrnoException): void { if (error.syscall !== 'listen') { throw error; } - var bind = typeof port === 'string' + let bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; @@ -81,10 +83,10 @@ function onError(error) { * Event listener for HTTP server "listening" event. */ -function onListening() { - var addr = server.address(); - var bind = typeof addr === 'string' +function onListening(): void { + let addr = server.address(); + let bind = typeof addr === 'string' ? 'pipe ' + addr - : 'port ' + addr.port; + : 'port ' + addr!.port; debug('Listening on ' + bind); } diff --git a/test/cmd.js b/test/cmd.js index c0711a73..317c2d28 100644 --- a/test/cmd.js +++ b/test/cmd.js @@ -74,7 +74,8 @@ describe('express(1)', function () { ' "http-errors": "~1.6.3",\n' + ' "jade": "~1.11.0",\n' + ' "morgan": "~1.9.1"\n' + - ' }\n' + + ' },\n' + + ' "devDependencies": {}\n' + '}\n') }) From 5d9afc837a27a82f6ee212b243737108a768d5ca Mon Sep 17 00:00:00 2001 From: Louis Yuen <15329894+louisyuenll@users.noreply.github.com> Date: Wed, 5 Feb 2020 23:03:33 +0800 Subject: [PATCH 3/7] gen: add typescript support Update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ca18976e..11a5e33a 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ This generator can also be further configured with the following command line fl --no-view use static html instead of view engine -c, --css