From d58ae21a99fb7c41261a8a68cfd7977af5bf40c7 Mon Sep 17 00:00:00 2001 From: Xinyu Liu Date: Wed, 6 Mar 2019 17:31:23 +0800 Subject: [PATCH 1/6] refactor($core): auto register layouts and pages --- .../core/lib/client/components/Content.js | 4 +-- packages/@vuepress/core/lib/client/util.js | 28 ++++--------------- .../node/internal-plugins/layoutComponents.js | 13 +++++---- .../node/internal-plugins/pageComponents.js | 13 +++++---- .../core/lib/node/internal-plugins/routes.js | 5 +--- 5 files changed, 24 insertions(+), 39 deletions(-) diff --git a/packages/@vuepress/core/lib/client/components/Content.js b/packages/@vuepress/core/lib/client/components/Content.js index c2ed88d487..b4811acf72 100644 --- a/packages/@vuepress/core/lib/client/components/Content.js +++ b/packages/@vuepress/core/lib/client/components/Content.js @@ -1,5 +1,3 @@ -import { isPageExists } from '../util' - export default { props: { pageKey: String, @@ -10,7 +8,7 @@ export default { }, render (h) { const pageKey = this.pageKey || this.$parent.$page.key - if (isPageExists(pageKey)) { + if (this.$vuepress.isPageExists(pageKey)) { return h(pageKey) } return h('') diff --git a/packages/@vuepress/core/lib/client/util.js b/packages/@vuepress/core/lib/client/util.js index 8a8f552e98..4db06866a1 100644 --- a/packages/@vuepress/core/lib/client/util.js +++ b/packages/@vuepress/core/lib/client/util.js @@ -1,46 +1,30 @@ import Vue from 'vue' -import layoutComponents from '@internal/layout-components' -import pageComponents from '@internal/page-components' -const asyncComponents = Object.assign({}, layoutComponents, pageComponents) - -// TODO: reuse this function in shared-utils function pascalize (source = '') { return source.replace(/(^|-)\w/g, s => s.slice(-1).toUpperCase()) } - export function isPageExists (pageKey) { - return Boolean(getPageAsyncComponent(pageKey)) + return Boolean(Vue.component(pascalize(pageKey))) } export function isPageLoaded (pageKey) { - return Boolean(Vue.component(pageKey)) + return Boolean(Vue.component(pascalize(pageKey))) } export function getPageAsyncComponent (pageKey) { - return pageComponents[pascalize(pageKey)] + return Vue.component(pascalize(pageKey)) } export function isLayoutExists (layout) { - return Boolean(getLayoutAsyncComponent(layout)) + return Boolean(Vue.component(pascalize(layout))) } export function isLayoutLoaded (layout) { - return Boolean(Vue.component(layout)) + return Boolean(Vue.component(pascalize(layout))) } export function getLayoutAsyncComponent (pageKey) { - return layoutComponents[pascalize(pageKey)] -} - -export function ensureAsyncComponentsLoaded (...names) { - return Promise.all(names.filter(v => v).map(async (name) => { - name = pascalize(name) - if (!Vue.component(name) && asyncComponents[name]) { - const comp = await asyncComponents[name]() - Vue.component(name, comp.default) - } - })) + return Vue.component(pascalize(pageKey)) } /** diff --git a/packages/@vuepress/core/lib/node/internal-plugins/layoutComponents.js b/packages/@vuepress/core/lib/node/internal-plugins/layoutComponents.js index a17c4daf21..60ad57bcd2 100644 --- a/packages/@vuepress/core/lib/node/internal-plugins/layoutComponents.js +++ b/packages/@vuepress/core/lib/node/internal-plugins/layoutComponents.js @@ -4,12 +4,15 @@ module.exports = (options, ctx) => { return { name: '@vuepress/internal-layout-components', - async clientDynamicModules () { + async enhanceAppFiles () { const componentNames = Object.keys(ctx.themeAPI.layoutComponentMap) - const code = `export default {\n${componentNames - .map(name => ` ${JSON.stringify(pascalize(name))}: () => import(${JSON.stringify(ctx.themeAPI.layoutComponentMap[name].path)})`) - .join(',\n')} \n}` - return { name: 'layout-components.js', content: code, dirname: 'internal' } + const code = `import Vue from 'vue'\n${componentNames + .map(name => `Vue.component(${JSON.stringify(pascalize(name))}, () => import(${JSON.stringify(ctx.themeAPI.layoutComponentMap[name].path)}))`) + .join(',\n')} \n` + return { + name: 'layout-components.js', + content: code + } } } } diff --git a/packages/@vuepress/core/lib/node/internal-plugins/pageComponents.js b/packages/@vuepress/core/lib/node/internal-plugins/pageComponents.js index ce190db599..022fc2fdc5 100644 --- a/packages/@vuepress/core/lib/node/internal-plugins/pageComponents.js +++ b/packages/@vuepress/core/lib/node/internal-plugins/pageComponents.js @@ -7,12 +7,15 @@ module.exports = (options, ctx) => { return { name: '@vuepress/internal-page-components', - async clientDynamicModules () { - const code = `export default {\n${pages + async enhanceAppFiles () { + const code = `import Vue from 'vue'\n${pages .filter(({ _filePath }) => _filePath) - .map(({ key, _filePath }) => ` ${JSON.stringify(pascalize(key))}: () => import(${JSON.stringify(_filePath)})`) - .join(',\n')} \n}` - return { name: 'page-components.js', content: code, dirname: 'internal' } + .map(({ key, _filePath }) => `Vue.component(${JSON.stringify(pascalize(key))}, () => import(${JSON.stringify(_filePath)}))`) + .join(',\n')} \n` + return { + name: 'page-components.js', + content: code + } } } } diff --git a/packages/@vuepress/core/lib/node/internal-plugins/routes.js b/packages/@vuepress/core/lib/node/internal-plugins/routes.js index d6cf90b9b1..8c91601c00 100644 --- a/packages/@vuepress/core/lib/node/internal-plugins/routes.js +++ b/packages/@vuepress/core/lib/node/internal-plugins/routes.js @@ -42,10 +42,7 @@ function routesCode (pages) { { name: ${JSON.stringify(componentName)}, path: ${JSON.stringify(pagePath)}, - component: GlobalLayout, - beforeEnter: (to, from, next) => { - ensureAsyncComponentsLoaded(${JSON.stringify(layout || 'Layout')}, ${JSON.stringify(componentName)}).then(next) - },${_meta ? `\n meta: ${JSON.stringify(_meta)}` : ''} + component: GlobalLayout,${_meta ? `\n meta: ${JSON.stringify(_meta)}` : ''} }` const dncodedPath = decodeURIComponent(pagePath) From 0c143b43b682147373518e2341f66057935ae14a Mon Sep 17 00:00:00 2001 From: Xinyu Liu Date: Wed, 6 Mar 2019 17:41:48 +0800 Subject: [PATCH 2/6] tweaks --- .../@vuepress/core/lib/client/plugins/VuePress.d.ts | 2 -- packages/@vuepress/core/lib/client/plugins/VuePress.js | 2 -- packages/@vuepress/core/lib/client/util.js | 10 ++++------ 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/@vuepress/core/lib/client/plugins/VuePress.d.ts b/packages/@vuepress/core/lib/client/plugins/VuePress.d.ts index ef4cf3782f..03bc0747e6 100644 --- a/packages/@vuepress/core/lib/client/plugins/VuePress.d.ts +++ b/packages/@vuepress/core/lib/client/plugins/VuePress.d.ts @@ -4,8 +4,6 @@ import { AsyncComponent } from 'vue' declare class VuePress extends Store { isPageExists (pageKey: string): boolean; - isPageLoaded (pageKey: string): boolean; - getPageAsyncComponent (pageKey: string): () => Promise; loadPageAsyncComponent (pageKey: string): Promise; diff --git a/packages/@vuepress/core/lib/client/plugins/VuePress.js b/packages/@vuepress/core/lib/client/plugins/VuePress.js index bdb93e1b54..b7f500604e 100644 --- a/packages/@vuepress/core/lib/client/plugins/VuePress.js +++ b/packages/@vuepress/core/lib/client/plugins/VuePress.js @@ -1,7 +1,6 @@ import Store from './Store' import { isPageExists, - isPageLoaded, getPageAsyncComponent, isLayoutExists, isLayoutLoaded, @@ -12,7 +11,6 @@ class VuePress extends Store {} Object.assign(VuePress.prototype, { isPageExists, - isPageLoaded, getPageAsyncComponent, isLayoutExists, isLayoutLoaded, diff --git a/packages/@vuepress/core/lib/client/util.js b/packages/@vuepress/core/lib/client/util.js index 4db06866a1..7ee25fcbb6 100644 --- a/packages/@vuepress/core/lib/client/util.js +++ b/packages/@vuepress/core/lib/client/util.js @@ -1,13 +1,11 @@ import Vue from 'vue' -function pascalize (source = '') { - return source.replace(/(^|-)\w/g, s => s.slice(-1).toUpperCase()) -} -export function isPageExists (pageKey) { - return Boolean(Vue.component(pascalize(pageKey))) +function pascalize (str = '') { + const cache = Object.create(null) + return str => str in cache ? cache[str] : (cache[str] = str.replace(/(^|-)\w/g, s => s.slice(-1).toUpperCase())) } -export function isPageLoaded (pageKey) { +export function isPageExists (pageKey) { return Boolean(Vue.component(pascalize(pageKey))) } From 1084cd96daa3f8933798d303d94924f994f9a794 Mon Sep 17 00:00:00 2001 From: Xinyu Liu Date: Wed, 6 Mar 2019 17:42:47 +0800 Subject: [PATCH 3/6] tweaks --- packages/@vuepress/core/lib/client/plugins/VuePress.js | 2 -- packages/@vuepress/core/lib/client/util.js | 4 ---- 2 files changed, 6 deletions(-) diff --git a/packages/@vuepress/core/lib/client/plugins/VuePress.js b/packages/@vuepress/core/lib/client/plugins/VuePress.js index b7f500604e..ef952a54ba 100644 --- a/packages/@vuepress/core/lib/client/plugins/VuePress.js +++ b/packages/@vuepress/core/lib/client/plugins/VuePress.js @@ -3,7 +3,6 @@ import { isPageExists, getPageAsyncComponent, isLayoutExists, - isLayoutLoaded, getLayoutAsyncComponent } from '../util' @@ -13,7 +12,6 @@ Object.assign(VuePress.prototype, { isPageExists, getPageAsyncComponent, isLayoutExists, - isLayoutLoaded, getLayoutAsyncComponent }) diff --git a/packages/@vuepress/core/lib/client/util.js b/packages/@vuepress/core/lib/client/util.js index 7ee25fcbb6..a993d44a88 100644 --- a/packages/@vuepress/core/lib/client/util.js +++ b/packages/@vuepress/core/lib/client/util.js @@ -17,10 +17,6 @@ export function isLayoutExists (layout) { return Boolean(Vue.component(pascalize(layout))) } -export function isLayoutLoaded (layout) { - return Boolean(Vue.component(pascalize(layout))) -} - export function getLayoutAsyncComponent (pageKey) { return Vue.component(pascalize(pageKey)) } From 0922b27057bc82e4bcf119697a1a9a1ae8beb66c Mon Sep 17 00:00:00 2001 From: Xinyu Liu Date: Wed, 6 Mar 2019 17:50:11 +0800 Subject: [PATCH 4/6] tweaks --- packages/@vuepress/core/lib/client/app.js | 4 ---- .../@vuepress/core/lib/client/plugins/VuePress.d.ts | 6 +----- .../@vuepress/core/lib/client/plugins/VuePress.js | 8 ++------ packages/@vuepress/core/lib/client/util.js | 11 +---------- 4 files changed, 4 insertions(+), 25 deletions(-) diff --git a/packages/@vuepress/core/lib/client/app.js b/packages/@vuepress/core/lib/client/app.js index bcccec1797..969a5a0d6b 100644 --- a/packages/@vuepress/core/lib/client/app.js +++ b/packages/@vuepress/core/lib/client/app.js @@ -9,7 +9,6 @@ import globalUIComponents from '@internal/global-ui' import ClientComputedMixin from '@transform/ClientComputedMixin' import VuePress from './plugins/VuePress' import { handleRedirectForCleanUrls } from './redirect.js' -import { getLayoutAsyncComponent } from './util' // built-in components import Content from './components/Content.js' @@ -44,9 +43,6 @@ Vue.component('ContentSlotsDistributor', ContentSlotsDistributor) Vue.component('OutboundLink', OutboundLink) // component for client-only content Vue.component('ClientOnly', ClientOnly) -// core components -Vue.component('Layout', getLayoutAsyncComponent('Layout')) -Vue.component('NotFound', getLayoutAsyncComponent('NotFound')) // markdown components Vue.component('TOC', TOC) diff --git a/packages/@vuepress/core/lib/client/plugins/VuePress.d.ts b/packages/@vuepress/core/lib/client/plugins/VuePress.d.ts index 03bc0747e6..48af0be18c 100644 --- a/packages/@vuepress/core/lib/client/plugins/VuePress.d.ts +++ b/packages/@vuepress/core/lib/client/plugins/VuePress.d.ts @@ -4,11 +4,7 @@ import { AsyncComponent } from 'vue' declare class VuePress extends Store { isPageExists (pageKey: string): boolean; - getPageAsyncComponent (pageKey: string): () => Promise; - - loadPageAsyncComponent (pageKey: string): Promise; - - registerPageAsyncComponent (pageKey: string): void; + isLayoutExists (pageKey: string): boolean; } declare module "vue/types/vue" { diff --git a/packages/@vuepress/core/lib/client/plugins/VuePress.js b/packages/@vuepress/core/lib/client/plugins/VuePress.js index ef952a54ba..71d1aa67a5 100644 --- a/packages/@vuepress/core/lib/client/plugins/VuePress.js +++ b/packages/@vuepress/core/lib/client/plugins/VuePress.js @@ -1,18 +1,14 @@ import Store from './Store' import { isPageExists, - getPageAsyncComponent, - isLayoutExists, - getLayoutAsyncComponent + isLayoutExists } from '../util' class VuePress extends Store {} Object.assign(VuePress.prototype, { isPageExists, - getPageAsyncComponent, - isLayoutExists, - getLayoutAsyncComponent + isLayoutExists }) export default { diff --git a/packages/@vuepress/core/lib/client/util.js b/packages/@vuepress/core/lib/client/util.js index a993d44a88..206497d802 100644 --- a/packages/@vuepress/core/lib/client/util.js +++ b/packages/@vuepress/core/lib/client/util.js @@ -1,26 +1,17 @@ import Vue from 'vue' function pascalize (str = '') { - const cache = Object.create(null) - return str => str in cache ? cache[str] : (cache[str] = str.replace(/(^|-)\w/g, s => s.slice(-1).toUpperCase())) + return str.replace(/(^|-)\w/g, s => s.slice(-1).toUpperCase()) } export function isPageExists (pageKey) { return Boolean(Vue.component(pascalize(pageKey))) } -export function getPageAsyncComponent (pageKey) { - return Vue.component(pascalize(pageKey)) -} - export function isLayoutExists (layout) { return Boolean(Vue.component(pascalize(layout))) } -export function getLayoutAsyncComponent (pageKey) { - return Vue.component(pascalize(pageKey)) -} - /** * Inject option to Vue SFC * @param {object} options From 3edbd8b68e203d91299968311422b367021b1e8a Mon Sep 17 00:00:00 2001 From: Xinyu Liu Date: Wed, 6 Mar 2019 17:58:26 +0800 Subject: [PATCH 5/6] chore: cache pascalize function --- packages/@vuepress/core/lib/client/util.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/@vuepress/core/lib/client/util.js b/packages/@vuepress/core/lib/client/util.js index 206497d802..e4bc6e7abd 100644 --- a/packages/@vuepress/core/lib/client/util.js +++ b/packages/@vuepress/core/lib/client/util.js @@ -1,9 +1,17 @@ import Vue from 'vue' -function pascalize (str = '') { - return str.replace(/(^|-)\w/g, s => s.slice(-1).toUpperCase()) +function cached (fn) { + const cache = Object.create(null) + return str => { + if (typeof cache[str] === 'undefined') { + cache[str] = fn(str) + } + return cache[str] + } } +const pascalize = cached((str = '') => str.replace(/(^|-)\w/g, s => s.slice(-1).toUpperCase())) + export function isPageExists (pageKey) { return Boolean(Vue.component(pascalize(pageKey))) } From c3d91a3f8f6b56d58d4ce5200ee8ba3d34047bf3 Mon Sep 17 00:00:00 2001 From: Shigma <1700011071@pku.edu.cn> Date: Wed, 6 Mar 2019 18:38:52 +0800 Subject: [PATCH 6/6] vuepress class methods --- packages/@vuepress/core/lib/client/app.js | 3 +- .../core/lib/client/plugins/VuePress.js | 31 +++++++++++++------ packages/@vuepress/core/lib/client/util.js | 22 ------------- 3 files changed, 23 insertions(+), 33 deletions(-) diff --git a/packages/@vuepress/core/lib/client/app.js b/packages/@vuepress/core/lib/client/app.js index 969a5a0d6b..a98c4afb71 100644 --- a/packages/@vuepress/core/lib/client/app.js +++ b/packages/@vuepress/core/lib/client/app.js @@ -15,7 +15,6 @@ import Content from './components/Content.js' import ContentSlotsDistributor from './components/ContentSlotsDistributor' import OutboundLink from './components/OutboundLink.vue' import ClientOnly from './components/ClientOnly' -import TOC from './components/TOC.vue' // suggest dev server restart on base change if (module.hot) { @@ -44,7 +43,7 @@ Vue.component('OutboundLink', OutboundLink) // component for client-only content Vue.component('ClientOnly', ClientOnly) // markdown components -Vue.component('TOC', TOC) +Vue.component('TOC', () => import('./components/TOC.vue')) // global helper for adding base path to absolute urls Vue.prototype.$withBase = function (path) { diff --git a/packages/@vuepress/core/lib/client/plugins/VuePress.js b/packages/@vuepress/core/lib/client/plugins/VuePress.js index 71d1aa67a5..c5043b3138 100644 --- a/packages/@vuepress/core/lib/client/plugins/VuePress.js +++ b/packages/@vuepress/core/lib/client/plugins/VuePress.js @@ -1,15 +1,28 @@ +import Vue from 'vue' import Store from './Store' -import { - isPageExists, - isLayoutExists -} from '../util' -class VuePress extends Store {} +// TODO: reuse this function in shared-utils +function cached (fn) { + const cache = Object.create(null) + return str => { + if (typeof cache[str] === 'undefined') { + cache[str] = fn(str) + } + return cache[str] + } +} -Object.assign(VuePress.prototype, { - isPageExists, - isLayoutExists -}) +const pascalize = cached((str = '') => str.replace(/(^|-)\w/g, s => s.slice(-1).toUpperCase())) + +class VuePress extends Store { + isPageExists (pageKey) { + return Boolean(Vue.component(pascalize(pageKey))) + } + + isLayoutExists (layout) { + return Boolean(Vue.component(pascalize(layout))) + } +} export default { install (Vue) { diff --git a/packages/@vuepress/core/lib/client/util.js b/packages/@vuepress/core/lib/client/util.js index e4bc6e7abd..5094b3dc9e 100644 --- a/packages/@vuepress/core/lib/client/util.js +++ b/packages/@vuepress/core/lib/client/util.js @@ -1,25 +1,3 @@ -import Vue from 'vue' - -function cached (fn) { - const cache = Object.create(null) - return str => { - if (typeof cache[str] === 'undefined') { - cache[str] = fn(str) - } - return cache[str] - } -} - -const pascalize = cached((str = '') => str.replace(/(^|-)\w/g, s => s.slice(-1).toUpperCase())) - -export function isPageExists (pageKey) { - return Boolean(Vue.component(pascalize(pageKey))) -} - -export function isLayoutExists (layout) { - return Boolean(Vue.component(pascalize(layout))) -} - /** * Inject option to Vue SFC * @param {object} options