阅读本文你需要了解(pre-knowledge)

  1. dvajs框架
  2. 了解http web server
  3. 了解http代理服务

目录

  1. 前言
  2. 设置请求代理

前言

在上一篇文章中, 我们为我们的项目增加了tslint、多语言支持和动态加载js的功能. 本文将会以上一篇文章为基础, 实现一些项目开发中会用到的功能.
为了使后面的内容更加贴近真实的开发场景, 我将会使用smart interface项目为例.

创建一个web server

在开发环境中, 我们使用了webpack-dev-server作为我们的web服务器. 而在生产环境中, 我们需要用一个高性能的静态文件服务器作为我们的web服务器, 我们一般会选择nginx或者caddy等, 因为他们有丰富的配置功能并且对高并发的支持非常好.
但是如果我们要实现服务端渲染(server side render)的功能, 则需要自己实现一个有额外功能的web server.
我们选用node和express框架来开发这个web server, 因为node中的js引擎对我们实现服务端渲染有较大的优势.

创建项目

  • 我们使用express-generator来创建并初始化一个express项目webserver, 参考express官方文档.
  • 启动项目后, 我们可以在localhost:3000看到express的欢迎界面.

增加路由

接下来为我们的webserver增加路由. 这里需要注意, 为我们的react项目增加路由比较特殊, 详细说明如下:

  • 我们的整个项目只有一个入口页面index.html
  • 我们的项目有一系列的js和css文件.
  • 我们的项目存在一些异步路由段, 需要转发到相应的api服务.

根据上面的这些要求, 我们制定路由规则如下:

  1. 判断当前路由是否属于需要转发的异步路由段. 如果是, 则按规则转发, 否则交给下一条规则处理.
  2. 判断当前路由是否对应静态文件资源(js、css、图片,或者其他文件). 如果是, 则返回该文件, 否则交给下一条规则处理.
  3. 返回index.html 按照我们定义的规则, 代码实现如下:
// app.js
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var express = require('express');
var app = express();
var proxyReq = require('./proxy').proxyReq;
var proxyTable = require('./config').proxyTable;

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(cookieParser());

// 1. 文件路由
app.use('/', express.static('app/build'));

// 2. setting proxy table
for (var segement in proxyTable) {
    app.use(segement, proxyReq);
}

// 3. index.html
app.use('*', getpage);

function getpage(req, res) {
    // 将我们的react项目放在app目录下面, 并将bundle文件构建到app/build下.
    res.sendFile(path.join(__dirname + '/app/build/index.html')); 
}

module.exports = app;
/**
 * setting proxy table
 */
exports.proxyTable = {
    "/user": 'localhost:8888' // request starts with /user will proxy to localhost:8088
}

// proxy.js
var proxy = require('express-http-proxy');
var proxyTable = require("./config").proxyTable;

/**
 * 
 * @param {*} req 
 * @param {*} res 
 * @param {*} next 
 */
exports.proxyReq = function (req, res, next) {
    proxy(proxyTable[req.baseUrl], {
        proxyReqPathResolver: function (req) {
            var urlObject = require('url').parse(req.url, true);
            urlObject.query["nirvanacmsuserid"] = +resData.trim();
            return urlObject.pathname + "?" + require("querystring").stringify(urlObject.query);
        }
    })(req, res, next);
}

tips: 需要安装express-http-proxy, npm i express-http-proxy --save 这样, 我们的简易web server就搭建好了.

开发环境与生产环境

设置请求代理

为了能成功地请求到服务端的api, 我们需要为我们的web server(在这里是webpack-dev-server)设置api代理, 观察api文档可以发现, 我们的异步api都是以/async开头的, 所以代理配置如下:

// ...
devServer: {
    contentBase: './dist',
    port: 80,
    proxy: {
      '/async': 'https://smartinterface.narro.me'
    }
  }
// ...