import { ViteDevServer, FilterPattern, IndexHtmlTransformContext, IndexHtmlTransformResult, Plugin } from 'vite'; import { Rewrite } from 'connect-history-api-fallback'; import { Options } from 'html-minifier-terser'; type AllowedEvent = 'add' | 'unlink' | 'change' | 'unlinkDir' | 'addDir'; /** * Ensure string follow the extension convention */ type ExtStr = T extends `/${infer P}` ? ExtStr : T extends `${infer Q}.${E}` ? ExtStr : `${T}.${E}`; type FileStr = ExtStr<'html', T>; type TplStr = ExtStr<'ejs' | 'html', T>; interface Page { /** * Required. Name is used to generate default rewrite rules, it just a common string and please don't include '/'. * You can use filename option not name option if you want to customize the path of generated files. */ name: Name extends `${string}/${string}` ? never : Name; /** * Relative path to the output directory, which should end with .html and not startWith '/' * @default `${name}.html` */ filename?: FileStr; /** * **Higher priority template file**, which will overwrite the default template. */ template?: TplStr; /** * Entry file that will append to body, which you should remove from the EJS template file. * It must always start with `'/'` which represents your project root directory. */ entry?: `/${string}`; /** * Data to inject with ejs. */ data?: Record; } type WatchHandler = (ctx: { server: ViteDevServer; file: string; type: Event; /** * You can update the pages configuration by calling this function. * @params pages Your MPA core configurations, which will replace default `pages` config */ reloadPages: (pages: Page[]) => void; }) => void; interface WatchOptions { /** * Specifies the files to **include**, based on `Rollup.createFilter` * @see https://vitejs.dev/guide/api-plugin.html#filtering-include-exclude-pattern */ include?: Exclude; /** * Specifies the files to **exclude**, based on `Rollup.createFilter` * @see https://vitejs.dev/guide/api-plugin.html#filtering-include-exclude-pattern */ excluded?: Exclude; /** * File events you wanna deal with. * @default ['add', 'unlink', 'change', 'unlinkDir', 'addDir'] */ events?: Event[]; /** * Execute your own logic when file events fired. */ handler: WatchHandler; } interface ScanOptions { /** * Directory path to scan, subdirectory's name will be used as unique page name. */ scanDirs: string | string[]; /** * Customize the **entry file** path relative to the scanned dir. * It doesn't effect when the file specified doesn't exist. */ entryFile?: string; /** * Customize the **virtual file** name(output filename). * @param name Subdirectory name */ filename?: (name: string) => string; /** * Customize the **template file** path relative to the scanned dir. * It doesn't effect when the file specified doesn't exist. */ template?: string; } type RewriteRule = false | Rewrite[]; interface MpaOptions { /** * Whether to print log. * @default true */ verbose?: boolean; /** * Default template file. * @default index.html */ template?: TplStr; /** * Configure your dev server's rewrite rules, only proceed fallback html requests. * @see https://github.com/bripkens/connect-history-api-fallback */ rewrites?: RewriteRule; /** * Configure your preview server's rewrite rules. * @see https://github.com/bripkens/connect-history-api-fallback */ previewRewrites?: RewriteRule; /** * Sometimes you might want to reload `pages` config or restart ViteDevServer when * there are some files added, removed, changed and so on. You can set `watchOptions` to * customize your own logic. */ watchOptions?: WatchHandler | WatchOptions; /** * Your MPA core configurations, you can write directly or use `createPages` function independently outside and then pass it to this field. */ pages?: Page[]; /** * Use to scan directories that have similar structure to generate pages. * Detected pages will be appended to `pages` option, page with name existed will be ignored. */ scanOptions?: ScanOptions; /** * Dedicated hook for transforming template HTML, inherit from `transformIndexHtml`. * @see https://vitejs.dev/guide/api-plugin#transformindexhtml */ transformHtml?: (html: string, ctx: IndexHtmlTransformContext & { page: Page; }) => IndexHtmlTransformResult; /** * Whether to minify html file. Powered by [html-minify-terser](https://github.com/terser/html-minifier-terser). * @default false */ htmlMinify?: Options | boolean; } /** * This function simply converts the arguments to an array and returns them. * It helps creating pages configuration with type hints independently outside plugin function. */ declare function createPages(pages: Page | Page[]): Page[]; declare function createMpaPlugin(config: MpaOptions): Plugin[]; export { type AllowedEvent, type ExtStr, type FileStr, type MpaOptions, type Page, type RewriteRule, type ScanOptions, type TplStr, type WatchHandler, type WatchOptions, createMpaPlugin, createPages };