Skip to content

Commit

Permalink
feat: support multiple instances
Browse files Browse the repository at this point in the history
closes #83
  • Loading branch information
hannoeru committed Apr 5, 2022
1 parent c6e41b4 commit 54e0b9f
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 8 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ export default {
- **Type:** `string[]`
- **Default:**
- Vue: `['vue', 'ts', 'js']`
- React: `['tsx', 'jsx']`
- React: `['tsx', 'jsx', 'ts', 'js']`
- Solid: `['tsx', 'jsx', 'ts', 'js']`

An array of valid file extensions for pages.
Expand Down Expand Up @@ -324,6 +324,16 @@ Use file system dynamic routing supporting:

Route resolver, support `vue`, `react`, `solid` or custom `PageResolver`.

### moduleId

- **Type:** `string`
- **Default:**
- Vue: `'~pages'`
- React: `'~react-pages'`
- Solid: `'~solid-pages'`

Module id for routes import, useful when you what to use multiple pages plugin in one project.

### extendRoute

- **Type:**
Expand Down
14 changes: 10 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { MODULE_IDS, MODULE_ID_VIRTUAL, ROUTE_BLOCK_ID_VIRTUAL, routeBlockQueryRE } from './constants'
import { MODULE_ID_VIRTUAL, ROUTE_BLOCK_ID_VIRTUAL, routeBlockQueryRE } from './constants'
import { PageContext } from './context'

import { parsePageRequest } from './utils'
import type { UserOptions } from './types'
import type { Plugin } from 'vite'

Expand Down Expand Up @@ -33,16 +34,21 @@ function pagesPlugin(userOptions: UserOptions = {}): Plugin {
ctx.setupViteServer(server)
},
resolveId(id) {
if (MODULE_IDS.includes(id))
return MODULE_ID_VIRTUAL
if (ctx.options.moduleIds.includes(id))
return `${MODULE_ID_VIRTUAL}?id=${id}`

if (routeBlockQueryRE.test(id))
return ROUTE_BLOCK_ID_VIRTUAL

return null
},
async load(id) {
if (id === MODULE_ID_VIRTUAL)
const {
moduleId,
pageId,
} = parsePageRequest(id)

if (moduleId === MODULE_ID_VIRTUAL && pageId && ctx.options.moduleIds.includes(pageId))
return ctx.resolveRoutes()

if (id === ROUTE_BLOCK_ID_VIRTUAL) {
Expand Down
6 changes: 6 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { slash, toArray } from '@antfu/utils'
import { getPageDirs } from './files'

import { ReactResolver, SolidResolver, VueResolver } from './resolvers'
import { MODULE_IDS } from './constants'
import type { ImportModeResolver, ResolvedOptions, UserOptions } from './types'

function resolvePageDirs(dirs: UserOptions['dirs'], root: string, exclude: string[]) {
Expand Down Expand Up @@ -75,10 +76,15 @@ export function resolveOptions(userOptions: UserOptions, viteRoot?: string): Res

const routeStyle = userOptions.nuxtStyle ? 'nuxt' : userOptions.routeStyle || 'next'

const moduleIds = userOptions.moduleId
? [userOptions.moduleId]
: resolver.resolveModuleIds?.() || MODULE_IDS

const resolvedOptions: ResolvedOptions = {
dirs: resolvedDirs,
routeStyle,
routeBlockLang,
moduleIds,
root,
extensions,
importMode,
Expand Down
3 changes: 3 additions & 0 deletions src/resolvers/react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ async function resolveReactRoutes(ctx: PageContext) {

export function ReactResolver(): PageResolver {
return {
resolveModuleIds() {
return ['~react-pages', 'virtual:generated-pages-react']
},
resolveExtensions() {
return ['tsx', 'jsx', 'ts', 'js']
},
Expand Down
3 changes: 3 additions & 0 deletions src/resolvers/solid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ async function resolveSolidRoutes(ctx: PageContext) {

export function SolidResolver(): PageResolver {
return {
resolveModuleIds() {
return ['~solid-pages']
},
resolveExtensions() {
return ['tsx', 'jsx', 'ts', 'js']
},
Expand Down
3 changes: 3 additions & 0 deletions src/resolvers/vue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ export function VueResolver(): PageResolver {
resolveExtensions() {
return ['vue', 'ts', 'js']
},
resolveModuleIds() {
return ['~pages', 'pages-generated', 'virtual:generated-pages']
},
async resolveRoutes(ctx) {
return await resolveVueRoutes(ctx, customBlockMap)
},
Expand Down
16 changes: 13 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface PageOptions {
}

export interface PageResolver {
resolveModuleIds: () => string[]
resolveExtensions: () => string[]
resolveRoutes: (ctx: PageContext) => Awaitable<string>
stringify?: {
Expand Down Expand Up @@ -66,12 +67,12 @@ interface Options {
*/
nuxtStyle: boolean
/**
* Use routing style
* Routing style
* @default false
*/
routeStyle: 'next' | 'nuxt' | 'remix'
/**
* Use case for route paths
* Case for route paths
* @default false
*/
caseSensitive: boolean
Expand All @@ -80,6 +81,11 @@ interface Options {
* @default 'json5'
*/
routeBlockLang: 'json5' | 'json' | 'yaml' | 'yml'
/**
* Module id for routes import
* @default '~pages'
*/
moduleId: string
/**
* Generate React Route
* @default 'auto detect'
Expand Down Expand Up @@ -112,7 +118,7 @@ interface Options {

export type UserOptions = Partial<Options>

export interface ResolvedOptions extends Omit<Options, 'pagesDir' | 'replaceSquareBrackets' | 'nuxtStyle' | 'syncIndex'> {
export interface ResolvedOptions extends Omit<Options, 'pagesDir' | 'replaceSquareBrackets' | 'nuxtStyle' | 'syncIndex' | 'moduleId'> {
/**
* Resolves to the `root` value from Vite config.
* @default config.root
Expand All @@ -130,4 +136,8 @@ export interface ResolvedOptions extends Omit<Options, 'pagesDir' | 'replaceSqua
* RegExp to match extensions
*/
extensionsRE: RegExp
/**
* Module IDs for routes import
*/
moduleIds: string[]
}
12 changes: 12 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { resolve, win32 } from 'path'
import { URLSearchParams } from 'url'
import Debug from 'debug'
import { slash } from '@antfu/utils'
import { MODULE_ID_VIRTUAL, cacheAllRouteRE, countSlashRE, dynamicRouteRE, nuxtCacheAllRouteRE, nuxtDynamicRouteRE, replaceDynamicRouteRE, replaceIndexRE } from './constants'
Expand Down Expand Up @@ -175,3 +176,14 @@ export function buildReactRemixRoutePath(node: string): string | undefined {

return result || undefined
}

export function parsePageRequest(id: string) {
const [moduleId, rawQuery] = id.split('?', 2)
const query = new URLSearchParams(rawQuery)
const pageId = query.get('id')
return {
moduleId,
query,
pageId,
}
}
54 changes: 54 additions & 0 deletions test/__snapshots__/options.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ exports[`Options resolve > react 1`] = `
],
"extensionsRE": /\\\\\\.\\(tsx\\|jsx\\|ts\\|js\\)\\$/,
"importMode": [Function],
"moduleIds": [
"~react-pages",
"virtual:generated-pages-react",
],
"onClientGenerated": undefined,
"onRoutesGenerated": undefined,
"resolver": {
"resolveExtensions": [Function],
"resolveModuleIds": [Function],
"resolveRoutes": [Function],
"stringify": {
"component": [Function],
Expand Down Expand Up @@ -55,10 +60,14 @@ exports[`Options resolve > solid 1`] = `
],
"extensionsRE": /\\\\\\.\\(tsx\\|jsx\\|ts\\|js\\)\\$/,
"importMode": [Function],
"moduleIds": [
"~solid-pages",
],
"onClientGenerated": undefined,
"onRoutesGenerated": undefined,
"resolver": {
"resolveExtensions": [Function],
"resolveModuleIds": [Function],
"resolveRoutes": [Function],
"stringify": {
"dynamicImport": [Function],
Expand All @@ -71,6 +80,45 @@ exports[`Options resolve > solid 1`] = `
}
`;
exports[`Options resolve > vue - custom module id 1`] = `
{
"caseSensitive": false,
"dirs": [
{
"baseRoute": "",
"dir": "examples/vue/src/pages",
},
],
"exclude": [],
"extendRoute": undefined,
"extensions": [
"vue",
"ts",
"js",
],
"extensionsRE": /\\\\\\.\\(vue\\|ts\\|js\\)\\$/,
"importMode": [Function],
"moduleIds": [
"~vue-pages",
],
"onClientGenerated": undefined,
"onRoutesGenerated": undefined,
"resolver": {
"hmr": {
"added": [Function],
"changed": [Function],
"removed": [Function],
},
"resolveExtensions": [Function],
"resolveModuleIds": [Function],
"resolveRoutes": [Function],
},
"root": Any<String>,
"routeBlockLang": "json5",
"routeStyle": "next",
}
`;
exports[`Options resolve > vue 1`] = `
{
"caseSensitive": false,
Expand All @@ -89,6 +137,11 @@ exports[`Options resolve > vue 1`] = `
],
"extensionsRE": /\\\\\\.\\(vue\\|ts\\|js\\)\\$/,
"importMode": [Function],
"moduleIds": [
"~pages",
"pages-generated",
"virtual:generated-pages",
],
"onClientGenerated": undefined,
"onRoutesGenerated": undefined,
"resolver": {
Expand All @@ -98,6 +151,7 @@ exports[`Options resolve > vue 1`] = `
"removed": [Function],
},
"resolveExtensions": [Function],
"resolveModuleIds": [Function],
"resolveRoutes": [Function],
},
"root": Any<String>,
Expand Down
10 changes: 10 additions & 0 deletions test/options.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ describe('Options resolve', () => {
})
})

test('vue - custom module id', () => {
const options = resolveOptions({
dirs: 'examples/vue/src/pages',
moduleId: '~vue-pages',
})
expect(options).toMatchSnapshot({
root: expect.any(String),
})
})

test('react', () => {
const options = resolveOptions({
dirs: 'examples/react/src/pages',
Expand Down

0 comments on commit 54e0b9f

Please sign in to comment.