pull/869/head
Georges Gomes 3 years ago
parent a689f6b6d3
commit 2e4a33eb82

@ -6,6 +6,7 @@ export default defineConfig({
description: 'Vite & Vue powered static site generator.',
lastUpdated: true,
cleanUrls: true,
themeConfig: {
nav: nav(),

@ -42,9 +42,14 @@ export function createRouter(
function go(href: string = inBrowser ? location.href : '/') {
// ensure correct deep link so page refresh lands on correct files.
const url = new URL(href, fakeHost)
if (!url.pathname.endsWith('/') && !url.pathname.endsWith('.html')) {
url.pathname += '.html'
href = url.pathname + url.search + url.hash
// ensure correct deep link so page refresh lands on correct files.
if (siteDataRef.value.cleanUrls) {
// Should we replace `/foo.html` -> `/foo` ? :thinking:
} else {
if (!url.pathname.endsWith('/') && !url.pathname.endsWith('.html')) {
url.pathname += '.html'
href = url.pathname + url.search + url.hash
}
}
if (inBrowser) {
// save scroll position before changing url
@ -101,7 +106,12 @@ export function createRouter(
}
}
} catch (err: any) {
if (!err.message.match(/fetch/) && !href.match(/^[\\/]404\.html$/)) {
if (
!err.message.match(/fetch/) &&
(siteDataRef.value.cleanUrls
? !href.match(/^[\\/]404$/)
: !href.match(/^[\\/]404\.html$/))
) {
console.error(err)
}

@ -165,11 +165,22 @@ export async function renderPage(
${inlinedScript}
</body>
</html>`.trim()
const htmlFileName = path.join(config.outDir, page.replace(/\.md$/, '.html'))
const htmlFileName = path.join(
config.outDir,
transformHTMLFileName(page, config.cleanUrls)
)
await fs.ensureDir(path.dirname(htmlFileName))
await fs.writeFile(htmlFileName, html)
}
function transformHTMLFileName(page: string, shouldCleanUrls: boolean): string {
if (page === 'index.md' || page.endsWith('/index.md') || page === '404.md') {
return page.replace(/\.md$/, '.html')
}
return page.replace(/\.md$/, shouldCleanUrls ? '/index.html' : '.html')
}
function resolvePageImports(
config: SiteConfig,
page: string,

@ -71,6 +71,14 @@ export interface UserConfig<ThemeConfig = any> {
* @default false
*/
ignoreDeadLinks?: boolean
/**
* Always use "clean URLs" without the `.html`.
* Also generate static files as `foo/index.html` insted of `foo.html`.
* Works with MPA config too.
* (default: false)
*/
cleanUrls?: boolean
}
export type RawConfigExports<ThemeConfig = any> =
@ -98,6 +106,7 @@ export interface SiteConfig<ThemeConfig = any>
tempDir: string
alias: AliasOptions
pages: string[]
cleanUrls: boolean
}
const resolve = (root: string, file: string) =>
@ -166,7 +175,8 @@ export async function resolveConfig(
vite: userConfig.vite,
shouldPreload: userConfig.shouldPreload,
mpa: !!userConfig.mpa,
ignoreDeadLinks: userConfig.ignoreDeadLinks
ignoreDeadLinks: userConfig.ignoreDeadLinks,
cleanUrls: !!userConfig.cleanUrls
}
return config
@ -270,7 +280,8 @@ export async function resolveSiteData(
themeConfig: userConfig.themeConfig || {},
locales: userConfig.locales || {},
langs: createLangDictionary(userConfig),
scrollOffset: userConfig.scrollOffset || 90
scrollOffset: userConfig.scrollOffset || 90,
cleanUrls: userConfig.cleanUrls || false
}
}

@ -56,7 +56,8 @@ export type { Header }
export const createMarkdownRenderer = async (
srcDir: string,
options: MarkdownOptions = {},
base = '/'
base = '/',
cleanUrls: boolean = false
): Promise<MarkdownRenderer> => {
const md = MarkdownIt({
html: true,
@ -81,7 +82,8 @@ export const createMarkdownRenderer = async (
rel: 'noopener noreferrer',
...options.externalLinks
},
base
base,
cleanUrls
)
// 3rd party plugins

@ -12,7 +12,8 @@ const indexRE = /(^|.*\/)index.md(#?.*)$/i
export const linkPlugin = (
md: MarkdownIt,
externalAttrs: Record<string, string>,
base: string
base: string,
shouldCleanUrls: boolean
) => {
md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
const token = tokens[idx]
@ -37,7 +38,7 @@ export const linkPlugin = (
// links to files (other than html/md)
!/\.(?!html|md)\w+($|\?)/i.test(url)
) {
normalizeHref(hrefAttr)
normalizeHref(hrefAttr, shouldCleanUrls)
}
// encode vite-specific replace strings in case they appear in URLs
@ -50,7 +51,7 @@ export const linkPlugin = (
return self.renderToken(tokens, idx, options)
}
function normalizeHref(hrefAttr: [string, string]) {
function normalizeHref(hrefAttr: [string, string], shouldCleanUrls: boolean) {
let url = hrefAttr[1]
const indexMatch = url.match(indexRE)
@ -58,13 +59,17 @@ export const linkPlugin = (
const [, path, hash] = indexMatch
url = path + hash
} else {
let cleanUrl = url.replace(/[?#].*$/, '')
// .md -> .html
let cleanUrl = url.replace(/[?#].*$/, '').replace(/\?.*$/, '')
// transform foo.md -> foo[.html]
if (cleanUrl.endsWith('.md')) {
cleanUrl = cleanUrl.replace(/\.md$/, '.html')
cleanUrl = cleanUrl.replace(/\.md$/, shouldCleanUrls ? '' : '.html')
}
// ./foo -> ./foo.html
if (!cleanUrl.endsWith('.html') && !cleanUrl.endsWith('/')) {
// transform ./foo -> ./foo[.html]
if (
!shouldCleanUrls &&
!cleanUrl.endsWith('.html') &&
!cleanUrl.endsWith('/')
) {
cleanUrl += '.html'
}
const parsed = new URL(url, 'http://a.com')

@ -28,9 +28,10 @@ export async function createMarkdownToVueRenderFn(
userDefines: Record<string, any> | undefined,
isBuild = false,
base = '/',
includeLastUpdatedData = false
includeLastUpdatedData = false,
cleanUrls: boolean = false
) {
const md = await createMarkdownRenderer(srcDir, options, base)
const md = await createMarkdownRenderer(srcDir, options, base, cleanUrls)
pages = pages.map((p) => slash(p.replace(/\.md$/, '')))

@ -45,7 +45,8 @@ export async function createVitePressPlugin(
vue: userVuePluginOptions,
vite: userViteConfig,
pages,
ignoreDeadLinks
ignoreDeadLinks,
cleanUrls
} = siteConfig
let markdownToVue: Awaited<ReturnType<typeof createMarkdownToVueRenderFn>>
@ -83,7 +84,8 @@ export async function createVitePressPlugin(
config.define,
config.command === 'build',
config.base,
siteConfig.lastUpdated
siteConfig.lastUpdated,
cleanUrls
)
},

1
types/shared.d.ts vendored

@ -57,6 +57,7 @@ export interface SiteData<ThemeConfig = any> {
label: string
}
>
cleanUrls: boolean
}
export type HeadConfig =

Loading…
Cancel
Save