UNPKG

iles

Version:

Vite & Vue powered static site generator with partial hydration

291 lines (254 loc) 8.69 kB
import type { ResolveFn, UserConfig as ViteOptions, ConfigEnv, PluginOption as VitePluginOption } from 'vite' import type { GetModuleInfo } from 'rolldown' import type { App, Ref, DefineComponent, VNode, AsyncComponentLoader } from 'vue' import type { Plugin as VuePlugin, Options as VueOptions } from '@vitejs/plugin-vue' import type ComponentsPlugin from 'unplugin-vue-components/vite' import type { Options as ComponentOptions } from 'unplugin-vue-components/types' import type { Options as RequiredSolidOptions } from 'vite-plugin-solid' import type { Options as SvelteOptions } from '@sveltejs/vite-plugin-svelte' import type { PreactPluginOptions as PreactOptions } from '@preact/preset-vite' import type { Router, RouteRecordRaw, RouteMeta, RouterOptions as VueRouterOptions, RouteComponent, RouteRecordNormalized, RouteLocationNormalizedLoaded, RouteParams } from 'vue-router' import type { HeadClient, HeadObject } from '@unhead/vue' import type { PagesApi, PagesOptions, PageFrontmatter, PageMeta } from '@islands/pages' export type { RawPageMatter, PageFrontmatter, PageMeta } from '@islands/pages' export type { OnLoadFn } from '@islands/hydration/dist/vanilla' import type { MarkdownOptions } from '@islands/mdx' export type { ViteOptions, ConfigEnv } export type { Router, RouteRecordRaw, RouteMeta } export type { RouteLocationNormalizedLoaded } from 'vue-router' export type RouterOptions = VueRouterOptions & { base?: string } export interface PageProps extends Record<string, any> {} type SolidOptions = Partial<RequiredSolidOptions> export type { PreactOptions, SolidOptions, SvelteOptions, } interface WithFrontmatter extends PageFrontmatter, PageMeta { frontmatter: PageFrontmatter meta: PageMeta } export interface PageComponent extends RouteComponent, WithFrontmatter { layoutName: string layoutFn: false | (() => Promise<DefineComponent>) getStaticPaths?: GetStaticPaths staticPaths: Ref<StaticPath<any>[]> render?: (props?: any) => VNode<any, any, any> } export type Document<T = void> = AsyncComponentLoader<PageComponent & T> & WithFrontmatter & { component: () => Promise<PageComponent & T> } & T export interface PageData<T = PageProps> { readonly page: Ref<PageComponent> readonly route: RouteLocationNormalizedLoaded readonly props: T readonly meta: PageMeta readonly frontmatter: PageFrontmatter readonly site: UserSite } export type HeadConfig = HeadObject export interface CreateAppConfig { /** * Current router path on SSG, `undefined` on client side. */ routePath?: string /** * Props for the current page on SSG, `undefined` on client side. */ ssrProps?: any } export interface AppContext extends PageData { app: App config: AppClientConfig head: HeadClient router: Router routes: RouteRecordRaw[] } export interface StaticPath<T = Record<string, any>> { params: RouteParams props: T } export interface RouteToRender { path: string ssrProps: StaticPath['props'] outputFilename: string rendered: string } export interface GetStaticPathsArgs { route: RouteLocationNormalizedLoaded | RouteRecordNormalized } export type GetStaticPaths<T = any> = (args: GetStaticPathsArgs) => StaticPath<T>[] | Promise<StaticPath<T>[]> export type CreateAppFactory = (options?: CreateAppConfig) => Promise<AppContext> export type LayoutFactory = (name: string | false) => any export interface NamedPlugins { pages: { api: PagesApi } vue: ReturnType<typeof VuePlugin> components: ReturnType<typeof ComponentsPlugin> } export interface SSGContext { config: AppConfig pages: RouteToRender[] } export interface BaseIlesConfig extends PagesOptions { /** * Configuration options for Vite.js */ vite: ViteOptions /** * Configuration options for @vitejs/plugin-vue */ vue: VueOptions /** * Configuration options for unplugin-vue-components, which manages automatic * imports for components in Vue and MDX files. */ components: ComponentOptions /** * Configuration options for @preact/preset-vite */ preact?: boolean | PreactOptions /** * Configuration options for vite-plugin-solid */ solid?: boolean | SolidOptions /** * Configuration options for @sveltejs/vite-plugin-svelte */ svelte?: boolean | SvelteOptions /** * Configuration options for markdown processing in îles, including remark * and rehype plugins. */ markdown: MarkdownOptions /** * Options for iles build. */ ssg: { /** * This hook will be invoked before îles renders a page. * Plugins may alter the rendered HTML */ beforePageRender?: (page: RouteToRender, config: AppConfig) => RouteToRender | void | Promise<void | RouteToRender> /** * This hook will be invoked once îles has bundled client, SSR, and islands. */ onSiteBundled?: (context: SSGContext) => void | Promise<void> /** * This hook will be invoked once îles has rendered the entire site. */ onSiteRendered?: (context: SSGContext) => void | Promise<void> /** * Allows to configure how JS chunks for islands should be grouped. */ manualChunks?: (id: string, meta: { getModuleInfo: GetModuleInfo }) => string | void /** * Whether to generate a sitemap.xml and inject the meta tag referencing it. * NOTE: Must provide siteUrl to enable sitemap generation. * @default true */ sitemap?: boolean } } export interface IlesModule extends Partial<BaseIlesConfig> { name: string config?: (config: UserConfig, env: ConfigEnv) => UserConfig | null | void | Promise<UserConfig | null | void> configResolved?: (config: AppConfig, env: ConfigEnv) => void | Promise<void> } export type EnhanceAppContext = AppContext export type MDXComponents = Record<string, any> export interface UserApp { head?: HeadConfig | ((ctx: EnhanceAppContext) => HeadConfig) enhanceApp?: (ctx: EnhanceAppContext) => void | Promise<void> mdxComponents?: MDXComponents | ((ctx: EnhanceAppContext) => MDXComponents | Promise<MDXComponents>) router?: Omit<VueRouterOptions, 'history', 'routes'> socialTags?: boolean } export type UserSite = typeof import('~/site').default & { url: string canonical: string } export type IlesModuleLike = IlesModule | IlesModule[] | false | null | undefined export type IlesModuleOption = IlesModuleLike | Promise<IlesModuleLike> | string | [string, any] export interface RequiredConfig { /** * URL for site in production, used to generate absolute URLs for sitemap.xml * and social meta tags. Available as `site.url` and `site.canonical`. * @type {string} */ siteUrl: string /** * Whether to enable SPA-like navigation by avoiding full-page reloads. * @default false */ turbo: boolean /** * Whether to output more information about islands and hydration in development. * @default true */ debug: boolean | 'log' /** * Which framework to use to process `.jsx` and `.tsx` files. */ jsx?: 'vue' | 'preact' | 'solid' /** * Whether to skip `.html` in hrefs and router paths. * @default true */ prettyUrls: boolean /** * Specify the output directory (relative to project root). * @default 'dist' */ outDir: string /** * Specify the pages directory (relative to srcDir). * @default 'pages' */ pagesDir: string /** * Specify the layouts directory (relative to srcDir). * @default 'layouts' */ layoutsDir: string /** * Specify the directory where the app source is located (relative to project root). * @default 'src' */ srcDir: string tempDir: string /** * Specify the directory to nest generated assets under (relative to outDir). * @default 'assets' */ assetsDir: string } export interface UserConfig extends Partial<RequiredConfig>, Partial<IlesModule> { /** * Whether to display drafts in documents and pages. */ drafts?: boolean modules?: IlesModuleOption[] } export interface AppConfig extends RequiredConfig, Omit<BaseIlesConfig, 'pagesDir'> { base: string root: string drafts: boolean configPath: string modules: IlesModule[] namedPlugins: NamedPlugins vitePlugins: VitePluginOption[] resolvePath: ResolveFn } export type AppClientConfig = Pick<AppConfig, 'base' | 'root' | 'debug' | 'siteUrl' | 'jsx'> & { overrideElements?: MarkdownOptions['overrideElements'] sitemap?: boolean } export interface IslandDefinition { id: string script: string placeholder: string componentPath: string entryFilename?: string } export type IslandsByPath = Record<string, IslandDefinition[]> export type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T