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 @@ + + + + Express + + + + +

Express

+

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, --css ', 'add stylesheet support (less|stylus|compass|sass) (defaults to plain css)') .option(' --git', 'add .gitignore') .option('-f, --force', 'force on non-empty directory') + .option(' --typescript', 'add TypeScript support') .parse(process.argv) if (!exit.exited) { @@ -147,12 +148,33 @@ function createApplication (name, dir) { dependencies: { 'debug': '~2.6.9', 'express': '~4.16.1' + }, + devDependencies: { } } + if (program.typescript) { + pkg.scripts['build'] = 'tsc' + + pkg.devDependencies['typescript'] = '~3.7.5' + pkg.devDependencies['ts-node'] = '~8.6.2' + pkg.devDependencies['@types/node'] = '~13.7.0' + pkg.devDependencies['@types/debug'] = '~4.1.5' + pkg.devDependencies['@types/express'] = '~4.17.2' + } + // JavaScript - var app = loadTemplate('js/app.js') - var www = loadTemplate('js/www') + var appTemplatePath + var wwwTemplatePath + if (program.typescript) { + appTemplatePath = 'ts/app.ts' + wwwTemplatePath = 'ts/www.ts' + } else { + appTemplatePath = 'js/app.js' + wwwTemplatePath = 'js/www' + } + var app = loadTemplate(appTemplatePath) + var www = loadTemplate(wwwTemplatePath) // App name www.locals.name = name @@ -167,6 +189,9 @@ function createApplication (name, dir) { app.locals.modules.logger = 'morgan' app.locals.uses.push("logger('dev')") pkg.dependencies.morgan = '~1.9.1' + if (program.typescript) { + pkg.devDependencies['@types/morgan'] = '~1.7.37' + } // Body parsers app.locals.uses.push('express.json()') @@ -176,6 +201,9 @@ function createApplication (name, dir) { app.locals.modules.cookieParser = 'cookie-parser' app.locals.uses.push('cookieParser()') pkg.dependencies['cookie-parser'] = '~1.4.4' + if (program.typescript) { + pkg.devDependencies['@types/cookie-parser'] = '~1.4.2' + } if (dir !== '.') { mkdir(dir, '.') @@ -206,13 +234,25 @@ function createApplication (name, dir) { } // copy route templates + var routeScriptsDir + var routeScriptsNameGlob + if (program.typescript) { + routeScriptsDir = 'ts/routes' + routeScriptsNameGlob = '*.ts' + } else { + routeScriptsDir = 'js/routes' + routeScriptsNameGlob = '*.js' + } mkdir(dir, 'routes') - copyTemplateMulti('js/routes', dir + '/routes', '*.js') + copyTemplateMulti(routeScriptsDir, dir + '/routes', routeScriptsNameGlob) if (program.view) { // Copy view templates mkdir(dir, 'views') pkg.dependencies['http-errors'] = '~1.6.3' + if (program.typescript) { + pkg.devDependencies['@types/http-errors'] = '~1.6.3' + } switch (program.view) { case 'dust': copyTemplateMulti('views', dir + '/views', '*.dust') @@ -250,21 +290,33 @@ function createApplication (name, dir) { app.locals.modules.compass = 'node-compass' app.locals.uses.push("compass({ mode: 'expanded' })") pkg.dependencies['node-compass'] = '0.2.3' + if (program.typescript) { + copyTemplate('declarations/node-compass.d.ts', path.join(dir, 'node-compass.d.ts')) + } break case 'less': app.locals.modules.lessMiddleware = 'less-middleware' app.locals.uses.push("lessMiddleware(path.join(__dirname, 'public'))") pkg.dependencies['less-middleware'] = '~2.2.1' + if (program.typescript) { + pkg.devDependencies['less-middleware'] = '~2.0.31' + } break case 'sass': app.locals.modules.sassMiddleware = 'node-sass-middleware' app.locals.uses.push("sassMiddleware({\n src: path.join(__dirname, 'public'),\n dest: path.join(__dirname, 'public'),\n indentedSyntax: true, // true = .sass and false = .scss\n sourceMap: true\n})") pkg.dependencies['node-sass-middleware'] = '0.11.0' + if (program.typescript) { + pkg.devDependencies['node-sass-middleware'] = '0.0.31' + } break case 'stylus': app.locals.modules.stylus = 'stylus' app.locals.uses.push("stylus.middleware(path.join(__dirname, 'public'))") pkg.dependencies['stylus'] = '0.54.5' + if (program.typescript) { + pkg.devDependencies['@types/stylus'] = '0.48.32' + } break } @@ -325,15 +377,27 @@ function createApplication (name, dir) { if (program.git) { copyTemplate('js/gitignore', path.join(dir, '.gitignore')) } + if (program.typescript) { + copyTemplate('ts/tsconfig.json', path.join(dir, 'tsconfig.json')) + } // sort dependencies like npm(1) pkg.dependencies = sortedObject(pkg.dependencies) // write files - write(path.join(dir, 'app.js'), app.render()) + var appScriptName + var wwwScriptName + if (program.typescript) { + appScriptName = 'app.ts' + wwwScriptName = 'bin/www.ts' + } else { + appScriptName = 'app.js' + wwwScriptName = 'bin/www' + } + write(path.join(dir, appScriptName), app.render()) write(path.join(dir, 'package.json'), JSON.stringify(pkg, null, 2) + '\n') mkdir(dir, 'bin') - write(path.join(dir, 'bin/www'), www.render(), MODE_0755) + write(path.join(dir, wwwScriptName), www.render(), MODE_0755) var prompt = launchedFromCmd() ? '>' : '$' @@ -346,6 +410,11 @@ function createApplication (name, dir) { console.log() console.log(' install dependencies:') console.log(' %s npm install', prompt) + if (program.typescript) { + console.log() + console.log(' compile code:') + console.log(' %s npm run build', prompt) + } console.log() console.log(' run the app:') diff --git a/templates/ts/app.js.ejs b/templates/ts/app.ts.ejs similarity index 72% rename from templates/ts/app.js.ejs rename to templates/ts/app.ts.ejs index 2ef75aec..1c21171d 100644 --- a/templates/ts/app.js.ejs +++ b/templates/ts/app.ts.ejs @@ -1,17 +1,17 @@ <% if (view) { -%> -var createError = require('http-errors'); +import createError from 'http-errors'; <% } -%> -var express = require('express'); -var path = require('path'); +import express from 'express'; +import * as path from 'path'; <% Object.keys(modules).sort().forEach(function (variable) { -%> -var <%- variable %> = require('<%- modules[variable] %>'); +import <%- variable %> from '<%- modules[variable] %>'; <% }); -%> <% Object.keys(localModules).sort().forEach(function (variable) { -%> -var <%- variable %> = require('<%- localModules[variable] %>'); +import <%- variable %> from '<%- localModules[variable] %>'; <% }); -%> -var app = express(); +let app = express(); <% if (view) { -%> // view engine setup @@ -32,12 +32,12 @@ app.use(<%= mount.path %>, <%- mount.code %>); <% if (view) { -%> // catch 404 and forward to error handler -app.use(function(req, res, next) { +app.use((req, res, next) => { next(createError(404)); }); // error handler -app.use(function(err, req, res, next) { +app.use(((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 : {}; @@ -45,7 +45,7 @@ app.use(function(err, req, res, next) { // render the error page res.status(err.status || 500); res.render('error'); -}); +}) as express.ErrorRequestHandler); <% } -%> -module.exports = app; +export default app; diff --git a/templates/ts/declarations/node-compass.d.ts b/templates/ts/declarations/node-compass.d.ts new file mode 100644 index 00000000..36ae2438 --- /dev/null +++ b/templates/ts/declarations/node-compass.d.ts @@ -0,0 +1,4 @@ +declare module 'node-compass' { + const compass: any; + export default compass; +} diff --git a/templates/ts/gitignore b/templates/ts/gitignore deleted file mode 100644 index d1bed128..00000000 --- a/templates/ts/gitignore +++ /dev/null @@ -1,61 +0,0 @@ -# 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 deleted file mode 100644 index ab1ad8a9..00000000 --- a/templates/ts/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - Express - - - - -

Express

-

Welcome 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 add stylesheet support (less|stylus|compass|sass) (defaults to plain css) --git add .gitignore + --typescript add TypeScript support -f, --force force on non-empty directory -h, --help output usage information From 22b02d66ff6c302b046b248e57d2696218b2268e Mon Sep 17 00:00:00 2001 From: Louis Yuen <15329894+louisyuenll@users.noreply.github.com> Date: Wed, 5 Feb 2020 23:07:44 +0800 Subject: [PATCH 4/7] gen: add typescript support Remove unused dependency --- bin/express-cli.js | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/express-cli.js b/bin/express-cli.js index 3c302378..91e25e5d 100755 --- a/bin/express-cli.js +++ b/bin/express-cli.js @@ -157,7 +157,6 @@ function createApplication (name, dir) { pkg.scripts['build'] = 'tsc' pkg.devDependencies['typescript'] = '~3.7.5' - pkg.devDependencies['ts-node'] = '~8.6.2' pkg.devDependencies['@types/node'] = '~13.7.0' pkg.devDependencies['@types/debug'] = '~4.1.5' pkg.devDependencies['@types/express'] = '~4.17.2' From 13040ebd06701eb5665582a55d00dfb1864ca2e5 Mon Sep 17 00:00:00 2001 From: Louis Yuen <15329894+louisyuenll@users.noreply.github.com> Date: Fri, 7 Feb 2020 03:13:02 +0800 Subject: [PATCH 5/7] gen: add typescript support Updated to add devDependencies into package.json only when using TypeScript template --- bin/express-cli.js | 6 ++++-- test/cmd.js | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/bin/express-cli.js b/bin/express-cli.js index 91e25e5d..13562e14 100755 --- a/bin/express-cli.js +++ b/bin/express-cli.js @@ -148,14 +148,13 @@ function createApplication (name, dir) { dependencies: { 'debug': '~2.6.9', 'express': '~4.16.1' - }, - devDependencies: { } } if (program.typescript) { pkg.scripts['build'] = 'tsc' + pkg.devDependencies = {} pkg.devDependencies['typescript'] = '~3.7.5' pkg.devDependencies['@types/node'] = '~13.7.0' pkg.devDependencies['@types/debug'] = '~4.1.5' @@ -382,6 +381,9 @@ function createApplication (name, dir) { // sort dependencies like npm(1) pkg.dependencies = sortedObject(pkg.dependencies) + if (pkg.devDependencies) { + pkg.devDependencies = sortedObject(pkg.devDependencies) + } // write files var appScriptName diff --git a/test/cmd.js b/test/cmd.js index 317c2d28..c0711a73 100644 --- a/test/cmd.js +++ b/test/cmd.js @@ -74,8 +74,7 @@ describe('express(1)', function () { ' "http-errors": "~1.6.3",\n' + ' "jade": "~1.11.0",\n' + ' "morgan": "~1.9.1"\n' + - ' },\n' + - ' "devDependencies": {}\n' + + ' }\n' + '}\n') }) From f1fb0a5175b52c8e0065c1f726386921410ee55b Mon Sep 17 00:00:00 2001 From: Louis Yuen <15329894+louisyuenll@users.noreply.github.com> Date: Fri, 7 Feb 2020 03:18:42 +0800 Subject: [PATCH 6/7] gen: add typescript support Adjust @types/express to align with express Include tslib to avoid duplicated polyfill codes in output --- bin/express-cli.js | 4 +++- templates/ts/tsconfig.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/express-cli.js b/bin/express-cli.js index 13562e14..22dba3c9 100755 --- a/bin/express-cli.js +++ b/bin/express-cli.js @@ -158,7 +158,9 @@ function createApplication (name, dir) { pkg.devDependencies['typescript'] = '~3.7.5' pkg.devDependencies['@types/node'] = '~13.7.0' pkg.devDependencies['@types/debug'] = '~4.1.5' - pkg.devDependencies['@types/express'] = '~4.17.2' + pkg.devDependencies['@types/express'] = '~4.16.1' + + pkg.dependencies['tslib'] = '~1.10.0' } // JavaScript diff --git a/templates/ts/tsconfig.json b/templates/ts/tsconfig.json index eda460a5..f6a6ea84 100644 --- a/templates/ts/tsconfig.json +++ b/templates/ts/tsconfig.json @@ -18,7 +18,7 @@ // "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'. */ + "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'). */ From ecca77f652bbb625d35a655be9423d053cc877ff Mon Sep 17 00:00:00 2001 From: Louis Yuen <15329894+louisyuenll@users.noreply.github.com> Date: Fri, 31 Jul 2020 21:17:19 +0800 Subject: [PATCH 7/7] gen: add typescript support Fixed the devDependecies to include the correct typings --- bin/express-cli.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/express-cli.js b/bin/express-cli.js index 22dba3c9..b8dae952 100755 --- a/bin/express-cli.js +++ b/bin/express-cli.js @@ -299,7 +299,7 @@ function createApplication (name, dir) { app.locals.uses.push("lessMiddleware(path.join(__dirname, 'public'))") pkg.dependencies['less-middleware'] = '~2.2.1' if (program.typescript) { - pkg.devDependencies['less-middleware'] = '~2.0.31' + pkg.devDependencies['@types/less-middleware'] = '~2.0.31' } break case 'sass': @@ -307,7 +307,7 @@ function createApplication (name, dir) { app.locals.uses.push("sassMiddleware({\n src: path.join(__dirname, 'public'),\n dest: path.join(__dirname, 'public'),\n indentedSyntax: true, // true = .sass and false = .scss\n sourceMap: true\n})") pkg.dependencies['node-sass-middleware'] = '0.11.0' if (program.typescript) { - pkg.devDependencies['node-sass-middleware'] = '0.0.31' + pkg.devDependencies['@types/node-sass-middleware'] = '0.0.31' } break case 'stylus':