5

I'm having an issue with express static data serving in vue 2 project (webpack-simple template) because of different production and development structure.

development: localhost/app

production: server/some-directory/app

some-directory changes quite often so it is set dynamically in the config file.

My serving part of server.js:

if (config.root !== '/') {
  app.use(`/${config.root}`, express.static(path.join(__dirname)));
}

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

Transpiled JS files are in /dist folder.

This is index.html file which serves as app entry point:

<!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>

It works in development because app is in root.

But in production build it doesn't work because app is served from server subfolder.

Any ideas how to solve this?

Thanks.

user2199236
  • 53
  • 1
  • 3

2 Answers2

11

Assuming your express js server is in the same folder as your vue app:

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);
});

Don't forget to build your Vue app first!

DBFS
  • 119
  • 1
  • 6
  • 3
    Instead of just posting your code, it would be a good idea to also include explanation as to how you are solving the problem – Andreas Dec 13 '18 at 03:47
  • 1
    My app failed to run, and I realized the error was in the res.sendFile(__dirname, '/dist/index.html'); so I changed mine to: res.sendFile(__dirname + '/dist/index.html'); The function expects a complete string to the index file in the first parameter – James Shisiah Nov 05 '19 at 11:10
0

But in production build it doesn't work because app is served from server subfolder.

The phrase "it doesn't work" tells us nothing, really. What doesn't work? Do you get some error on the client? Error on the server? Do you get 404 for HTML? HTML is fine but 404 for images? You didn't specify what's wrong so I can only give you some general advice here.

If you create a router with Express:

const router = require('express').Router();
router.get('/a', ...);
router.get('/b', ...);
router.use('/c', express.static(...));

then you will be able to put your entire app in any sub-path very easily:

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

where /x is your required prefix.

But you also need to make sure that all of your static assets like HTML files don't use any absolute paths - e.g. things like:

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

but only relative paths like:

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

etc. This is also true if you leave your app alone and use a reverse proxy to add the required path prefix - which you could also do instead of messing with your Node code, and it may be easier in this case. For more info on reverse proxies with Node apps see those questions:

Community
  • 1
  • 1
rsp
  • 107,747
  • 29
  • 201
  • 177
  • It doesn't work means it still gets data from root URL and not the served static content. I tried your solution but no luck there. And since this is webpack template application I need to use absolute paths because otherwise application won't be able to find transpiled assets. For example: src="../assets/logo.png" will become src="/dist/logo.png" after build. Is it possible to change all links to have prefix /custom-directory/ using node or express? – user2199236 Apr 19 '17 at 12:14