mirror of
https://github.com/wahyd4/vuepress.git
synced 2026-08-16 16:55:53 +10:00
195 lines
5.4 KiB
JavaScript
195 lines
5.4 KiB
JavaScript
const fs = require('fs-extra')
|
|
const path = require('path')
|
|
const globby = require('globby')
|
|
const createMarkdown = require('../markdown')
|
|
const loadConfig = require('./loadConfig')
|
|
const { encodePath, fileToPath, sort, getGitLastUpdatedTimeStamp } = require('./util')
|
|
const {
|
|
inferTitle,
|
|
extractHeaders,
|
|
parseFrontmatter
|
|
} = require('../util/index')
|
|
|
|
module.exports = async function resolveOptions (sourceDir) {
|
|
const vuepressDir = path.resolve(sourceDir, '.vuepress')
|
|
const siteConfig = loadConfig(vuepressDir)
|
|
|
|
// normalize head tag urls for base
|
|
const base = siteConfig.base || '/'
|
|
if (base !== '/' && siteConfig.head) {
|
|
siteConfig.head.forEach(tag => {
|
|
const attrs = tag[1]
|
|
if (attrs) {
|
|
for (const name in attrs) {
|
|
if (name === 'src' || name === 'href') {
|
|
const value = attrs[name]
|
|
if (value.charAt(0) === '/') {
|
|
attrs[name] = base + value.slice(1)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
// resolve outDir
|
|
const outDir = siteConfig.dest
|
|
? path.resolve(siteConfig.dest)
|
|
: path.resolve(sourceDir, '.vuepress/dist')
|
|
|
|
// resolve theme
|
|
const useDefaultTheme = (
|
|
!siteConfig.theme &&
|
|
!fs.existsSync(path.resolve(vuepressDir, 'theme'))
|
|
)
|
|
const defaultThemePath = path.resolve(__dirname, '../default-theme')
|
|
let themePath = null
|
|
let themeLayoutPath = null
|
|
let themeNotFoundPath = null
|
|
let themeEnhanceAppPath = null
|
|
|
|
if (useDefaultTheme) {
|
|
// use default theme
|
|
themePath = defaultThemePath
|
|
themeLayoutPath = path.resolve(defaultThemePath, 'Layout.vue')
|
|
themeNotFoundPath = path.resolve(defaultThemePath, 'NotFound.vue')
|
|
} else {
|
|
// resolve theme Layout
|
|
if (siteConfig.theme) {
|
|
// use external theme
|
|
try {
|
|
themeLayoutPath = require.resolve(`vuepress-theme-${siteConfig.theme}/Layout.vue`, {
|
|
paths: [
|
|
path.resolve(__dirname, '../../node_modules'),
|
|
path.resolve(sourceDir)
|
|
]
|
|
})
|
|
themePath = path.dirname(themeLayoutPath)
|
|
} catch (e) {
|
|
throw new Error(`[vuepress] Failed to load custom theme "${
|
|
siteConfig.theme
|
|
}". File vuepress-theme-${siteConfig.theme}/Layout.vue does not exist.`)
|
|
}
|
|
} else {
|
|
// use custom theme
|
|
themePath = path.resolve(vuepressDir, 'theme')
|
|
themeLayoutPath = path.resolve(themePath, 'Layout.vue')
|
|
if (!fs.existsSync(themeLayoutPath)) {
|
|
throw new Error(`[vuepress] Cannot resolve Layout.vue file in .vuepress/theme.`)
|
|
}
|
|
}
|
|
|
|
// resolve theme NotFound
|
|
themeNotFoundPath = path.resolve(themePath, 'NotFound.vue')
|
|
if (!fs.existsSync(themeNotFoundPath)) {
|
|
themeNotFoundPath = path.resolve(defaultThemePath, 'NotFound.vue')
|
|
}
|
|
|
|
// resolve theme enhanceApp
|
|
themeEnhanceAppPath = path.resolve(themePath, 'enhanceApp.js')
|
|
if (!fs.existsSync(themeEnhanceAppPath)) {
|
|
themeEnhanceAppPath = null
|
|
}
|
|
}
|
|
|
|
// resolve theme config
|
|
const themeConfig = siteConfig.themeConfig || {}
|
|
|
|
// resolve algolia
|
|
const isAlgoliaSearch = (
|
|
themeConfig.algolia ||
|
|
Object.keys(siteConfig.locales && themeConfig.locales || {})
|
|
.some(base => themeConfig.locales[base].algolia)
|
|
)
|
|
|
|
// resolve markdown
|
|
const markdown = createMarkdown(siteConfig)
|
|
|
|
// resolve pageFiles
|
|
const patterns = ['**/*.md', '!.vuepress', '!node_modules']
|
|
if (siteConfig.dest) {
|
|
// #654 exclude dest folder when dest dir was set in
|
|
// sourceDir but not in '.vuepress'
|
|
const outDirRelative = path.relative(sourceDir, outDir)
|
|
if (!outDirRelative.includes('..')) {
|
|
patterns.push('!' + outDirRelative)
|
|
}
|
|
}
|
|
const pageFiles = sort(await globby(patterns, { cwd: sourceDir }))
|
|
|
|
// resolve lastUpdated
|
|
const shouldResolveLastUpdated = (
|
|
themeConfig.lastUpdated ||
|
|
Object.keys(siteConfig.locales && themeConfig.locales || {})
|
|
.some(base => themeConfig.locales[base].lastUpdated)
|
|
)
|
|
|
|
// resolve pagesData
|
|
const pagesData = await Promise.all(pageFiles.map(async (file) => {
|
|
const filepath = path.resolve(sourceDir, file)
|
|
const key = 'v-' + Math.random().toString(16).slice(2)
|
|
const data = {
|
|
key,
|
|
path: encodePath(fileToPath(file))
|
|
}
|
|
|
|
if (shouldResolveLastUpdated) {
|
|
data.lastUpdated = getGitLastUpdatedTimeStamp(filepath)
|
|
}
|
|
|
|
// extract yaml frontmatter
|
|
const content = await fs.readFile(filepath, 'utf-8')
|
|
const frontmatter = parseFrontmatter(content)
|
|
// infer title
|
|
const title = inferTitle(frontmatter)
|
|
if (title) {
|
|
data.title = title
|
|
}
|
|
const headers = extractHeaders(
|
|
frontmatter.content,
|
|
['h2', 'h3'],
|
|
markdown
|
|
)
|
|
if (headers.length) {
|
|
data.headers = headers
|
|
}
|
|
if (Object.keys(frontmatter.data).length) {
|
|
data.frontmatter = frontmatter.data
|
|
}
|
|
if (frontmatter.excerpt) {
|
|
const { html } = markdown.render(frontmatter.excerpt)
|
|
data.excerpt = html
|
|
}
|
|
return data
|
|
}))
|
|
|
|
// resolve site data
|
|
const siteData = {
|
|
title: siteConfig.title || '',
|
|
description: siteConfig.description || '',
|
|
base,
|
|
pages: pagesData,
|
|
themeConfig,
|
|
locales: siteConfig.locales
|
|
}
|
|
|
|
const options = {
|
|
siteConfig,
|
|
siteData,
|
|
sourceDir,
|
|
outDir,
|
|
publicPath: base,
|
|
pageFiles,
|
|
pagesData,
|
|
themePath,
|
|
themeLayoutPath,
|
|
themeNotFoundPath,
|
|
themeEnhanceAppPath,
|
|
useDefaultTheme,
|
|
isAlgoliaSearch,
|
|
markdown
|
|
}
|
|
|
|
return options
|
|
}
|