From c3969f8d8710f4d8c83dd95c03999d63c8e15d9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=90=AC=E6=B5=B7?= <445436867@qq.com>
Date: Fri, 7 Apr 2023 20:46:33 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0[...slug].vue?=
=?UTF-8?q?=E6=96=B9=E5=BC=8F=E6=9B=BF=E6=8D=A2*.vue=E5=AE=9E=E7=8E=B0?=
=?UTF-8?q?=E6=A8=A1=E7=B3=8A=E5=8C=B9=E9=85=8D=20(#183)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/guide/route.md | 262 ++++++++++--------
packages/fes-preset-built-in/src/index.js | 13 +-
.../fes => core/entry}/defaultContainer.tpl | 0
.../{generateFiles/fes => core/entry}/fes.tpl | 0
.../fes => core/entry}/index.js | 0
.../fes => core/entry}/initialState.tpl | 0
.../core/exports/coreExports.js | 4 +-
.../core/exports/coreExports.tpl | 0
.../{generateFiles => }/core/exports/doc.md | 0
.../core/exports/pluginExports.js | 16 +-
.../{generateFiles => }/core/plugin/index.js | 2 +-
.../core/plugin/plugin.tpl | 0
.../core/plugin/pluginRegister.tpl | 0
.../src/plugins/{ => core}/route/index.js | 31 ++-
.../route/template/routeExports.tpl | 0
.../{ => core}/route/template/routes.tpl | 0
.../{ => core}/route/template/runtime.tpl | 0
.../src/plugins/generateFiles/genType.js | 33 ---
.../src/plugins/registerType.js | 32 +++
.../src/pages/{@id => [id]}/add.vue | 0
.../src/pages/menuTest/{@id.vue => [id].vue} | 0
.../src/pages/route/{@id.vue => [id].vue} | 0
22 files changed, 226 insertions(+), 167 deletions(-)
rename packages/fes-preset-built-in/src/plugins/{generateFiles/fes => core/entry}/defaultContainer.tpl (100%)
rename packages/fes-preset-built-in/src/plugins/{generateFiles/fes => core/entry}/fes.tpl (100%)
rename packages/fes-preset-built-in/src/plugins/{generateFiles/fes => core/entry}/index.js (100%)
rename packages/fes-preset-built-in/src/plugins/{generateFiles/fes => core/entry}/initialState.tpl (100%)
rename packages/fes-preset-built-in/src/plugins/{generateFiles => }/core/exports/coreExports.js (88%)
rename packages/fes-preset-built-in/src/plugins/{generateFiles => }/core/exports/coreExports.tpl (100%)
rename packages/fes-preset-built-in/src/plugins/{generateFiles => }/core/exports/doc.md (100%)
rename packages/fes-preset-built-in/src/plugins/{generateFiles => }/core/exports/pluginExports.js (58%)
rename packages/fes-preset-built-in/src/plugins/{generateFiles => }/core/plugin/index.js (97%)
rename packages/fes-preset-built-in/src/plugins/{generateFiles => }/core/plugin/plugin.tpl (100%)
rename packages/fes-preset-built-in/src/plugins/{generateFiles => }/core/plugin/pluginRegister.tpl (100%)
rename packages/fes-preset-built-in/src/plugins/{ => core}/route/index.js (92%)
rename packages/fes-preset-built-in/src/plugins/{ => core}/route/template/routeExports.tpl (100%)
rename packages/fes-preset-built-in/src/plugins/{ => core}/route/template/routes.tpl (100%)
rename packages/fes-preset-built-in/src/plugins/{ => core}/route/template/runtime.tpl (100%)
delete mode 100644 packages/fes-preset-built-in/src/plugins/generateFiles/genType.js
rename packages/fes-template/src/pages/{@id => [id]}/add.vue (100%)
rename packages/fes-template/src/pages/menuTest/{@id.vue => [id].vue} (100%)
rename packages/fes-template/src/pages/route/{@id.vue => [id].vue} (100%)
diff --git a/docs/guide/route.md b/docs/guide/route.md
index 2f4b3bd4..7307754a 100644
--- a/docs/guide/route.md
+++ b/docs/guide/route.md
@@ -5,122 +5,153 @@
## 路由配置
在配置文件 `.fes.js`中通过 `router` 进行配置。
+
```js
export default {
router: {
routes: [],
- mode: 'hash'
- }
-}
+ mode: 'hash',
+ },
+};
```
### routes
+
`routes` 是配置添加到路由的初始路由列表,格式为路由信息的数组。具体使用参考 [Vue Router 文档](https://next.router.vuejs.org/zh/guide/) 中关于路由配置、路由匹配相关内容。
+### mode
-### mode
创建历史记录的类型:
-- **history**,对应 [createWebHistory](https://next.router.vuejs.org/zh/api/#createwebhistory)
-- **hash**,对应 [createWebHashHistory](https://next.router.vuejs.org/zh/api/#createWebHashHistory)
-- **memory**,对应 [createMemoryHistory](https://next.router.vuejs.org/zh/api/#createWebHashHistory)
+
+- **history**,对应 [createWebHistory](https://next.router.vuejs.org/zh/api/#createwebhistory)
+- **hash**,对应 [createWebHashHistory](https://next.router.vuejs.org/zh/api/#createWebHashHistory)
+- **memory**,对应 [createMemoryHistory](https://next.router.vuejs.org/zh/api/#createWebHashHistory)
默认是`hash`模式。
## 约定式路由
-约定式路由也叫文件路由,就是不需要手写配置,文件系统即路由,通过目录和文件及其命名分析出路由配置。
+
+约定式路由也叫文件路由,就是不需要手写配置,文件系统即路由,通过目录和文件及其命名分析出路由配置。
### 约定规范
+
比如以下文件结构:
+
```
pages
├── index.vue # 根路由页面 路径为 /
-├── *.vue # 模糊匹配 路径为 *
+├── [...slug].vue # 模糊匹配 路径为 /:slug(.*)
├── a.vue # 路径 /a
├── b # 文件夹b
│ ├── index.vue # 路径 /b
-│ ├── @id.vue # 动态路由 /b/:id
+│ ├── [slug].vue # 动态路由 /b/:slug
│ ├── c.vue # 路径 /b/c
│ └── layout.vue # /b 路径下所有页面公共的布局组件
└── layout.vue # 根路由下所有页面共用的布局组件
```
+
编译后会得到以下路由配置:
+
```js
[
{
- "path": "/",
- "component": require('@/pages/layout').default,
- "count": 5,
- "children": [
+ path: '/',
+ component: require('@/pages/layout').default,
+ count: 5,
+ children: [
{
- "path": "/a",
- "component": require('@/pages/a').default,
- "name": "a",
- "meta": {},
- "count": 7
+ path: '/a',
+ component: require('@/pages/a').default,
+ name: 'a',
+ meta: {},
+ count: 7,
},
{
- "path": "/b",
- "component": require('@/pages/b/layout').default,
- "count": 7,
- "children": [
+ path: '/b',
+ component: require('@/pages/b/layout').default,
+ count: 7,
+ children: [
{
- "path": "/b/c",
- "component": require('@/pages/b/c').default,
- "name": "b_c",
- "meta": {},
- "count": 14
+ path: '/b/c',
+ component: require('@/pages/b/c').default,
+ name: 'b_c',
+ meta: {},
+ count: 14,
},
{
- "path": "/b/:id",
- "component": require('@/pages/b/@id').default,
- "name": "b__id",
- "meta": {},
- "count": 13
+ path: '/b/:id',
+ component: require('@/pages/b/@id').default,
+ name: 'b__id',
+ meta: {},
+ count: 13,
},
{
- "path": "/b",
- "component": require('@/pages/b/index').default,
- "name": "b_index",
- "meta": {},
- "count": 7
- }
- ]
+ path: '/b',
+ component: require('@/pages/b/index').default,
+ name: 'b_index',
+ meta: {},
+ count: 7,
+ },
+ ],
},
{
- "path": "/",
- "component": require('@/pages/index').default,
- "name": "index",
- "meta": {},
- "count": 5
+ path: '/',
+ component: require('@/pages/index').default,
+ name: 'index',
+ meta: {},
+ count: 5,
},
{
- "path": "/:pathMatch(.*)",
- "component": require('@/pages/*').default,
- "name": "FUZZYMATCH",
- "meta": {},
- "count": 3
- }
- ]
- }
-]
+ path: '/:pathMatch(.*)',
+ component: require('@/pages/*').default,
+ name: 'FUZZYMATCH',
+ meta: {},
+ count: 3,
+ },
+ ],
+ },
+];
```
**需要注意的是,满足以下任意规则的文件不会被注册为路由**:
-- 不是 `.vue .jsx` 文件
-- `components` 目录中的文件
+- 不是 `.vue .jsx` 文件
+- `components` 目录中的文件
### 动态路由
-Fes.js 里约定以 `@` 开头的文件或文件夹映射为动态路由。
+
+Fes.js 里约定名称为 `[slug]`格式的文件或文件夹映射为动态路由。
比如:
-- `src/pages/users/@id.vue` 会成为 `/users/:id`
-- `src/pages/users/@id/settings.vue` 会成为 `/users/:id/settings`
+- `src/pages/users/[id].vue` 会成为 `/users/:id`
+- `src/pages/users/[id]/settings.vue` 会成为 `/users/:id/settings`
+
+
+:::warning
+`@slug`形式下版本会弃用,请替换为`[slug]`~
+:::
+
+### 模糊匹配
+
+Fes.js 里约定名称为 `[...slug]`格式的文件或文件夹映射为动态路由中的模糊匹配形式。
+比如:
+
+- `src/pages/users/[...].vue` 会成为 `/users/:pathMatch(.*)`
+- `src/pages/users/[...id].vue` 会成为 `/users/:id(.*)`
+- `src/pages/users/[...id]/settings.vue` 会成为 `/users/:id(.*)/settings`
+
+
+:::warning
+`*`形式下版本会弃用,请替换为`[...slug]`~
+:::
+
### 嵌套路由
+
Fes.js 里约定目录下有 `layout.vue` 时会生成嵌套路由,以 `layout.vue` 为该目录的公共父组件,`layout.vue` 中必须实现 `RouterView`
比如以下目录结构:
+
```
pages
└── users
@@ -128,21 +159,25 @@ pages
├── index.vue
└── list.vue
```
+
会生成路由:
+
```js
[
- {
- path: '/users', component: require('@/pages/users/layout').default,
+ {
+ path: '/users',
+ component: require('@/pages/users/layout').default,
children: [
{ path: '/users', component: require('@/pages/users/index').default },
{ path: '/users/list', component: require('@/pages/users/list').default },
- ]
- }
-]
+ ],
+ },
+];
```
### 模糊匹配
-Fes.js 下约定文件名为 `*` 的路由是模糊匹配路由,可以用此特性实现 [404 路由](https://next.router.vuejs.org/zh/guide/essentials/dynamic-matching.html#%E6%8D%95%E8%8E%B7%E6%89%80%E6%9C%89%E8%B7%AF%E7%94%B1%E6%88%96-404-not-found-%E8%B7%AF%E7%94%B1)。
+
+Fes.js 下约定文件名为 `*` 的路由是模糊匹配路由,可以用此特性实现 [404 路由](https://next.router.vuejs.org/zh/guide/essentials/dynamic-matching.html#%E6%8D%95%E8%8E%B7%E6%89%80%E6%9C%89%E8%B7%AF%E7%94%B1%E6%88%96-404-not-found-%E8%B7%AF%E7%94%B1)。
比如以下目录结构:
@@ -151,26 +186,35 @@ pages
├── index.vue # 根路由页面 路径为 /
└── *.vue # 模糊匹配 路径为 *
```
+
会生成路由:
+
```js
[
- {
- path: '/', component: require('@/pages/index').default, count: 5
+ {
+ path: '/',
+ component: require('@/pages/index').default,
+ count: 5,
},
{
- path: '/:pathMatch(.*)', component: require('@/pages/**').default, count: 3
- }
-]
+ path: '/:pathMatch(.*)',
+ component: require('@/pages/**').default,
+ count: 3,
+ },
+];
```
+
这样,如果访问 `/foo`,`/` 不能匹配,会 fallback 到 `*` 路由,通过 `src/pages/*.vue` 进行渲染。
### 智能路由
+
可以看到,编译后路由都会有 `count` 属性,这是我们根据精准匹配优先算法原则设计出路由排名算法,对匹配到的路由打分:
-- 路由的路径每个子项得到4分
-- 子项为静态细分(`/list`)再加3分
-- 子项为动态细分(`/:orderId`)再加2分
-- 根段(`/`)再1分
-- 通配符(`*`)匹配到的减去1分
+
+- 路由的路径每个子项得到 4 分
+- 子项为静态细分(`/list`)再加 3 分
+- 子项为动态细分(`/:orderId`)再加 2 分
+- 根段(`/`)再 1 分
+- 通配符(`*`)匹配到的减去 1 分
当我们跳转路由时,如果 URL 匹配到多个路由,则选择分数最高的路由。
@@ -180,32 +224,31 @@ pages
```js
const router = new VueRouter({
- routes: [
- {
- path: '/foo',
- component: Foo,
- children: [
+ routes: [
{
- path: 'bar',
- component: Bar,
- // a meta field
- meta: { requiresAuth: true }
- }
- ]
- }
- ]
-})
+ path: '/foo',
+ component: Foo,
+ children: [
+ {
+ path: 'bar',
+ component: Bar,
+ // a meta field
+ meta: { requiresAuth: true },
+ },
+ ],
+ },
+ ],
+});
```
-
我们使用`defineRouteMeta` 配置 `meta`:
```js
import { defineRouteMeta } from '@fesjs/fes';
defineRouteMeta({
- name: "store",
- title: "vuex测试"
-})
+ name: 'store',
+ title: 'vuex测试',
+});
```
当然在单文件组件中,还可以通过``配置 `meta`:
@@ -223,14 +266,13 @@ defineRouteMeta({
推荐使用`defineRouteMete`,有更好的提示。
:::
-
-
路由元信息在编译后会附加到路由配置中:
+
```js{5-8}
[
- {
- path: '/a',
- component: require('@/pages/a').default,
+ {
+ path: '/a',
+ component: require('@/pages/a').default,
meta: {
"name": "store",
"title": "vuex测试"
@@ -240,9 +282,11 @@ defineRouteMeta({
```
## 路由跳转
+
想学习更多,可以查看 [Vue Router 官方文档](https://next.router.vuejs.org/zh/guide/essentials/navigation.html#%E6%9B%BF%E6%8D%A2%E5%BD%93%E5%89%8D%E4%BD%8D%E7%BD%AE)。
### 声明式
+
```vue
Home
@@ -250,24 +294,25 @@ defineRouteMeta({
```
### 命令式
+
页面跳转 API 由 `router` 实例提供,查看 [Vue Rouer 文档](https://next.router.vuejs.org/zh/api/#router-%E6%96%B9%E6%B3%95)了解更多。
```js
import { useRouter } from '@fesjs/fes';
export default {
- setup(){
+ setup() {
const router = useRouter();
// 这三种形式是等价的
- router.push('/users/posva#bio')
- router.push({ path: '/users/posva', hash: '#bio' })
- router.push({ name: 'users', params: { username: 'posva' }, hash: '#bio' })
+ router.push('/users/posva#bio');
+ router.push({ path: '/users/posva', hash: '#bio' });
+ router.push({ name: 'users', params: { username: 'posva' }, hash: '#bio' });
// 只改变 hash
- router.push({ hash: '#bio' })
+ router.push({ hash: '#bio' });
// 只改变 query
- router.push({ query: { page: '2' } })
+ router.push({ query: { page: '2' } });
// 只改变 param
- router.push({ params: { username: 'jolyne' } })
+ router.push({ params: { username: 'jolyne' } });
// 跳转到上一个路由
router.goBack();
@@ -277,7 +322,6 @@ export default {
// 替换历史堆栈中的记录
router.replace('/new');
- }
-}
-
-```
\ No newline at end of file
+ },
+};
+```
diff --git a/packages/fes-preset-built-in/src/index.js b/packages/fes-preset-built-in/src/index.js
index 15bc035a..add31ded 100644
--- a/packages/fes-preset-built-in/src/index.js
+++ b/packages/fes-preset-built-in/src/index.js
@@ -6,11 +6,11 @@ export default function () {
require.resolve('./plugins/registerType'),
// generate files
- require.resolve('./plugins/generateFiles/core/plugin'),
- require.resolve('./plugins/generateFiles/core/exports/coreExports'),
- require.resolve('./plugins/generateFiles/core/exports/pluginExports'),
- require.resolve('./plugins/generateFiles/fes'),
- require.resolve('./plugins/generateFiles/genType'),
+ require.resolve('./plugins/core/plugin'),
+ require.resolve('./plugins/core/exports/coreExports'),
+ require.resolve('./plugins/core/exports/pluginExports'),
+ require.resolve('./plugins/core/entry'),
+ require.resolve('./plugins/core/route'),
// bundle configs
require.resolve('./plugins/features/alias'),
@@ -31,9 +31,6 @@ export default function () {
require.resolve('./plugins/features/terserOptions'),
require.resolve('./plugins/features/title'),
- // route
- require.resolve('./plugins/route'),
-
// commands
require.resolve('./plugins/commands/help'),
require.resolve('./plugins/commands/info'),
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/fes/defaultContainer.tpl b/packages/fes-preset-built-in/src/plugins/core/entry/defaultContainer.tpl
similarity index 100%
rename from packages/fes-preset-built-in/src/plugins/generateFiles/fes/defaultContainer.tpl
rename to packages/fes-preset-built-in/src/plugins/core/entry/defaultContainer.tpl
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/fes/fes.tpl b/packages/fes-preset-built-in/src/plugins/core/entry/fes.tpl
similarity index 100%
rename from packages/fes-preset-built-in/src/plugins/generateFiles/fes/fes.tpl
rename to packages/fes-preset-built-in/src/plugins/core/entry/fes.tpl
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/fes/index.js b/packages/fes-preset-built-in/src/plugins/core/entry/index.js
similarity index 100%
rename from packages/fes-preset-built-in/src/plugins/generateFiles/fes/index.js
rename to packages/fes-preset-built-in/src/plugins/core/entry/index.js
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/fes/initialState.tpl b/packages/fes-preset-built-in/src/plugins/core/entry/initialState.tpl
similarity index 100%
rename from packages/fes-preset-built-in/src/plugins/generateFiles/fes/initialState.tpl
rename to packages/fes-preset-built-in/src/plugins/core/entry/initialState.tpl
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/core/exports/coreExports.js b/packages/fes-preset-built-in/src/plugins/core/exports/coreExports.js
similarity index 88%
rename from packages/fes-preset-built-in/src/plugins/generateFiles/core/exports/coreExports.js
rename to packages/fes-preset-built-in/src/plugins/core/exports/coreExports.js
index 60ea2516..fb93df0c 100644
--- a/packages/fes-preset-built-in/src/plugins/generateFiles/core/exports/coreExports.js
+++ b/packages/fes-preset-built-in/src/plugins/core/exports/coreExports.js
@@ -1,7 +1,7 @@
import { readFileSync } from 'fs';
import { join } from 'path';
-import generateExports from '../../../../utils/generateExports';
-import { runtimePath } from '../../../../utils/constants';
+import generateExports from '../../../utils/generateExports';
+import { runtimePath } from '../../../utils/constants';
export default function (api) {
api.onGenerateFiles(async () => {
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/core/exports/coreExports.tpl b/packages/fes-preset-built-in/src/plugins/core/exports/coreExports.tpl
similarity index 100%
rename from packages/fes-preset-built-in/src/plugins/generateFiles/core/exports/coreExports.tpl
rename to packages/fes-preset-built-in/src/plugins/core/exports/coreExports.tpl
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/core/exports/doc.md b/packages/fes-preset-built-in/src/plugins/core/exports/doc.md
similarity index 100%
rename from packages/fes-preset-built-in/src/plugins/generateFiles/core/exports/doc.md
rename to packages/fes-preset-built-in/src/plugins/core/exports/doc.md
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/core/exports/pluginExports.js b/packages/fes-preset-built-in/src/plugins/core/exports/pluginExports.js
similarity index 58%
rename from packages/fes-preset-built-in/src/plugins/generateFiles/core/exports/pluginExports.js
rename to packages/fes-preset-built-in/src/plugins/core/exports/pluginExports.js
index f481a9b8..cabc3107 100644
--- a/packages/fes-preset-built-in/src/plugins/generateFiles/core/exports/pluginExports.js
+++ b/packages/fes-preset-built-in/src/plugins/core/exports/pluginExports.js
@@ -1,11 +1,11 @@
-import generateExports from '../../../../utils/generateExports';
+import generateExports from '../../../utils/generateExports';
export default function (api) {
api.onGenerateFiles(async () => {
const fesExports = await api.applyPlugins({
key: 'addPluginExports',
type: api.ApplyPluginsType.add,
- initialValue: []
+ initialValue: [],
});
const fesExportsHook = {}; // repeated definition
@@ -13,11 +13,13 @@ export default function (api) {
api.writeTmpFile({
path: absoluteFilePath,
content: `${fesExports
- .map(item => generateExports(absoluteFilePath, {
- item,
- fesExportsHook
- }))
- .join('\n')}\n`
+ .map((item) =>
+ generateExports(absoluteFilePath, {
+ item,
+ fesExportsHook,
+ }),
+ )
+ .join('\n')}\n`,
});
});
}
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/core/plugin/index.js b/packages/fes-preset-built-in/src/plugins/core/plugin/index.js
similarity index 97%
rename from packages/fes-preset-built-in/src/plugins/generateFiles/core/plugin/index.js
rename to packages/fes-preset-built-in/src/plugins/core/plugin/index.js
index a09a45f2..03fd66a1 100644
--- a/packages/fes-preset-built-in/src/plugins/generateFiles/core/plugin/index.js
+++ b/packages/fes-preset-built-in/src/plugins/core/plugin/index.js
@@ -1,7 +1,7 @@
import { readFileSync } from 'fs';
import { join } from 'path';
import { winPath } from '@fesjs/utils';
-import { runtimePath } from '../../../../utils/constants';
+import { runtimePath } from '../../../utils/constants';
export default function (api) {
const {
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/core/plugin/plugin.tpl b/packages/fes-preset-built-in/src/plugins/core/plugin/plugin.tpl
similarity index 100%
rename from packages/fes-preset-built-in/src/plugins/generateFiles/core/plugin/plugin.tpl
rename to packages/fes-preset-built-in/src/plugins/core/plugin/plugin.tpl
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/core/plugin/pluginRegister.tpl b/packages/fes-preset-built-in/src/plugins/core/plugin/pluginRegister.tpl
similarity index 100%
rename from packages/fes-preset-built-in/src/plugins/generateFiles/core/plugin/pluginRegister.tpl
rename to packages/fes-preset-built-in/src/plugins/core/plugin/pluginRegister.tpl
diff --git a/packages/fes-preset-built-in/src/plugins/route/index.js b/packages/fes-preset-built-in/src/plugins/core/route/index.js
similarity index 92%
rename from packages/fes-preset-built-in/src/plugins/route/index.js
rename to packages/fes-preset-built-in/src/plugins/core/route/index.js
index d6368bc8..8cfc6433 100644
--- a/packages/fes-preset-built-in/src/plugins/route/index.js
+++ b/packages/fes-preset-built-in/src/plugins/core/route/index.js
@@ -2,15 +2,15 @@ import { readdirSync, statSync, readFileSync } from 'fs';
import { join, extname, basename } from 'path';
import { lodash, parser, generator, logger, winPath } from '@fesjs/utils';
import { parse } from '@vue/compiler-sfc';
-import { runtimePath } from '../../utils/constants';
+import { runtimePath } from '../../../utils/constants';
// pages
// ├── index.vue # 根路由页面 路径 /
-// ├── *.vue # 模糊匹配 路径 *
+// ├── [...slug].vue # 模糊匹配 路径 /:slug(.*)
// ├── a.vue # 路径 /a
// ├── b
// │ ├── index.vue # 路径 /b
-// │ ├── @id.vue # 动态路由 /b/:id
+// │ ├── [slug].vue # 动态路由 /b/:slug
// │ └── c.vue # 路径 /b/c
// └── layout.vue # 根路由下所有page共用的外层
@@ -38,7 +38,14 @@ const checkHasLayout = function (path) {
const getRouteName = function (parentRoutePath, fileName) {
const routeName = winPath(join(parentRoutePath, fileName));
- return routeName.slice(1).replace(/\//g, '_').replace(/@/g, '_').replace(/:/g, '_').replace(/\*/g, 'FUZZYMATCH');
+ return routeName
+ .slice(1)
+ .replace(/\//g, '_')
+ .replace(/@/g, '_')
+ .replace(/:/g, '_')
+ .replace(/\*/g, 'FUZZYMATCH')
+ .replace(/\[([a-zA-Z]+)\]/, '_$1')
+ .replace(/\[...([a-zA-Z]*)\]/, 'FUZZYMATCH-$1');
};
const getRoutePath = function (parentRoutePath, fileName, isFile = true) {
@@ -48,12 +55,22 @@ const getRoutePath = function (parentRoutePath, fileName, isFile = true) {
}
// /@id.vue -> /:id
if (fileName.startsWith('@')) {
+ logger.warn(`[WARNING]: ${fileName} is deprecated, please use [slug]`);
fileName = fileName.replace(/@/, ':');
}
// /*.vue -> :pathMatch(.*)
if (fileName.includes('*')) {
+ logger.warn(`[WARNING]: ${fileName} is deprecated, please use [...slug]`);
fileName = fileName.replace('*', ':pathMatch(.*)');
}
+ // /[slug].vue -> /:slug
+ if (/\[[a-zA-Z]+\]/.test(fileName)) {
+ fileName = fileName.replace(/\[([a-zA-Z]+)\]/g, ':$1');
+ }
+ // /[...slug].vue -> /:slug(.*)
+ if (/\[...[a-zA-Z]*\]/.test(fileName)) {
+ fileName = fileName.replace(/\[...([a-zA-Z]*)\]/, ':$1(.*)').replace(':(.*)', ':pathMatch(.*)');
+ }
return winPath(join(parentRoutePath, fileName));
};
@@ -75,7 +92,7 @@ function getRouteMeta(content) {
const fn = eval(`() => (${argument.code})`);
return fn();
}
- } catch (err) { }
+ } catch (err) {}
return null;
}
@@ -186,9 +203,9 @@ const rank = function (routes) {
let count = 0;
arr.forEach((sonPath) => {
count += 4;
- if (sonPath.indexOf(':') !== -1 && sonPath.indexOf(':pathMatch(.*)') === -1) {
+ if (sonPath.indexOf(':') !== -1 && sonPath.indexOf('(.*)') === -1) {
count += 2;
- } else if (sonPath.indexOf(':pathMatch(.*)') !== -1) {
+ } else if (sonPath.indexOf('(.*)') !== -1) {
count -= 1;
} else if (sonPath === '') {
count += 1;
diff --git a/packages/fes-preset-built-in/src/plugins/route/template/routeExports.tpl b/packages/fes-preset-built-in/src/plugins/core/route/template/routeExports.tpl
similarity index 100%
rename from packages/fes-preset-built-in/src/plugins/route/template/routeExports.tpl
rename to packages/fes-preset-built-in/src/plugins/core/route/template/routeExports.tpl
diff --git a/packages/fes-preset-built-in/src/plugins/route/template/routes.tpl b/packages/fes-preset-built-in/src/plugins/core/route/template/routes.tpl
similarity index 100%
rename from packages/fes-preset-built-in/src/plugins/route/template/routes.tpl
rename to packages/fes-preset-built-in/src/plugins/core/route/template/routes.tpl
diff --git a/packages/fes-preset-built-in/src/plugins/route/template/runtime.tpl b/packages/fes-preset-built-in/src/plugins/core/route/template/runtime.tpl
similarity index 100%
rename from packages/fes-preset-built-in/src/plugins/route/template/runtime.tpl
rename to packages/fes-preset-built-in/src/plugins/core/route/template/runtime.tpl
diff --git a/packages/fes-preset-built-in/src/plugins/generateFiles/genType.js b/packages/fes-preset-built-in/src/plugins/generateFiles/genType.js
deleted file mode 100644
index b6076c06..00000000
--- a/packages/fes-preset-built-in/src/plugins/generateFiles/genType.js
+++ /dev/null
@@ -1,33 +0,0 @@
-function importsToStr(imports) {
- return imports.map((imp) => {
- const { source } = imp;
- return `export * from '${source}';`;
- });
-}
-
-function genTypeContent(imports) {
- return {
- imports: importsToStr(imports).join('\n'),
- };
-}
-
-export default function (api) {
- const {
- utils: { Mustache },
- } = api;
-
- api.onGenerateFiles(async () => {
- const typeTpl = `
-{{{ imports }}}
-`;
- const importSources = await api.applyPlugins({
- key: 'addConfigType',
- type: api.ApplyPluginsType.add,
- initialValue: [],
- });
- api.writeTmpFile({
- path: 'configType.d.ts',
- content: Mustache.render(typeTpl, genTypeContent(importSources)),
- });
- });
-}
diff --git a/packages/fes-preset-built-in/src/plugins/registerType.js b/packages/fes-preset-built-in/src/plugins/registerType.js
index 5b7e7f0e..8f773137 100644
--- a/packages/fes-preset-built-in/src/plugins/registerType.js
+++ b/packages/fes-preset-built-in/src/plugins/registerType.js
@@ -1,9 +1,41 @@
import { name } from '../../package.json';
+function importsToStr(imports) {
+ return imports.map((imp) => {
+ const { source } = imp;
+ return `export * from '${source}';`;
+ });
+}
+
+function genTypeContent(imports) {
+ return {
+ imports: importsToStr(imports).join('\n'),
+ };
+}
+
export default function (api) {
+ const {
+ utils: { Mustache },
+ } = api;
+
api.addConfigType(() => ({
source: name,
runtime: ['InnerRuntimeConfig'],
build: ['InnerBuildConfig'],
}));
+
+ api.onGenerateFiles(async () => {
+ const typeTpl = `
+{{{ imports }}}
+`;
+ const importSources = await api.applyPlugins({
+ key: 'addConfigType',
+ type: api.ApplyPluginsType.add,
+ initialValue: [],
+ });
+ api.writeTmpFile({
+ path: 'configType.d.ts',
+ content: Mustache.render(typeTpl, genTypeContent(importSources)),
+ });
+ });
}
diff --git a/packages/fes-template/src/pages/@id/add.vue b/packages/fes-template/src/pages/[id]/add.vue
similarity index 100%
rename from packages/fes-template/src/pages/@id/add.vue
rename to packages/fes-template/src/pages/[id]/add.vue
diff --git a/packages/fes-template/src/pages/menuTest/@id.vue b/packages/fes-template/src/pages/menuTest/[id].vue
similarity index 100%
rename from packages/fes-template/src/pages/menuTest/@id.vue
rename to packages/fes-template/src/pages/menuTest/[id].vue
diff --git a/packages/fes-template/src/pages/route/@id.vue b/packages/fes-template/src/pages/route/[id].vue
similarity index 100%
rename from packages/fes-template/src/pages/route/@id.vue
rename to packages/fes-template/src/pages/route/[id].vue