mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-03-01 11:59:10 -06:00
feat!: make router a separate plugin (#4196)
* refactor: move router to its own plugin * refactor: rename routerHistoryMode option to historyMode * test: add @vue/cli-plugin-router tests * feat: change src/router.js for most common use cases * fix: fix cli-ui tests * docs: Remove router root option from docs * fix: add support for legacy router option
This commit is contained in:
committed by
Haoqun Jiang
parent
9eadfe1eba
commit
246ae678cb
2
packages/@vue/cli-plugin-router/.npmignore
Normal file
2
packages/@vue/cli-plugin-router/.npmignore
Normal file
@@ -0,0 +1,2 @@
|
||||
__tests__
|
||||
__mocks__
|
||||
9
packages/@vue/cli-plugin-router/README.md
Normal file
9
packages/@vue/cli-plugin-router/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# @vue/cli-plugin-router
|
||||
|
||||
> router plugin for vue-cli
|
||||
|
||||
## Installing in an Already Created Project
|
||||
|
||||
``` sh
|
||||
vue add @vue/router
|
||||
```
|
||||
@@ -0,0 +1,64 @@
|
||||
const generateWithPlugin = require('@vue/cli-test-utils/generateWithPlugin')
|
||||
|
||||
test('base', async () => {
|
||||
const { files, pkg } = await generateWithPlugin({
|
||||
id: 'router',
|
||||
apply: require('../generator'),
|
||||
options: {}
|
||||
})
|
||||
|
||||
expect(files['src/router/index.js']).toBeTruthy()
|
||||
expect(files['src/router/index.js']).not.toMatch('history')
|
||||
expect(files['src/views/About.vue']).toBeTruthy()
|
||||
expect(files['src/views/Home.vue']).toBeTruthy()
|
||||
expect(files['src/App.vue']).toMatch('<router-link to="/">Home</router-link>')
|
||||
expect(files['src/App.vue']).not.toMatch('<script>')
|
||||
expect(files['src/App.vue']).toMatch('#nav a.router-link-exact-active')
|
||||
|
||||
expect(pkg.dependencies).toHaveProperty('vue-router')
|
||||
})
|
||||
|
||||
test('history mode', async () => {
|
||||
const { files, pkg } = await generateWithPlugin({
|
||||
id: 'router',
|
||||
apply: require('../generator'),
|
||||
options: {
|
||||
historyMode: true
|
||||
}
|
||||
})
|
||||
|
||||
expect(files['src/router/index.js']).toBeTruthy()
|
||||
expect(files['src/router/index.js']).toMatch('history')
|
||||
expect(files['src/views/About.vue']).toBeTruthy()
|
||||
expect(files['src/views/Home.vue']).toBeTruthy()
|
||||
expect(files['src/App.vue']).toMatch('<router-link to="/">Home</router-link>')
|
||||
expect(files['src/App.vue']).not.toMatch('<script>')
|
||||
expect(files['src/App.vue']).toMatch('#nav a.router-link-exact-active')
|
||||
|
||||
expect(pkg.dependencies).toHaveProperty('vue-router')
|
||||
})
|
||||
|
||||
test('use with Babel', async () => {
|
||||
const { pkg, files } = await generateWithPlugin([
|
||||
{
|
||||
id: 'babel',
|
||||
apply: require('@vue/cli-plugin-babel/generator'),
|
||||
options: {}
|
||||
},
|
||||
{
|
||||
id: 'router',
|
||||
apply: require('../generator'),
|
||||
options: {}
|
||||
}
|
||||
])
|
||||
|
||||
expect(files['src/router/index.js']).toBeTruthy()
|
||||
expect(files['src/router/index.js']).toMatch('component: () => import')
|
||||
expect(files['src/views/About.vue']).toBeTruthy()
|
||||
expect(files['src/views/Home.vue']).toBeTruthy()
|
||||
expect(files['src/App.vue']).toMatch('<router-link to="/">Home</router-link>')
|
||||
expect(files['src/App.vue']).not.toMatch('<script>')
|
||||
expect(files['src/App.vue']).toMatch('#nav a.router-link-exact-active')
|
||||
|
||||
expect(pkg.dependencies).toHaveProperty('vue-router')
|
||||
})
|
||||
@@ -1,34 +1,22 @@
|
||||
module.exports = (api, options = {}) => {
|
||||
api.assertCliVersion('^4.0.0-alpha.3')
|
||||
api.assertCliServiceVersion('^4.0.0-alpha.3')
|
||||
|
||||
api.injectImports(api.entryFile, `import router from './router'`)
|
||||
api.injectRootOptions(api.entryFile, `router`)
|
||||
|
||||
api.extendPackage({
|
||||
dependencies: {
|
||||
'vue-router': '^3.0.6'
|
||||
}
|
||||
})
|
||||
|
||||
api.render('./template', {
|
||||
historyMode: options.routerHistoryMode,
|
||||
historyMode: options.historyMode,
|
||||
doesCompile: api.hasPlugin('babel') || api.hasPlugin('typescript')
|
||||
})
|
||||
|
||||
if (api.invoking) {
|
||||
api.postProcessFiles(files => {
|
||||
const appFile = files[`src/App.vue`]
|
||||
if (appFile) {
|
||||
files[`src/App.vue`] = appFile.replace(/^<template>[^]+<\/script>/, `
|
||||
<template>
|
||||
<div id="app">
|
||||
<div id="nav">
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/about">About</router-link>
|
||||
</div>
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
`.trim())
|
||||
}
|
||||
})
|
||||
|
||||
if (api.hasPlugin('typescript')) {
|
||||
/* eslint-disable-next-line node/no-extraneous-require */
|
||||
const convertFiles = require('@vue/cli-plugin-typescript/generator/convert')
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
extend: '@vue/cli-service/generator/template/src/App.vue'
|
||||
replace:
|
||||
- !!js/regexp /<template>[^]*?<\/template>/
|
||||
- !!js/regexp /\n<script>[^]*?<\/script>\n/
|
||||
- !!js/regexp / margin-top[^]*?<\/style>/
|
||||
---
|
||||
|
||||
<%# REPLACE %>
|
||||
<template>
|
||||
<div id="app">
|
||||
<div id="nav">
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/about">About</router-link>
|
||||
</div>
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
<%# END_REPLACE %>
|
||||
|
||||
<%# REPLACE %>
|
||||
<%# END_REPLACE %>
|
||||
|
||||
<%# REPLACE %>
|
||||
}
|
||||
|
||||
<%_ if (rootOptions.cssPreprocessor !== 'stylus') { _%>
|
||||
<%_ if (!rootOptions.cssPreprocessor) { _%>
|
||||
#nav {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
#nav a {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
#nav a.router-link-exact-active {
|
||||
color: #42b983;
|
||||
}
|
||||
<%_ } else { _%>
|
||||
#nav {
|
||||
padding: 30px;
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
|
||||
&.router-link-exact-active {
|
||||
color: #42b983;
|
||||
}
|
||||
}
|
||||
}
|
||||
<%_ } _%>
|
||||
<%_ } else { _%>
|
||||
#nav
|
||||
padding 30px
|
||||
a
|
||||
font-weight bold
|
||||
color #2c3e50
|
||||
&.router-link-exact-active
|
||||
color #42b983
|
||||
<%_ } _%>
|
||||
</style>
|
||||
<%# END_REPLACE %>
|
||||
@@ -0,0 +1,37 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import Home from '../views/Home.vue'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: Home
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (about.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
<%_ if (doesCompile) { _%>
|
||||
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
|
||||
<%_ } else { _%>
|
||||
component: function () {
|
||||
return import(/* webpackChunkName: "about" */ '../views/About.vue')
|
||||
}
|
||||
<%_ } _%>
|
||||
}
|
||||
]
|
||||
|
||||
const router = new VueRouter({
|
||||
<%_ if (historyMode) { _%>
|
||||
mode: 'history',
|
||||
base: process.env.BASE_URL,
|
||||
<%_ } _%>
|
||||
routes
|
||||
})
|
||||
|
||||
export default router
|
||||
1
packages/@vue/cli-plugin-router/index.js
Normal file
1
packages/@vue/cli-plugin-router/index.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = (api, options = {}) => {}
|
||||
31
packages/@vue/cli-plugin-router/package.json
Normal file
31
packages/@vue/cli-plugin-router/package.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-router",
|
||||
"version": "4.0.0-alpha.3",
|
||||
"description": "router plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vuejs/vue-cli.git",
|
||||
"directory": "packages/@vue/cli-plugin-router"
|
||||
},
|
||||
"keywords": [
|
||||
"vue",
|
||||
"cli",
|
||||
"router"
|
||||
],
|
||||
"author": "Evan You",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vuejs/vue-cli/issues"
|
||||
},
|
||||
"homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-router#readme",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue/cli-shared-utils": "^4.0.0-alpha.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-test-utils": "^4.0.0-alpha.3"
|
||||
}
|
||||
}
|
||||
13
packages/@vue/cli-plugin-router/prompts.js
Normal file
13
packages/@vue/cli-plugin-router/prompts.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// these prompts are used if the plugin is late-installed into an existing
|
||||
// project and invoked by `vue invoke`.
|
||||
|
||||
const { chalk } = require('@vue/cli-shared-utils')
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
name: 'historyMode',
|
||||
type: 'confirm',
|
||||
message: `Use history mode for router? ${chalk.yellow(`(Requires proper server setup for index fallback in production)`)}`,
|
||||
description: `By using the HTML5 History API, the URLs don't need the '#' character anymore.`
|
||||
}
|
||||
]
|
||||
@@ -8,8 +8,8 @@ const create = require('@vue/cli-test-utils/createTestProject')
|
||||
if (!process.env.APPVEYOR) {
|
||||
test('cypress', async () => {
|
||||
const project = await create('ts-e2e-cypress-router', {
|
||||
router: true,
|
||||
plugins: {
|
||||
'@vue/cli-plugin-router': {},
|
||||
'@vue/cli-plugin-typescript': {},
|
||||
'@vue/cli-plugin-e2e-cypress': {}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
extend: '@vue/cli-service/generator/router/template/src/views/Home.vue'
|
||||
when: 'rootOptions.router'
|
||||
extend: '@vue/cli-plugin-router/generator/template/src/views/Home.vue'
|
||||
when: "rootOptions.plugins && rootOptions.plugins['@vue/cli-plugin-router']"
|
||||
replace:
|
||||
- !!js/regexp /Welcome to Your Vue\.js App/
|
||||
- !!js/regexp /<script>[^]*?<\/script>/
|
||||
|
||||
@@ -29,7 +29,9 @@ test('serve', async () => {
|
||||
|
||||
test('serve with router', async () => {
|
||||
const project = await create('e2e-serve-router', Object.assign({}, defaultPreset, {
|
||||
router: true
|
||||
plugins: {
|
||||
'@vue/cli-plugin-router': {}
|
||||
}
|
||||
}))
|
||||
|
||||
await serve(
|
||||
@@ -49,6 +51,29 @@ test('serve with router', async () => {
|
||||
)
|
||||
})
|
||||
|
||||
test('serve with legacy router option', async () => {
|
||||
const project = await create('e2e-serve-legacy-router', Object.assign({}, defaultPreset, {
|
||||
router: true,
|
||||
routerHistoryMode: true
|
||||
}))
|
||||
|
||||
await serve(
|
||||
() => project.run('vue-cli-service serve'),
|
||||
async ({ page, helpers }) => {
|
||||
expect(await helpers.getText('h1')).toMatch(`Welcome to Your Vue.js App`)
|
||||
expect(await helpers.hasElement('#nav')).toBe(true)
|
||||
expect(await helpers.hasClass('a[href="/"]', 'router-link-exact-active')).toBe(true)
|
||||
expect(await helpers.hasClass('a[href="/about"]', 'router-link-exact-active')).toBe(false)
|
||||
|
||||
await page.click('a[href="/about"]')
|
||||
expect(await helpers.getText('h1')).toMatch(`This is an about page`)
|
||||
expect(await helpers.hasElement('#nav')).toBe(true)
|
||||
expect(await helpers.hasClass('a[href="/"]', 'router-link-exact-active')).toBe(false)
|
||||
expect(await helpers.hasClass('a[href="/about"]', 'router-link-exact-active')).toBe(true)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
test('serve with inline entry', async () => {
|
||||
const project = await create('e2e-serve-inline-entry', defaultPreset)
|
||||
|
||||
|
||||
@@ -25,10 +25,6 @@ module.exports = (api, options) => {
|
||||
]
|
||||
})
|
||||
|
||||
if (options.router) {
|
||||
require('./router')(api, options)
|
||||
}
|
||||
|
||||
if (options.vuex) {
|
||||
require('./vuex')(api, options)
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import Home from './views/Home.vue'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
export default new Router({
|
||||
<%_ if (historyMode) { _%>
|
||||
mode: 'history',
|
||||
base: process.env.BASE_URL,
|
||||
<%_ } _%>
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: Home
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (about.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
<%_ if (doesCompile) { _%>
|
||||
component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
|
||||
<%_ } else { _%>
|
||||
component: function () {
|
||||
return import(/* webpackChunkName: "about" */ './views/About.vue')
|
||||
}
|
||||
<%_ } _%>
|
||||
}
|
||||
]
|
||||
})
|
||||
@@ -1,4 +1,3 @@
|
||||
<%_ if (!rootOptions.router) { _%>
|
||||
<template>
|
||||
<div id="app">
|
||||
<img alt="Vue logo" src="./assets/logo.png">
|
||||
@@ -9,7 +8,7 @@
|
||||
<%_ } _%>
|
||||
</div>
|
||||
</template>
|
||||
<%_ if (!rootOptions.bare) { _%>
|
||||
<%_ if (!rootOptions.bare) { _%>
|
||||
|
||||
<script>
|
||||
import HelloWorld from './components/HelloWorld.vue'
|
||||
@@ -21,21 +20,8 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<%_ } _%>
|
||||
<%_ } else { _%>
|
||||
<template>
|
||||
<div id="app">
|
||||
<div id="nav">
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/about">About</router-link>
|
||||
</div>
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
<%_ } _%>
|
||||
<%_ if (!rootOptions.bare) { _%>
|
||||
<%_ if (rootOptions.cssPreprocessor !== 'stylus') { _%>
|
||||
|
||||
<%_ if (rootOptions.cssPreprocessor !== 'stylus') { _%>
|
||||
<style<%-
|
||||
rootOptions.cssPreprocessor
|
||||
? ` lang="${
|
||||
@@ -51,37 +37,8 @@ export default {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
<%_ if (!rootOptions.router) { _%>
|
||||
margin-top: 60px;
|
||||
<%_ } _%>
|
||||
}
|
||||
<%_ if (rootOptions.router) { _%>
|
||||
<%_ if (!rootOptions.cssPreprocessor) { _%>
|
||||
#nav {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
#nav a {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
#nav a.router-link-exact-active {
|
||||
color: #42b983;
|
||||
}
|
||||
<%_ } else { _%>
|
||||
#nav {
|
||||
padding: 30px;
|
||||
a {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
&.router-link-exact-active {
|
||||
color: #42b983;
|
||||
}
|
||||
}
|
||||
}
|
||||
<%_ } _%>
|
||||
<%_ } _%>
|
||||
</style>
|
||||
<%_ } else { _%>
|
||||
<style lang="stylus">
|
||||
@@ -91,19 +48,7 @@ export default {
|
||||
-moz-osx-font-smoothing grayscale
|
||||
text-align center
|
||||
color #2c3e50
|
||||
<%_ if (!rootOptions.router) { _%>
|
||||
margin-top 60px
|
||||
<%_ } _%>
|
||||
<%_ if (rootOptions.router) { _%>
|
||||
|
||||
#nav
|
||||
padding 30px
|
||||
a
|
||||
font-weight bold
|
||||
color #2c3e50
|
||||
&.router-link-exact-active
|
||||
color #42b983
|
||||
<%_ } _%>
|
||||
</style>
|
||||
<%_ } _%>
|
||||
<%_ } _%>
|
||||
|
||||
@@ -64,8 +64,7 @@ class PluginAPI {
|
||||
* @return {boolean}
|
||||
*/
|
||||
hasPlugin (id) {
|
||||
if (id === 'router') id = 'vue-router'
|
||||
if (['vue-router', 'vuex'].includes(id)) {
|
||||
if (['vuex'].includes(id)) {
|
||||
const pkg = this.service.pkg
|
||||
return ((pkg.dependencies && pkg.dependencies[id]) || (pkg.devDependencies && pkg.devDependencies[id]))
|
||||
}
|
||||
|
||||
@@ -397,8 +397,7 @@ class PluginApi {
|
||||
* @param {string} id Plugin id or short id
|
||||
*/
|
||||
hasPlugin (id) {
|
||||
if (id === 'router') id = 'vue-router'
|
||||
if (['vue-router', 'vuex'].includes(id)) {
|
||||
if (['vuex'].includes(id)) {
|
||||
const pkg = folders.readPackage(this.cwd, this.context, true)
|
||||
return ((pkg.dependencies && pkg.dependencies[id]) || (pkg.devDependencies && pkg.devDependencies[id]))
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
describe('Plugins', () => {
|
||||
it('Should display the plugins', () => {
|
||||
cy.visit('/plugins')
|
||||
cy.get('.project-plugin-item').should('have.length', 4)
|
||||
cy.get('.project-plugin-item').should('have.length', 5)
|
||||
})
|
||||
|
||||
it('Should add a plugin', () => {
|
||||
@@ -26,6 +26,6 @@ describe('Plugins', () => {
|
||||
.should('be.visible')
|
||||
.should('not.have.class', 'disabled')
|
||||
.click()
|
||||
cy.get('.project-plugin-item').should('have.length', 4)
|
||||
cy.get('.project-plugin-item').should('have.length', 5)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@ const VUE_CONFIG_OPEN = 'org.vue.vue-config-open'
|
||||
module.exports = api => {
|
||||
api.onViewOpen(({ view }) => {
|
||||
if (view.id === 'vue-project-plugins') {
|
||||
if (!api.hasPlugin('vue-router')) {
|
||||
if (!api.hasPlugin('router')) {
|
||||
api.addSuggestion({
|
||||
id: ROUTER,
|
||||
type: 'action',
|
||||
@@ -16,7 +16,7 @@ module.exports = api => {
|
||||
message: 'org.vue.cli-service.suggestions.vue-router-add.message',
|
||||
link: 'https://router.vuejs.org/',
|
||||
async handler () {
|
||||
await install(api, 'vue-router')
|
||||
await install(api, 'router')
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -73,16 +73,19 @@ async function install (api, id) {
|
||||
progress: -1
|
||||
})
|
||||
|
||||
const name = id === 'vue-router' ? 'router' : id
|
||||
const context = api.getCwd()
|
||||
|
||||
let error
|
||||
|
||||
try {
|
||||
await invoke.runGenerator(context, {
|
||||
id: `core:${name}`,
|
||||
apply: loadModule(`@vue/cli-service/generator/${name}`, context)
|
||||
})
|
||||
if (id === 'router') {
|
||||
await invoke(id, {}, context)
|
||||
} else {
|
||||
await invoke.runGenerator(context, {
|
||||
id: `core:${id}`,
|
||||
apply: loadModule(`@vue/cli-service/generator/${id}`, context)
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
error = e
|
||||
}
|
||||
|
||||
@@ -92,10 +92,20 @@ module.exports = class Creator extends EventEmitter {
|
||||
preset.plugins['@vue/cli-service'] = Object.assign({
|
||||
projectName: name
|
||||
}, preset)
|
||||
|
||||
if (cliOptions.bare) {
|
||||
preset.plugins['@vue/cli-service'].bare = true
|
||||
}
|
||||
|
||||
// legacy support for router
|
||||
if (preset.router) {
|
||||
preset.plugins['@vue/cli-plugin-router'] = {}
|
||||
|
||||
if (preset.routerHistoryMode) {
|
||||
preset.plugins['@vue/cli-plugin-router'].historyMode = true
|
||||
}
|
||||
}
|
||||
|
||||
const packageManager = (
|
||||
cliOptions.packageManager ||
|
||||
loadOptions().packageManager ||
|
||||
|
||||
@@ -243,8 +243,7 @@ module.exports = class Generator {
|
||||
}
|
||||
|
||||
hasPlugin (_id) {
|
||||
if (_id === 'router') _id = 'vue-router'
|
||||
if (['vue-router', 'vuex'].includes(_id)) {
|
||||
if (['vuex'].includes(_id)) {
|
||||
const pkg = this.pkg
|
||||
return ((pkg.dependencies && pkg.dependencies[_id]) || (pkg.devDependencies && pkg.devDependencies[_id]))
|
||||
}
|
||||
|
||||
@@ -14,9 +14,6 @@ const {
|
||||
|
||||
async function add (pluginName, options = {}, context = process.cwd()) {
|
||||
// special internal "plugins"
|
||||
if (/^(@vue\/)?router$/.test(pluginName)) {
|
||||
return addRouter(context)
|
||||
}
|
||||
if (/^(@vue\/)?vuex$/.test(pluginName)) {
|
||||
return addVuex(context)
|
||||
}
|
||||
@@ -41,20 +38,6 @@ async function add (pluginName, options = {}, context = process.cwd()) {
|
||||
}
|
||||
}
|
||||
|
||||
async function addRouter (context) {
|
||||
const inquirer = require('inquirer')
|
||||
const options = await inquirer.prompt([{
|
||||
name: 'routerHistoryMode',
|
||||
type: 'confirm',
|
||||
message: `Use history mode for router? ${chalk.yellow(`(Requires proper server setup for index fallback in production)`)}`
|
||||
}])
|
||||
invoke.runGenerator(context, {
|
||||
id: 'core:router',
|
||||
apply: loadModule('@vue/cli-service/generator/router', context),
|
||||
options
|
||||
})
|
||||
}
|
||||
|
||||
async function addVuex (context) {
|
||||
invoke.runGenerator(context, {
|
||||
id: 'core:vuex',
|
||||
|
||||
@@ -10,6 +10,7 @@ const rcPath = exports.rcPath = getRcPath('.vuerc')
|
||||
const presetSchema = createSchema(joi => joi.object().keys({
|
||||
bare: joi.boolean(),
|
||||
useConfigFiles: joi.boolean(),
|
||||
// TODO: Use warn for router once @hapi/joi v16 releases
|
||||
router: joi.boolean(),
|
||||
routerHistoryMode: joi.boolean(),
|
||||
vuex: joi.boolean(),
|
||||
@@ -31,7 +32,6 @@ exports.validatePreset = preset => validate(preset, presetSchema, msg => {
|
||||
})
|
||||
|
||||
exports.defaultPreset = {
|
||||
router: false,
|
||||
vuex: false,
|
||||
useConfigFiles: false,
|
||||
cssPreprocessor: undefined,
|
||||
|
||||
@@ -19,9 +19,11 @@ test('router', async () => {
|
||||
]
|
||||
|
||||
const expectedOptions = {
|
||||
router: true,
|
||||
routerHistoryMode: true,
|
||||
plugins: {}
|
||||
plugins: {
|
||||
'@vue/cli-plugin-router': {
|
||||
historyMode: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await assertPromptModule(
|
||||
|
||||
@@ -9,7 +9,7 @@ module.exports = cli => {
|
||||
})
|
||||
|
||||
cli.injectPrompt({
|
||||
name: 'routerHistoryMode',
|
||||
name: 'historyMode',
|
||||
when: answers => answers.features.includes('router'),
|
||||
type: 'confirm',
|
||||
message: `Use history mode for router? ${chalk.yellow(`(Requires proper server setup for index fallback in production)`)}`,
|
||||
@@ -19,8 +19,9 @@ module.exports = cli => {
|
||||
|
||||
cli.onPromptComplete((answers, options) => {
|
||||
if (answers.features.includes('router')) {
|
||||
options.router = true
|
||||
options.routerHistoryMode = answers.routerHistoryMode
|
||||
options.plugins['@vue/cli-plugin-router'] = {
|
||||
historyMode: answers.historyMode
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ const { toShortPluginId } = require('@vue/cli-shared-utils')
|
||||
exports.getFeatures = (preset) => {
|
||||
const features = []
|
||||
if (preset.router) {
|
||||
features.push('vue-router')
|
||||
features.push('router')
|
||||
}
|
||||
if (preset.vuex) {
|
||||
features.push('vuex')
|
||||
|
||||
Reference in New Issue
Block a user