diff --git a/packages/@vuepress/core/lib/app/app.js b/packages/@vuepress/core/lib/app/app.js index f2ea2b02..ebe03591 100644 --- a/packages/@vuepress/core/lib/app/app.js +++ b/packages/@vuepress/core/lib/app/app.js @@ -1,7 +1,7 @@ /* global VUEPRESS_TEMP_PATH */ import Vue from 'vue' import Router from 'vue-router' -import dataMixin from './dataMixin' +import dataMixin from '../data-mixins/client' import { routes } from '@internal/routes' import { siteData } from '@internal/siteData' import appEnhancers from '@internal/app-enhancers' diff --git a/packages/@vuepress/core/lib/app/dataMixin.js b/packages/@vuepress/core/lib/data-mixins/base.js similarity index 72% rename from packages/@vuepress/core/lib/app/dataMixin.js rename to packages/@vuepress/core/lib/data-mixins/base.js index 3a109e1c..35f54059 100644 --- a/packages/@vuepress/core/lib/app/dataMixin.js +++ b/packages/@vuepress/core/lib/data-mixins/base.js @@ -1,30 +1,25 @@ -/* global VUEPRESS_TEMP_PATH */ +// This file would be used at both client and server side. -import Vue from 'vue' -import { findPageForPath } from './util' - -export default function dataMixin (siteData) { - prepare(siteData) - const store = new Vue({ - data: { - siteData, - disableScrollBehavior: false +function findPageForPath (pages, path) { + for (let i = 0; i < pages.length; i++) { + const page = pages[i] + if (page.path === path) { + return page } - }) - Vue.$store = store - - if (module.hot) { - module.hot.accept(VUEPRESS_TEMP_PATH + '/internal/siteData.js', () => { - prepare(siteData) - store.siteData = siteData - }) } + return { + path: '', + frontmatter: {} + } +} +module.exports = function dataMixin (siteData, route) { return { computed: { $site () { - return store.siteData + return siteData }, + $localeConfig () { const { locales = {}} = this.$site let targetLang @@ -38,9 +33,11 @@ export default function dataMixin (siteData) { } return targetLang || defaultLang || {} }, + $siteTitle () { return this.$localeConfig.title || this.$site.title || '' }, + $title () { const page = this.$page const siteTitle = this.$siteTitle @@ -54,6 +51,7 @@ export default function dataMixin (siteData) { : siteTitle : selfTitle || 'VuePress' }, + $description () { // #565 hoist description from meta if (this.$page.frontmatter.meta) { @@ -62,30 +60,26 @@ export default function dataMixin (siteData) { } return this.$page.frontmatter.description || this.$localeConfig.description || this.$site.description || '' }, + $lang () { return this.$page.frontmatter.lang || this.$localeConfig.lang || 'en-US' }, + $localePath () { return this.$localeConfig.path || '/' }, + $themeLocaleConfig () { return (this.$site.themeConfig.locales || {})[this.$localePath] || {} }, + $page () { return findPageForPath( this.$site.pages, - this.$route.path + route && route.path || this.$route.path ) } } } } -function prepare (siteData) { - if (siteData.locales) { - Object.keys(siteData.locales).forEach(path => { - siteData.locales[path].path = path - }) - } - Object.freeze(siteData) -} diff --git a/packages/@vuepress/core/lib/data-mixins/client.js b/packages/@vuepress/core/lib/data-mixins/client.js new file mode 100644 index 00000000..14cd81d7 --- /dev/null +++ b/packages/@vuepress/core/lib/data-mixins/client.js @@ -0,0 +1,33 @@ +/* global VUEPRESS_TEMP_PATH */ + +import Vue from 'vue' +import dataMixin from '@internal/data-mixins' + +export default function (siteData) { + prepare(siteData) + const store = new Vue({ + data: { + siteData, + disableScrollBehavior: false + } + }) + Vue.$store = store + + if (module.hot) { + module.hot.accept(VUEPRESS_TEMP_PATH + '/internal/siteData.js', () => { + prepare(siteData) + store.siteData = siteData + }) + } + + return dataMixin(siteData) +} + +function prepare (siteData) { + if (siteData.locales) { + Object.keys(siteData.locales).forEach(path => { + siteData.locales[path].path = path + }) + } + Object.freeze(siteData) +} diff --git a/packages/@vuepress/core/lib/internal-plugins/data-mixins.js b/packages/@vuepress/core/lib/internal-plugins/data-mixins.js new file mode 100644 index 00000000..5090aa9d --- /dev/null +++ b/packages/@vuepress/core/lib/internal-plugins/data-mixins.js @@ -0,0 +1,18 @@ +const path = require('path') +const { fs } = require('@vuepress/shared-utils') + +// This plugin generate a mirror es module of '/core/lib/data-mixins/base.js' +// Since for now Webpack cannot allow 'ES6 import' to import a a commonjs +// module. +// +// Ref: https://github.com/webpack/webpack/issues/4039 +module.exports = (options, context) => ({ + name: '@vuepress/internal-enhance-app', + + // @internal/data-mixins + async clientDynamicModules () { + const dataMixinsCommonjsModule = await fs.readFile(path.resolve(__dirname, '../data-mixins/base.js'), 'utf-8') + const dataMixinsEsModule = dataMixinsCommonjsModule.replace('module.exports =', 'export default') + return { name: 'data-mixins.js', content: dataMixinsEsModule, dirname: 'internal' } + } +}) diff --git a/packages/@vuepress/core/lib/prepare/index.js b/packages/@vuepress/core/lib/prepare/index.js index c46630d6..19cd487e 100644 --- a/packages/@vuepress/core/lib/prepare/index.js +++ b/packages/@vuepress/core/lib/prepare/index.js @@ -33,6 +33,7 @@ module.exports = async function prepare ({ .use(require('../internal-plugins/enhanceApp')) .use(require('../internal-plugins/siteData')) .use(require('../internal-plugins/overrideCSS')) + .use(require('../internal-plugins/data-mixins')) // user plugin .useByPluginsConfig(cliPlugins) .useByPluginsConfig(siteConfig.plugins)