Vue-cli: Add a configuration to specify "source" public folder.

Created on 5 Sep 2018  ยท  8Comments  ยท  Source: vuejs/vue-cli

What problem does this feature solve?

Presently npm run build will copy all files in the folder ./public (relative to the project folder) to the destination specified in outputDir. Which is fine if you stick to the default scaffolded folder structure (created by vue create [project_name]).

However in my case my entire vue project resides in slightly quirky folder structure like this (the public folder is in a 'sub folder' called vue-project). The 'sub folder' sort of 'encapsulates' the vue project), except for the babel, tsconfig.json, vue.config.js, etc. which all still reside in the root of the 'project folder.'

```.
โ”œโ”€โ”€ data
โ”œโ”€โ”€ vue-project
โ”‚ย ย  โ”œโ”€โ”€ assets
โ”‚ย ย  โ”œโ”€โ”€ components
โ”‚ย ย  โ”œโ”€โ”€ dist
โ”‚ย ย  โ”œโ”€โ”€ public
โ”‚ย ย  โ””โ”€โ”€ src
โ”œโ”€โ”€ lib-src
โ””โ”€โ”€ lib-tests

The code which copies the 'public' folder assets 
// copy static assets in public/
const publicDir = api.resolve('public')
if (!isLegacyBundle && fs.existsSync(publicDir)) {
  webpackConfig
    .plugin('copy')
     ....
```api.resolve('public')``` resolves to either the `[project folder]/public` or `[environment variable VUE_CLI_CONTEXT]/public`.

Unfortunately you can't workaround it by executing ```cd vue-project && npm run build``` nor by ```VUE_CLI_CONTEXT=vue-project npm run build``` since other parts of the cli rely on the context being correct. 

EDIT:
A workaround is possible through `vue.config.js` using `CopyWebpackPlugin`, it's less pretty through:
outputDir: 'example/dist',
pages: {
    index: {
        entry: ...,
        template: 'example/public/index.html',
        filename: 'index.html',
    },
},
...
configureWebpack: config => {
    config.plugins.push(new CopyWebpackPlugin([{
        from: 'example/public/',
        to: '.',
        ignore: ['index.html', '.DS_Store']
    }]));
}

```

What does the proposed API look like?

Add a setting called sourcePublicDir in vue.config.js which value is resolved in places where api.resolve('public') (and api.resolve('public/index.html') etc.) are called.

feature request cli-service build

Most helpful comment

This is one of the sitations where i'm unsure what makes sense to add as another config option and what should be seen as a usecase for chainWebpack / configureWebpack.

Instead of pushing a new plugin, you could adjust the existing one:

chainWebpack: config => {
  config.plugin('copy').tap(([options]) => {
    options[0].from = 'example/public'
  })
}

at which point the question is:

Is this one-liner too much to leave to users?
v.
Is the use case of needing another public folder wide-spread enough to add *another option to the config file?*

If we add every possible option to the config file, we will have a list of options longer than webpack itself one day.

All 8 comments

This is one of the sitations where i'm unsure what makes sense to add as another config option and what should be seen as a usecase for chainWebpack / configureWebpack.

Instead of pushing a new plugin, you could adjust the existing one:

chainWebpack: config => {
  config.plugin('copy').tap(([options]) => {
    options[0].from = 'example/public'
  })
}

at which point the question is:

Is this one-liner too much to leave to users?
v.
Is the use case of needing another public folder wide-spread enough to add *another option to the config file?*

If we add every possible option to the config file, we will have a list of options longer than webpack itself one day.

Unfortunately the plugin('copy') is only added to the list if and when the 'public' folder (in the root level) exists (if (!isLegacyBundle && fs.existsSync(publicDir) { // then create and configure plugin('copy')). So I would have to leave an empty 'public' folder (in the root level). For now I've opted and settled with the pushing a new plugin.

I am seeing this same thing in that I want to host my vue app using Gitlab Pages. However pages have to be served from the "public" folder in the root of the repo. So I would love to be able to change the name of the public folder to "public_assets" and then copy the contents of "dist" to "public" on the CI build.

+1 for sourcePublicDir, a lot of php framework use public folder to serve file. Could be great to edit it

+1 also required to set up with Python frameworks.

+1 on this. I am working a PHP / Vue project and want them on the same domain.
Not being able to control the source/destination directories is creating a big restriction for me.

Yes I realise it's possible to do it manually but for every project we work on?
Causing headache when on of the many developers accidentally changes something in that file

  1. Our overall guideline is - all CLI projects should have consistent file structures as much as possible. The CLI is opinionated by nature. This is why we do not provide options for configuring source directory or public directory names. If we add an option for this we essentially need to add options for renaming every possible config file and directory, and that would

    • make it more work to maintain all these options
    • increase possibility of edge cases due to different directory names
    • make Vue CLI projects all look different from one another.
  2. The recommended workflow for using Vue CLI with a backend framework is let the Vue CLI app live in its own isolated directory and (after build) target/copy your dist folder to proper location in your backend framework, as demonstrated in this example.

    The CLI is based upon the opinion that your frontend code and backend code should be separated. If you disagree with that, you should not use the CLI.

@yyx990803 Thank you for your well thought out answer. Would you possibly be able to address what the recommended usage is to address the name collision for static hosting products like Gitlab Pages where the public folder at the root of a git repo has special meaning. This seems like a pretty significant collision that does not apply to renaming all of the other directories and happens with a lot of static hosting products.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

eladcandroid picture eladcandroid  ยท  3Comments

wahidrahim picture wahidrahim  ยท  3Comments

JIANGYUJING1995 picture JIANGYUJING1995  ยท  3Comments

chasegiunta picture chasegiunta  ยท  3Comments

brandon93s picture brandon93s  ยท  3Comments