/** * yohobuy app * @author: xuqi<qi.xu@yoho.cn> * @date: 2016/4/25 */ 'use strict'; if (process.env.USE_APM === '1' && process.env.NODE_ENV === 'production') { require('oneapm'); } const config = require('./config/common'); global.Promise = require('bluebird'); const yohoLib = require('yoho-node-lib'); // 全局注册library yohoLib.global(config); const express = require('express'); const compression = require('compression'); const path = require('path'); const bodyParser = require('body-parser'); const cookieParser = require('cookie-parser'); const favicon = require('serve-favicon'); const _ = require('lodash'); const fp = require('lodash/fp'); const CookieSession = require('client-sessions'); const MemcachedSession = require('yoho-express-session'); const memcached = require('connect-memcached'); const MemcachedStore = memcached(MemcachedSession); const pkg = require('./package.json'); const app = express(); const helpers = global.yoho.helpers; // tdk global.yoho.redis = require('./doraemon/middleware/redis'); const tdk = require('./utils/getTDK'); // NOTE: 这里修改了图片质量的参数 helpers.image = _.flow(helpers.image, fp.replace(/\/quality\/\d*$/, '/quality/90')); // NOTE:这里修改了参数的个数 helpers.getUrlBySkc = skn => `//item.yohobuy.com/${skn}.html`; global.middleware = path.resolve('./doraemon/middleware'); global.utils = path.resolve('./utils'); global.appRoot = path.resolve(__dirname); // 向模板注入变量 app.locals.devEnv = app.get('env') === 'development'; app.locals.isProduction = app.get('env') === 'production'; app.locals.version = pkg.version; // zookeeper if (config.zookeeperServer) { require('yoho-zookeeper')(config.zookeeperServer, 'pc', app.locals.pc = {}, global.yoho.cache); } app.enable('trust proxy'); // 请求限制中间件 if (!app.locals.devEnv) { app.use(require('./doraemon/middleware/limiter')); } app.set('subdomain offset', 2); // 添加请求上下文 app.use(global.yoho.httpCtx()); app.use(global.yoho.hbs({ extname: '.hbs', defaultLayout: 'layout', layoutsDir: path.join(__dirname, 'doraemon/views'), partialsDir: path.join(__dirname, 'doraemon/views/partial'), views: path.join(__dirname, 'doraemon/views'), helpers: Object.assign(global.yoho.helpers, require('./utils/helpers')) })); app.use(favicon(path.join(__dirname, '/favicon.ico'))); app.use(express.static(path.join(__dirname, 'static'))); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false})); app.use(cookieParser()); app.use(compression()); app.use(MemcachedSession({ // eslint-disable-line proxy: true, resave: false, saveUninitialized: true, unset: 'destroy', secret: '82dd7e724f2c6870472c89dfa43cf48d', name: 'yohobuy_session', cookie: { domain: 'yohobuy.com', httpOnly: false }, store: new MemcachedStore({ hosts: config.memcache.session, prefix: config.sessionMemcachedPrefix, reconnect: 5000, timeout: 1000, retries: 0 }) })); app.use(CookieSession({ // eslint-disable-line requestKey: 'session2', cookieName: 'yohobuy_session_cookie', secret: '82dd7e724f2c6870472c89dfa43cf48d', cookie: { domain: config.cookieDomain, ephemeral: true } })); app.use((req, res, next) => { if (req.session) { let sessionKeys = Object.keys(req.session || {}); let backSessionKeys = Object.keys(req.session2.sessionBack || {}); if (backSessionKeys.length > sessionKeys.length) { let differences = _.difference(backSessionKeys, sessionKeys); _.forEach(differences, d => { req.session[d] = req.session2.sessionBack[d]; }); } req.session2.sessionBack = req.session; } else { req.session = new MemcachedSession.Session(req); req.session.cookie = new MemcachedSession.Cookie({ domain: 'yohobuy.com', httpOnly: false }); req.session = _.assign(req.session, req.session2.sessionBack); } if (typeof req.session.reset !== 'function') { req.session.reset = function() { req.session = null; req.session2.reset(); }; } next(); }); app.use((req, res, next) => { req.user = {}; // 全局的用户数据 req.yoho = {}; // req和res绑定yoho对象,用于传递全局数据, 如req.yoho.channel等 if (!req.session) { req.session = {}; } // req.app.locals = _.merge(req.app.locals, { // pc: { // geetest: { // validation: true // } // } // }); next(); }); // redis seo app.use((req, res, next) => { if (!req.xhr) { tdk('url', `${req.hostname}${req.originalUrl}`, req).then(TDKObj =>{ if (TDKObj[0]) { req.tdk = { title: TDKObj[1], keywords: TDKObj[2], description: TDKObj[3] }; } next(); }); } else { return next(); } }); const logger = global.yoho.logger; // dispatcher try { const setYohoData = require('./doraemon/middleware/set-yoho-data'); const htaccess = require('./doraemon/middleware/htaccess'); const subDomain = require('./doraemon/middleware/sub-domain'); const mobileRefer = require('./doraemon/middleware/mobile-refer'); const mobileCheck = require('./doraemon/middleware/mobile-check'); const user = require('./doraemon/middleware/user'); const seo = require('./doraemon/middleware/seo'); const errorHanlder = require('./doraemon/middleware/error-handler'); const setPageInfo = require('./doraemon/middleware/set-pageinfo'); const layoutTools = require('./doraemon/middleware/layout-tools'); const pageCache = require('./doraemon/middleware/page-cache'); const devtool = require('./doraemon/middleware/devtools'); // YOHO 前置中间件 app.use(setYohoData()); app.use(htaccess()); app.use(subDomain()); app.use(mobileRefer()); app.use(mobileCheck()); app.use(user()); app.use(seo()); app.use(setPageInfo()); app.use(layoutTools()); app.use(pageCache()); if (app.locals.devEnv) { app.use(devtool()); } require('./dispatch')(app); app.all('*', errorHanlder.notFound()); // 404 // YOHO 后置中间件 app.use(errorHanlder.serverError()); } catch (err) { logger.error(err); } // listener app.listen(config.port, function() { logger.info('yohobuy start'); });