Skip to content

Commit b94b163

Browse files
committed
feat: map mode + remove deprecated options
1 parent 71f4241 commit b94b163

File tree

4 files changed

+63
-49
lines changed

4 files changed

+63
-49
lines changed

src/node/build/build.ts

+16-6
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,22 @@ import { renderPage } from './render'
66
import { OutputChunk, OutputAsset } from 'rollup'
77
import ora from 'ora'
88

9-
export async function build(root: string, buildOptions: BuildOptions = {}) {
9+
export async function build(
10+
root: string,
11+
buildOptions: BuildOptions & { mpa?: string } = {}
12+
) {
1013
const start = Date.now()
1114

1215
process.env.NODE_ENV = 'production'
1316
const siteConfig = await resolveConfig(root)
1417

18+
if (buildOptions.mpa) {
19+
siteConfig.mpa = true
20+
delete buildOptions.mpa
21+
}
22+
1523
try {
16-
const [clientResult, , pageToHashMap] = await bundle(
24+
const [clientResult, serverResult, pageToHashMap] = await bundle(
1725
siteConfig,
1826
buildOptions
1927
)
@@ -22,11 +30,13 @@ export async function build(root: string, buildOptions: BuildOptions = {}) {
2230
spinner.start('rendering pages...')
2331

2432
try {
25-
const appChunk = clientResult.output.find(
26-
(chunk) => chunk.type === 'chunk' && chunk.isEntry
27-
) as OutputChunk
33+
const appChunk =
34+
clientResult &&
35+
(clientResult.output.find(
36+
(chunk) => chunk.type === 'chunk' && chunk.isEntry
37+
) as OutputChunk)
2838

29-
const cssChunk = clientResult.output.find(
39+
const cssChunk = (clientResult || serverResult).output.find(
3040
(chunk) => chunk.type === 'asset' && chunk.fileName.endsWith('.css')
3141
) as OutputAsset
3242

src/node/build/bundle.ts

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import ora from 'ora'
22
import path from 'path'
3+
import fs from 'fs-extra'
34
import { slash } from '../utils/slash'
45
import { APP_PATH } from '../alias'
56
import { SiteConfig } from '../config'
@@ -71,7 +72,8 @@ export async function bundle(
7172
})
7273
}
7374
},
74-
minify: ssr ? false : !process.env.DEBUG
75+
// minify with esbuild in MPA mode (for CSS)
76+
minify: ssr ? (config.mpa ? 'esbuild' : false) : !process.env.DEBUG
7577
}
7678
})
7779

@@ -82,7 +84,7 @@ export async function bundle(
8284
spinner.start('building client + server bundles...')
8385
try {
8486
;[clientResult, serverResult] = await (Promise.all([
85-
build(resolveViteConfig(false)),
87+
config.mpa ? null : build(resolveViteConfig(false)),
8688
build(resolveViteConfig(true))
8789
]) as Promise<[RollupOutput, RollupOutput]>)
8890
} catch (e) {
@@ -95,6 +97,23 @@ export async function bundle(
9597
symbol: okMark
9698
})
9799

100+
if (config.mpa) {
101+
// in MPA mode, we need to copy over the non-js asset files from the
102+
// server build since there is no client-side build.
103+
for (const chunk of serverResult.output) {
104+
if (!chunk.fileName.endsWith('.js')) {
105+
const tempPath = path.resolve(config.tempDir, chunk.fileName)
106+
const outPath = path.resolve(config.outDir, chunk.fileName)
107+
await fs.copy(tempPath, outPath)
108+
}
109+
}
110+
// also copy over public dir
111+
const publicDir = path.resolve(config.srcDir, 'public')
112+
if (fs.existsSync(publicDir)) {
113+
await fs.copy(publicDir, config.outDir)
114+
}
115+
}
116+
98117
return [clientResult, serverResult, pageToHashMap]
99118
}
100119

src/node/build/render.ts

+20-17
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,20 @@ export async function renderPage(
3939
))
4040
const pageData = JSON.parse(__pageData)
4141

42-
const preloadLinks = [
43-
// resolve imports for index.js + page.md.js and inject script tags for
44-
// them as well so we fetch everything as early as possible without having
45-
// to wait for entry chunks to parse
46-
...resolvePageImports(config, page, result, appChunk),
47-
pageClientJsFileName,
48-
appChunk.fileName
49-
]
50-
.map((file) => {
51-
return `<link rel="modulepreload" href="${siteData.base}${file}">`
52-
})
53-
.join('\n ')
42+
const preloadLinks = config.mpa
43+
? ''
44+
: [
45+
// resolve imports for index.js + page.md.js and inject script tags for
46+
// them as well so we fetch everything as early as possible without having
47+
// to wait for entry chunks to parse
48+
...resolvePageImports(config, page, result, appChunk),
49+
pageClientJsFileName,
50+
appChunk.fileName
51+
]
52+
.map((file) => {
53+
return `<link rel="modulepreload" href="${siteData.base}${file}">`
54+
})
55+
.join('\n ')
5456

5557
const stylesheetLink = cssChunk
5658
? `<link rel="stylesheet" href="${siteData.base}${cssChunk.fileName}">`
@@ -83,11 +85,12 @@ export async function renderPage(
8385
</head>
8486
<body>
8587
<div id="app">${content}</div>
86-
<script>__VP_HASH_MAP__ = JSON.parse(${hashMapString})</script>
87-
<script type="module" async src="${siteData.base}${
88-
appChunk.fileName
89-
}"></script>
90-
</body>
88+
${
89+
config.mpa
90+
? ``
91+
: `<script>__VP_HASH_MAP__ = JSON.parse(${hashMapString})</script>` +
92+
`<script type="module" async src="${siteData.base}${appChunk.fileName}"></script>`
93+
}</body>
9194
</html>`.trim()
9295
const htmlFileName = path.join(config.outDir, page.replace(/\.md$/, '.html'))
9396
await fs.ensureDir(path.dirname(htmlFileName))

src/node/config.ts

+6-24
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export { resolveSiteDataByRoute } from './shared'
2222
const debug = require('debug')('vitepress:config')
2323

2424
export interface UserConfig<ThemeConfig = any> {
25+
extends?: RawConfigExports
2526
lang?: string
2627
base?: string
2728
title?: string
@@ -43,15 +44,9 @@ export interface UserConfig<ThemeConfig = any> {
4344
srcExclude?: string[]
4445

4546
/**
46-
* @deprecated use `srcExclude` instead
47-
*/
48-
exclude?: string[]
49-
/**
50-
* @deprecated use `vue` instead
47+
* Enable MPA / zero-JS mode
5148
*/
52-
vueOptions?: VuePluginOptions
53-
54-
extends?: RawConfigExports
49+
mpa?: boolean
5550
}
5651

5752
type RawConfigExports =
@@ -72,6 +67,7 @@ export interface SiteConfig<ThemeConfig = any> {
7267
markdown: MarkdownOptions | undefined
7368
vue: VuePluginOptions | undefined
7469
vite: ViteConfig | undefined
70+
mpa: boolean
7571
}
7672

7773
const resolve = (root: string, file: string) =>
@@ -81,22 +77,7 @@ export async function resolveConfig(
8177
root: string = process.cwd()
8278
): Promise<SiteConfig> {
8379
const userConfig = await resolveUserConfig(root)
84-
85-
if (userConfig.vueOptions) {
86-
console.warn(
87-
chalk.yellow(`[vitepress] "vueOptions" option has been renamed to "vue".`)
88-
)
89-
}
90-
if (userConfig.exclude) {
91-
console.warn(
92-
chalk.yellow(
93-
`[vitepress] "exclude" option has been renamed to "ssrExclude".`
94-
)
95-
)
96-
}
97-
9880
const site = await resolveSiteData(root, userConfig)
99-
10081
const srcDir = path.resolve(root, userConfig.srcDir || '.')
10182

10283
// resolve theme path
@@ -120,7 +101,8 @@ export async function resolveConfig(
120101
markdown: userConfig.markdown,
121102
alias: resolveAliases(themeDir),
122103
vue: userConfig.vue,
123-
vite: userConfig.vite
104+
vite: userConfig.vite,
105+
mpa: !!userConfig.mpa
124106
}
125107

126108
return config

0 commit comments

Comments
 (0)