From 47ac48562b72097bdc94a21ed4c3a46ff2ae383e Mon Sep 17 00:00:00 2001 From: ULIVZ <472590061@qq.com> Date: Thu, 27 Sep 2018 13:24:06 +0800 Subject: [PATCH] fix($core): Cannot assign to read only property 'exports' of object (close: #869) This is weird issue of webpack. since ClientComputedMixin was used both in server and client side, client es module will import this commonJS module, it should work but webpack throw error: 'Uncaught TypeError: Cannot assign to read only property 'exports' of object '#''. related issue: https://github.com/webpack/webpack/issues/4039 --- packages/@vuepress/core/lib/app/app.js | 2 +- .../lib/internal-plugins/transformModule.js | 27 ++++++++++++++ .../@vuepress/core/lib/prepare/AppContext.js | 1 + .../core/lib/prepare/ClientComputedMixin.js | 36 +++++++------------ 4 files changed, 41 insertions(+), 25 deletions(-) create mode 100644 packages/@vuepress/core/lib/internal-plugins/transformModule.js diff --git a/packages/@vuepress/core/lib/app/app.js b/packages/@vuepress/core/lib/app/app.js index 171cfd29..b379fff4 100644 --- a/packages/@vuepress/core/lib/app/app.js +++ b/packages/@vuepress/core/lib/app/app.js @@ -6,7 +6,7 @@ import { routes } from '@internal/routes' import { siteData } from '@internal/siteData' import appEnhancers from '@internal/app-enhancers' import globalUIComponents from '@internal/global-ui' -import ClientComputedMixin from '../prepare/ClientComputedMixin' +import ClientComputedMixin from '@transform/ClientComputedMixin' import Store from './Store' // generated from user config diff --git a/packages/@vuepress/core/lib/internal-plugins/transformModule.js b/packages/@vuepress/core/lib/internal-plugins/transformModule.js new file mode 100644 index 00000000..10c60a3a --- /dev/null +++ b/packages/@vuepress/core/lib/internal-plugins/transformModule.js @@ -0,0 +1,27 @@ +const path = require('path') +const { fs } = require('@vuepress/shared-utils') + +const DIR = 'transform' + +module.exports = (options, ctx) => ({ + name: '@vuepress/internal-transform-modules', + + alias: { + '@transform': path.resolve(ctx.tempPath, DIR) + }, + + async clientDynamicModules () { + const files = [ + path.resolve(__dirname, '../prepare/ClientComputedMixin.js') + ] + + const modules = await Promise.all(files.map(async file => { + const { base } = path.parse(file) + let content = await fs.readFile(file, 'utf-8') + content = content.replace('module.exports =', 'export default') + return { name: base, content, dirname: DIR } + })) + + return modules + } +}) diff --git a/packages/@vuepress/core/lib/prepare/AppContext.js b/packages/@vuepress/core/lib/prepare/AppContext.js index 6b1d9458..6e9c60a5 100644 --- a/packages/@vuepress/core/lib/prepare/AppContext.js +++ b/packages/@vuepress/core/lib/prepare/AppContext.js @@ -110,6 +110,7 @@ module.exports = class AppContext { .use(require('../internal-plugins/overrideCSS')) .use(require('../internal-plugins/layoutComponents')) .use(require('../internal-plugins/pageComponents')) + .use(require('../internal-plugins/transformModule')) // user plugin .useByPluginsConfig(this.cliOptions.plugins) .useByPluginsConfig(this.siteConfig.plugins) diff --git a/packages/@vuepress/core/lib/prepare/ClientComputedMixin.js b/packages/@vuepress/core/lib/prepare/ClientComputedMixin.js index 59228194..63913c62 100644 --- a/packages/@vuepress/core/lib/prepare/ClientComputedMixin.js +++ b/packages/@vuepress/core/lib/prepare/ClientComputedMixin.js @@ -30,21 +30,18 @@ function findPageForPath (pages, path) { */ module.exports = siteData => { - // We cannot use class here. webpack will throw error. - function ClientComputedMixin () {} - - ClientComputedMixin.prototype = { + return class ClientComputedMixin { setPage (page) { this.__page = page - }, + } get $site () { return siteData - }, + } get $themeConfig () { return this.$site.themeConfig - }, + } get $localeConfig () { const { locales = {}} = this.$site @@ -58,11 +55,11 @@ module.exports = siteData => { } } return targetLang || defaultLang || {} - }, + } get $siteTitle () { return this.$localeConfig.title || this.$site.title || '' - }, + } get $title () { const page = this.$page @@ -76,7 +73,7 @@ module.exports = siteData => { ? (selfTitle + ' | ' + siteTitle) : siteTitle : selfTitle || 'VuePress' - }, + } get $description () { // #565 hoist description from meta @@ -84,24 +81,20 @@ module.exports = siteData => { if (description) { return description } - // if (this.$page.frontmatter.meta) { - // const descriptionMeta = this.$page.frontmatter.meta.filter(item => item.name === 'description')[0] - // if (descriptionMeta) return descriptionMeta.content - // } return this.$page.frontmatter.description || this.$localeConfig.description || this.$site.description || '' - }, + } get $lang () { return this.$page.frontmatter.lang || this.$localeConfig.lang || 'en-US' - }, + } get $localePath () { return this.$localeConfig.path || '/' - }, + } get $themeLocaleConfig () { return (this.$site.themeConfig.locales || {})[this.$localePath] || {} - }, + } get $page () { if (this.__page) { @@ -113,16 +106,11 @@ module.exports = siteData => { ) } } - - return ClientComputedMixin } function getMetaDescription (meta) { if (meta) { - // Why '(() => 'name')()' ? - // You can use item.name directly and see what happened. - // "How many pits did webpack bury?" - const descriptionMeta = meta.filter(item => item[(() => 'name')()] === 'description')[0] + const descriptionMeta = meta.filter(item => item.name === 'description')[0] if (descriptionMeta) return descriptionMeta.content } } -- GitLab