I just spent many hours trying to work out how to mount the dev server at a child path in the URL.
For example; my application is mounted at a child path of /app/. The root of the url http://someaddress.com/ is owned by other code and the Vuejs app needed to be mounted under http://someaddress.com/app/
Finally I found the solution which is two part:
assetsPublicPath in the config/index.js file like so: dev: {
env: require('./dev.env'),
port: 2001,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/app/',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
}
dev-server.js file, change the connect-history-api-fallback middleware to support a new index path:app.use(require('connect-history-api-fallback')({
index: '/app/index.html'
}))
I suggest a change to the template to make it easier to change the base url used for mounting the app. I quick example of the change being something like this:
app.use(require('connect-history-api-fallback')({
index: config.dev.publicPath + '/index.html'
}))
That dynamic path would need to be parsed but you get the idea. Maybe behind a flag of changeBaseUrl or something like that.
I've been thinking on this last night. Rather than some multi-option like changeBaseUrl it would be better just to expose the index file option. Something like this:
{
defaultDocument: `/index.html`
}
// In the dev-server.js
app.use(require('connect-history-api-fallback')({
index: config.dev.defaultDocument
}))
This then allows the user to set the value to anything rather than just change the sub-path. Couple this with a good documentation example of how to change the Vue application to a sup-path and you are set.
Also, an example which mentions nginx and other proxy solutions would help people searching the internet for it.
Note: index.html is also referenced here:
https://github.com/vuejs-templates/webpack/blob/master/template/build/webpack.dev.conf.js#L29
and here:
https://github.com/vuejs-templates/webpack/blob/master/template/build/webpack.prod.conf.js#L54
Ah, thanks @LinusBorg.
Documentation on those to extra references: https://github.com/jantimon/html-webpack-plugin
I don't think I need to change those setting in my use case however I'm not sure how you would want to expose them to a template user through configuration.
Maybe something like the following config options:
{
htmlDevServerDefaultDocument: 'index.html',
htmlTemplate: 'index.html',
htmlBuildFile: 'index.html'
}
Another option would be to not add these configuration options and just document how to change them and what they do?
I think the browser default document should be added though because in its current state there is no configuration for the 'connect-history-api-fallback' constructor.
Thank you for the direction on getting this going... for me I also had to modify build/dev-client.js to have the __webpack_hmr requesting through the sub path by adding a path argument to the hotclient:
javascript
var hotClient = require('webpack-hot-middleware/client?path=/app/__webpack_hmr&noInfo=true&reload=true')
Which if you may also want to consider for your configuration or documentation... Or if there is a better way of accomplishing the above please let me know.
@iAlexanderMoon Hi. I didn't know about this change. Thanks for chiming in. I'll try it out however the client seems to be working ok as it is. I am using nginx as a front-end so it might be handling it for me.
[Edit]
Ah! I was just about to look at this and read the change. I am not having issues because of my nginx config which has this section in it:
location ~ ^/__webpack_hmr {
proxy_pass http://localnode:2001;
proxy_redirect off;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
I got this trick in the past from working with browsersync.
I just tried your change and it is not working. Took out the section of the ngnix config and added the path string. The browser is requesting /app/__webpack_hmr which means the path change has taken effect. It is getting a 404 though.
OK, I got it working @iAlexanderMoon. Requires two changes:
1) dev-client.js add the path as you have shown above:
/* eslint-disable */
require('eventsource-polyfill')
var hotClient = require('webpack-hot-middleware/client?path=/app/__webpack_hmr&noInfo=true&reload=true')
hotClient.subscribe(function (event) {
if (event.action === 'reload') {
window.location.reload()
}
})
2) In the dev-server.js add the path option:
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
path: '/app/__webpack_hmr',
reload: true, // <= I changed this. Do we need it?
log: console.log // <= I added this. I prefer more feedback in my console.
})
Note: The webpack-hot-middleware options came from here https://github.com/glenjamin/webpack-hot-middleware/blob/master/client.js
To change the base url of the dev-server.js which is used during npm run dev on the template, you need to make the following changes. Note that the changes below assume a child path of /app/.
assetsPublicPath in the config/index.js file like so: dev: {
env: require('./dev.env'),
port: 2001,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/app/',
proxyTable: {},
cssSourceMap: false
}
build/dev-server.js file, change the connect-history-api-fallback middleware to support a new index path:app.use(require('connect-history-api-fallback')({
index: '/app/index.html'
}))
build/dev-client.js add the path into the option string for the hot module reload client:/* eslint-disable */
require('eventsource-polyfill')
var hotClient = require('webpack-hot-middleware/client?path=/app/__webpack_hmr&noInfo=true&reload=true')
hotClient.subscribe(function (event) {
if (event.action === 'reload') {
window.location.reload()
}
})
build/dev-server.js file add the path option for the webpack-hot-middleware:var hotMiddleware = require('webpack-hot-middleware')(compiler, {
path: '/app/__webpack_hmr',
reload: true, // <= I changed this. Do we need it?
log: console.log // <= I added this. I prefer more feedback in my console.
})
index.html so another name like default.htm then you will need to change the filename/template names in these files and in step 2 above:https://github.com/vuejs-templates/webpack/blob/master/template/build/webpack.dev.conf.js#L29
https://github.com/vuejs-templates/webpack/blob/master/template/build/webpack.prod.conf.js#L54
@LinusBorg This should be broken up into two problems; default document name and child path.
How I finally did it (I serve my backend from an other server)
build/dev-client.js
// add the full path "path=http://localhost:8080/__webpack_hmr"
var hotClient = require(
'webpack-hot-middleware/client?noInfo=true&reload=true&path=http://localhost:8080/__webpack_hmr')
build/dev-server.js
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
headers: { 'Access-Control-Allow-Origin': '*' }, // add headers for CORS
quiet: true
})
config/index.js
...
assetsSubDirectory: 'static',
assetsPublicPath: 'http://localhost:8080/', // put the full path here too (for hot-updates)
proxyTable: {},
...
@BafS 's solution should be added to the README
I could be wrong here however @BafS solution is just proxying. This issue is about child paths.
Any idea how to make the paths in the router js file respect the base url app ?
the router has a base: option, check it out in the docs.
how to set the baseurl on production?
Since we switched to webpack-dev-server, this no longer applies afaics
For anyone looking into how to this with webpack-dev-server.
You just need to change assetsPublicPath and proxy everything that does not match it.
assetsPublicPath: '/app/',
proxyTable: {
'!/app/**': {
target: 'http://localhost:5000',
changeOrigin: true
}
},
Thanks @schettino72 but i still cant enable hot reloading when using proxy
Most helpful comment
How I finally did it (I serve my backend from an other server)
build/dev-client.js
build/dev-server.js
config/index.js