Skip to content

Commit 20e520d

Browse files
committed
feat($core): multiple layout directories
1 parent 0b89d9c commit 20e520d

File tree

1 file changed

+34
-18
lines changed

1 file changed

+34
-18
lines changed

packages/@vuepress/core/lib/prepare/loadTheme.js

+34-18
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ module.exports = async function loadTheme (theme, sourceDir, vuepressDir) {
6767
// handle theme api
6868
const {
6969
plugins: themePlugins,
70-
palette: themePalette,
71-
layoutDir = useLocalTheme
72-
? '.'
73-
: 'layouts'
70+
palette: themePalette
7471
} = themeIndexFile
7572

76-
const layoutDirPath = path.resolve(themePath, layoutDir)
73+
const layoutDirs = [
74+
path.resolve(themePath, 'layouts'),
75+
path.resolve(themePath, '.')
76+
]
7777

7878
// normalize component name
7979
const getComponentName = filename => {
@@ -84,29 +84,45 @@ module.exports = async function loadTheme (theme, sourceDir, vuepressDir) {
8484
return filename
8585
}
8686

87+
const readdirSync = dir => fs.existsSync(dir) && fs.readdirSync(dir) || []
88+
8789
// built-in named layout or not.
8890
const isInternal = componentName => componentName === 'Layout' ||
8991
componentName === 'NotFound'
9092

91-
const layoutComponentMap = fs.readdirSync(layoutDirPath)
92-
.filter(filename => filename.endsWith('.vue'))
93-
.reduce((map, filename) => {
94-
const componentName = getComponentName(filename)
95-
const componentPath = path.resolve(layoutDirPath, filename)
96-
map[componentName] = { filename, componentName, path: componentPath }
97-
if (isInternal(componentName)) {
98-
map[componentName].isInternal = true
99-
}
93+
const layoutComponentMap = layoutDirs
94+
.map(
95+
layourDir => readdirSync(layourDir)
96+
.filter(filename => filename.endsWith('.vue'))
97+
.map(filename => {
98+
const componentName = getComponentName(filename)
99+
return {
100+
filename, componentName,
101+
isInternal: isInternal(componentName),
102+
path: path.resolve(layourDir, filename)
103+
}
104+
})
105+
)
106+
107+
.reduce((arr, next) => {
108+
arr.push(...next)
109+
return arr
110+
}, [])
111+
112+
.reduce((map, component) => {
113+
map[component.componentName] = component
100114
return map
101115
}, {})
102116

103-
if (!layoutComponentMap.Layout && !fs.existsSync(layoutComponentMap.Layout.path)) {
104-
throw new Error(`[vuepress] Cannot resolve Layout.vue file in \n ${layoutComponentMap.Layout.path}`)
117+
const { Layout = {}, NotFound = {}} = layoutComponentMap
118+
119+
if (!Layout && !fs.existsSync(Layout.path)) {
120+
throw new Error(`[vuepress] Cannot resolve Layout.vue file in \n ${Layout.path}`)
105121
}
106122

107123
// use default 404 component.
108-
if (!layoutComponentMap.NotFound || !fs.existsSync(layoutComponentMap.NotFound.path)) {
109-
layoutComponentMap['NotFound'] = {
124+
if (!NotFound || !fs.existsSync(NotFound.path)) {
125+
layoutComponentMap.NotFound = {
110126
filename: 'Layout.vue',
111127
componentName: 'NotFound',
112128
path: path.resolve(__dirname, '../app/components/NotFound.vue'),

0 commit comments

Comments
 (0)