首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >historyApiFallback在Webpack开发服务器中不工作

historyApiFallback在Webpack开发服务器中不工作
EN

Stack Overflow用户
提问于 2016-05-17 08:37:13
回答 8查看 36.2K关注 0票数 32

我使用Webpack开发服务器和反应路由器中的browserHistory通过HTML5历史API操纵urls。历史回顾-选项在我的webpack配置文件中不工作。在刷新http://localhost:8080/usershttp://localhost:8080/products之后,我得到了404。

webpack.config.js

代码语言:javascript
运行
复制
var webpack = require('webpack');
var merge = require('webpack-merge');

const TARGET = process.env.npm_lifecycle_event;

var common = {
    cache: true,
    debug: true,
    entry: './src/script/index.jsx',
    resolve: {
        extensions: ['', '.js', '.jsx']
    },
    output: {
        sourceMapFilename: '[file].map'
    },
    module: {
        loaders: [
            {
                test: /\.js[x]?$/,
                loader: 'babel-loader',
                exclude: /(node_modules)/
            }
        ]
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery"
        })
    ]
};

if(TARGET === 'dev' || !TARGET) {
    module.exports = merge(common,{
        devtool: 'eval-source-map',
        devServer: {
            historyApiFallback: true
        },
        output: {
            filename: 'index.js',
            publicPath: 'http://localhost:8090/assets/'
        },
        plugins: [
            new webpack.DefinePlugin({
                'process.env.NODE_ENV': JSON.stringify('dev')
            })
        ]
    });
}

index.html

代码语言:javascript
运行
复制
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
        <title>Test</title>
    </head>
    <body>
        <div id="content">
            <!-- this is where the root react component will get rendered -->
        </div>
        <script src="http://localhost:8090/webpack-dev-server.js"></script>
        <script type="text/javascript" src="http://localhost:8090/assets/index.js"></script>
    </body>
</html>

index.jsx

代码语言:javascript
运行
复制
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {Router, Route, useRouterHistory, browserHistory, Link} from 'react-router';

class Home extends Component{
  constructor(props) {
    super(props);
  }

  render() {
      return <div>
          I am home component
          <Link to="/users" activeClassName="active">Users</Link>
          <Link to="/products" activeClassName="active">Products</Link>
        </div>;
  }
}

class Users extends Component{
  constructor(props) {
    super(props);
  }

  render() {
      return <div> I am Users component </div>;
  }
}

class Products extends Component{
  constructor(props) {
    super(props);
  }

  render() {
      return <div> I am Products component </div>;
  }
}

ReactDOM.render(
    <Router history={browserHistory} onUpdate={() => window.scrollTo(0, 0)}>
        <Route path="/" component={Home}/>
        <Route path="/users" component={Users} type="users"/>
        <Route path="/products" component={Products} type="products"/>
    </Router>
    , document.getElementById('content'));

package.json

代码语言:javascript
运行
复制
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.jsx",
  "scripts": {
    "start": "npm run serve | npm run dev",
    "serve": "./node_modules/.bin/http-server -p 8080",
    "dev": "webpack-dev-server -d --progress --colors --port 8090 --history-api-fallback"
  },
  "author": "",
  "license": "MIT",
  "dependencies": {
    "events": "^1.1.0",
    "jquery": "^2.2.3",
    "path": "^0.12.7",
    "react": "^15.0.2",
    "react-dom": "^15.0.2",
    "react-mixin": "^3.0.5",
    "react-router": "^2.4.0"
  },
  "devDependencies": {
    "babel": "^6.5.2",
    "babel-core": "^6.8.0",
    "babel-loader": "^6.2.4",
    "babel-polyfill": "^6.8.0",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "babel-register": "^6.8.0",
    "http-server": "^0.9.0",
    "webpack": "^1.13.0",
    "webpack-dev-server": "^1.14.1",
    "webpack-merge": "^0.12.0"
  }
}

我试图在我的配置中更改devServer,但是它没有帮助:

代码语言:javascript
运行
复制
devServer: {
    historyApiFallback: {
        index: 'index.html',
    }
},

devServer: {
    historyApiFallback: {
        index: 'index.js',
    }
},

devServer: {
    historyApiFallback: {
        index: 'http://localhost:8090/assets',
    }
},

devServer: {
    historyApiFallback: {
        index: 'http://localhost:8090/assets/',
    }
},

devServer: {
    historyApiFallback: {
        index: 'http://localhost:8090/assets/index.html',
    }
},

devServer: {
    historyApiFallback: {
        index: 'http://localhost:8090/assets/index.js',
    }
},

devServer: {
    historyApiFallback: {
        index: 'http://localhost:8090/assets/index.js',
    }
},
output: {
    filename: 'index.js',
            publicPath: 'http://localhost:8090/assets/'
},
EN

Stack Overflow用户

发布于 2021-05-07 01:59:53

这里发生了一件非常棘手的事情!

下面的404可以是,两个完全不同的。您可以打开Chrome的“网络”选项卡,看看是最初的请求是404,还是内部的资产。

如果您不害怕终端,也可以做curl -v http://localhost:8081/product来查看实际的HTTP响应代码。

案例1:初始HTML页面上的404

在这种情况下,设置historyFallbackApi是不正确的。

通常,只有historyApiFallback: true应该在Webpack的devServer吐露中工作。(来源)但是,如果您碰巧有一个自定义的output文件夹,则必须将historyApiFallbackindex属性设置为相同的路径,就像对jsdeveloper's切津氏这样的问题的其他答案所建议的那样。

案例2: 404关于资产(例如bundle.jsvendor.js)

这个很有趣!

在本例中,您确实获得了初始的view-source: (即,如果在view-source:http://localhost:8081/admin之前添加view-source:http://localhost:8081/admin,则会看到HTML和/或curl命令显示HTML),但页面在浏览器中无法工作。

historyApiFallback所做的事情,听起来可能很神奇,实际上只是将快速服务器的req.url设置为index.html文件,用于域中的任何传入GET请求。(源代码中的主要两行)

但是,如果您的资产的路径是相对的(例如,在视图源中,您看到了<script src="vendor.js"></script>) ,那么您要登陆的路径与索引的路径深度不同(例如,当主服务器位于http://localhost:8081/admin时,您正在尝试加载http://localhost:8081/admin/user/12/summary ),那么它将无法为您的JavaScript代码找到.js文件。(就我而言,http://localhost:8081/admin/user/12/vendor.js)

请注意,这里处理HTML5历史记录的任何路由器(react路由器或vue路由器)都知道如何在初始负载时初始化到document.location.href的内部路径。但是,它不知道正确更新资产路径的“根”在哪里。(就责任而言,这甚至都不是它的工作。)因此,资产路径将根据URL的路径计算,而不是index.html的路径!因此,对于没有绝对/前缀的src="vendor.js",它尝试查找/admin/user/12/vendor.js而不是/vendor.js

这里您需要做的是确保您的output路径是WebPack的,一个绝对路径,并以/开头,所以不管登陆URL如何,它总是可以工作的。也就是说,它始终是<script src="/vendor.js"></script>源文件中的HTML。

要做到这一点,您必须将output.publicPath设置为绝对路径(有域还是不带域)。您可以通过上面的view-source:curl技术验证这一点。:)

票数 7
EN
查看全部 8 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37271062

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档