From b6a90b69ccce08fd7f06875e9b0fcd4c997c63ac Mon Sep 17 00:00:00 2001 From: Xinyu Liu Date: Fri, 27 Apr 2018 18:01:05 +0800 Subject: [PATCH 1/2] refactor: make the prepare process clearer and modify the resolve alias --- lib/app/app.js | 7 -- lib/prepare.js | 169 ++++++++++++++++++-------------- lib/webpack/createBaseConfig.js | 6 +- 3 files changed, 99 insertions(+), 83 deletions(-) diff --git a/lib/app/app.js b/lib/app/app.js index 8040f5fc7a..df78547b85 100644 --- a/lib/app/app.js +++ b/lib/app/app.js @@ -3,7 +3,6 @@ import Router from 'vue-router' import Content from './Content' import ClientOnly from './ClientOnly' import dataMixin from './dataMixin' -import NotFound from '@notFound' import { routes } from '@temp/routes' import { siteData } from '@temp/siteData' import enhanceApp from '@temp/enhanceApp' @@ -41,12 +40,6 @@ Vue.prototype.$withBase = function (path) { } } -// add 404 route -routes.push({ - path: '*', - component: NotFound -}) - export function createApp () { const router = new Router({ base: siteData.base, diff --git a/lib/prepare.js b/lib/prepare.js index 2d0fc56db2..ae9a420c2d 100644 --- a/lib/prepare.js +++ b/lib/prepare.js @@ -19,6 +19,15 @@ async function writeTemp (file, content) { } } +async function writeEnhanceTemp (destName, srcPath) { + await writeTemp( + destName, + fs.existsSync(srcPath) + ? `export { default } from ${JSON.stringify(srcPath)}` + : `export default function () {}` + ) +} + module.exports = async function prepare (sourceDir) { // 1. load options const options = await resolveOptions(sourceDir) @@ -50,29 +59,12 @@ if (!Object.assign) Object.assign = require('object-assign')` const hasUserOverride = options.useDefaultTheme && fs.existsSync(overridePath) await writeTemp(`override.styl`, hasUserOverride ? `@import(${JSON.stringify(overridePath)})` : ``) - async function writeEnhanceTemp (destName, srcPath, isEnhanceExist) { - await writeTemp( - destName, - isEnhanceExist - ? `export { default } from ${JSON.stringify(srcPath)}` - : `export default function () {}` - ) - } - // 6. handle enhanceApp.js const enhanceAppPath = path.resolve(sourceDir, '.vuepress/enhanceApp.js') - writeEnhanceTemp( - 'enhanceApp.js', - enhanceAppPath, - fs.existsSync(enhanceAppPath) - ) + await writeEnhanceTemp('enhanceApp.js', enhanceAppPath) // 7. handle the theme enhanceApp.js - writeEnhanceTemp( - 'themeEnhanceApp.js', - options.themeEnhanceAppPath, - fs.existsSync(options.themeEnhanceAppPath) - ) + await writeEnhanceTemp('themeEnhanceApp.js', options.themeEnhanceAppPath) return options } @@ -84,6 +76,8 @@ async function resolveOptions (sourceDir) { const configTomlPath = path.resolve(vuepressDir, 'config.toml') delete require.cache[configPath] + + // resolve siteConfig let siteConfig = {} if (fs.existsSync(configYmlPath)) { siteConfig = await parseConfig(configYmlPath) @@ -111,6 +105,11 @@ async function resolveOptions (sourceDir) { }) } + // resolve outDir + const outDir = siteConfig.dest + ? path.resolve(siteConfig.dest) + : path.resolve(sourceDir, '.vuepress/dist') + // resolve theme const useDefaultTheme = ( !siteConfig.theme && @@ -125,63 +124,60 @@ async function resolveOptions (sourceDir) { .some(base => themeConfig.locales[base].algolia) ) - const options = { - siteConfig, - sourceDir, - outDir: siteConfig.dest - ? path.resolve(siteConfig.dest) - : path.resolve(sourceDir, '.vuepress/dist'), - publicPath: base, - pageFiles: sort(await globby(['**/*.md', '!.vuepress', '!node_modules'], { cwd: sourceDir })), - pagesData: null, - themePath: null, - notFoundPath: null, - useDefaultTheme, - isAlgoliaSearch, - markdown: createMarkdown(siteConfig) - } + // resolve 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 - options.themePath = path.resolve(__dirname, 'default-theme/Layout.vue') - options.notFoundPath = path.resolve(__dirname, 'default-theme/NotFound.vue') + themePath = defaultThemePath + themeLayoutPath = path.resolve(defaultThemePath, 'Layout.vue') + themeNotFoundPath = path.resolve(defaultThemePath, 'NotFound.vue') } else { - let themeDir - let themePath - // resolve custom theme + // resolve theme Layout if (siteConfig.theme) { + // use external theme try { - themePath = require.resolve(`vuepress-theme-${siteConfig.theme}/Layout.vue`) - themeDir = path.dirname(themePath) + themeLayoutPath = require.resolve(`vuepress-theme-${siteConfig.theme}/Layout.vue`) + 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 { - themeDir = path.resolve(vuepressDir, 'theme') - themePath = path.resolve(themeDir, 'Layout.vue') - if (!fs.existsSync(themePath)) { + // 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.`) } } - options.themePath = themePath - const notFoundPath = path.resolve(themeDir, 'NotFound.vue') - if (fs.existsSync(notFoundPath)) { - options.notFoundPath = notFoundPath - } else { - options.notFoundPath = path.resolve(__dirname, 'default-theme/NotFound.vue') + // resolve theme NotFound + themeNotFoundPath = path.resolve(themePath, 'NotFound.vue') + if (!fs.existsSync(themeNotFoundPath)) { + themeNotFoundPath = path.resolve(defaultThemePath, 'NotFound.vue') } - const themeEnhanceAppPath = path.resolve(themeDir, 'enhanceApp.js') - if (fs.existsSync(themeEnhanceAppPath)) { - options.themeEnhanceAppPath = themeEnhanceAppPath + // resolve theme enhanceApp + themeEnhanceAppPath = path.resolve(themePath, 'enhanceApp.js') + if (!fs.existsSync(themeEnhanceAppPath)) { + themeEnhanceAppPath = null } } - // resolve pages - const pagesData = await Promise.all(options.pageFiles.map(async (file) => { + // resolve markdown + const markdown = createMarkdown(siteConfig) + + // resolve pageFiles + const pageFiles = sort(await globby(['**/*.md', '!.vuepress', '!node_modules'], { cwd: sourceDir })) + + // resolve pagesData + const pagesData = await Promise.all(pageFiles.map(async (file) => { const data = { path: fileToPath(file) } @@ -197,7 +193,7 @@ async function resolveOptions (sourceDir) { const headers = extractHeaders( frontmatter.content, ['h2', 'h3'], - options.markdown + markdown ) if (headers.length) { data.headers = headers @@ -212,15 +208,32 @@ async function resolveOptions (sourceDir) { })) // resolve site data - options.siteData = { + const siteData = { title: siteConfig.title || '', description: siteConfig.description || '', - base: siteConfig.base || '/', + 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 } @@ -279,30 +292,38 @@ async function genRoutesFile ({ siteData: { pages }, sourceDir, pageFiles }) { const file = pageFiles[index] const filePath = path.resolve(sourceDir, file) let code = ` - { - path: ${JSON.stringify(pagePath)}, - component: Theme, - beforeEnter: (to, from, next) => { - import(${JSON.stringify(filePath)}).then(comp => { - Vue.component(${JSON.stringify(fileToComponentName(file))}, comp.default) - next() - }) - } - }` + { + path: ${JSON.stringify(pagePath)}, + component: ThemeLayout, + beforeEnter: (to, from, next) => { + import(${JSON.stringify(filePath)}).then(comp => { + Vue.component(${JSON.stringify(fileToComponentName(file))}, comp.default) + next() + }) + } + }` if (/\/$/.test(pagePath)) { - code += `,{ - path: ${JSON.stringify(pagePath + 'index.html')}, - redirect: ${JSON.stringify(pagePath)} - }` + code += `, + { + path: ${JSON.stringify(pagePath + 'index.html')}, + redirect: ${JSON.stringify(pagePath)} + }` } return code } + const notFoundRoute = `, + { + path: '*', + component: ThemeNotFound + }` + return ( - `import Theme from '@theme'\n` + - `export const routes = [${pages.map(genRoute).join(',')}\n]` + `import ThemeLayout from '@themeLayout'\n` + + `import ThemeNotFound from '@themeNotFound'\n` + + `export const routes = [${pages.map(genRoute).join(',')}${notFoundRoute}\n]` ) } diff --git a/lib/webpack/createBaseConfig.js b/lib/webpack/createBaseConfig.js index e56879f001..809791e2f4 100644 --- a/lib/webpack/createBaseConfig.js +++ b/lib/webpack/createBaseConfig.js @@ -6,7 +6,8 @@ module.exports = function createBaseConfig ({ outDir, publicPath, themePath, - notFoundPath, + themeLayoutPath, + themeNotFoundPath, isAlgoliaSearch, markdown }, { debug } = {}, isServer) { @@ -36,7 +37,8 @@ module.exports = function createBaseConfig ({ .set('symlinks', true) .alias .set('@theme', themePath) - .set('@notFound', notFoundPath) + .set('@themeLayout', themeLayoutPath) + .set('@themeNotFound', themeNotFoundPath) .set('@source', sourceDir) .set('@app', path.resolve(__dirname, '../app')) .set('@temp', path.resolve(__dirname, '../app/.temp')) From 56aaf5440e8591c7177e7ed478688f27d23f7287 Mon Sep 17 00:00:00 2001 From: Xinyu Liu Date: Mon, 30 Apr 2018 11:28:47 +0800 Subject: [PATCH 2/2] tweak: put the resolve theme section together --- lib/prepare.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/prepare.js b/lib/prepare.js index ae9a420c2d..1ba21461c7 100644 --- a/lib/prepare.js +++ b/lib/prepare.js @@ -115,16 +115,6 @@ async function resolveOptions (sourceDir) { !siteConfig.theme && !fs.existsSync(path.resolve(vuepressDir, 'theme')) ) - - // resolve algolia - const themeConfig = siteConfig.themeConfig || {} - const isAlgoliaSearch = ( - themeConfig.algolia || - Object.keys(siteConfig.locales && themeConfig.locales || {}) - .some(base => themeConfig.locales[base].algolia) - ) - - // resolve theme const defaultThemePath = path.resolve(__dirname, 'default-theme') let themePath = null let themeLayoutPath = null @@ -170,6 +160,16 @@ async function resolveOptions (sourceDir) { } } + // 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)