Skip to content

Make router a separate plugin #4196

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/dev-guide/ui-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1274,15 +1274,15 @@ const ROUTER = 'vue-router-add'

api.onViewOpen(({ view }) => {
if (view.id === 'vue-project-plugins') {
if (!api.hasPlugin('vue-router')) {
if (!api.hasPlugin('router')) {
api.addSuggestion({
id: ROUTER,
type: 'action',
label: 'org.vue.cli-service.suggestions.vue-router-add.label',
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')
}
})
}
Expand Down
11 changes: 2 additions & 9 deletions docs/guide/plugins-and-presets.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@ You can pass generator options to the installed plugin (this will skip the promp
vue add @vue/eslint --config airbnb --lintOn save
```

`vue-router` and `vuex` are special cases - they do not have their own plugins, but you can add them nonetheless:

``` bash
vue add router
vue add vuex
```

If a plugin is already installed, you can skip the installation and only invoke its generator with the `vue invoke` command. The command takes the same arguments as `vue add`.

::: tip
Expand Down Expand Up @@ -112,15 +105,15 @@ Here's an example preset:
``` json
{
"useConfigFiles": true,
"router": true,
"vuex": true,
"cssPreprocessor": "sass",
"plugins": {
"@vue/cli-plugin-babel": {},
"@vue/cli-plugin-eslint": {
"config": "airbnb",
"lintOn": ["save", "commit"]
}
},
"@vue/cli-plugin-router": {}
}
}
```
Expand Down
4 changes: 2 additions & 2 deletions docs/ru/dev-guide/ui-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1274,15 +1274,15 @@ const ROUTER = 'vue-router-add'

api.onViewOpen(({ view }) => {
if (view.id === 'vue-project-plugins') {
if (!api.hasPlugin('vue-router')) {
if (!api.hasPlugin('router')) {
api.addSuggestion({
id: ROUTER,
type: 'action',
label: 'org.vue.cli-service.suggestions.vue-router-add.label',
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')
}
})
}
Expand Down
11 changes: 2 additions & 9 deletions docs/ru/guide/plugins-and-presets.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@ vue add @foo/bar
vue add @vue/eslint --config airbnb --lintOn save
```

Добавление `vue-router` и `vuex` — особый случай, у них нет собственных плагинов, но вы тем не менее можете их добавить:

``` bash
vue add router
vue add vuex
```

Если плагин уже установлен, вы можете пропустить установку и только вызвать его генератор с помощью команды `vue invoke`. Команда принимает такие же аргументы, как и `vue add`.

::: tip Совет
Expand Down Expand Up @@ -112,15 +105,15 @@ vue add vuex
``` json
{
"useConfigFiles": true,
"router": true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though we now have a standalone router plugin, the legacy preset format (router and routerHistoryMode option) can and should still be supported, so as to reduce the migration costs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added support for legacy router option but have it removed from docs completely.

"vuex": true,
"cssPreprocessor": "sass",
"plugins": {
"@vue/cli-plugin-babel": {},
"@vue/cli-plugin-eslint": {
"config": "airbnb",
"lintOn": ["save", "commit"]
}
},
"@vue/cli-plugin-router": {}
}
}
```
Expand Down
11 changes: 2 additions & 9 deletions docs/zh/guide/plugins-and-presets.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@ vue add @foo/bar
vue add @vue/eslint --config airbnb --lintOn save
```

`vue-router` 和 `vuex` 的情况比较特殊——它们并没有自己的插件,但是你仍然可以这样添加它们:

``` bash
vue add router
vue add vuex
```

如果一个插件已经被安装,你可以使用 `vue invoke` 命令跳过安装过程,只调用它的生成器。这个命令会接受和 `vue add` 相同的参数。

::: tip 提示
Expand Down Expand Up @@ -112,15 +105,15 @@ vue add vuex
``` json
{
"useConfigFiles": true,
"router": true,
"vuex": true,
"cssPreprocessor": "sass",
"plugins": {
"@vue/cli-plugin-babel": {},
"@vue/cli-plugin-eslint": {
"config": "airbnb",
"lintOn": ["save", "commit"]
}
},
"@vue/cli-plugin-router": {}
}
}
```
Expand Down
2 changes: 2 additions & 0 deletions packages/@vue/cli-plugin-router/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__tests__
__mocks__
9 changes: 9 additions & 0 deletions packages/@vue/cli-plugin-router/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# @vue/cli-plugin-router

> router plugin for vue-cli

## Installing in an Already Created Project

``` sh
vue add @vue/router
```
64 changes: 64 additions & 0 deletions packages/@vue/cli-plugin-router/__tests__/routerGenerator.spec.js
Original file line number Diff line number Diff line change
@@ -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')
})
Original file line number Diff line number Diff line change
@@ -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')
Expand Down
65 changes: 65 additions & 0 deletions packages/@vue/cli-plugin-router/generator/template/src/App.vue
Original file line number Diff line number Diff line change
@@ -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 %>
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions packages/@vue/cli-plugin-router/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = (api, options = {}) => {}
31 changes: 31 additions & 0 deletions packages/@vue/cli-plugin-router/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
Loading