问题
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.
Why the vue.js app works when I go the root route even though
index.html
doesn't contain the built app script?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