diff --git a/ConfigSys.js b/ConfigSys.js new file mode 100644 index 0000000..dcb89c0 --- /dev/null +++ b/ConfigSys.js @@ -0,0 +1,9 @@ +module.exports={ + protocol:'httpall', + host:'localhost', + port:undefined, + // 如果使用 https 协议,必须填写以下内容,或在命令行参数中设置: + // sslKey: '/etc/letsencrypt/live/bittic.org/privkey.pem', // ssl key file, + // sslCert: '/etc/letsencrypt/live/bittic.org/cert.pem', // ssl cert file, + // sslCA: '../SSL/ca_bundle.crt', // ssl ca file, +} \ No newline at end of file diff --git a/ConfigUser.js b/ConfigUser.js new file mode 100644 index 0000000..054eb83 --- /dev/null +++ b/ConfigUser.js @@ -0,0 +1,3 @@ +module.exports={ + +} \ No newline at end of file diff --git a/package.json b/package.json index f7c0b3e..1b8799f 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,18 @@ }, "dependencies": { "axios": "^0.18.0", + "body-parser": "^1.18.2", + "compression": "^1.7.3", + "cookie-parser": "^1.4.3", + "deepmerge": "^2.1.0", + "errorhandler": "^1.5.0", + "express": "^4.16.2", "lodash": "^4.17.11", "material-design-icons-iconfont": "^3.0.3", - "tic.common": "^0.1.4", + "method-override": "^2.3.10", + "morgan": "^1.9.0", + "serve-favicon": "^2.4.5", + "tic.common": "git+https://git.faronear.org/tic/tic.common.git", "vue": "^2.5.17", "vue-axios": "^2.1.3", "vue-i18n": "^8.1.0", diff --git a/server.js b/server.js new file mode 100644 index 0000000..2201a0a --- /dev/null +++ b/server.js @@ -0,0 +1,113 @@ +const fs = require('fs') +const path = require('path') + +function config(){ + const commander = require('commander') + const deepmerge = require('deepmerge') + + var Config={} + + // 读取配置文件 +try { + if (fs.existsSync('./ConfigSys.js')) { + Config=require('./ConfigSys.js') + console.info('ConfigSys loaded') + } + if (fs.existsSync('./ConfigUser.js')) { // 如果存在,覆盖掉 ConfigSys 里的默认参数 + Config=deepmerge(Config, require('./ConfigUser.js')) // 注意,objectMerge后,产生了一个新的对象,而不是在原来的Config里添加 + console.info('ConfigUser loaded') + } + if (fs.existsSync('./ConfigSecret.js')) { // 如果存在,覆盖掉 ConfigSys 和 ConfigUser 里的参数 + Config=deepmerge(Config, require('./ConfigSecret.js')) + console.info('ConfigSecret loaded') + } +}catch(err){ + console.error('Loading config files failed: '+err.message) +} + + // 载入命令行参数 + commander + .version(Config.VERSION, '-v, --version') // 默认是 -V。如果要 -v,就要加 '-v --version' + .option('-H, --host ', 'host ip or domain name') + .option('-P, --protocol ', 'Web server protocol http|https|httpall, default to httpall') + .option('-p, --port ', 'Server port, default to 80|443') + .option('--sslCert ', 'SSL cert file') + .option('--sslKey ', 'SSL privkey file') + .option('--sslCA ', 'SSL ca bundle file') + .parse(process.argv) + + // 把命令行参数 合并入配置。 + Config.host=commander.host || Config.host + Config.protocol=commander.protocol || Config.protocol // 默认同时启用 http 和 https + Config.port=parseInt(commander.port) || parseInt(Config.port) || (Config.protocol==='http'?80:Config.protocol==='https'?443:undefined) // 端口默认为 http:80, https:443, httpall: 80|443 + Config.sslCert=commander.sslCert || Config.sslCert + Config.sslKey=commander.sslKey || Config.sslKey + Config.sslCA=commander.sslCA || Config.sslCA + + console.info('Configuration is ready.') + + return Config +} + +async function init(){ /*** 设置全局对象 ***/ + global.wo={} // wo 代表 world或‘我’,是当前的命名空间,把各种类都放在这里,防止和其他库的冲突。 + wo.Config=config() // 依次载入系统默认配置、用户配置文件、命令行参数 +} + +(async function start(){ + await init() + + var express = require('express') + var favicon = require('serve-favicon') + var logger = require('morgan') + var cookieParser = require('cookie-parser') + var bodyParser = require('body-parser') + const compression = require('compression') + + var server = express() + + /*** 通用中间件 ***/ + // uncomment after placing your favicon in /public + //server.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))) + server.use(logger('development'===server.get('env')?'dev':'combined')) + server.use(bodyParser.json()) + server.use(bodyParser.urlencoded({ extended: false })) + server.use(cookieParser()) + server.use(compression()) + + /*** 路由 ***/ + server.use(express.static(path.join(__dirname,'dist'), {index:'index.html'})) + +// var vhost = require('vhost') +// var webroot=express.static(path.join(__dirname,'dist'), {index:'index.html'}) + // server.use(vhost('bittic.org', webroot)) + // server.use(vhost('www.bittic.org', webroot)) + // server.use(vhost('*', webroot)) + // server.use(vhost('*.*', webroot)) + // server.use(vhost('*.*.*', webroot)) + // server.use(vhost('*.*.*.*', webroot)) + + /*** 启动 Web 服务 ***/ + if ('http'===wo.Config.protocol) { + require('http').createServer(server).listen(wo.Config.port, function(err) { + console.log('Server listening on %s://%s:%d for %s environment', wo.Config.protocol, wo.Config.host, wo.Config.port, server.settings.env) + }) + }else if ('https'===wo.Config.protocol) { + require('https').createServer({ + key: fs.readFileSync(wo.Config.sslKey), cert: fs.readFileSync(wo.Config.sslCert) // , ca: [ fs.readFileSync(wo.Config.sslCA) ] // only for self-signed certificate: https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener + }, server).listen(wo.Config.port, function(err){ + console.log('Server listening on %s://%s:%d for %s environment', wo.Config.protocol, wo.Config.host, wo.Config.port, server.settings.env) + }) + }else if ('httpall'===wo.Config.protocol) { + let portHttp=wo.Config.port?wo.Config.port:80 // 如果port参数已设置,使用它;否则默认为80 + require('http').createServer(server).listen(portHttp, function(err) { + console.log('Server listening on %s://%s:%d for %s environment', wo.Config.protocol, wo.Config.host, portHttp, server.settings.env) + }) + + let portHttps=(wo.Config.port && wo.Config.port!==80)?wo.Config.port+443:443 // 如果port参数已设置,使用它+443;否则默认为443 + require('https').createServer({ + key: fs.readFileSync(wo.Config.sslKey), cert: fs.readFileSync(wo.Config.sslCert) // , ca: [ fs.readFileSync(wo.Config.sslCA) ] // https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener + }, server).listen(portHttps, function(err){ + console.log('Server listening on %s://%s:%d for %s environment', wo.Config.protocol, wo.Config.host, portHttps, server.settings.env) + }) + }