vuejs / vue-cli

🛠️ webpack-based tooling for Vue.js Development
https://cli.vuejs.org/
MIT License
29.76k stars 6.33k forks source link

dev-server contentBase is not taken into account #5070

Closed innocenzi closed 1 year ago

innocenzi commented 4 years ago

Version

4.1.2

Reproduction link

https://github.com/hawezo/minimal-content-base-issue-reproduction

Environment info

System:
    OS: Windows 10 10.0.18363
    CPU: (6) x64 Intel(R) Core(TM) i5-8500 CPU @ 3.00GHz
  Binaries:
    Node: 12.5.0 - d:\programmes\laragon\bin\nodejs\node-v12\node.EXE
    Yarn: 1.19.2 - D:\Programmes\Laragon\bin\yarn\bin\yarn.CMD
    npm: 6.9.0 - d:\programmes\laragon\bin\nodejs\node-v12\npm.CMD
  Browsers:
    Edge: 44.18362.449.0
  npmPackages:
    @vue/babel-helper-vue-jsx-merge-props:  1.0.0
    @vue/babel-plugin-transform-vue-jsx:  1.1.2
    @vue/babel-preset-app:  4.1.2
    @vue/babel-preset-jsx:  1.1.2
    @vue/babel-sugar-functional-vue:  1.1.2
    @vue/babel-sugar-inject-h:  1.1.2
    @vue/babel-sugar-v-model:  1.1.2
    @vue/babel-sugar-v-on:  1.1.2
    @vue/cli-overlay:  4.1.2
    @vue/cli-plugin-babel: ^4.1.2 => 4.1.2
    @vue/cli-plugin-router:  4.1.2
    @vue/cli-plugin-typescript: ^4.1.2 => 4.1.2
    @vue/cli-plugin-vuex:  4.1.2
    @vue/cli-service: ^4.1.2 => 4.1.2
    @vue/cli-shared-utils:  4.1.2
    @vue/component-compiler-utils:  3.1.1
    @vue/preload-webpack-plugin:  1.1.1
    @vue/web-component-wrapper:  1.2.0
    typescript: ^3.7.4 => 3.7.4
    vue: ^2.6.10 => 2.6.11
    vue-hot-reload-api:  2.3.4
    vue-loader:  15.8.3
    vue-style-loader:  4.1.2
    vue-template-compiler: ^2.6.10 => 2.6.11
    vue-template-es2015-compiler:  1.9.1
  npmGlobalPackages:
    @vue/cli: Not Found

Steps to reproduce

  1. Initialize a vue-cli application.
  2. Move /src and /public to a folder, in this case /playground.
  3. Create a vue.config.js according to the documentation (which leads to this one).
  4. serve the application and notice that the index.html is not the same (check the meta title or whatever).

What is expected?

The contentBase parameter should be taken into account so the new public folder location is served.

What is actually happening?

The new public folder location is not served. Instead, the server is looking for a /public folder at the root of the project.

m0dch3n commented 4 years ago

@LinusBorg seems @hawezo is experiencing the same problem, that we can't change the contentBase because of this hardcoded line

https://github.com/vuejs/vue-cli/blob/8fcea225b7b4406ff7c03e34d4e962b45d78ef9f/packages/%40vue/cli-service/lib/commands/serve.js#L172

LinusBorg commented 4 years ago

That's because it's not just the devServer that relies on this folder. It's the HML Plugin, webpack plugins that come with the pwa cli-plugin, the CopyWebpackPlugin and possibly more.

All of these look for files in /public or write stuff to that folder.

So changing he contentBase will simply break your serve/build process, pretty surely.

If we want to make this customizable we need a custom option in vue.config.js.

Xantier commented 4 years ago

I believe the (closed) pull request linked to this issue would solve this. Using user configurable contentBase from vue.config.js/devServer block if one is defined, otherwise defaulting to current hardcoded value.

LinusBorg commented 4 years ago

It would not entirely, as it only changes the contentBase, adn only for npm run serve. the copy-webpack plugin would still look at /public by default.

Granted, the config for the latter can be adjusted through the webpack config options while the former is hardcoded.

But similarly to the publicPath option we have, I think if we make this folder name/location customizable, the new config option for it should change it in all places necessary.

Xantier commented 4 years ago

As far as I've understood the CLI npm run serve is to start a WebpackDevServer. The contentBase configuration option is specifically for that dev server. For us it is used especially in cases where the underlying HTML, and possibly other static assets, are not served via dev-server or from the public folder, but from another location. With this option we don't have to conform with the imposed folder structure and can more easily integrate vue-cli to legacy projects.

I don't think CopyWebpackPlugin has option for content base and since it can be adjusted with another config option I don't think it is very relevant to this issue in any case.

LinusBorg commented 4 years ago

I don't think CopyWebpackPlugin has option for content base and since it can be adjusted with another config option I don't think it is very relevant to this issue in any case.

It doesn't have a contentBase option, but the path that is configured for this pugin is the same: it points to /public.

So I consider it very relevant, as allowing to change contentBase on its own makes the devserver work like you want it, but it will break the build process as the copy webpack plugin still copies files from /public, not from that other location you want it to.

Now, as I explained myself and you mentioned as well, you can fix this by adjusting the config. But for that you have to be aware that it's the copy-webpack-plugin's config that has to be adjusted. Which many, many users won't be.

So we either have to write some Troubleshooting guide for this, or we come up with an implementation of a custom /public folder that changes all of those locations where it's being used - contentBase being only one of them.

Xantier commented 4 years ago

I think we might be talking about different things here, so correct me if I'm wrong. The contentBase option is solely for the dev-server and the webpack-copy-plugin is not used with the dev-server. I'm not certain what that plugin has to do with dev-server and making options for the dev server to actually be configurable.

LinusBorg commented 4 years ago

I think we might be talking about different things here,

Not different things - different perspectives on the same things, probably.

The contentBase is usually setup so that the devServer can serve static content that is part of our project. In Vue CLI, that content is usually defined in /public. You want to be able to change contentBase so that this static content can be located somewhere else.

So now a couple of questionds about your scenario, situations:

These are just a couple of interdependecies where the /public folder plays a role - and only changing contentBase alone might actually create new problems for you. Many of them can be worked around, but they all don't manifest as long as we all stick to a default folder.

So that's part of the reason why currently, we essentially force people to use /public - and if they need it to point somewhere else, use a symlink or something: If we make it configurable, a lot of "behind the scenes" interdependencies break and people need to be aware of them to fix them.

We are open to chaneg that and make it more flexible. But providing this flexibility in a way that people can understand is a must. Otherwise, we end up with many issues of people claiming that build or serve "doesn't work", but in reality they just broke it themselves.

Xantier commented 4 years ago

For our use case neither the HTML nor assets are served along with the vue app, so the /public folder does not really play a role in our setup at all. It might be that vue-cli is simplifying the configuration too much to match our project and it might be better for us to revert to plain webpack configuration for more flexibility. I understand that sane defaults should be striven for and try to keep the already complex FE build process as dumbed down as possible so it is more approachable.

Meanwhile it might be worthwhile to modify the documentation to state this expection in the dev-server configuration: image

m0dch3n commented 4 years ago

@Xantier take a look at my cordova plugin, how I solved to add cordova.js to the devserver, without copying it to the public folder

https://github.com/m0dch3n/vue-cli-plugin-cordova/blob/master/index.js

I simply added a middleware to the express server, which does serve all the files I don't want to copy to /public folder...

m0dch3n commented 4 years ago

@LinusBorg

btw if someone is setting contentBase, which is not taken into account, is as confusing, and requires the same research the documentatiin and investigation to know why, as letting the user changing it, and letting him reseach and investigate, why now the build is maybe broken...

In both cases, you need know some special information, unfortunately not yet well enough documented currently... (or at least it was not documented, when I had this problem, a year ago)

@allTheOthersHereInThisIssue In the special case, where you need files served, from outside of the vue framework, without needing to bundle them to you app all the time, the best way, is to create either a proxy around your devserver (because in production, you would also serve your files from somewhere else), or add a middleware to the devserver

TimYi commented 3 years ago

I know that publicPath is used by many components and affects the whole body. However, if publicPath can be modified in the build command, the design of our automatic build system will be much simpler.

Different customers sometimes have specific requirements for the deployment path, but our code is the same.