Blame view

app.js 7.45 KB
ccbikai authored
1 2 3 4 5
/**
 * yohobuy app
 * @author: xuqi<qi.xu@yoho.cn>
 * @date: 2016/4/25
 */
周奇琪 authored
6
'use strict';
ccbikai authored
7
周奇琪 authored
8 9
const config = require('./config/common');
姜枫 authored
10 11 12 13
global.Promise = require('bluebird');

const yohoLib = require('yoho-node-lib');
郭成尧 authored
14 15 16
// 全局注册library
yohoLib.global(config);
17 18
const express = require('express');
const path = require('path');
姜枫 authored
19
const compression = require('compression');
20 21
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
22
const moment = require('moment');
郭成尧 authored
23
const uuid = require('uuid');
姜枫 authored
24
25
const pkg = require('./package.json');
陈峰 authored
26
const hbsEvent = require('./config/hbsevent');
姜枫 authored
27
const _ = require('lodash');
郭成尧 authored
28
const stringProcess = require('./utils/string-process');
ccbikai authored
29
30
const app = express();
31
毕凯 authored
32
// 向模板注入变量
yyq authored
33 34 35 36 37 38 39 40 41 42 43 44 45 46
switch (app.get('env')) {
    case 'development':
        global.devEnv = app.locals.devEnv = true;
        break;
    case 'test':
        global.isTest = app.locals.isTest = true;
        break;
    case 'production':
        global.isProduction = app.locals.isProduction = true;
        break;
    default:
        break;
}
47
global.version = app.locals.version = pkg.version;
48
app.locals.startTime = moment().format('YYYYMMDDHH');
49
app.locals.currentYear = moment().format('YYYY');
ccbikai(👎🏻🍜) authored
50
51 52
const logger = global.yoho.logger;
徐祁xuqi authored
53 54
// zookeeper
if (config.zookeeperServer) {
yyq authored
55 56
    const monitor = global.yoho.monitorSender;
    const monitorType = _.get(monitor, 'type.ZOOKEEPER');
yyq authored
57 58 59

    require('yoho-zookeeper')(config.zookeeperServer, 'wap', app.locals.wap = {}, false, {
        onerror: (err) => {
yyq authored
60
            monitor.tallyFail(monitorType, {
yyq authored
61 62 63 64 65
                code: err.code,
                message: err.name
            });
        }
    });
徐祁xuqi authored
66 67
}
郭成尧 authored
68
// 访问域名层级
69
app.set('subdomain offset', 3);
郭成尧 authored
70
ccbikai(👎🏻🍜) authored
71 72
app.set('etag', false);
郝肖肖 authored
73 74
app.enable('trust proxy');
毕凯 authored
75 76
app.disable('x-powered-by');
毕凯 authored
77 78
// docker验证项目是否正常发布
app.use('/node/status.html', (req, res) => {
陈峰 authored
79
    return res.status(200).end();
毕凯 authored
80
});
陈峰 authored
81 82 83
app.head('*', (req, res) => {
    res.status(200).end();
});
毕凯 authored
84
htoooth authored
85
app.use((req, res, next) => {
郭成尧 authored
86
    req.url = stringProcess.decodeURIComponent(req.url) || '/404';// 错误的网址编码重定向404
毕凯 authored
87
    req.isApmReport = _.get(req.app.locals, 'wap.open.bughd', false); // 把错误上报的开关绑定到上下文,node-lib 库要使用
陈峰 authored
88 89 90
    let isSpider = /spider/i.test(req.get('User-Agent') || '');

    if (config.aliasDomains.some(d => d === req.hostname) || isSpider) {
陈峰 authored
91
        // 如果是非m.yohobuy.com域名(无法设置sessionid到cookie域名不同)或是爬虫访问,session降级使用cookiesession
陈峰 authored
92 93 94 95
        req.session = {
            degrage: true
        };
    }
htoooth authored
96
    next();
97 98
});
htoooth authored
99 100 101
// 添加请求上下文
app.use(global.yoho.httpCtx());
102
// 指定libray目录
ccbikai authored
103
global.utils = path.resolve('./utils');
104
105
// 访问域名层级
郭成尧 authored
106
app.set('subdomain offset', 3);
lijing authored
107
姜枫 authored
108
app.use(global.yoho.hbs({
ccbikai authored
109 110
    extname: '.hbs',
    defaultLayout: 'layout',
姜枫 authored
111 112 113
    layoutsDir: path.join(__dirname, 'doraemon/views'),
    partialsDir: path.join(__dirname, 'doraemon/views/partial'),
    views: path.join(__dirname, 'doraemon/views'),
陈峰 authored
114 115
    helpers: _.assign(global.yoho.helpers, require('./utils/helpers')),
    cb: hbsEvent.cb
ccbikai authored
116
}));
ccbikai authored
117
姜枫 authored
118
ccbikai authored
119
app.use(bodyParser.json());
姜枫 authored
120 121 122
app.use(bodyParser.urlencoded({
    extended: false
}));
ccbikai authored
123
app.use(cookieParser());
姜枫 authored
124
app.use(compression());
ccbikai authored
125
htoooth authored
126
require('./doraemon/middleware/yoho-session')(app);
127 128

app.use((req, res, next) => {
ccbikai authored
129 130
    req.user = {}; // 全局的用户数据
    req.yoho = {}; // req和res绑定yoho对象,用于传递全局数据, 如req.yoho.channel等
131
    req.app.locals.wap = app.locals.wap; // zookeper对象赋值
郭成尧 authored
132
郭成尧 authored
133
    // 判断请求是否来自app
郭成尧 authored
134
    req.yoho.isMiniApp = /miniProgram/i.test(req.get('User-Agent') || '') ||
郭成尧 authored
135
        req.query.client_type === 'miniapp';
郭成尧 authored
136 137 138
    req.yoho.isNowApp = /yohonow/i.test(req.get('User-Agent') || '');
    req.yoho.isMarsApp = /yohomars/i.test(req.get('User-Agent') || '');
    req.yoho.isYohoApp = /YohoBuy/i.test(req.get('User-Agent') || '');
郭成尧 authored
139
    req.yoho.isApp = req.yoho.isMiniApp ||
郭成尧 authored
140
        req.yoho.isNowApp ||
郭成尧 authored
141 142
        req.yoho.isMarsApp ||
        req.yoho.isYohoApp ||
郭成尧 authored
143 144
        (req.query.app_version && req.query.app_version !== 'false') ||
        (req.query.appVersion && req.query.appVersion !== 'false');
郭成尧 authored
145 146

    // 独立的 UDID
郭成尧 authored
147
    if (!req.cookies.udid || (req.yoho.isApp && req.query.udid)) {
毕凯 authored
148 149
        let udid = uuid.v4();
郭成尧 authored
150 151 152 153
        if (req.yoho.isApp && req.query.udid) {
            udid = req.query.udid;
        }
毕凯 authored
154
        res.cookie('udid', udid, {
郭成尧 authored
155 156 157
            domain: 'yohobuy.com',
            expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000)
        });
毕凯 authored
158
        req.cookies.udid = udid;
郭成尧 authored
159
    }
ccbikai authored
160 161 162
    next();
});
htoooth authored
163 164 165 166
function isOpenApmRisk(req) {
    return _.get(req.app.locals, 'wap.open.apmrisk', false);
}
ccbikai authored
167
// dispatcher
htoooth authored
168
try {
shijian authored
169
    const tdkUrl = require('./doraemon/middleware/redis-url');
ccbikai authored
170
    const user = require('./doraemon/middleware/user');
徐炜 authored
171
    const reqParamsFilter = require('./doraemon/middleware/req-params-filter');
172
    const urlRewrite = require('./doraemon/middleware/url-rewrite');
173
    const subDomain = require('./doraemon/middleware/sub-domain');
郭成尧 authored
174
    const itemNameHandler = require('./doraemon/middleware/item-name-handler');
ccbikai authored
175
    const setYohoData = require('./doraemon/middleware/set-yoho-data');
ccbikai authored
176
    const errorHanlder = require('./doraemon/middleware/error-handler');
biao authored
177
    const setPageInfo = require('./doraemon/middleware/set-pageinfo');
Aiden Xu authored
178
    const devtools = require('./doraemon/middleware/devtools');
徐炜 authored
179
    const layoutTools = require('./doraemon/middleware/layout-tools');
180
    const seo = require('./doraemon/middleware/seo');
姜枫 authored
181
    const pageCache = require('./doraemon/middleware/page-cache');
毕凯 authored
182
    const downloadBar = require('./doraemon/middleware/download-bar');
htoooth authored
183
    const routeEncode = require('./doraemon/middleware/route-encode');
htoooth authored
184 185
    const ifElseMd = require('./doraemon/middleware/ifElseMd');
    const riskManagementApm = require('./doraemon/middleware/risk-management2');
郝肖肖 authored
186
    const riskManagement = require('./doraemon/middleware/risk-management');
陈峰 authored
187
    const statics = require('./doraemon/middleware/statics');
ccbikai authored
188 189

    // YOHO 前置中间件
shijian authored
190
    app.use(tdkUrl());
徐炜 authored
191
    app.use(reqParamsFilter());
192
    app.use(urlRewrite());
193
    app.use(subDomain());
郭成尧 authored
194
    app.use(itemNameHandler);
ccbikai authored
195
    app.use(setYohoData());
ccbikai authored
196 197
    app.use(user());
郝肖肖 authored
198 199
    // 请求限制中间件
    if (!app.locals.devEnv) {
htoooth authored
200 201 202 203
        const limiter = require('./doraemon/middleware/limiter');
        const limiterApm = require('./doraemon/middleware/limiter/index2');

        app.use(ifElseMd(isOpenApmRisk, limiterApm, limiter));
郝肖肖 authored
204
    }
ccbikai authored
205
Aiden Xu authored
206 207 208 209
    if (app.locals.devEnv) {
        app.use(devtools());
    }
郝肖肖 authored
210 211
    app.use(seo());
    app.use(setPageInfo());
徐炜 authored
212
    app.use(layoutTools());
姜枫 authored
213
    app.use(pageCache());
htoooth authored
214
    app.use(routeEncode.md);
毕凯 authored
215
    app.use(downloadBar());
htoooth authored
216
    app.use(ifElseMd(isOpenApmRisk, riskManagementApm(), riskManagement()));
陈峰 authored
217
    app.use(statics(app));
毕凯 authored
218
htoooth authored
219
    require('./dispatch')(app);
ccbikai authored
220 221 222 223 224 225
    app.all('*', errorHanlder.notFound()); // 404

    // YOHO 后置中间件
    app.use(errorHanlder.serverError());
} catch (err) {
    logger.error(err);
htoooth authored
226
}
ccbikai authored
227 228

// listener
ccbikai(👎🏻🍜) authored
229
app.listen(config.port, function() {
ccbikai authored
230
    logger.info('yohobuy start');
陈峰 authored
231
    hbsEvent.event.on('hbs-complete', () => {
毕凯 authored
232
        process.send && process.send('ready');
陈峰 authored
233 234 235 236 237 238
        logger.info('hbs-all-complete');
        if (!process.env.NODE_ENV || process.env.NODE_ENV === 'dev') {
            let {devHost, port} = require('./config/devtools');

            require('request-promise')({
                url: `http://${devHost}:${port}/event?action=reload`
陈峰 authored
239
            }).then(() => {}, () =>{});
陈峰 authored
240 241
        }
    });
ccbikai authored
242
});