vuejs / vue-cli

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

App.vue cannot be overwritten or customized using vue-cli presets #5106

Open tbl0605 opened 4 years ago

tbl0605 commented 4 years ago

Version

4.1.2

Reproduction link

https://github.com/tbl0605/vue-cli-plugin-preset-bug-demo

Environment info

  System:
    OS: Windows 10 10.0.18363
    CPU: (8) x64 Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
  Binaries:
    Node: 12.14.1 - E:\tools\nodejs\node.EXE
    Yarn: 1.16.0 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 6.13.4 - E:\tools\nodejs\npm.CMD   
  Browsers:
    Edge: 44.18362.449.0
  npmPackages:
    @fortawesome/vue-fontawesome: * => 0.1.9 
    @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.0 => 4.1.2
    @vue/cli-plugin-eslint: ^4.1.0 => 4.1.2
    @vue/cli-plugin-router: ^4.1.0 => 4.1.2
    @vue/cli-plugin-vuex: ^4.1.0 => 4.1.2
    @vue/cli-service: ^4.1.0 => 4.1.2
    @vue/cli-shared-utils:  4.1.2
    @vue/component-compiler-utils:  3.1.1
    @vue/eslint-config-prettier: ^5.0.0 => 5.1.0
    @vue/preload-webpack-plugin:  1.1.1
    @vue/web-component-wrapper:  1.2.0
    eslint-plugin-vue: ^5.2.3 => 5.2.3
    vue: ^2.6.10 => 2.6.11
    vue-cli-webpack:  1.0.0
    vue-eslint-parser:  undefined (5.0.0)
    vue-hot-reload-api:  2.3.4
    vue-loader:  15.8.3
    vue-resource: * => 1.5.1
    vue-router: ^3.1.5 => 3.1.5
    vue-style-loader:  4.1.2
    vue-template-compiler: ^2.6.10 => 2.6.11
    vue-template-es2015-compiler:  1.9.1
    vuex: ^3.1.2 => 3.1.2
  npmGlobalPackages:
    @vue/cli: Not Found

Steps to reproduce

create a new project using:

vue create vue-demo-app --preset tbl0605/vue-cli-plugin-preset-bug-demo

What is expected?

The file src/App.vue in project vue-demo-app should be overwritten by file generator/template/src/App.vue from preset vue-cli-plugin-preset-bug-demo

This problem does not occur with any other file that I'll add to directory generator/template/

What is actually happening?

The content of the file src/App.vue in project vue-demo-app will exclusively be based on the file App.vue from @vue/cli-service without taking account of generator/template/src/App.vue from preset vue-cli-plugin-preset-bug-demo


I tested with other presets found on github and the same problem occurred with their App.vue files.

When I create a new project using following commands, everything works as expected:

vue create vue-demo-app
cd vue-demo-app
npm install --save-dev file:/local/path/to/vue-cli-plugin-preset-bug-demo
vue invoke vue-cli-plugin-preset-bug-demo

I can also workaround this problem in preset vue-cli-plugin-preset-bug-demo by renaming generator/template/src/App.vue as generator/template/src/App.tmpl.vue and by adding a hook in generator/index.js to write App.tmpl.vue back to App.vue:

const fs = require('fs');
module.exports = api => {
  api.render('./template');
};

module.exports.hooks = api => {
  api.afterInvoke(() => {
    let mainTemplateVuePath = api.resolve('./src/App.tmpl.vue');
    let mainVuePath = mainTemplateVuePath.replace(/App\.tmpl\.vue$/, 'App.vue');
    fs.unlinkSync(mainVuePath);
    fs.renameSync(mainTemplateVuePath, mainVuePath);
  });
};
fangbinwei commented 4 years ago

your src/App.vue was overwritten by @vue/cli-plugin-router

template render order is @vue/cli-service template-> your plugin template -> @vue/cli-plugin-router.

I have another workaround, modify the preset.json like this

{
  "useConfigFiles": true,
  "plugins": {
    "@vue/cli-plugin-babel": {},
    "@vue/cli-plugin-eslint": {
      "config": "prettier",
      "lintOn": [
        "save"
      ]
    },
+   "@vue/cli-plugin-router": {
+     "historyMode": true
+   }
  },
- "router": true, // legacy support
- "routerHistoryMode": true,
  "vuex": true,
  "cssPreprocessor": "dart-sass"
}

this preset leads to expected render order. releated code.

maybe Vue CLI needs another order control mechanism like tapable/webpack-chain?(personal opinion)

tbl0605 commented 4 years ago

your src/App.vue was overwritten by @vue/cli-plugin-router

template render order is @vue/cli-service template-> your plugin template -> @vue/cli-plugin-router.

I have another workaround, modify the preset.json like this

{
  "useConfigFiles": true,
  "plugins": {
    "@vue/cli-plugin-babel": {},
    "@vue/cli-plugin-eslint": {
      "config": "prettier",
      "lintOn": [
        "save"
      ]
    },
+   "@vue/cli-plugin-router": {
+     "historyMode": true
+   }
  },
- "router": true, // legacy support
- "routerHistoryMode": true,
  "vuex": true,
  "cssPreprocessor": "dart-sass"
}

this preset leads to expected render order. releated code.

maybe Vue CLI needs another order control mechanism like tapable/webpack-chain?(personal opinion)

Thank you very much fangbinwei for your advice, I'll try that out. I didn't know about the rendering order stuff, for me the user preset should always be applied at very last (on top of other presets), that would be more logical, no?

My actual preset is the one I've saved using vue create and strangely its content is far from the example you give or from those seen at https://cli.vuejs.org/guide/plugins-and-presets.html#presets

At least, there should be some warning about rendering order in the official guide, and at best vue-cli (or vue-router?) should save the presets like the examples given at https://cli.vuejs.org/guide/plugins-and-presets.html#presets

Also just my personal opinion ;)

fangbinwei commented 4 years ago

I agree, rendering order should be mentioned in document. ✋And I guess you generated preset by vue cli 3? I tested version 4.1.2, it works.

tbl0605 commented 4 years ago

I agree, rendering order should be mentioned in document. ✋And I guess you generated preset by vue cli 3? I tested version 4.1.2, it works.

Yes, I generated it using vue-cli 3 and reused it for vue-cli 4. My preset maybe worked correctly for vue-cli 3, but I only created a customized App.vue file very recently (to use with vue-cli 4).

DelToney commented 4 years ago

Bump on this. I'm running into the same issue except with the vuetify cli plugin. I wish there could be a way to manually specify at what point the generator template (or certain files within it) get copied over