如何告诉Webpack开发服务器为任何路由提供index.html


148

React Router允许React应用处理/arbitrary/route。为了使其正常工作,我需要我的服务器在任何匹配的路由上发送React应用程序。

但是webpack开发服务器不能处理任意端点。

这里有一个使用附加快递服务器的解决方案。 如何允许webpack-dev-server允许react-router的入口点

但是我不想启动另一个Express服务器来允许路由匹配。我只想告诉webpack开发服务器匹配任何URL,并向我发送我的react应用。请。



Answers:


169

我发现最简单的解决方案包括一个小的配置:

  devServer: {
    port: 3000,
    historyApiFallback: {
      index: 'index.html'
    }
  }

我通过访问以下内容找到的:PUSHSTATE WITH WEBPACK-DEV-SERVER


18
您也可以将其用作CLI选项:--history-api-fallback
VonD

7
我有2新版本使用这样的事情devServer: { port: 3000, historyApiFallback: true },
阿德里安Moisa

1
确实,您必须同时使用cli选项“ --history-api-fallback”,并且在webpack开发服务器配置上,如上面对此答案所述,将解析度设置为索引文件。
Jc Figueroa

86

historyApiFallback对官方文档选项的WebPack-DEV-服务器清楚地解释了如何通过使用实现

historyApiFallback: true

当找不到路由时,它只是退回到index.html

要么

// output.publicPath: '/foo-app/'
historyApiFallback: {
  index: '/foo-app/'
}


但是实际上webpack-dev-server现在正在维护中。它的继任者是github.com/webpack-contrib/…,它支持historyApiFallback
jacob

3
对于任何在2019年阅读此书的人 webpack-dev-server来说,根据github.com/webpack-contrib/webpack-serve#webpack-serve是继任者webpack-serve,而不是stackoverflow.com/questions/31945763/…中提到的相反方法。
ur5us

ur5us的评论实际上是错误的。webpack-serve是webpack-dev-server的计划后继者。我是webpack-serv的作者和webpack-dev-server的前维护者。当我休假一段时间后,痛苦的组织成员弃用了webpack-serve,自那以后我就将其发布了。
shellscape

23

在配置中添加公共路径有助于Webpack理解真正的根(/),即使您在子路由上也是如此。/article/uuid

因此,修改您的webpack配置并添加以下内容:

output: {
    publicPath: "/"
}

devServer: {
    historyApiFallback: true
}

如果没有publicPath资源,则可能无法正确加载,只有index.html。

在Webpack上测试 4.6

配置的更大部分(只是为了获得更好的画面):

entry: "./main.js",
output: {
  publicPath: "/",
  path: path.join(__dirname, "public"),
  filename: "bundle-[hash].js"
},
devServer: {
  host: "domain.local",
  https: true,
  port: 123,
  hot: true,
  contentBase: "./public",
  inline: true,
  disableHostCheck: true,
  historyApiFallback: true
}

哇,这对我也有用!由于historyApiFallback某种原因,该技巧仅适用于URL的最后一部分。/test会工作,但/test/test将给予404
亚历克斯。P.19年

除了historyApiFallback: {index: '/'} historyApiFallback: true(两者都对我有用),publicPath在我的情况下,设置也是必不可少的(Router 5.2)。
Marcus Junius Brutus

17

这样为我工作

devServer: {
    contentBase: "./src",
    hot: true,
    port: 3000,
    historyApiFallback: true

},

在防暴应用程序上工作


14

我的情况有点不同,因为我使用的带的WebPack和运行后的“弹出”选项角CLI 纳克弹出命令。我在package.json中为'npm start'修改了弹出的npm脚本以传递--history-api-fallback标志

“开始”:“ webpack-dev-server --port = 4200 --history-api-fallback

"scripts": {
"ng": "ng",
"start": "webpack-dev-server --port=4200 --history-api-fallback",
"build": "webpack",
"test": "karma start ./karma.conf.js",
"lint": "ng lint",
"e2e": "protractor ./protractor.conf.js",
"prepree2e": "npm start",
"pree2e": "webdriver-manager update --standalone false --gecko false --quiet",
"startold": "webpack-dev-server --inline --progress --port 8080",
"testold": "karma start",
"buildold": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"},

6

如果选择使用webpack-dev-server,则不应使用它来服务整个React应用程序。您应该使用它来服务bundle.js文件以及静态依赖项。在这种情况下,您将必须启动2台服务器,其中一台用于Node.js入口点,它们实际上将处理路由并为HTML服务,另一台用于捆绑和静态资源。

如果您确实想要一台服务器,则必须停止使用,webpack-dev-server并开始在应用程序服务器中使用webpack-dev-middleware。它将“即时”处理捆绑包(我认为它支持缓存和热模块替换),并确保您的调用bundle.js始终是最新的。


2
我仅将webpack-dev-server用于开发热重载源地图等。否则,我有一个静态网站,可以在任何地方托管文件。
eguneys 2015年

3

如果在此位置未找到其他资源,则可以启用historyApiFallback服务index.html而不是404错误。

let devServer = new WebpackDevServer(compiler, {
    historyApiFallback: true,
});

如果要为不同的URI提供不同的文件,则可以向此选项添加基本重写规则。该index.html仍将担任了其他路径。

let devServer = new WebpackDevServer(compiler, {
    historyApiFallback: {
        rewrites: [
            { from: /^\/page1/, to: '/page1.html' },
            { from: /^\/page2/, to: '/page2.html' },
            { from: /^\/page3/, to: '/page3.html' },
        ]
    },
});

2

我知道这个问题是针对webpack-dev-server的,但是对于使用webpack-serve 2.0的任何人webpack 4.16.5 ; webpack-serve允许附加组件。您需要创建serve.config.js

const serve = require('webpack-serve');
const argv = {};
const config = require('./webpack.config.js');

const history = require('connect-history-api-fallback');
const convert = require('koa-connect');

serve(argv, { config }).then((result) => {
  server.on('listening', ({ server, options }) => {
      options.add: (app, middleware, options) => {

          // HistoryApiFallback
          const historyOptions = {
              // ... configure options
          };

          app.use(convert(history(historyOptions)));
      }
  });
});

参考

您将需要将dev脚本从更改webpack-servenode serve.config.js


2

对我来说,我有点“。” 在我的路径,例如,/orgs.csv所以我不得不把它放在我的webpack confg中。

devServer: {
  historyApiFallback: {
    disableDotRule: true,
  },
},

0

我同意大多数现有答案。

我想提到的关键一件事是,如果您在较深的路径手动重新加载页面时遇到问题,该路径将保留路径的最后一部分,并保留js捆绑文件名称的名称,那么您可能需要一个额外的设置(特别是该publicPath设置)。

例如,如果我有一个路径,/foo/bar并且我的捆绑程序文件称为bundle.js。当我尝试手动刷新页面时,出现404提示/foo/bundle.js找不到。有趣的是,如果您尝试从路径重新加载,则/foo不会出现任何问题(这是因为后备处理了它)。

尝试结合使用以下内容和现有webpack配置来解决此问题。output.publicPath是关键!

output: {
    filename: 'bundle.js',
    publicPath: '/',
    path: path.resolve(__dirname, 'public')
},
...
devServer: {
    historyApiFallback: true
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.