diff --git a/README.md b/README.md
index 39fd988..15b9721 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,31 @@ export default defineUniPages({
现在所有的 page 都会被自动发现!
-### SFC 自定义块用于路由数据
+### 页面调用方式(1): `definePage` 宏定义路由数据
+```html
+
+
+
+
+
+```
+
+### 页面调用方式(2):SFC 自定义块用于路由数据
通过添加一个 `` 块到 SFC 中来添加路由元数据。这将会在路由生成后直接添加到路由中,并且会覆盖。
diff --git a/packages/core/README.md b/packages/core/README.md
index 5a66ce3..56f0153 100644
--- a/packages/core/README.md
+++ b/packages/core/README.md
@@ -44,7 +44,31 @@ export default defineUniPages({
Now all pages will be found automatically!
-### SFC custom block for Route Data
+### Page usage (1): `definePage` macro define page options
+```html
+
+
+
+
+
+```
+
+### Page usage (2): SFC custom block for Route Data
Add route meta to the route by adding a `` block to the SFC. This will be
directly added to the route after it is generated, and will override it.
diff --git a/packages/core/client.d.ts b/packages/core/client.d.ts
index 9af7099..0ae9dc2 100644
--- a/packages/core/client.d.ts
+++ b/packages/core/client.d.ts
@@ -5,3 +5,7 @@ declare module 'virtual:uni-pages' {
export const pages: PageMetaDatum[]
export const subPackages: SubPackage[]
}
+
+declare module globalThis {
+ export const definePage: import('./src/types').DefinePage
+}
diff --git a/packages/core/package.json b/packages/core/package.json
index bed53e1..153a1d3 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -40,8 +40,11 @@
"stub": "unbuild --stub"
},
"dependencies": {
+ "@babel/generator": "^7.24.1",
+ "@babel/types": "^7.24.0",
"@uni-helper/uni-env": "^0.1.1",
"@vue/compiler-sfc": "^3.4.21",
+ "ast-kit": "^0.12.1",
"chokidar": "^3.6.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
@@ -53,6 +56,8 @@
},
"devDependencies": {
"@antfu/utils": "^0.7.7",
+ "@babel/parser": "^7.24.1",
+ "@types/babel__generator": "^7.6.8",
"@types/debug": "^4.1.12",
"@types/node": "^20.11.24"
}
diff --git a/packages/core/src/constant.ts b/packages/core/src/constant.ts
index e3eafdb..ee13441 100644
--- a/packages/core/src/constant.ts
+++ b/packages/core/src/constant.ts
@@ -4,3 +4,5 @@ export const RESOLVED_MODULE_ID_VIRTUAL = `\0${MODULE_ID_VIRTUAL}`
export const OUTPUT_NAME = 'pages.json'
export const FILE_EXTENSIONS = ['vue', 'nvue', 'uvue']
+
+export const DEFINE_PAGE = 'definePage'
diff --git a/packages/core/src/context.ts b/packages/core/src/context.ts
index f5cc0e2..a6c56b6 100644
--- a/packages/core/src/context.ts
+++ b/packages/core/src/context.ts
@@ -2,7 +2,6 @@ import path from 'node:path'
import process from 'node:process'
import type { FSWatcher } from 'chokidar'
import type { Logger, ViteDevServer } from 'vite'
-import { normalizePath } from 'vite'
import { loadConfig } from 'unconfig'
import { slash } from '@antfu/utils'
import dbg from 'debug'
@@ -10,30 +9,25 @@ import { platform } from '@uni-helper/uni-env'
import type { PagesConfig } from './config/types'
import type { PageMetaDatum, PagePath, ResolvedOptions, SubPageMetaDatum, UserOptions } from './types'
import { writeDeclaration } from './declaration'
-
import {
debug,
invalidatePagesModule,
isTargetFile,
mergePageMetaDataArray,
- useCachedPages,
} from './utils'
import { resolveOptions } from './options'
import { checkPagesJsonFile, getPageFiles, writeFileSync } from './files'
-import { getRouteBlock, getRouteSfcBlock } from './customBlock'
import { OUTPUT_NAME } from './constant'
+import { Page } from './page'
let lsatPagesJson = ''
-const { setCache, hasChanged } = useCachedPages()
export class PageContext {
private _server: ViteDevServer | undefined
pagesGlobConfig: PagesConfig | undefined
pagesConfigSourcePaths: string[] = []
- pagesPath: PagePath[] = []
- subPagesPath: Record = {}
pageMetaData: PageMetaDatum[] = []
subPageMetaData: SubPageMetaDatum[] = []
@@ -46,6 +40,9 @@ export class PageContext {
withUniPlatform = false
+ pages: Page[] = []
+ subPages: Record = {}
+
constructor(userOptions: UserOptions, viteRoot: string = process.cwd()) {
this.rawOptions = userOptions
this.root = slash(viteRoot)
@@ -79,18 +76,24 @@ export class PageContext {
return { dir, files: getPagePaths(dir, this.options) }
})
- this.pagesPath = pageDirFiles.map(page => page.files).flat()
- debug.pages(this.pagesPath)
+ const paths = pageDirFiles.map(page => page.files).flat()
+ debug.pages(paths)
+
+ this.pages = paths.map(path => new Page(this, path))
}
async scanSubPages() {
- const subPagesPath: Record = {}
+ const paths: Record = {}
+ const subPages: Record = {}
for (const dir of this.options.subPackages) {
const pagePaths = getPagePaths(dir, this.options)
- subPagesPath[dir] = pagePaths
+ paths[dir] = pagePaths
+
+ subPages[dir] = pagePaths.map(path => new Page(this, path))
}
- this.subPagesPath = subPagesPath
- debug.subPages(this.subPagesPath)
+ debug.subPages(JSON.stringify(paths, null, 2))
+
+ this.subPages = subPages
}
setupViteServer(server: ViteDevServer) {
@@ -167,23 +170,6 @@ export class PageContext {
})
}
- async parsePage(page: PagePath): Promise {
- const { relativePath, absolutePath } = page
- const routeSfcBlock = await getRouteSfcBlock(absolutePath)
- const routeBlock = await getRouteBlock(absolutePath, routeSfcBlock, this.options)
- setCache(absolutePath, routeSfcBlock)
- const relativePathWithFileName = relativePath.replace(path.extname(relativePath), '')
- const pageMetaDatum: PageMetaDatum = {
- path: normalizePath(relativePathWithFileName),
- type: routeBlock?.attr.type ?? 'page',
- }
-
- if (routeBlock)
- Object.assign(pageMetaDatum, routeBlock.content)
-
- return pageMetaDatum
- }
-
/**
* parse pages rules && set page type
* @param pages page path array
@@ -191,8 +177,8 @@ export class PageContext {
* @param overrides custom page config
* @returns pages rules
*/
- async parsePages(pages: PagePath[], type: 'main' | 'sub', overrides?: PageMetaDatum[]) {
- const generatedPageMetaData = await Promise.all(pages.map(async page => await this.parsePage(page)))
+ async parsePages(pages: Page[], type: 'main' | 'sub', overrides?: PageMetaDatum[]) {
+ const generatedPageMetaData = await Promise.all(pages.map(async page => await page.getOptions()))
const customPageMetaData = overrides || []
const result = customPageMetaData.length
@@ -231,7 +217,7 @@ export class PageContext {
}
async mergePageMetaData() {
- const pageMetaData = await this.parsePages(this.pagesPath, 'main', this.pagesGlobConfig?.pages)
+ const pageMetaData = await this.parsePages(this.pages, 'main', this.pagesGlobConfig?.pages)
this.pageMetaData = pageMetaData
debug.pages(this.pageMetaData)
}
@@ -240,7 +226,7 @@ export class PageContext {
const subPageMaps: Record = {}
const subPackages = this.pagesGlobConfig?.subPackages || []
- for (const [dir, pages] of Object.entries(this.subPagesPath)) {
+ for (const [dir, pages] of Object.entries(this.subPages)) {
const root = path.basename(dir)
const globPackage = subPackages?.find(v => v.root === root)
@@ -260,9 +246,24 @@ export class PageContext {
debug.subPages(this.subPageMetaData)
}
+ private getPageByPath(absolutePath: string) {
+ const page = this.pages.find(page => page.file.absolutePath === absolutePath)
+ if (page)
+ return page
+
+ for (const pages of Object.values(this.subPages)) {
+ const subPage = pages.find(page => page.file.absolutePath === absolutePath)
+ if (subPage)
+ return subPage
+ }
+
+ return undefined
+ }
+
async updatePagesJSON(filepath?: string) {
if (filepath) {
- if (!await hasChanged(filepath)) {
+ const page = this.getPageByPath(filepath)
+ if (page && !await page.hasChanged()) {
debug.cache(`The route block on page ${filepath} did not send any changes, skipping`)
return false
}
diff --git a/packages/core/src/customBlock.ts b/packages/core/src/customBlock.ts
deleted file mode 100644
index 8df8fb9..0000000
--- a/packages/core/src/customBlock.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import fs from 'node:fs'
-import JSON5 from 'json5'
-import { parse as YAMLParser } from 'yaml'
-import { parse as VueParser } from '@vue/compiler-sfc'
-import type { SFCBlock, SFCDescriptor } from '@vue/compiler-sfc'
-import { debug } from './utils'
-import type { CustomBlock, ResolvedOptions } from './types'
-
-export async function parseSFC(code: string): Promise {
- try {
- return (
- VueParser(code, {
- pad: 'space',
- }).descriptor
- // for @vue/compiler-sfc ^2.7
- || (VueParser as any)({
- source: code,
- })
- )
- }
- catch (error) {
- throw new Error(`[vite-plugin-uni-pages] Vue3's "@vue/compiler-sfc" is required. \nOriginal error: \n${error}`)
- }
-}
-
-export function parseCustomBlock(
- block: SFCBlock,
- filePath: string,
- options: ResolvedOptions,
-): CustomBlock | undefined {
- const lang = block.lang ?? options.routeBlockLang
- const attr = {
- type: 'page',
- ...block.attrs,
- }
- let content: Record | undefined
- debug.routeBlock(`use ${lang} parser`)
-
- if (lang === 'json5' || lang === 'jsonc') {
- try {
- content = JSON5.parse(block.content)
- }
- catch (err: any) {
- throw new Error(
- `Invalid JSON5 format of <${block.type}> content in ${filePath}\n${err.message}`,
- )
- }
- }
- else if (lang === 'json') {
- try {
- content = JSON.parse(block.content)
- }
- catch (err: any) {
- throw new Error(
- `Invalid JSON format of <${block.type}> content in ${filePath}\n${err.message}`,
- )
- }
- }
- else if (lang === 'yaml' || lang === 'yml') {
- try {
- content = YAMLParser(block.content)
- }
- catch (err: any) {
- throw new Error(
- `Invalid YAML format of <${block.type}> content in ${filePath}\n${err.message}`,
- )
- }
- }
- return {
- attr,
- content: content ?? {},
- }
-}
-
-export async function getRouteSfcBlock(path: string): Promise {
- const content = fs.readFileSync(path, 'utf8')
-
- const parsedSFC = await parseSFC(content)
- const blockStr = parsedSFC?.customBlocks.find(b => b.type === 'route')
-
- return blockStr
-}
-
-export async function getRouteBlock(path: string, blockStr: SFCBlock | undefined, options: ResolvedOptions): Promise {
- if (!blockStr)
- return
- return parseCustomBlock(blockStr, path, options)
-}
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 3f2a07d..b3cf30c 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -5,14 +5,18 @@ import type { Plugin } from 'vite'
import { createLogger } from 'vite'
import MagicString from 'magic-string'
import chokidar from 'chokidar'
+import { parse as parseSFC } from '@vue/compiler-sfc'
import type { UserOptions } from './types'
import { PageContext } from './context'
import {
+ DEFINE_PAGE,
MODULE_ID_VIRTUAL,
OUTPUT_NAME,
RESOLVED_MODULE_ID_VIRTUAL,
} from './constant'
import { checkPagesJsonFile } from './files'
+import { findMacro } from './page'
+import { isTargetFile } from './utils'
export * from './config'
export * from './types'
@@ -21,7 +25,7 @@ export * from './context'
export * from './utils'
export * from './files'
export * from './options'
-export * from './customBlock'
+export * from './page'
async function restart() {
return new Promise((resolve) => {
@@ -78,19 +82,33 @@ export function VitePluginUniPages(userOptions: UserOptions = {}): Plugin {
},
// Applet do not support custom route block, so we need to remove the route block here
async transform(code: string, id: string) {
- if (!/\.n?vue$/.test(id) && !code.includes(''))
+ if (!isTargetFile(id))
return null
+
+ const { descriptor: sfc, errors } = parseSFC(code, { filename: id })
+
+ if (errors.length)
+ throw new Error(errors[0].message)
+
+ const macro = findMacro(sfc.scriptSetup)
+ const routeBlock = sfc.customBlocks.find(block => block.type === 'route')
+
+ if (!macro && !routeBlock)
+ return null
+
+ if (macro && routeBlock)
+ throw new Error(`mixed ${DEFINE_PAGE}() and is not allowed`)
+
const s = new MagicString(code)
- const routeBlockMatches = s.original.matchAll(
- /]*>([\s\S]*?)<\/route>/g,
- )
-
- for (const match of routeBlockMatches) {
- const index = match.index!
- const length = match[0].length
- s.remove(index, index + length)
+
+ if (macro) {
+ const setupOffset = sfc.scriptSetup!.loc.start.offset
+ s.remove(setupOffset + macro.start!, setupOffset + macro.end!)
}
+ if (routeBlock)
+ s.remove(routeBlock.loc.start.offset, routeBlock.loc.end.offset)
+
if (s.hasChanged()) {
return {
code: s.toString(),
diff --git a/packages/core/src/page.ts b/packages/core/src/page.ts
new file mode 100644
index 0000000..2c29c18
--- /dev/null
+++ b/packages/core/src/page.ts
@@ -0,0 +1,189 @@
+import { readFileSync } from 'node:fs'
+import { extname } from 'node:path'
+import type { SFCDescriptor, SFCScriptBlock } from '@vue/compiler-sfc'
+import { parse as VueParser } from '@vue/compiler-sfc'
+import { babelParse, isCallOf } from 'ast-kit'
+import * as t from '@babel/types'
+import generate from '@babel/generator'
+import JSON5 from 'json5'
+import { parse as YAMLParser } from 'yaml'
+import { normalizePath } from 'vite'
+import type { PageContext } from './context'
+import { debug } from './utils'
+import type { DefinePageOptions, PageMetaDatum, PagePath, RouteBlockLang } from './types'
+import { DEFINE_PAGE } from './constant'
+
+export class Page {
+ ctx: PageContext
+
+ file: PagePath
+
+ private rawOptions: string = ''
+ private options: PageMetaDatum | undefined
+
+ constructor(ctx: PageContext, file: PagePath) {
+ this.ctx = ctx
+ this.file = file
+ }
+
+ async getOptions(forceUpdate = false) {
+ if (forceUpdate || !this.options)
+ await this.readOptions()
+
+ return this.options!
+ }
+
+ async hasChanged() {
+ const { hasChanged } = await this.readOptions()
+ return hasChanged
+ }
+
+ async readOptions() {
+ try {
+ const { relativePath, absolutePath } = this.file
+
+ // eslint-disable-next-line unused-imports/no-unused-vars
+ const { path, ...others } = await readPageOptionsFromFile(absolutePath, this.ctx.options.routeBlockLang)
+ this.options = {
+ path: normalizePath(relativePath.replace(extname(relativePath), '')),
+ ...others,
+ }
+
+ const raw = (this.options ? JSON.stringify(this.options) : '')
+ const hasChanged = this.rawOptions !== raw
+ this.rawOptions = raw
+ return {
+ options: this.options,
+ hasChanged,
+ }
+ }
+ catch (err: any) {
+ throw new Error(`Read page options fail in ${this.file.relativePath}\n${err.message}`)
+ }
+ }
+}
+
+async function readPageOptionsFromFile(path: string, routeBlockLang: RouteBlockLang) {
+ const content = readFileSync(path, 'utf-8')
+ const sfc = VueParser(content).descriptor
+
+ const macroOptions = await readPageOptionsFromMacro(path, sfc)
+ if (macroOptions)
+ return macroOptions
+
+ const blockOptions = readPageOptionsFromBlock(path, routeBlockLang, sfc)
+ if (blockOptions)
+ return blockOptions
+
+ return {} as DefinePageOptions
+}
+
+async function readPageOptionsFromMacro(path: string, sfc?: SFCDescriptor) {
+ if (!sfc) {
+ const content = readFileSync(path, 'utf-8')
+ sfc = VueParser(content).descriptor
+ }
+
+ const { macro } = findMacroWithImports(sfc.scriptSetup)
+
+ if (!macro)
+ return
+
+ if (sfc?.customBlocks.find(b => b.type === 'route'))
+ throw new Error(`mixed ${DEFINE_PAGE}() and is not allowed`)
+
+ const [arg] = macro.arguments
+
+ if (!arg)
+ return
+
+ const code = generate(arg).code
+
+ const script = t.isFunctionExpression(arg) || t.isArrowFunctionExpression(arg)
+ ? `return await Promise.resolve((${code})())`
+ : `return ${code}`
+
+ const AsyncFunction = Object.getPrototypeOf(async () => { }).constructor
+
+ const fn = new AsyncFunction(script)
+
+ const options = await fn() as DefinePageOptions
+
+ return options
+}
+
+function readPageOptionsFromBlock(path: string, routeBlockLang: RouteBlockLang, sfc?: SFCDescriptor) {
+ if (!sfc) {
+ const content = readFileSync(path, 'utf-8')
+ sfc = VueParser(content).descriptor
+ }
+
+ const block = sfc.customBlocks.find(b => b.type === 'route')
+
+ if (!block)
+ return
+
+ const lang = (block.lang ?? routeBlockLang) as RouteBlockLang
+
+ debug.routeBlock(`use ${lang} parser`)
+
+ let options = {} as PageMetaDatum
+
+ if (['json5', 'jsonc', 'json'].includes(lang))
+ options = JSON5.parse(block.content) as PageMetaDatum
+ else if (['yaml', 'yml'].includes(lang))
+ options = YAMLParser(block.content) as PageMetaDatum
+
+ if (!options.type)
+ options.type = (typeof block.attrs.type === 'string') && block.attrs.type.length ? block.attrs.type : 'page'
+
+ return options
+}
+
+function findMacroWithImports(scriptSetup: SFCScriptBlock | null) {
+ const empty = { imports: [], macro: undefined }
+
+ if (!scriptSetup)
+ return empty
+
+ const parsed = babelParse(scriptSetup.content, scriptSetup.lang || 'js', {
+ plugins: [['importAttributes', { deprecatedAssertSyntax: true }]],
+ })
+
+ const stmts = parsed.body
+
+ const nodes = stmts
+ .map((raw: t.Node) => {
+ let node = raw
+ if (raw.type === 'ExpressionStatement')
+ node = raw.expression
+ return isCallOf(node, DEFINE_PAGE) ? node : undefined
+ })
+ .filter((node): node is t.CallExpression => !!node)
+
+ if (!nodes.length)
+ return empty
+
+ if (nodes.length > 1)
+ throw new Error(`duplicate ${DEFINE_PAGE}() call`)
+
+ const macro = nodes[0]
+
+ const [arg] = macro.arguments
+
+ if (arg && !t.isFunctionExpression(arg) && !t.isArrowFunctionExpression(arg) && !t.isObjectExpression(arg))
+ throw new Error(`${DEFINE_PAGE}() only accept argument in function or object`)
+
+ const imports = stmts
+ .map((node: t.Node) => (node.type === 'ImportDeclaration') ? node : undefined)
+ .filter((node): node is t.ImportDeclaration => !!node)
+
+ return {
+ imports,
+ macro,
+ }
+}
+
+export function findMacro(scriptSetup: SFCScriptBlock | null) {
+ return findMacroWithImports(scriptSetup).macro
+}
diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts
index f727612..3271803 100644
--- a/packages/core/src/types.ts
+++ b/packages/core/src/types.ts
@@ -12,6 +12,8 @@ export type debugType = keyof typeof debug
export type ConfigSource = string | LoadConfigSource | LoadConfigSource[]
+export type RouteBlockLang = 'json5' | 'jsonc' | 'json' | 'yaml' | 'yml'
+
export interface Options {
/**
@@ -68,7 +70,7 @@ export interface Options {
* Set the default route block parser, or use `` in SFC route block
* @default 'json5'
*/
- routeBlockLang: 'json5' | 'json' | 'yaml' | 'yml'
+ routeBlockLang: RouteBlockLang
/**
* minify the `pages.json`
@@ -140,3 +142,13 @@ export interface SubPageMetaDatum {
root: string
pages: PageMetaDatum[]
}
+
+export interface DefinePageOptions extends Partial {
+ /**
+ * 配置页面路径
+ * @deprecated 无效,将会根据文件路径自动生成
+ */
+ path?: string
+}
+
+export type DefinePage = (options: DefinePageOptions | (() => DefinePageOptions) | (() => Promise)) => void
diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts
index 3a5173d..11160b5 100644
--- a/packages/core/src/utils.ts
+++ b/packages/core/src/utils.ts
@@ -1,10 +1,8 @@
import Debug from 'debug'
-import { type ModuleNode, type ViteDevServer, normalizePath } from 'vite'
+import type { ModuleNode, ViteDevServer } from 'vite'
import { groupBy } from 'lodash-unified'
-import type { SFCBlock } from '@vue/compiler-sfc'
import { FILE_EXTENSIONS, RESOLVED_MODULE_ID_VIRTUAL } from './constant'
import type { PageMetaDatum } from './types'
-import { getRouteSfcBlock } from './customBlock'
export function invalidatePagesModule(server: ViteDevServer) {
const { moduleGraph } = server
@@ -56,30 +54,3 @@ export function mergePageMetaDataArray(pageMetaData: PageMetaDatum[]) {
}
return result
}
-
-export function useCachedPages() {
- const pages = new Map()
-
- function parseData(block?: SFCBlock) {
- return {
- content: block?.loc.source.trim() ?? '',
- attr: block?.attrs ?? '',
- }
- }
-
- function setCache(filePath: string, routeBlock?: SFCBlock) {
- pages.set(filePath, JSON.stringify(parseData(routeBlock)))
- }
-
- async function hasChanged(filePath: string, routeBlock?: SFCBlock) {
- if (!routeBlock)
- routeBlock = await getRouteSfcBlock(normalizePath(filePath))
-
- return !pages.has(filePath) || JSON.stringify(parseData(routeBlock)) !== pages.get(filePath)
- }
-
- return {
- setCache,
- hasChanged,
- }
-}
diff --git a/packages/playground/src/pages/macros/async-function.vue b/packages/playground/src/pages/macros/async-function.vue
new file mode 100644
index 0000000..b645698
--- /dev/null
+++ b/packages/playground/src/pages/macros/async-function.vue
@@ -0,0 +1,22 @@
+
+
+
+ test
+
diff --git a/packages/playground/src/pages/macros/function.vue b/packages/playground/src/pages/macros/function.vue
new file mode 100644
index 0000000..b701ed7
--- /dev/null
+++ b/packages/playground/src/pages/macros/function.vue
@@ -0,0 +1,21 @@
+
+
+
+ test
+
diff --git a/packages/playground/src/pages/macros/object.vue b/packages/playground/src/pages/macros/object.vue
new file mode 100644
index 0000000..4b4dab4
--- /dev/null
+++ b/packages/playground/src/pages/macros/object.vue
@@ -0,0 +1,14 @@
+
+
+
+ test
+
diff --git a/packages/playground/src/uni-pages.d.ts b/packages/playground/src/uni-pages.d.ts
index 32a1f53..328608a 100644
--- a/packages/playground/src/uni-pages.d.ts
+++ b/packages/playground/src/uni-pages.d.ts
@@ -3,7 +3,7 @@
// @ts-nocheck
// Generated by vite-plugin-uni-pages
-export interface NavigateToOptions {
+interface NavigateToOptions {
url: "/pages/index" |
"/pages/A-top" |
"/pages/i18n" |
@@ -12,13 +12,16 @@ export interface NavigateToOptions {
"/pages/test" |
"/pages/blog/index" |
"/pages/blog/post" |
+ "/pages/macros/async-function" |
+ "/pages/macros/function" |
+ "/pages/macros/object" |
"/pages-sub/index" |
"/pages-sub/about/index" |
"/pages-sub/about/your";
}
interface RedirectToOptions extends NavigateToOptions {}
-export interface SwitchTabOptions {
+interface SwitchTabOptions {
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9ec156b..459c7a0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -41,12 +41,21 @@ importers:
packages/core:
dependencies:
+ '@babel/generator':
+ specifier: ^7.24.1
+ version: 7.24.1
+ '@babel/types':
+ specifier: ^7.24.0
+ version: 7.24.0
'@uni-helper/uni-env':
specifier: ^0.1.1
version: 0.1.1(typescript@5.3.3)(vitest@1.3.1)
'@vue/compiler-sfc':
specifier: ^3.4.21
version: 3.4.21
+ ast-kit:
+ specifier: ^0.12.1
+ version: 0.12.1
chokidar:
specifier: ^3.6.0
version: 3.6.0
@@ -75,6 +84,12 @@ importers:
'@antfu/utils':
specifier: ^0.7.7
version: 0.7.7
+ '@babel/parser':
+ specifier: ^7.24.1
+ version: 7.24.1
+ '@types/babel__generator':
+ specifier: ^7.6.8
+ version: 7.6.8
'@types/debug':
specifier: ^4.1.12
version: 4.1.12
@@ -324,11 +339,11 @@ packages:
dependencies:
'@ampproject/remapping': 2.3.0
'@babel/code-frame': 7.23.5
- '@babel/generator': 7.23.6
+ '@babel/generator': 7.24.1
'@babel/helper-compilation-targets': 7.23.6
'@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
'@babel/helpers': 7.24.0
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@babel/template': 7.24.0
'@babel/traverse': 7.24.0
'@babel/types': 7.24.0
@@ -340,8 +355,8 @@ packages:
transitivePeerDependencies:
- supports-color
- /@babel/generator@7.23.6:
- resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==}
+ /@babel/generator@7.24.1:
+ resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.24.0
@@ -555,8 +570,8 @@ packages:
chalk: 2.4.2
js-tokens: 4.0.0
- /@babel/parser@7.24.0:
- resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==}
+ /@babel/parser@7.24.1:
+ resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
@@ -1469,7 +1484,7 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.23.5
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@babel/types': 7.24.0
/@babel/traverse@7.24.0:
@@ -1477,12 +1492,12 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.23.5
- '@babel/generator': 7.23.6
+ '@babel/generator': 7.24.1
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-function-name': 7.23.0
'@babel/helper-hoist-variables': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@babel/types': 7.24.0
debug: 4.3.4
globals: 11.12.0
@@ -1566,7 +1581,7 @@ packages:
'@ampproject/remapping': 2.3.0
'@babel/code-frame': 7.23.5
'@babel/core': 7.24.0
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@babel/types': 7.24.0
'@dcloudio/uni-i18n': 3.0.0-alpha-4000220240302002
'@dcloudio/uni-shared': 3.0.0-alpha-4000220240302002
@@ -1713,8 +1728,8 @@ packages:
/@dcloudio/uni-mp-compiler@3.0.0-alpha-4000220240302002(postcss@8.4.35)(rollup@3.29.4)(vue@3.4.21):
resolution: {integrity: sha512-kQ02IVWozEdA4gi0txiN0GgzBslG1f+hDeq8cehjXFb+Cpanj8l3yjaR5y2lao7iynsYc7TTMeplpxZ6DmlY6A==}
dependencies:
- '@babel/generator': 7.23.6
- '@babel/parser': 7.24.0
+ '@babel/generator': 7.24.1
+ '@babel/parser': 7.24.1
'@babel/types': 7.24.0
'@dcloudio/uni-cli-shared': 3.0.0-alpha-4000220240302002(postcss@8.4.35)(rollup@3.29.4)(vue@3.4.21)
'@dcloudio/uni-shared': 3.0.0-alpha-4000220240302002
@@ -3615,7 +3630,7 @@ packages:
/@types/babel__core@7.20.5:
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
dependencies:
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@babel/types': 7.24.0
'@types/babel__generator': 7.6.8
'@types/babel__template': 7.4.4
@@ -3631,7 +3646,7 @@ packages:
/@types/babel__template@7.4.4:
resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
dependencies:
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@babel/types': 7.24.0
dev: true
@@ -4157,14 +4172,14 @@ packages:
'@babel/core': 7.24.0
'@babel/helper-module-imports': 7.22.15
'@babel/helper-plugin-utils': 7.24.0
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@vue/compiler-sfc': 3.4.21
dev: true
/@vue/compiler-core@3.3.11:
resolution: {integrity: sha512-h97/TGWBilnLuRaj58sxNrsUU66fwdRKLOLQ9N/5iNDfp+DZhYH9Obhe0bXxhedl8fjAgpRANpiZfbgWyruQ0w==}
dependencies:
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@vue/shared': 3.3.11
estree-walker: 2.0.2
source-map-js: 1.0.2
@@ -4172,7 +4187,7 @@ packages:
/@vue/compiler-core@3.4.21:
resolution: {integrity: sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==}
dependencies:
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@vue/shared': 3.4.21
entities: 4.5.0
estree-walker: 2.0.2
@@ -4193,7 +4208,7 @@ packages:
/@vue/compiler-sfc@3.3.11:
resolution: {integrity: sha512-U4iqPlHO0KQeK1mrsxCN0vZzw43/lL8POxgpzcJweopmqtoYy9nljJzWDIQS3EfjiYhfdtdk9Gtgz7MRXnz3GA==}
dependencies:
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@vue/compiler-core': 3.3.11
'@vue/compiler-dom': 3.3.11
'@vue/compiler-ssr': 3.3.11
@@ -4207,7 +4222,7 @@ packages:
/@vue/compiler-sfc@3.4.21:
resolution: {integrity: sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==}
dependencies:
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@vue/compiler-core': 3.4.21
'@vue/compiler-dom': 3.4.21
'@vue/compiler-ssr': 3.4.21
@@ -4236,7 +4251,7 @@ packages:
/@vue/reactivity-transform@3.3.11:
resolution: {integrity: sha512-fPGjH0wqJo68A0wQ1k158utDq/cRyZNlFoxGwNScE28aUFOKFEnCBsvyD8jHn+0kd0UKVpuGuaZEQ6r9FJRqCg==}
dependencies:
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@vue/compiler-core': 3.3.11
'@vue/shared': 3.3.11
estree-walker: 2.0.2
@@ -4477,6 +4492,14 @@ packages:
/assertion-error@1.1.0:
resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
+ /ast-kit@0.12.1:
+ resolution: {integrity: sha512-O+33g7x6irsESUcd47KdfWUrS2F6aGp9KeVJFGj0YjIznfXpBxVGjA0w+y/1OKqX4mFOfmZ9Xpf1ixPT4n9xxw==}
+ engines: {node: '>=16.14.0'}
+ dependencies:
+ '@babel/parser': 7.24.1
+ pathe: 1.1.2
+ dev: false
+
/asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: true
@@ -7018,7 +7041,7 @@ packages:
engines: {node: '>=8'}
dependencies:
'@babel/core': 7.24.0
- '@babel/parser': 7.24.0
+ '@babel/parser': 7.24.1
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.2
semver: 6.3.1
@@ -7437,7 +7460,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
'@babel/core': 7.24.0
- '@babel/generator': 7.23.6
+ '@babel/generator': 7.24.1
'@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.0)
'@babel/traverse': 7.24.0
'@babel/types': 7.24.0