美文网首页React.js
reactjs重构java vm方案

reactjs重构java vm方案

作者: Aaaaaaaaaaayou | 来源:发表于2016-11-23 10:50 被阅读144次

起因

目前妈妈送房采用的是经典的MVC架构,前端模版使用vm,对于即会java又懂前端的人来说,这种方式没有什么不好,反而开发会很快。

但是,现在的互联网是分工协作的,我们现在的方式是前端开发人员负责静态页面样式及交互的开发,后端人员拿到静态页面进行数据的绑定,如果一次能搞定,那当然没什么问题,但是一旦涉及到bug的修改,功能的调整,那就是折磨了。再加上几经人手,前端代码已经丑陋不堪。所以,我萌生出了对项目进行重构并进行前后端分离的想法。为什么要前后端分离,这篇文章讲得不错

刚好最近学习了react,实战中也尝试了下,并且我们的这个项目特别适合做成一个SPA(single page application,单页面应用),所以就决定利用其进行逐步重构。

项目路径规划

因为SPA的代码最后都需要编译打包成一个文件,所以我把我的前端工程跟java工程放在一起,方便文件直接生成到java工程中

project.png

webpack打包路径设置

...
var staticPath = '../../webapp/assets'; // java工程静态文件路径
var viewFilename= '../../webapp/view/main/mmsf/mmsfIndex.vm' // java工程试图文件路径
...
// 文件打包后直接生成到java工程下
    entry: {
      bundle:path.resolve(__dirname, 'app/main.js')
  },
  output: {
    path: path.resolve(__dirname ,staticPath ),
    publicPath: '/',
    filename: '/js/mmsf/[name].js'
  },
...
// 图片
  module: {
    loaders:[
      ...
      { test: /\.(png|jpg)$/, loader: 'file-loader?limit=8192&name=i/mmsf/[name].[ext]'},
    ]
  },
...
// html文件及配置文件处理
plugins: [
    ...
    new CopyWebpackPlugin([
      { from: './app/mmsfIndex.html', to: path.resolve(__dirname, viewFilename) },
      { from: './app/config.js', to: path.resolve(__dirname ,staticPath + '/js/mmsf/config.js') },
    ]),
  ]

如何方便的与后端进行接口联调

前后端分离时,数据交换一般采取http的方式。开发时由于前后端不在同一个域,需要进行一些处理,以解决js跨越的限制。
常见的方法有:

  • 浏览器设置(chrome),原来确实是一个最方便的方式,在新版的chrome浏览器上试过,但是没成功
  • jsonp的方式,有点麻烦,放弃
  • 后端设置http头(Access-Allow-Control-Origin),本公司后端不会,懒得去求他们,还是自己想办法吧。
  • ngix,最后决定用这个

ngix配置

如果我将ngix配置成如下所示:

#user  nobody;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    #access_log  logs/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        #access_log  logs/host.access.log  main;
        location /api {
                  proxy_connect_timeout   3;  
            proxy_send_timeout      30;  
            proxy_read_timeout      30;
                  #rewrite (.*) site-web-personal/$1 permanent;
                  proxy_set_header   Host    $host;
            proxy_set_header   Remote_Addr    $remote_addr;
            proxy_set_header   X-Real-IP    $remote_addr;
            proxy_set_header   X-Forwarded-For    $proxy_add_x_forwarded_for;
            proxy_pass http://192.168.10.171:8282/api;
        }       
        location / {
                  proxy_connect_timeout   3;  
            proxy_send_timeout      30;  
            proxy_read_timeout      30;
                  #rewrite (.*) site-web-personal/$1 permanent;
                  proxy_set_header   Host    $host;
            proxy_set_header   Remote_Addr    $remote_addr;
            proxy_set_header   X-Real-IP    $remote_addr;
            proxy_set_header   X-Forwarded-For    $proxy_add_x_forwarded_for;
            proxy_pass http://192.168.10.169:8888/;  
        }       
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

这样当我访问http://localhost/*时会转发到我本地起的前端调试web服务,当我访问http://localhost/api时会转发到后端接口服务。

但是,我们的后端一开始并没有统一规划,所以也就没有区别接口的url地址和访问页面的url地址。

最后想到的办法是,利用eclipse->server可以给工程配置一个统一的url根目录来解决:

Paste_Image.png

然后ngix配置改成:

...
location /house-web-web {
    proxy_connect_timeout   3;  
    proxy_send_timeout      30;  
    proxy_read_timeout      30;
    #rewrite (.*) site-web-personal/$1 permanent;
    proxy_set_header   Host    $host;
    proxy_set_header   Remote_Addr    $remote_addr;
    proxy_set_header   X-Real-IP    $remote_addr;
    proxy_set_header   X-Forwarded-For    $proxy_add_x_forwarded_for;
    proxy_pass http://192.168.10.171:8282/house-web-web;
}       
...

此时,访问http://localhost/house-web-web的请求会转发给后台接口,当然前端也需要进行配置:

// 上线需要改这两个参数
window.debug = true;

// baseurl
window.apiBase = window.debug ? '/house-web-web' : ''

// 前端路由
window.url = {
    'discoverIndex' : '/discover/index.htm', // 发现首页
    'discoverDetail' :  '/discover/detail.htm', //  发现详情
    'searchIndex' : '/search/index.htm', // 搜索首页
    'searchDetail' : '/search/detail.htm' // 搜索详情
}

// api
 window.api = {
    'discoverIndex': window.apiBase + '/discover/getIndexJson.htm', //发现首页
    'discoverDetail': window.apiBase + '/discover/detailPage.htm', // 发现详情
 }

这样,此时在浏览器中访问http://localhost/#/discover/index.htm则会到本地前端调试的服务,在该页面中访问http://localhost/house-web-web/discover/getIndexJson.htm则会访问后台的接口

前端路由

react的前端路由有两种方式hashHistorybrowserHistory
由于开发时webpack-dev-server启动的服务不支持browserHistory,所以开发时用hashHistory,生产上用browserHistory

  <Router history={window.debug ? hashHistory : browserHistory}>
            <Route path="/">
                 <Route path={window.url.discoverIndex} component={DiscoverList}/>
                 <Route path={window.url.discoverDetail} component={DiscoverDetail}/>
                 <Route path={window.url.searchIndex} component={SearchIndex}/>
                  <Route path={window.url.searchDetail} component={SearchDetail}/>
            </Route>
          </Router>

图片处理

图片有点不好弄,因为react中引入图片是相对于工程的路径,而到浏览器中访问时是相对于java静态文件目录的路径,所以这里的处理方式是:

  • 对于小图片,统一使用base64格式,这样不仅优化了访问速度,也解决了图片路径问题
  • 对于大图片,保证前端图片路径与java静态文件图片路径一致,且图片的访问路径用绝对路径

例子:

background-image: url('/assets/i/mmsf/search-banner.png')

为了确保webpack对图片进行处理,在react中对用到的图片均import

// 这里引入只是为了使webpack将图片拷贝到正确的路径
import bannerElderly from '../../assets/i/mmsf/discover-detail-banner.png'
import iconShare from '../../assets/i/mmsf/icon-share.png'

后端url处理

由于生产上还是需要使用真实路径,所以需要后端进行配合,所有用前端路由的url地址均渲染mmsfIndex.vm

Paste_Image.png

总结

总的下来,实现这一方案,用了很多非主流的方法,也让我知道了做技术只要掌握了原理,是可以根据自己的需要进行变通的。接下来就是逐步把原来的页面都迁移到新项目中来了,可以跟原来丑陋的代码说拜拜咯。
代码地址

相关文章

网友评论

    本文标题:reactjs重构java vm方案

    本文链接:https://www.haomeiwen.com/subject/gpkepttx.html