How to make Vue.js app with routing work in Heroku?

早过忘川 提交于 2019-12-10 19:25:34

问题


I followed this article to deploy the app to heroku. It works at a minimal level.

The app utilizes vue-router. The common thing about single app application is that routing doesn't work if we don't to home page first to bootstrap the framework.

Since I am using Express.js to create a server for the app, which doesn't have a backend, I created a wildcard route to server the index.html to all routes. So if a user entered /some-route, express.js servers the index.html which will bootstrap the framework, then it should work out how to serve components to that route.

server.js

app.get('/*', function (req, res) {
  res.sendFile(path.join(__dirname, 'index.html'))
})

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>front</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->

    <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js" crossorigin="anonymous"></script>
    <script src="https://cdn.rawgit.com/scottjehl/picturefill/3.0.2/dist/picturefill.min.js" crossorigin="anonymous"></script>
  </body>
</html>

Server.js does it job. The index.html is sent to every route. But the page is blank because index.html doesn't have the script (like, dist/app.js) to bootstrap the vue.js framework.

The thing is, I don't need the script if I just go to the root route. Everything works even though index.html doesn't have built app.js script. It doesn't work if I go to other routes. The page is blank.

So I thought, maybe I should add that built script to index.html manually. However, when Heroku build the app, every built file has a version number, like this:

remote:        > node build/build.js
remote:        
remote:        
remote:        Starting to optimize CSS...
remote:        Processing static/css/app.0b5f04e14ffb7ccea3fa9f8f33ffbb29.css...
remote:        Processed static/css/app.0b5f04e14ffb7ccea3fa9f8f33ffbb29.css, before: 2008, after: 1940, ratio: 96.61%
remote:        Hash: f26c9282218b6a3fa3a5
remote:        Version: webpack 2.4.1
remote:        Time: 12380ms
remote:        Asset     Size  Chunks             Chunk Names
remote:        static/js/app.629caa4c18bbb9036878.js  21.1 kB       0  [emitted]  app
remote:        static/js/vendor.32e38f7fbd283989a03f.js   199 kB       1  [emitted]  vendor
remote:        static/js/manifest.d0cfe9987077f3610ffd.js   1.5 kB       2  [emitted]  manifest
remote:        static/css/app.0b5f04e14ffb7ccea3fa9f8f33ffbb29.css  1.94 kB       0  [emitted]  app
remote:        static/js/app.629caa4c18bbb9036878.js.map    99 kB       0  [emitted]  app
remote:        static/css/app.0b5f04e14ffb7ccea3fa9f8f33ffbb29.css.map   4.7 kB       0  [emitted]  app
remote:        static/js/vendor.32e38f7fbd283989a03f.js.map  2.24 MB       1  [emitted]  vendor
remote:        static/js/manifest.d0cfe9987077f3610ffd.js.map  14.4 kB       2  [emitted]  manifest
remote:        index.html  1.45 kB          [emitted]
remote:        
remote:        Build complete.

So I can't just add static/js/app.js to index.html.

So now I am stuck.

  1. Why the vue.js app works when I go the root route even though index.html doesn't contain the built app script?

  2. How to handle routing in production, in this caes, Heroku, so that users don't need to go to root route first to bootstrap the framework. They could just go to /some-route and everything should work.


回答1:


Here is a server.js file that should work for you:

var express = require('express')
var history = require('connect-history-api-fallback')
var path = require('path')
var serveStatic = require('serve-static')


var app = express()

// Use a fallback for non-root routes (required for Vue router)
//   NOTE: History fallback must be "used" before the static serving middleware!
app.use(history({
    // OPTIONAL: Includes more verbose logging
    verbose: true
}))

// Serve static assets from the build files (images, etc)
app.use(serveStatic(path.join(__dirname, '/dist')))

var port = process.env.PORT || 5000

app.listen(port, () => {
  console.log('Server started at http://localhost:5000')
})



回答2:


I now use https://nuxtjs.org/ to handle server side rendering. And I don't need to worry about routing.



来源:https://stackoverflow.com/questions/43726961/how-to-make-vue-js-app-with-routing-work-in-heroku

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!