使用 Node 后端设置 webpack 热开发服务器以进行生产

Setup webpack hot dev-server with a Node backend for production

本文关键字:服务器 开发 后端 Node 设置 webpack 使用      更新时间:2023-09-26

我有一个与 webpack 捆绑在一起的前端应用程序,它由 Node 后端服务器提供服务并与之通信。

Webpack 热开发服务器正在8080上运行。节点后端在 1985 上运行。

我想从 Node 提供index.html,但希望在开发期间从热开发服务器提供资产。为了实现这一目标,我有:

在 webpack 配置中设置一个绝对的公共路径值:

  output: {
    publicPath: 'http://localhost:8080/'
  },

并在index.html中使用绝对 URL 指向热开发服务器:

<script src="http://localhost:8080/webpack-dev-server.js"></script>
<script src="http://localhost:8080/js/vendors.js"></script>
<script src="http://localhost:8080/js/bundle.js"></script>

所以我可以运行热开发服务器并运行我的 Node 服务器并浏览到 http://localhost:1985 .一切都很棒。

但是当我开始在生产中部署/运行时,这绝对不是我想要的。我想要vendors.jsbundle.js的相对 URL,我绝对不想包含webpack-dev-server.js脚本。

我可以在服务器上使用 Handlebars 或其他一些模板来指定绝对/相对路径,但它不会提供删除热开发服务器脚本的干净方法。我也可以为每个设置提供不同的索引文件,但这似乎很快就会导致错误。

如何最好地构建/部署它,以便在开发中使用热开发服务器,同时仍然允许在生产中通过 Node 部署和服务整个事情?

我们目前正在使用您为路径建议的模板化方法,并通过引入一个环境变量来减轻 webpack-dev-server.js 脚本标签的丑陋,该变量指定我们是"构建"还是"开发"。

如果您使用 gulp 作为任务运行程序(我们是),您可以使用 process.env.NAME = VALUE .

如果您使用的是 npm 构建,您可以通过带有 --NAME VALUE 的命令行添加它们。

后端服务器的最后一步是创建变量,然后这些变量适合我们的索引.html模板:

    <%
    // connect the hot-reload dev server
    if (mode === 'dev') {
        print("<script type='text/javascript' src='" + webpackURL + "/webpack-dev-server.js'></script>");
    }
    %>
    <script type="text/javascript" src="<%= webpackURL %>/js/bundle.js"></script>

出于这个原因,我停止使用webpack-dev-server,而是使用 webpack-dev-middleware/webpack-hot-middleware 的组合,因为后者允许您将它们挂载到现有的快速服务器中。

我的服务器基本上是这样做的:

const express = require('express');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const config = require('./webpack.config.js');
const app = express();
if (process.env.WEBPACK_DEV_SERVER === 'true') {
    const config = webpack(config);
    app.use(webpackDevMiddleware(compiler));
    app.use(webpackHotMiddleware(compiler));
} else {
    app.use(express.static(path.join(__dirname, './dist'));
}
app.use((req, res) => {
    res.status(200).send(`
        <!doctype html>
        <html>
        <head>
            <title>App</title>
        </head>
        <body>
            <div id="root"></div>
            <script src="/bundle.js"></script>
        </body>
        </html>
    `);
});

您可以在 60fram.es react 样板中看到一个完整的示例