Vue 2 应用中如何使用 Express 提供静态文件服务

5
我遇到了一个问题,是在vue 2项目(使用webpack-simple模板)中,基于不同的生产和开发环境结构,无法正确提供express静态数据服务。
开发环境: localhost/app 生产环境: server/some-directory/app 由于“some-directory”会经常变化,因此它会在配置文件中动态设置。下面是我的服务代码(server.js)部分:
if (config.root !== '/') {
  app.use(`/${config.root}`, express.static(path.join(__dirname)));
}

app.use('/dist', express.static(path.join(__dirname, 'dist')));

转译后的JS文件存储在/dist文件夹中。

这是作为应用程序入口点的index.html文件:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>App Demo</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="/dist/build.js"></script>
  </body>
</html>

在开发环境中,应用程序位于根目录,因此它可以正常工作。

但是,在生产环境中,由于应用程序是从服务器子文件夹提供服务的,所以它无法正常工作。

有什么解决方法吗?

谢谢。

2个回答

11

假设你的 express js 服务器与 vue 应用程序在同一个文件夹中:

const express = require('express');
const path = require('path');

const hostname = 'localhost';
const port = 3000;

const app = express();
app.use(express.static(path.join(__dirname, 'dist')));

app.get('*', (req, res) => {
  res.sendFile(__dirname, '/dist/index.html');
});

app.listen(port, hostname, () => {
  console.log("Listening at http://%s:%s/", hostname, port);
});

不要忘记先构建您的Vue应用程序!


3
除了发布代码外,同时附加解释如何解决问题是个好主意。 - Andreas
1
我的应用程序无法运行,我发现错误在 res.sendFile(__dirname, '/dist/index.html'); 中。所以我把它改成了:res.sendFile(__dirname + '/dist/index.html');这个函数期望第一个参数为完整的索引文件字符串。 - James Shisiah

0
但在生产版本中,它不起作用,因为应用程序是从服务器子文件夹提供的。 “它不起作用”这个短语并没有告诉我们任何有用信息。什么不起作用?客户端出错了吗?服务端出错了吗?HTML返回404错误吗?HTML没问题,但是图片返回404错误吗?由于您没有说明问题出在哪里,所以我只能给您一些一般性建议。 如果您使用Express创建路由器:
const router = require('express').Router();
router.get('/a', ...);
router.get('/b', ...);
router.use('/c', express.static(...));

这样,您就可以轻松地将整个应用程序放置在任何子路径中:

app.use('/x', router);

其中/x是您所需的前缀。

但您还需要确保所有静态资源(如HTML文件)不使用任何绝对路径,例如:

<a href="/a/b/c.html">...</a>
<script src="/a/b/c.js"></script>

但仅限于相对路径,例如:

<a href="b/c.html">...</a>
<script src="../../a/b/c.js"></script>

等等。如果您让应用程序保持不变,并使用反向代理添加所需的路径前缀,这也是正确的 - 您可以这样做,而不必干扰您的Node代码,在这种情况下可能更容易。有关使用Node应用程序的反向代理的更多信息,请参见以下问题:


它不起作用意味着它仍然从根URL获取数据,而不是提供的静态内容。我尝试了你的解决方案,但没有运气。由于这是webpack模板应用程序,我需要使用绝对路径,否则应用程序将无法找到已转换的资产。例如:src =“../ assets / logo.png”在构建后将变为src =“/ dist / logo.png”。是否可以使用node或express更改所有链接以具有前缀/custom-directory/? - user2199236

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