Skip to content

Commit

Permalink
feat!: use syncIndexResolver, remove syncIndex option.
Browse files Browse the repository at this point in the history
  • Loading branch information
hannoeru committed Mar 15, 2022
1 parent 7c8f4b9 commit c0c7a67
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 57 deletions.
29 changes: 23 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,9 @@ export default {

### importMode

- **Type:** `'sync' | 'async' | (filepath: string) => 'sync' | 'async')`
- **Type:** `'sync' | 'async' | (filepath: string, pluginOptions: ResolvedOptions) => 'sync' | 'async')`
- **Default:**
- Top level index file: `'sync'`, can turn off by option `syncIndex`.
- Others(Vue): `'async'`
- Others(React): `'sync'`
- Top level index file: `'sync'`, others: `async`.

Import mode can be set to either `async`, `sync`, or a function which returns
one of those values.
Expand All @@ -268,15 +266,34 @@ can use a function to resolve the value based on the route path. For example:
export default {
plugins: [
Pages({
importMode(path) {
importMode(filepath, options) {
// default resolver
// for (const page of options.dirs) {
// if (page.baseRoute === '' && filepath.startsWith(`/${page.dir}/index`))
// return 'sync'
// }
// return 'async'

// Load about page synchronously, all other pages are async.
return path.includes('about') ? 'sync' : 'async'
return filepath.includes('about') ? 'sync' : 'async'
},
}),
],
}
```

If you are using `async` mode with `react-router`, you will need to wrap your route components with `Suspense`:
```tsx
const App = () => {
return (
// eslint-disable-next-line react/jsx-no-undef
<Suspense fallback={<p>Loading...</p>}>
{useRoutes(routes)}
</Suspense>
)
}
```

### routeBlockLang

- **Type:** `string`
Expand Down
8 changes: 6 additions & 2 deletions examples/react/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { Suspense } from 'react'
import ReactDOM from 'react-dom'
import {
BrowserRouter as Router,
Expand All @@ -13,7 +13,11 @@ import routes from '~react-pages'
console.log(routes)

function App() {
return useRoutes(routes)
return (
<Suspense fallback={<p>Loading...</p>}>
{useRoutes(routes)}
</Suspense>
)
}

ReactDOM.render(
Expand Down
4 changes: 3 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ function pagesPlugin(userOptions: UserOptions = {}): Plugin {
}

export * from './types'
export {
export type {
VueRoute,
ReactRoute,
SolidRoute,
} from './resolvers'

export { syncIndexResolver } from './options'
export { PageContext }
export default pagesPlugin
30 changes: 24 additions & 6 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { resolve } from 'path'
import { slash, toArray } from '@antfu/utils'
import { getPageDirs } from './files'

import type { ResolvedOptions, UserOptions } from './types'
import type { ImportModeResolver, ResolvedOptions, UserOptions } from './types'

function resolvePageDirs(dirs: UserOptions['dirs'], root: string, exclude: string[]) {
dirs = toArray(dirs)
Expand All @@ -18,25 +18,44 @@ function resolvePageDirs(dirs: UserOptions['dirs'], root: string, exclude: strin
})
}

export const syncIndexResolver: ImportModeResolver = (filepath, options) => {
for (const page of options.dirs) {
if (page.baseRoute === '' && filepath.startsWith(`/${page.dir}/index`))
return 'sync'
}
return 'async'
}

const getExtensions = (resolver: ResolvedOptions['resolver']) => {
switch (resolver) {
case 'vue':
return ['vue', 'ts', 'js']
case 'react':
case 'solid':
return ['tsx', 'jsx', 'ts', 'js']
default:
throw new Error(`Unsupported resolver: ${resolver}`)
}
}

export function resolveOptions(userOptions: UserOptions, viteRoot?: string): ResolvedOptions {
const {
dirs = userOptions.pagesDir || ['src/pages'],
routeBlockLang = 'json5',
exclude = [],
syncIndex = true,
caseSensitive = false,
resolver = 'vue',
syncIndex = true,
extendRoute,
onRoutesGenerated,
onClientGenerated,
} = userOptions

const root = viteRoot || slash(process.cwd())

// TODO: default import mode for solid
const importMode = userOptions.importMode || (resolver === 'react' ? 'sync' : 'async')
const importMode = userOptions.importMode || (syncIndex ? syncIndexResolver : 'async')

const extensions = userOptions.extensions || (resolver === 'react' ? ['tsx', 'jsx'] : resolver === 'solid' ? ['tsx', 'jsx', 'ts', 'js'] : ['vue', 'ts', 'js'])
const extensions = userOptions.extensions || getExtensions(resolver)

const extensionsRE = new RegExp(`\\.(${extensions.join('|')})$`)

Expand All @@ -52,7 +71,6 @@ export function resolveOptions(userOptions: UserOptions, viteRoot?: string): Res
extensions,
importMode,
exclude,
syncIndex,
caseSensitive,
resolver,
extensionsRE,
Expand Down
1 change: 0 additions & 1 deletion src/stringify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export function stringifyRoutes(

if (options.resolver === 'react')
return str.replace(replaceStr, `React.createElement(${importName})`)
// TODO: solid sync case
else
return str.replace(replaceStr, importName)
} else {
Expand Down
9 changes: 5 additions & 4 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Awaitable } from '@antfu/utils'
export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>

export type ImportMode = 'sync' | 'async'
export type ImportModeResolveFn = (filepath: string) => ImportMode
export type ImportModeResolver = (filepath: string, pluginOptions: ResolvedOptions) => ImportMode

export type CustomBlock = Record<string, any>

Expand Down Expand Up @@ -34,12 +34,13 @@ interface Options {
exclude: string[]
/**
* Import routes directly or as async components
* @default 'async'
* @default 'root index file => "sync", others => "async"'
*/
importMode: ImportMode | ImportModeResolveFn
importMode: ImportMode | ImportModeResolver
/**
* Sync load top level index file
* @default true
* @deprecated use `importMode` instead
*/
syncIndex: boolean
/**
Expand Down Expand Up @@ -95,7 +96,7 @@ interface Options {

export type UserOptions = Partial<Options>

export interface ResolvedOptions extends Omit<Options, 'pagesDir' | 'replaceSquareBrackets' | 'nuxtStyle'> {
export interface ResolvedOptions extends Omit<Options, 'pagesDir' | 'replaceSquareBrackets' | 'nuxtStyle' | 'syncIndex'> {
/**
* Resolves to the `root` value from Vite config.
* @default config.root
Expand Down
11 changes: 1 addition & 10 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,7 @@ export function resolveImportMode(
) {
const mode = options.importMode
if (typeof mode === 'function')
return mode(filepath)

for (const page of options.dirs) {
if (
options.syncIndex
&& page.baseRoute === ''
&& filepath === `/${page.dir}/index.vue`
)
return 'sync'
}
return mode(filepath, options)
return mode
}

Expand Down
34 changes: 7 additions & 27 deletions test/__snapshots__/generate.spec.ts.snap

Large diffs are not rendered by default.

0 comments on commit c0c7a67

Please sign in to comment.