Skip to content

Commit

Permalink
feat: allow enabling experimental data fetching
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Aug 2, 2022
1 parent e5583a4 commit 1b7e6b3
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 17 deletions.
4 changes: 1 addition & 3 deletions e2e/__snapshots__/routes.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// Vitest Snapshot v1

exports[`generates the routes 1`] = `
"import { _LoaderSymbol } from 'unplugin-vue-router/runtime'
export const routes = [
"export const routes = [
{
path: '/',
name: '/',
Expand Down
1 change: 1 addition & 0 deletions playground/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default defineConfig({
plugins: [
Vue({}),
VueRouter({
dataFetching: true,
routesFolder: [
// can add multiple routes folders
{
Expand Down
24 changes: 18 additions & 6 deletions src/codegen/vueRouterModule.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
// NOTE: this code needs to be generated because otherwise it doesn't go through transforms and `@vue-router/routes`

import type { ResolvedOptions } from '../options'

// cannot be resolved.
export function generateVueRouterProxy(routesModule: string) {
export function generateVueRouterProxy(
routesModule: string,
{ dataFetching }: ResolvedOptions
) {
return `
import { routes } from '${routesModule}'
import { createRouter as _createRouter } from 'vue-router'
import {
_setupDataFetchingGuard,
} from 'unplugin-vue-router/runtime'
${
dataFetching
? `import { _setupDataFetchingGuard } from 'unplugin-vue-router/runtime'`
: ``
}
export * from 'vue-router'
export {
Expand All @@ -20,9 +28,13 @@ export function createRouter(options) {
options,
{ routes: typeof extendRoutes === 'function' ? extendRoutes(routes) : routes },
))
${
dataFetching
? `
_setupDataFetchingGuard(router)
`
: ``
}
return router
}
`
Expand Down
15 changes: 9 additions & 6 deletions src/core/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ export function createRoutesContext(options: ResolvedOptions) {
// TODO: do they return the symbolic link path or the original file?
// followSymbolicLinks: false,
ignore: options.exclude,
// TODO: is this flat necessary?
})
.then((files) => files.map((file) => resolve(folder.src, file)))
.then((files) =>
Expand Down Expand Up @@ -104,7 +103,8 @@ export function createRoutesContext(options: ResolvedOptions) {
resolve(root, path)
)
node.setCustomRouteBlock(path, routeBlock)
node.value.includeLoaderGuard = await hasNamedExports(path)
node.value.includeLoaderGuard =
options.dataFetching && (await hasNamedExports(path))

routeMap.set(path, node)
}
Expand All @@ -117,7 +117,8 @@ export function createRoutesContext(options: ResolvedOptions) {
return
}
node.setCustomRouteBlock(path, await getRouteBlock(path, options))
node.value.includeLoaderGuard = await hasNamedExports(path)
node.value.includeLoaderGuard =
options.dataFetching && (await hasNamedExports(path))
}

function removePage({ filePath: path, routePath }: HandlerContext) {
Expand All @@ -144,8 +145,10 @@ export function createRoutesContext(options: ResolvedOptions) {
}

function generateRoutes() {
return `import { _LoaderSymbol } from 'unplugin-vue-router/runtime'
const imports = options.dataFetching
? `import { _LoaderSymbol } from 'unplugin-vue-router/runtime'\n\n`
: ``
return `${imports}\
export const routes = ${generateRouteRecord(routeTree)}
`
}
Expand All @@ -165,7 +168,7 @@ export const routes = ${generateRouteRecord(routeTree)}
// NOTE: this code needs to be generated because otherwise it doesn't go through transforms and `@vue-router/routes`
// cannot be resolved.
function generateVueRouterProxy() {
return _generateVueRouterProxy(MODULE_ROUTES_PATH)
return _generateVueRouterProxy(MODULE_ROUTES_PATH, options)
}

let lastDTS: string | undefined
Expand Down
11 changes: 11 additions & 0 deletions src/data-fetching/dataFetchingGuard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,18 @@ export interface DataFetchingOptions {
lazy?: boolean | number | (() => boolean | number)
}

// dev only check
let added: boolean = false

export function setupDataFetchingGuard(router: Router) {
// TODO: dev only
if (added) {
console.warn(
'[vue-router]: Data fetching guard added twice. Make sure to remove the extra call'
)
return
}
added = true
return router.beforeEach((to) => {
// We run all loaders in parallel
return (
Expand Down
5 changes: 4 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
import { DEFAULT_OPTIONS, Options, ResolvedOptions } from './options'
import { createViteContext } from './core/vite'

export { Options }

export default createUnplugin<Options>((opt, meta) => {
const options: ResolvedOptions = { ...DEFAULT_OPTIONS, ...opt }
const ctx = createRoutesContext(options)
Expand Down Expand Up @@ -99,7 +101,8 @@ export type {
RouteRecordInfo,
} from './codegen/generateRouteMap'
export type {
// TODO: mark all of these as internals since the exposed versions are user to use
// TODO: mark all of these as internals since the dynamically exposed versions are fully typed, these are just helpers
// to generate the convenient types
RouteLocationAsRelativeTyped,
RouteLocationAsRelativeTypedList,
RouteLocationAsPathTyped,
Expand Down
7 changes: 6 additions & 1 deletion src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@ export interface ResolvedOptions {
* @default "src/pages"
*/
routesFolder: RoutesFolder
// TODO: add support for multiple routes folders and prepending a path segment

/**
* Method to generate the name of a route.
*/
getRouteName: (node: TreeLeaf) => string

/**
* EXPERIMENTAL: add the data fetching meta properties to generated routes.
*/
dataFetching: boolean

// TODO:
// importMode?:
// | 'sync'
Expand Down Expand Up @@ -77,6 +81,7 @@ export const DEFAULT_OPTIONS: ResolvedOptions = {
routesFolder: 'src/pages',
routeBlockLang: 'json5',
getRouteName: getFileBasedRouteName,
dataFetching: false,
root: process.cwd(),
dts: isPackageExists('typescript'),
logs: false,
Expand Down

0 comments on commit 1b7e6b3

Please sign in to comment.