Setting publicPath of webpack.conf to '/' is unnecessary. This will break the app if served form local file system, or a PhoneGap package.
@zhangxin840 I believe that was originally added because it was required for code splitting. Have you checked that code splitting still works when it's not set?
I'm a bit new to the whole SPA/JS/WebPack/modern webdev kerfuffle, could I be of help somehow? Building with build.assetsPublicPath set to './' the default template (also adding the
@chrisvfritz I set assetsPublicPath to '' and nothing goes wrong(at least in the project).
publicPath != assetsPublicPath
without an absolute public path, webpack fails to load split chunks when the url has changed (e.g. from using vue.router).
@LinusBorg Regardless it fixes the problem. I now am able to run my application over file:// with no issues. Everything builds just fine, I can serve the files just fine.
Yes, but we are not discussing assetPublicPath here.
@LinusBorg I think you're losing sight of the problem in favor of the details. In this case @zhangxin840 mentioned the problem explicitly. Changing assetsPublicPath to './' (instead of publicPath) solves the problem and everything seems to work on my end just fine afterwards, which was @chrisvfritz's worry.
In any case, how would I go about reproducing the problem you mentioned? Do you mean LiveReload breaks? Because the change is only applied to the build script, not dev.
when you use vue-router (or change the url history any other way), a relative publicpath (and most likely, also assetPublicPath will break your build.
At least I personally experienced that webpack will try to fetch chunks (from code splitting) relative to the current URL if public path is not absolute - which will fail if you are not in the root.
I use vue-router in my project. I have not touched publicPath, only assetPublicPath. As I said, everything builds and works just fine.
have you used code-splitting?
@LinusBorg I'm using ES6 modules. They compile together just fine.
@LinusBorg This is still a bug and should be reopened. In config/index.js changing build.assetsPublicPath to './' and leaving dev.assetsPublicPath fixes serving over file:/// protocol while at the same time allowing the npm run dev webserver to keep working.
Everything builds correctly in both situations. The files in dist can be used both over file and tested hosting them with python -m http.server and npm's http-server package with no issues found.
I haven't seen an example using code-splitting to test wether it breaks or not. But not working under Cordova is as much an issue.
This is still a bug
I fail to see why a config setting's default value should be considered a bug, just because it does not fit your specific usecase. If you need another value, change the config setting, that's what it is for.
Everything builds correctly in both situations.
Did you test with vue-router? Because relative asset Paths will break paths to your assets when using vue-router in history mode, which is a very popular usecase (or manipulate history API any other way): When you navigate from '/' to '/users', an asset's path will change with it, i.e. from './logo.png' will now point to './users/logo.npg' - and the file won't exist at that path, of course.
It's not "my" usecase. It's the default config breaking the file:/// protocol. Whenever it started doing that it became a bug. Not to mention that this not only affects Cordova (currently the only way to deploy Vue as a mobile application, at least until Weex starts supporting it) but pretty sure also affects Electron, another huge platform for cross-platform desktop development.
I'm using vue-router and just tested history mode with nginx. Works perfectly with assetsPublicPath set to './'.
When you build for production, it even tells you that the result is not intended to be used from file://.
https://github.com/vuejs-templates/webpack/blob/master/template/build/build.js#L14
It's not a bug. It's a default value that you have to change if you want to do something that the default is not intended for.
And, as explained at the very beginning of this issue, an absolute path is required for code splitting. That's a fact.
If you need a relative path for cordova, no problem . Change the setting, done.
I'd say with quite some confidence that the file:/// protocol is a bigger standard than code-splitting and therefore has more merit as a default.
But even if the default is not changed, even if there's a consensus among all devs that Electron, Cordova, the Principle Of Least Astonishment and standard local development all together matter less than code-splitting, shouldn't it be acknowledged in some place beside this issue (like the message shown on build you mentioned or an alternative build script that supports the norm of file:/// working) that there's a way to build without breaking the mentioned standard?
The question which is the bigger standard is not as important as the question what the default purpose of the template is.
Which is single file web applications, potentially big ones, which need code splitting (we advertise for it in various locations of our docs).
This template is simply not meant for mobile applications first and foremost. (and eg for electron there are templates provided by the community that are far better suited as a starting point than this one)
However,, note in the config can never be a bad idea., so I will reopen this issue for that.
But someone else will have to pick up as I'm on vacation for the next ten days.
I can add that note, though first I'd love to hear what other templates people are using and enjoying for mobile/electron. I'd like to add a few alternatives rather than just saying, "No!" 馃槃
I ran a simple test on the latest template with code splitting and setting assetsPublicPath to './', and everything seems to work fine. Take a look at https://github.com/asselin/vue-webpack-codesplit-test.
Does this resolve the final concern about changing assetsPublicPath to './' as a default?
Setting assetsPublicPath to './' fixes Cordova, file://, and serving from a higher directory (e.g. building into test/dist and serving test/), so it would be nice to make it the default if it there are no remaining reasons not to.
cc: @LinusBorg @chrisvfritz @mixedCase
Yeah, guess we should change it.
@LinusBorg Is there anything I can do to help get this change in?
We accept PRs :)
@LinusBorg Submitted PR #541 for this issue. Also, could you please take a look at PR #530 at the same time? It fixes a similar type of path issue loading fonts.
Thanks!
@LinusBorg I tested vue-router history mode, and ran into some issues. If the URL is only 1 level deep (e.g. /index.html or /menu), everything works fine. If it's 2+ levels deep (e.g. /user/menu), the relative URLs break.
Having said that, I'd still like to make a case for changing the default.
mode: 'history'" 3. Configure your server per https://router.vuejs.org/en/essentials/history-mode.html etc.)Alternatively, if you're concerned about changing the default and breaking support of history mode, how about a question in the template "Enable HTML5 history mode?" that would configure assetsPublicPath to '/' and add mode: 'history' if Yes was selected?
That sounds good so far, but I think there's one testcase still missing:
Lazy-loading a component in a nested route. The reason that this could be a special case is that for lazy-loaded components, styles are not extracted into the seperate .css file - instead they are injected into the page's head section when the component is loaded.
That means that with lazy-loaded routes, you may end up with CSS in your <head> that points to a wrong bakground-image etc.
As I said, paths in webpack can be very tricky... :/
I agree with @mixedCase that history mode is used less often than a) serving an app out of a subdirectory (i.e. building to /app/dist and serving /app) b) serving from file:// (especially Cordova)
assetsPath. We should improve the docs for this (no matter what path we take in the end -pun inteded), though, and make it easy to customize it during build with an ENV variable or something.That is not to say that we can't switch to relative paths at all - we still have to do some tests.
But if relative paths have problems with lazy-loaded routes and other edge cases, I would rather vote for staying with defaults that work best for a typical webapp, rather than something like cordova, which is not a focus of this template.
@LinusBorg Thanks for the reply. I'll take a look at lazy loaded components with assetsPath set to './' and see what's what.
I agree with you that Cordova isn't a focus for this template; I'm working on a Cordova template that I hope to publish soon.
Thinking about this some more, assuming lazy loaded components work, I think that adding a question at creation time about enabling history mode makes the most sense, that way the generated code is consistent.
I'll let you know what I find soon. Thank you!
assetsPublicPath setting to './' not working on Cordova when enabling vue-router lazy loading feature(webpack code splitting), unable to load file:/// resource, how to solve this?
Please don't highjack issues to ask support questions. I saw you already asked on the forum.
Hi everyone. I also think that this can be somehow improved.
Setting assetsPublicPath: '', allows for local usage, hosting as a static website and as I see in the comments above, cordova apps.
While assetsPublicPath: '/', covers more use-cases it forces to use some sort of web server to serve your website.
I think this stuff should be at least very well explained in the docs so it doesn't create confusion
Side note regarding code splitting: Code splitting works fine when used locally as a static website if the path is set to ''.
You can solve this problem in the following way (If you are use vue-webpack-template):
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]'),
publicPath: process.env.NODE_ENV === 'production' ? '../../' : '/'
}
},These settings are very useful for building applications using Cordova/Phonegap
@AbdullaevTimur this finally worked for me! Thank you!
Just so other who the same setup as mine, you can try his points.
My setup:
I had the ff issues:
Now working fine!
I am settingpublicPath: "./" but this doesn't work, the generated path is "js/...." and it should be "./js/...." In the documentation section it says this is possible but it doesn't work.
Most helpful comment
You can solve this problem in the following way (If you are use vue-webpack-template):
{ test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]'), publicPath: process.env.NODE_ENV === 'production' ? '../../' : '/' } },These settings are very useful for building applications using Cordova/Phonegap