天天看点

webpack-dev-server与单页应用路由

首先是三个使用React编写的文件:

index.js:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { BroswerRouter, Route } from 'react-router-dom';
import Home from './Home';
import List from './List';
class App extends Component {
    render(){
        return (
            <BroswerRouter>
                <Route path='/' component={Home}/>
                <Route path='/list' componnet={List}/>
            </BroswerRouter>
        );
    }
}
           

Home.js:

import React, { Component } from 'react';

class Home extends Component {
    render() {
        return (
            <div>
                HomePage
            </div>
        );
    }
}

export default Home;
           

List.js:

import React, { Component } from 'react';

class List extends Component {
    render() {
        return (
            <div>
                ListPage
            </div>
        );
    }
}

export default List;
           

从上面代码可以看见,我实现了一个及其简单的前端路由。

启动

webpack-dev-server

的服务之后,可以通过

localhost:8080

访问到首页,也就是

Home

模块渲染出来的页面:

webpack-dev-server与单页应用路由

那么按照预期,当我们在地址栏中输入

localhost:8080/list

的时候便会显示出

List

模块所渲染的页面,可是事与愿违:

webpack-dev-server与单页应用路由

会发现浏览器提示找不到这个资源,原因在于,通过地址栏直接输入地址,浏览器会想后端也就是

webpack-dev-server

请求

list.html

这个资源,而我们并没有,自然就会出现错误。

那怎么解决这个问题呢?

需要设置在配置文件中设置

devServer.historyApiFallback

{
   ...,
   devServer: {
       ...,
       historyApiFallback: true
   }
}
           

这个配置项的作用是,当产生任意的404响应都会被替代为

index.html

可以想见,当向

webpack-dev-server

请求

list.html

时,会产生404响应,于是就返回了

index.html

,而目前地址栏中URL的路径是

/list

,于是

React Router

根据我们写的路由规则跳转到

List

模块。

(只是通过在地址栏输入URL来访问会出现这种问题,而在应用中则根本不会出现页面的刷新,也就不会产生向后端的请求,直接切换到List)

查看官方文档我们知道,这个功能的实现是使用了

connect-history-api-fallback

这个包。

而这个包还有其他的一些配置。

historyApiFallback: {
  rewrites: [
    { from: /\/soccer/, to: '/soccer.html'}
  ]
};
           

上面这样的配置就是指,当请求路径为

/soccer

时,就返回

/scoccer.html

这个页面。

而我们将

historyApiFallback

设置为

true

,则代表着请求路径无论是什么,都跳转到

index.html

由前端路由决定跳转。

historyApiFallback: {
  rewrites: [
     {
      from: /^\/libs\/.*$/,
      to: function(context) {
        return '/bower_components' + context.parsedUrl.pathname;
      }
    }
  ]
};
           

甚至还可以这么写,可以通过一个函数,来获得请求路径的相关信息,再根据这些信息返回相关页面。