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

196

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

但是webpack dev server不处理任意终点。

这里有一个解决方案,使用额外的express服务器。 如何允许webpack-dev-server从react-router允许入口点

但我不想启动另一个express服务器来允许路由匹配。我只想告诉webpack dev server匹配任何URL并发送我的React应用程序。谢谢。


你看过React Router Mega Demo吗? - rojobuffalo
11个回答

208
我找到了最简单的方法来包含一个小的配置:

我找到了最简单的方法来包含一个小的配置:

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

我通过访问PUSHSTATE WITH WEBPACK-DEV-SERVER找到了这个。


22
你也可以将其用作CLI选项:--history-api-fallback - VonD
11
我需要使用类似于以下代码来适应新版2的开发服务器:devServer: { port: 3000, historyApiFallback: true }, - Adrian Moisa
3
确实,您必须同时使用cli选项“--history-api-fallback”和在webpack dev服务器配置中将分辨率设置为像上面回答中描述的索引文件。 - Jc Figueroa
应该是 index: '/index.html' 而不是其他的。 - Alex Buchatski

114

historyApiFallback选项在webpack-dev-server的官方文档中有清晰的解释,说明如何通过使用此选项实现。

historyApiFallback: true

当路由未找到时,它会简单地回退到index.html

或者

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

1
更新链接:https://webpack.js.org/configuration/dev-server/#devserver - Jakob Jingleheimer
但实际上,webpack-dev-server现在正在维护中。它的继任者是https://github.com/webpack-contrib/webpack-serve#add-function-parameters,支持`historyApiFallback`。 - Jakob Jingleheimer
3
如果您是在2019年阅读这篇文章,根据 https://github.com/webpack-contrib/webpack-serve#webpack-serve 的说法,webpack-dev-serverwebpack-serve 的后继者,而不是 https://dev59.com/71wZ5IYBdhLWcg3wBcSz?answertab=oldest#comment86936567_39985334 中提到的另一种方式。 - ur5us
ur5us的评论实际上是错误的。webpack-serve是webpack-dev-server的计划接任者。我是webpack-serve的作者和webpack-dev-server的前维护者。当我休息一段时间时,一些不满的组织成员已经将webpack-serve废弃,而我已在我的分支下发布了它。 - shellscape

44

将公共路径添加到配置中可帮助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
}

1
哇,这对我也起作用了!historyApiFallback技巧只在URL的最后一部分起作用,原因不明。 /test可以工作,但/test/test会出现404错误。 - Alex. P.
除了 historyApiFallback: {index: '/'} historyApiFallback: true(两者都对我有效),在我的情况下(Router 5.2),设置 publicPath 也是必不可少的。 - Marcus Junius Brutus
1
唯一解决整个问题的答案。谢谢! - Tomáš Vavřinka

19

这样对我来说是有效的

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

},

正在开发 Riot 应用程序


这个还存在吗?在2023年没有看到它。 - Daniel Kats

14

我的情况有些不同,因为我正在使用带有webpack和'eject'选项的angular CLI,并在运行ng eject命令后进行了修改。我在package.json中修改了'ejected npm script'的 'npm start',以传递--history-api-fallback标志。

"start": "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"},

9

我同意大部分已有的答案。

我想要强调的一点是,如果您在手动刷新页面时遇到问题,并且深层路径上保留了除了路径最后一部分之外的所有内容,并将你的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
}

6
如果你选择使用webpack-dev-server,应该不要用它来服务于整个React应用。应该使用它来服务于你的bundle.js文件以及静态依赖项。在这种情况下,你需要启动2个服务器,一个是用于Node.js入口点的,它实际上将处理路由并提供HTML,另一个是用于Bundle和静态资源的。
如果你真的想要一个单一的服务器,你必须停止使用webpack-dev-server并开始在你的应用程序服务器中使用webpack-dev-middleware。它将“即时”处理bundles(我认为它支持缓存和热模块替换),并确保你对bundle.js的调用始终是最新的。

2
我只在开发环境下使用 webpack-dev-server 进行热重载、资源映射等操作。否则,我有一个静态网站,可以从任何地方托管文件。 - eguneys

6

我在我的路径中有点 ".",例如 /orgs.csv,因此我必须将其放入我的 webpack 配置中。

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

5
你可以启用 historyApiFallback 来在没有找到其他资源时,服务于 index.html 而不是 404 错误页面。详见devserver-historyapifallback
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 4.16.5webpack-serve 2.0的人来说; 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)));
      }
  });
});

参考链接

您需要将开发脚本从webpack-serve更改为node serve.config.js


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接