├── CHANGELOG.md
├── docs
├── docs
│ ├── en
│ │ ├── guide
│ │ │ ├── options
│ │ │ │ ├── _meta.json
│ │ │ │ ├── index.md
│ │ │ │ ├── generateNotFoundHtml.md
│ │ │ │ └── pages.md
│ │ │ ├── start
│ │ │ │ ├── _meta.json
│ │ │ │ ├── introduction.md
│ │ │ │ └── getting-started.md
│ │ │ └── _meta.json
│ │ ├── _meta.json
│ │ └── index.md
│ ├── zh
│ │ ├── guide
│ │ │ ├── options
│ │ │ │ ├── _meta.json
│ │ │ │ ├── index.md
│ │ │ │ ├── generateNotFoundHtml.md
│ │ │ │ └── pages.md
│ │ │ ├── start
│ │ │ │ ├── _meta.json
│ │ │ │ ├── introduction.md
│ │ │ │ └── getting-started.md
│ │ │ └── _meta.json
│ │ ├── _meta.json
│ │ └── index.md
│ └── public
│ │ ├── rspress-icon.png
│ │ └── logo.svg
├── README.md
├── package.json
├── i18n.json
├── tsconfig.json
├── biome.json
└── rspress.config.ts
├── examples
├── react-ts
│ ├── src
│ │ ├── vite-env.d.ts
│ │ ├── main.tsx
│ │ ├── App.css
│ │ ├── App.tsx
│ │ ├── index.css
│ │ └── assets
│ │ │ └── react.svg
│ ├── tsconfig.json
│ ├── vite.config.ts
│ ├── .gitignore
│ ├── index.html
│ ├── tsconfig.node.json
│ ├── package.json
│ ├── tsconfig.app.json
│ ├── eslint.config.js
│ ├── public
│ │ └── vite.svg
│ ├── README.md
│ └── pnpm-lock.yaml
└── vue-ts
│ ├── src
│ ├── vite-env.d.ts
│ ├── pages
│ │ ├── index
│ │ │ ├── main.ts
│ │ │ └── app.vue
│ │ └── index2
│ │ │ ├── main.ts
│ │ │ └── app.vue
│ ├── assets
│ │ └── vue.svg
│ ├── components
│ │ └── HelloWorld.vue
│ └── style.css
│ ├── .vscode
│ └── extensions.json
│ ├── tsconfig.json
│ ├── .gitignore
│ ├── template
│ ├── index.html
│ ├── index3.html
│ └── index2.html
│ ├── README.md
│ ├── package.json
│ ├── tsconfig.app.json
│ ├── tsconfig.node.json
│ ├── vite.config.ts
│ ├── public
│ └── vite.svg
│ └── pnpm-lock.yaml
├── src
├── types.ts
├── constants
│ └── default-template.ts
├── load-html-content.ts
└── index.ts
├── .gitignore
├── tsup.config.ts
├── tsconfig.json
├── README.md
├── package.json
└── pnpm-lock.yaml
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/docs/en/guide/options/_meta.json:
--------------------------------------------------------------------------------
1 | ["pages", "generateNotFoundHtml"]
--------------------------------------------------------------------------------
/docs/docs/en/guide/start/_meta.json:
--------------------------------------------------------------------------------
1 | ["introduction", "getting-started"]
--------------------------------------------------------------------------------
/docs/docs/zh/guide/options/_meta.json:
--------------------------------------------------------------------------------
1 | ["pages", "generateNotFoundHtml"]
--------------------------------------------------------------------------------
/docs/docs/zh/guide/start/_meta.json:
--------------------------------------------------------------------------------
1 | ["introduction", "getting-started"]
--------------------------------------------------------------------------------
/examples/react-ts/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/examples/vue-ts/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/examples/vue-ts/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["Vue.volar"]
3 | }
4 |
--------------------------------------------------------------------------------
/docs/docs/public/rspress-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/moonlitusun/vite-plugin-mpa/HEAD/docs/docs/public/rspress-icon.png
--------------------------------------------------------------------------------
/docs/docs/en/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "Guide",
4 | "link": "/guide/start/introduction",
5 | "activeMatch": "/guide/"
6 | }
7 | ]
8 |
--------------------------------------------------------------------------------
/docs/docs/zh/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "text": "Guide",
4 | "link": "/guide/start/introduction",
5 | "activeMatch": "/guide/"
6 | }
7 | ]
8 |
--------------------------------------------------------------------------------
/docs/docs/zh/guide/options/index.md:
--------------------------------------------------------------------------------
1 | # 配置选项
2 |
3 | ```ts
4 | import type { Options } from '@sunday-sky/vite-plugin-mpa';
5 | ```
6 |
7 | 你可以通过`Options`查看所有配置选项的类型定义。
8 |
--------------------------------------------------------------------------------
/examples/vue-ts/src/pages/index/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import '@/style.css'
3 | import App from './app.vue'
4 |
5 | createApp(App).mount('#app')
6 |
--------------------------------------------------------------------------------
/examples/vue-ts/src/pages/index2/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import '@/style.css'
3 | import App from './app.vue'
4 |
5 | createApp(App).mount('#app')
6 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | export interface PageInfo {
2 | title: string;
3 | entry: string;
4 | template: string;
5 | }
6 |
7 | export type Pages = Record;
8 |
--------------------------------------------------------------------------------
/examples/react-ts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | { "path": "./tsconfig.app.json" },
5 | { "path": "./tsconfig.node.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/examples/vue-ts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | { "path": "./tsconfig.app.json" },
5 | { "path": "./tsconfig.node.json" }
6 | ],
7 | }
8 |
--------------------------------------------------------------------------------
/docs/docs/en/guide/options/index.md:
--------------------------------------------------------------------------------
1 | # Configuration Options
2 |
3 | ```ts
4 | import type { Options } from '@sunday-sky/vite-plugin-mpa';
5 | ```
6 |
7 | You can see all configuration option type definitions.
8 |
--------------------------------------------------------------------------------
/examples/react-ts/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vite.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 |
4 | # Local
5 | .DS_Store
6 | *.local
7 | *.log*
8 |
9 | # Dist
10 | node_modules
11 | dist/
12 | doc_build/
13 |
14 | # IDE
15 | .vscode/*
16 | !.vscode/extensions.json
17 | .idea
18 |
--------------------------------------------------------------------------------
/src/constants/default-template.ts:
--------------------------------------------------------------------------------
1 | export const defaultTemplate = `
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | `;
12 |
--------------------------------------------------------------------------------
/docs/docs/en/guide/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "type": "dir",
4 | "name": "start",
5 | "label": "gettingStarted"
6 | },
7 | {
8 | "type": "dir",
9 | "name": "options",
10 | "label": "options"
11 | }
12 | ]
13 |
--------------------------------------------------------------------------------
/docs/docs/zh/guide/_meta.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "type": "dir",
4 | "name": "start",
5 | "label": "gettingStarted"
6 | },
7 | {
8 | "type": "dir",
9 | "name": "options",
10 | "label": "options"
11 | }
12 | ]
13 |
--------------------------------------------------------------------------------
/examples/react-ts/src/main.tsx:
--------------------------------------------------------------------------------
1 | import { StrictMode } from 'react'
2 | import { createRoot } from 'react-dom/client'
3 | import './index.css'
4 | import App from './App.tsx'
5 |
6 | createRoot(document.getElementById('root')!).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/examples/react-ts/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/examples/vue-ts/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/docs/docs/zh/guide/options/generateNotFoundHtml.md:
--------------------------------------------------------------------------------
1 | # Options.generateNotFoundHtml
2 |
3 | :::warning
4 | `仅在开发环境有效`
5 | :::
6 |
7 | - 必填:否
8 | - 类型:`(rawPages: string) => string`
9 |
10 | ## 示例:
11 |
12 | ```ts
13 | generateNotFoundHtml: (rawPages: string) => {
14 | return `
15 |
Page not found, you can go to:
16 |
17 |
`;
18 | }
19 | ```
20 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Rspress website
2 |
3 | ## Setup
4 |
5 | Install the dependencies:
6 |
7 | ```bash
8 | npm install
9 | ```
10 |
11 | ## Get started
12 |
13 | Start the dev server:
14 |
15 | ```bash
16 | npm run dev
17 | ```
18 |
19 | Build the website for production:
20 |
21 | ```bash
22 | npm run build
23 | ```
24 |
25 | Preview the production build locally:
26 |
27 | ```bash
28 | npm run preview
29 | ```
30 |
--------------------------------------------------------------------------------
/examples/react-ts/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/vue-ts/template/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Index
8 |
9 |
10 |
11 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/examples/vue-ts/template/index3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + Vue + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/vue-ts/template/index2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + Vue + TS
8 |
9 |
10 |
11 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/examples/vue-ts/README.md:
--------------------------------------------------------------------------------
1 | # Vue 3 + TypeScript + Vite
2 |
3 | This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `
4 |
5 |
6 |
14 |
15 | This is Index Page
16 |
17 |
18 |
19 |
33 |
--------------------------------------------------------------------------------
/examples/vue-ts/src/pages/index2/app.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
14 |
15 | This is Index2 Page
16 |
17 |
18 |
19 |
33 |
--------------------------------------------------------------------------------
/examples/vue-ts/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4 | "target": "ES2022",
5 | "lib": ["ES2023"],
6 | "module": "ESNext",
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "verbatimModuleSyntax": true,
13 | "moduleDetection": "force",
14 | "noEmit": true,
15 |
16 | /* Linting */
17 | "strict": true,
18 | "noUnusedLocals": true,
19 | "noUnusedParameters": true,
20 | "erasableSyntaxOnly": true,
21 | "noFallthroughCasesInSwitch": true,
22 | "noUncheckedSideEffectImports": true,
23 | "paths": {
24 | "@sunday-sky/vite-plugin-mpa": ["../../dist"]
25 | }
26 | },
27 | "include": ["vite.config.ts"]
28 | }
29 |
--------------------------------------------------------------------------------
/docs/docs/en/guide/start/introduction.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | This plugin provides true MPA functionality for Vite, eliminating various limitations of Vite MP.
4 |
5 | **No matter where your entry files/template files are located, you can access pages through the root route, making it perfect for embedded page development.**
6 |
7 | ```plaintext
8 | http://localhost:5173/index.html
9 | http://localhost:5173/about.html
10 | ...
11 | ```
12 |
13 | 🙅🏻♀️: ~~No need to search everywhere for your MPA page addresses.~~
14 |
15 | Try the [demo](https://codesandbox.io/p/devbox/2lrppj).
16 |
17 | ## Features
18 |
19 | - True **MPA**.
20 | - Load pages on demand - no matter how many pages you have, only the current page will be loaded.
21 | - Support for reusing template files.
22 | - Support for 404 pages.
23 | - Support for `vue`, `react`...and all frameworks supported by Vite.
24 |
--------------------------------------------------------------------------------
/examples/react-ts/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import reactHooks from 'eslint-plugin-react-hooks'
4 | import reactRefresh from 'eslint-plugin-react-refresh'
5 | import tseslint from 'typescript-eslint'
6 |
7 | export default tseslint.config(
8 | { ignores: ['dist'] },
9 | {
10 | extends: [js.configs.recommended, ...tseslint.configs.recommended],
11 | files: ['**/*.{ts,tsx}'],
12 | languageOptions: {
13 | ecmaVersion: 2020,
14 | globals: globals.browser,
15 | },
16 | plugins: {
17 | 'react-hooks': reactHooks,
18 | 'react-refresh': reactRefresh,
19 | },
20 | rules: {
21 | ...reactHooks.configs.recommended.rules,
22 | 'react-refresh/only-export-components': [
23 | 'warn',
24 | { allowConstantExport: true },
25 | ],
26 | },
27 | },
28 | )
29 |
--------------------------------------------------------------------------------
/examples/vue-ts/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import type { PluginOption } from 'vite';
3 | import { resolve } from 'node:path';
4 | import vue from '@vitejs/plugin-vue';
5 | import vitePluginMPA from '@sunday-sky/vite-plugin-mpa';
6 |
7 | // https://vite.dev/config/
8 | export default defineConfig({
9 | resolve: {
10 | alias: {
11 | '@': resolve(__dirname, 'src'),
12 | },
13 | },
14 | plugins: [
15 | vue(),
16 | vitePluginMPA({
17 | pages: {
18 | index: {
19 | title: 'index',
20 | entry: 'src/pages/index/main.ts',
21 | template: 'template/index.html',
22 | },
23 | index2: {
24 | title: 'index2',
25 | entry: 'src/pages/index2/main.ts',
26 | template: 'template/index2.html',
27 | },
28 | },
29 | }) as PluginOption,
30 | ],
31 | });
32 |
--------------------------------------------------------------------------------
/docs/docs/zh/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageType: home
3 |
4 | hero:
5 | name: Vite Plugin MPA
6 | text:
7 | tagline: The vite plugin for multi-page application
8 | actions:
9 | - theme: brand
10 | text: 快速开始
11 | link: /guide/start/introduction
12 | - theme: alt
13 | text: GitHub
14 | link: https://github.com/moonlitusun/vite-plugin-mpa
15 | image:
16 | src: /logo.svg
17 | alt: Logo
18 | features:
19 | - title: 真正的MPA功能
20 | details: 提供真正的MPA功能,抛去了vite MP的种种限制。
21 | icon: 🔥
22 | - title: 根路由访问
23 | details: 无论你的入口文件/模版文件在哪里,都可以通过根路由访问页面,非常适合嵌入式页面开发。
24 | icon: 🌐
25 | - title: 按需加载页面
26 | details: 无论你启动了多少个页面,只会加载当前页面,确保最佳性能。
27 | icon: 🚀
28 | - title: 模版复用
29 | details: 支持在多个页面中复用模版文件,减少重复,提高可维护性。
30 | icon: 📄
31 | - title: 404页面支持
32 | details: 为更好的用户体验,支持自定义404页面。
33 | icon: 🔍
34 | - title: 框架无关
35 | details: 支持Vue, React, 以及所有Vite支持的框架,给你完全的灵活性。
36 | icon: 🛠️
37 | ---
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Vite-plugin-mpa
2 |
3 | ## Description
4 |
5 | This plugin provides true MPA functionality for Vite, eliminating various limitations of Vite MP.
6 |
7 | **No matter where your entry files/template files are located, you can access pages through the root route, making it perfect for embedded page development.**
8 |
9 | ```plaintext
10 | http://localhost:5173/index.html
11 | http://localhost:5173/about.html
12 | ...
13 | ```
14 |
15 | 🙅🏻♀️: ~~No need to search everywhere for your MPA page addresses.~~
16 |
17 | Try the [demo](https://codesandbox.io/p/devbox/2lrppj).
18 |
19 | ## Features
20 |
21 | - True **MPA**.
22 | - Load pages on demand - no matter how many pages you have, only the current page will be loaded.
23 | - Support for reusing template files.
24 | - Support for 404 pages.
25 | - Support for `vue`, `react`...and all frameworks supported by Vite.
26 |
27 | ## Docs
28 |
29 | More docs see [vite-plugin-mpa docs](https://moonlit.vip/vite-plugin-mpa).
30 |
--------------------------------------------------------------------------------
/examples/react-ts/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import reactLogo from './assets/react.svg'
3 | import viteLogo from '/vite.svg'
4 | import './App.css'
5 |
6 | function App() {
7 | const [count, setCount] = useState(0)
8 |
9 | return (
10 | <>
11 |
19 | Vite + React
20 |
21 |
24 |
25 | Edit src/App.tsx and save to test HMR
26 |
27 |
28 |
29 | Click on the Vite and React logos to learn more
30 |
31 | >
32 | )
33 | }
34 |
35 | export default App
36 |
--------------------------------------------------------------------------------
/examples/vue-ts/src/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 | {{ msg }}
11 |
12 |
13 |
14 |
15 | Edit
16 | components/HelloWorld.vue to test HMR
17 |
18 |
19 |
20 |
21 | Check out
22 | create-vue, the official Vue + Vite starter
25 |
26 |
27 | Learn more about IDE Support for Vue in the
28 | Vue Docs Scaling up Guide.
33 |
34 | Click on the Vite and Vue logos to learn more
35 |
36 |
37 |
42 |
--------------------------------------------------------------------------------
/docs/docs/zh/guide/start/getting-started.md:
--------------------------------------------------------------------------------
1 | # 使用
2 |
3 | ## 安装
4 |
5 | ```bash
6 | # 使用pnpm
7 | pnpm add @sunday-sky/vite-plugin-mpa
8 |
9 | # 或bun
10 | bun add @sunday-sky/vite-plugin-mpa
11 |
12 | # 或npm
13 | npm install @sunday-sky/vite-plugin-mpa
14 |
15 | # 或yarn
16 | yarn add @sunday-sky/vite-plugin-mpa
17 | ```
18 |
19 | ## 配置
20 |
21 | ```ts
22 | import { defineConfig } from 'vite';
23 | import type { PluginOption } from 'vite';
24 | import vitePluginMPA from '@sunday-sky/vite-plugin-mpa';
25 |
26 | // https://vite.dev/config/
27 | export default defineConfig({
28 | // ...
29 | plugins: [
30 | // ...
31 | vitePluginMPA({
32 | // 配置你的页面
33 | pages: {
34 | index: {
35 | title: 'index',
36 | entry: 'src/pages/index/main.ts',
37 | template: 'template/index.html',
38 | },
39 | index2: {
40 | title: 'index2',
41 | entry: 'src/pages/index2/main.ts',
42 | template: 'template/index2.html',
43 | },
44 | },
45 | }) as PluginOption,
46 | ],
47 | });
48 | ```
49 |
50 | ## 使用
51 |
52 | 启动`vite serve`,访问`http://localhost:5173/index.html`,即可看到页面。
53 |
--------------------------------------------------------------------------------
/docs/docs/en/guide/start/getting-started.md:
--------------------------------------------------------------------------------
1 | # Quick Start
2 |
3 | ## Installation
4 |
5 | ```bash
6 | # Using pnpm
7 | pnpm add @sunday-sky/vite-plugin-mpa
8 |
9 | # Or bun
10 | bun add @sunday-sky/vite-plugin-mpa
11 |
12 | # Or npm
13 | npm install @sunday-sky/vite-plugin-mpa
14 |
15 | # Or yarn
16 | yarn add @sunday-sky/vite-plugin-mpa
17 | ```
18 |
19 | ## Configuration
20 |
21 | ```ts
22 | import { defineConfig } from 'vite';
23 | import type { PluginOption } from 'vite';
24 | import vitePluginMPA from '@sunday-sky/vite-plugin-mpa';
25 |
26 | // https://vite.dev/config/
27 | export default defineConfig({
28 | // ...
29 | plugins: [
30 | // ...
31 | vitePluginMPA({
32 | // Configure your pages
33 | pages: {
34 | index: {
35 | title: 'index',
36 | entry: 'src/pages/index/main.ts',
37 | template: 'template/index.html',
38 | },
39 | index2: {
40 | title: 'index2',
41 | entry: 'src/pages/index2/main.ts',
42 | template: 'template/index2.html',
43 | },
44 | },
45 | }) as PluginOption,
46 | ],
47 | });
48 | ```
49 |
50 | ## Usage
51 |
52 | Start `vite serve`, visit `http://localhost:5173/index.html`, and you'll see the page.
53 |
--------------------------------------------------------------------------------
/docs/docs/zh/guide/options/pages.md:
--------------------------------------------------------------------------------
1 | # `options.pages`
2 |
3 | 页面配置,key为页面名称,value为页面配置。
4 |
5 | - 必填:是
6 | - 类型:`Record`
7 |
8 | ## 类型定义
9 |
10 | ```ts
11 | interface PageInfo {
12 | title: string;
13 | entry: string;
14 | template: string;
15 | }
16 |
17 | type Pages = Record;
18 | ```
19 |
20 | ## 示例
21 |
22 | ```ts
23 | pages: {
24 | index: {
25 | title: 'index',
26 | entry: 'src/pages/index/main.ts',
27 | template: 'template/index.html',
28 | },
29 | index2: {
30 | title: 'index2',
31 | entry: 'src/pages/index2/main.ts',
32 | template: 'template/index2.html',
33 | },
34 | }
35 | ```
36 |
37 | ## `page.title`
38 |
39 | 这个标题会显示在浏览器标签上。
40 |
41 | - 必填:是
42 | - 类型:`string`
43 |
44 | ## `page.entry`
45 |
46 | 页面入口文件。
47 |
48 | - 必填:是
49 | - 类型:`string`
50 | - 注意:
51 |
52 | **使用相对路径**,例如:
53 |
54 | ```ts
55 | entry: 'src/pages/index/main.ts',
56 | ```
57 |
58 | ## `page.template`
59 |
60 | Page template file.
61 |
62 | - Required: No
63 | - Type: `string`
64 | - Note:
65 |
66 | :::warning
67 | **为了复用模版,所以会自动把`options[page].entry`插入到模版中,所以模版内不需要带入口文件和`title`标签**
68 | :::
69 |
70 | 一个最简单的示例文件为:
71 |
72 | ```html
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | ```
83 |
--------------------------------------------------------------------------------
/docs/rspress.config.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'node:path';
2 | import { defineConfig } from 'rspress/config';
3 |
4 | export default defineConfig({
5 | root: path.join(__dirname, 'docs'),
6 | title: 'Vite Plugin MPA',
7 | icon: '/logo.svg',
8 | base: process.env.PUBLIC_PATH || '/',
9 | lang: 'en',
10 | logo: {
11 | light: '/logo.svg',
12 | dark: '/logo.svg',
13 | },
14 | route: {
15 | cleanUrls: true,
16 | exclude: ['**/fragments/**'],
17 | },
18 | themeConfig: {
19 | socialLinks: [
20 | {
21 | icon: 'github',
22 | mode: 'link',
23 | content: 'https://github.com/moonlitusun/vite-plugin-mpa',
24 | },
25 | ],
26 | locales: [
27 | {
28 | lang: 'zh',
29 | label: '简体中文',
30 | editLink: {
31 | docRepoBaseUrl:
32 | 'https://github.com/moonlitusun/vite-plugin-mpa/tree/main/docs',
33 | text: '📝 在 GitHub 上编辑此页',
34 | },
35 | overview: {
36 | filterNameText: '过滤',
37 | filterPlaceholderText: '输入关键词',
38 | filterNoResultText: '未找到匹配的 API',
39 | },
40 | },
41 | {
42 | lang: 'en',
43 | label: 'English',
44 | editLink: {
45 | docRepoBaseUrl:
46 | 'https://github.com/moonlitusun/vite-plugin-mpa/tree/main/docs',
47 | text: '📝 Edit this page on GitHub',
48 | },
49 | },
50 | ],
51 | },
52 | });
53 |
--------------------------------------------------------------------------------
/docs/docs/en/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | pageType: home
3 |
4 | hero:
5 | name: Vite Plugin MPA
6 | text:
7 | tagline: The vite plugin for multi-page application
8 | actions:
9 | - theme: brand
10 | text: Quick Start
11 | link: /guide/start/introduction
12 | - theme: alt
13 | text: GitHub
14 | link: https://github.com/moonlitusun/vite-plugin-mpa
15 | image:
16 | src: /logo.svg
17 | alt: Logo
18 | features:
19 | - title: True MPA Functionality
20 | details: Provides true MPA functionality for Vite, eliminating various limitations of Vite MP.
21 | icon: 🔥
22 | - title: Root Route Access
23 | details: Access pages through the root route no matter where your entry/template files are located, perfect for embedded page development.
24 | icon: 🌐
25 | - title: On-demand Page Loading
26 | details: No matter how many pages you have, only the current page will be loaded, ensuring optimal performance.
27 | icon: 🚀
28 | - title: Template Reusability
29 | details: Support for reusing template files across multiple pages, reducing duplication and improving maintainability.
30 | icon: 📄
31 | - title: 404 Page Support
32 | details: Custom 404 page generation for better user experience when accessing non-existent pages.
33 | icon: 🔍
34 | - title: Framework Agnostic
35 | details: Support for Vue, React, and all frameworks supported by Vite, giving you complete flexibility.
36 | icon: 🛠️
37 | ---
38 |
--------------------------------------------------------------------------------
/examples/react-ts/src/index.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
4 | font-weight: 400;
5 |
6 | color-scheme: light dark;
7 | color: rgba(255, 255, 255, 0.87);
8 | background-color: #242424;
9 |
10 | font-synthesis: none;
11 | text-rendering: optimizeLegibility;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | }
15 |
16 | a {
17 | font-weight: 500;
18 | color: #646cff;
19 | text-decoration: inherit;
20 | }
21 | a:hover {
22 | color: #535bf2;
23 | }
24 |
25 | body {
26 | margin: 0;
27 | display: flex;
28 | place-items: center;
29 | min-width: 320px;
30 | min-height: 100vh;
31 | }
32 |
33 | h1 {
34 | font-size: 3.2em;
35 | line-height: 1.1;
36 | }
37 |
38 | button {
39 | border-radius: 8px;
40 | border: 1px solid transparent;
41 | padding: 0.6em 1.2em;
42 | font-size: 1em;
43 | font-weight: 500;
44 | font-family: inherit;
45 | background-color: #1a1a1a;
46 | cursor: pointer;
47 | transition: border-color 0.25s;
48 | }
49 | button:hover {
50 | border-color: #646cff;
51 | }
52 | button:focus,
53 | button:focus-visible {
54 | outline: 4px auto -webkit-focus-ring-color;
55 | }
56 |
57 | @media (prefers-color-scheme: light) {
58 | :root {
59 | color: #213547;
60 | background-color: #ffffff;
61 | }
62 | a:hover {
63 | color: #747bff;
64 | }
65 | button {
66 | background-color: #f9f9f9;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/examples/vue-ts/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/react-ts/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/load-html-content.ts:
--------------------------------------------------------------------------------
1 | import { readFileSync, existsSync } from 'node:fs';
2 | import { isUndefined } from 'lodash-es';
3 | import type { Pages } from '@/types';
4 | import { defaultTemplate } from '@/constants/default-template';
5 |
6 | const templateContentCache = new Map();
7 | const entryContentCache = new Map();
8 |
9 | export const loadHtmlContent = async (
10 | pageName: string,
11 | pages: Pages,
12 | { isDev = true }: { isDev?: boolean } = {}
13 | ) => {
14 | const pageEntryInfo = pages[pageName];
15 | if (!pageEntryInfo) return null;
16 |
17 | const { entry, template, title } = pageEntryInfo;
18 |
19 | if (isDev) {
20 | const entryContent = entryContentCache.get(entry);
21 | if (entryContent) return entryContent;
22 | }
23 |
24 | let htmlContent = templateContentCache.get(template);
25 | if (!htmlContent) {
26 | if (existsSync(template)) {
27 | htmlContent = readFileSync(template, 'utf-8');
28 | } else {
29 | htmlContent = defaultTemplate;
30 | }
31 | templateContentCache.set(template, htmlContent || '');
32 | }
33 |
34 | htmlContent = htmlContent.replace(
35 | '
',
36 | ``
37 | );
38 | if (!isUndefined(title)) {
39 | htmlContent = htmlContent.replace(
40 | '
`
42 | );
43 | }
44 |
45 | if (isDev) {
46 | entryContentCache.set(entry, htmlContent);
47 | }
48 |
49 | return htmlContent;
50 | };
51 |
--------------------------------------------------------------------------------
/docs/docs/public/logo.svg:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/docs/docs/en/guide/options/pages.md:
--------------------------------------------------------------------------------
1 | # `options.pages`
2 |
3 | Page configuration, where key is the page name and value is the page configuration.
4 |
5 | - Required: Yes
6 | - Type: `Record`
7 |
8 | ## Type definition
9 |
10 | ```ts
11 | interface PageInfo {
12 | title: string;
13 | entry: string;
14 | template: string;
15 | }
16 |
17 | type Pages = Record;
18 | ```
19 |
20 | ## Example
21 |
22 | ```ts
23 | pages: {
24 | index: {
25 | title: 'index',
26 | entry: 'src/pages/index/main.ts',
27 | template: 'template/index.html',
28 | },
29 | index2: {
30 | title: 'index2',
31 | entry: 'src/pages/index2/main.ts',
32 | template: 'template/index2.html',
33 | },
34 | }
35 | ```
36 |
37 | ## `page.title`
38 |
39 | This title will be displayed in the browser tab.
40 |
41 | - Required: Yes
42 | - Type: `string`
43 |
44 | ## `page.entry`
45 |
46 | Page entry file.
47 |
48 | - Required: Yes
49 | - Type: `string`
50 | - Note:
51 |
52 | **Use relative paths**, for example:
53 |
54 | ```ts
55 | entry: 'src/pages/index/main.ts',
56 | ```
57 |
58 | ## `page.template`
59 |
60 | Page template file.
61 |
62 | - Required: No
63 | - Type: `string`
64 | - Note:
65 |
66 | :::warning
67 | **To reuse templates, `page.entry` will be automatically inserted into the template, so the template doesn't need to include the entry file and `title` tag**
68 | :::
69 |
70 | A minimal example file would be:
71 |
72 | ```html
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |