问题

使用vuepress写文档网站,为了实现element-ui类似的组件预览效果,项目里面将ant-design-vue和基于ant-design-vue的自己封装的组件引入项目中,开发环境能正常运行。当运行Build打包后,报错:error Error rendering /:

方案1

经查询vuepress github issuse 得到的答案是,vuepress是服务端渲染的,浏览器的 API 访问限制。在页面加载第三方组件的时候,可能出现找不到的情况,建议在当前页面使用时再引入。

内容链接:https://v1.vuepress.vuejs.org/zh/guide/using-vue.html#%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84-api-%E8%AE%BF%E9%97%AE%E9%99%90%E5%88%B6

当然,如果不需要组件预览效果,及:::demo标志,就不会报错。需要该效果时,按照官网的做法,使用component标签,在需要的md 代码块里面动态加载组件,可以解决该问题

 mounted(){import("my-component").then(myComponent=>{console.log("myComponent", myComponent)this.dynamicComponent = myComponent.Tree})},

当然还有一种方法就是在mounted里面import组件并且注册组件,template部分照常使用之前的标签

<template><my-tree/>
</template>
<script>
import Vue from "vue"export default {mounted(){import("my-component").then(myComponent=>{console.log("myComponent", myComponent)Vue.component("myTree",myComponent.Tree)})}}
</script>

然而运行后,报错my-tree没有注册。Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the “name” option.

found in

方案2

方案1,问题看是解决了,没有报错了,但是。这不是我们想要的。

本质需求是实现组件库的组件预览效果,并且能复制代码,方案1能预览,但是代码都变成了component标签,不符合需求。

接下来我们想排查下是什么组件影响了打包:

采用本地建测试仓库,本地建测试组件库,本地建测试文档项目,逐个移植原组件库的组件到测试组件库中,发布到测试仓库后,更新测试文档,然后执行本地预览和打包命令。最终找出影响打包的组件有dialog,uploadAvatar,preview,cropper-img等组件。这些组件的共同点就是都直接或间接用到了document操作dom,还有其他window的方法,或者bom的方法事件,或者在组件内注册第三方组件,如本项目中就用的atob,btoa,这个也是造成出现该错误的原因之一。经在upoadAvatar去掉document得到验证。目前除了这几个组件,其他均可以实现组件预览效果。但是这几个组件只要引入就报错,也影响了全局。

最终解决

知道了问题所在,结合上面的思路,总之的一点就是想要用window或bom方法事件,一定要在mounted后执行。这里来一个一个看。首先看dialog组件,之所以会报错就是dialog组件在created生命周期的时候用了document(下面只展示关键代码,多余的代码略)

import { VNode } from "vue"
import { Component, Prop, Vue, Watch } from "vue-property-decorator"
import { dialogConfig } from "./type"export default class Dialog extends Vue {created() {this.dialogInit()this.getWindowSize()}/*** 弹窗初始化* @private*/private dialogInit():void {this.id = "lc-dialog" + (Math.random() * 1000000 + new Date().getTime()).toString(16).split(".")[0]this.$nextTick(() => {const dialogDom:any = document.getElementById(that.id)if (!dialogDom) {return}this.dialogDom = dialogDomthis.headerDom = dialogDom.querySelector(".ant-modal-header")this.footerDom = dialogDom.querySelector(".ant-modal-footer")})}/*** 获取窗口尺寸* @private*/private getWindowSize():void {const that = this as anythis.windowSize = {windowWidth: document.documentElement.clientWidth,windowHeight: document.documentElement.clientHeight}// // console.log(that.dialogScreen)// // console.log(that.isScreen)window.onresize = () => {if (this.dialogScreen && this.isScreen) {clearTimeout(this.debounceTimeOut)this.debounceTimeOut = setTimeout(() => {this.windowSize = {windowWidth: document.documentElement.clientWidth,windowHeight: document.documentElement.clientHeight}}, 300)}}}render (h:any):VNode {...}
}

那这里就很简单,将created改成mounted就行

再来看看图片裁剪组件,之前的代码是

<!--图片裁剪-->
<template><lc-dialog:title="title":visible.sync="visible":width="800":footer="null"ref="cropperModal":before-close="beforeClose":z-index="zIndex"><vue-cropperref="cropper":img="img":info="true":auto-crop="options.autoCrop":output-type="config.outputType || (config.originFile ? config.originFile.type : '')":auto-crop-width="options.autoCropWidth":auto-crop-height="options.autoCropHeight":fixed-box="options.fixedBox"@real-time="realTime"></vue-cropper></lc-dialog>
</template>
<script>
import Vue from "vue"
import VueCropper from "vue-cropper"
import { getZIndexByDiv } from "../../utils/lc-methods"
Vue.use(VueCropper)export default {name: "CropperImg",...
}
</script>

这里需要解决的是vue-cropper组件的按需引入问题。按照vue-press的思路,可以使用动态import,于是开始尝试如下:

<!--图片裁剪-->
<template><lc-dialog:title="title":visible.sync="visible":width="800":footer="null"ref="cropperModal":before-close="beforeClose":z-index="zIndex"><componentv-if="component":is="component"ref="cropper":img="img":info="true":auto-crop="options.autoCrop":output-type="config.outputType || (config.originFile ? config.originFile.type : '')":auto-crop-width="options.autoCropWidth":auto-crop-height="options.autoCropHeight":fixed-box="options.fixedBox"@real-time="realTime"/></lc-dialog>
</template>
<script>
import { getZIndexByDiv } from "../../utils/lc-methods"export default {name: "CropperImg",mounted() {import("vue-cropper").then(VueCropperModule => {this.component = VueCropperModule.VueCropper} },...
}
</script>

然而运行后发现,没有生效。于是将import(“vue-cropper”).catch打印发现竟然报错了。vuepress是走node服务渲染模式,也可能和nodejs 服务端渲染不支持import有关,于是改成require引入,如下

<!--图片裁剪-->
<template><lc-dialog:title="title":visible.sync="visible":width="800":footer="null"ref="cropperModal":before-close="beforeClose":z-index="zIndex"><componentv-if="component":is="component"ref="cropper":img="img":info="true":auto-crop="options.autoCrop":output-type="config.outputType || (config.originFile ? config.originFile.type : '')":auto-crop-width="options.autoCropWidth":auto-crop-height="options.autoCropHeight":fixed-box="options.fixedBox"@real-time="realTime"/></lc-dialog>
</template>
<script>
import { getZIndexByDiv } from "../../utils/lc-methods"export default {name: "CropperImg",mounted() {const VueCropperModule = require("vue-cropper")// console.log("VueCropperModule", VueCropperModule)this.component = VueCropperModule.VueCropper},...
}
</script>

结果成功,引入该组件后,也不会再报错error Error rendering /:

然后看看头像上传组件,这个也比较坑。这个组件mounted没有document,也没引入第三方组件。无奈,只有使用注释大法逐步查找,最后确定是组件内部引入压缩图片的方法造成

import { compressImageFun } from "../../utils/img-method"

发现只要组件引入了该方法,不管是否使用,都会报错,而注释该方法就万事大吉。
于是取查找compressImageFun相关,开始因为无头绪,同样只能使用注释大法,最后查到罪魁祸首是atob,btoa函数。这样那么解决办法和引入第三方组件类似。compressImageFun里面不需要动,改引入的地方就行,如下

export default {name: "UploadAvatar",data () {return {compressImageFun: null, // 压缩函数    注意这里因为无法直接使用compressImageFun,所以需要存在data中使用}},mounted() {const imgMethod = require("../../utils/img-method")this.compressImageFun = imgMethod.compressImageFun},methods: {/*** 上传之前* @param file* @returns {boolean}*/async beforeUpload (file) {return new Promise(async (resolve, reject) => {...省略若干代码if (!this.noCompress) {newCompressFile = await this.compressImageFun({ file: cropperFile || file })cropperFile = newCompressFile.data}...})},
}

至此,该错误被攻克!!!

vuepress打包报错:error Error rendering /:相关推荐

  1. android打包报错 AAPT: error: IDAT: incorrect data check. AAPT: error: file failed to compile.

    android打包报错 AAPT: error: IDAT: incorrect data check. AAPT: error: file failed to compile. 解决方法: 在app ...

  2. yarn打包报错:error during build: Error: Assigning to rvalue (Note that you need plugins to import files

    欢迎关注csdn前端领域博主: 前端小王hs email: 337674757@qq.com 前端交流群: 598778642 error during build: Error: Assigning ...

  3. maven打包报错:Error creating shaded jar: invalid LOC header (bad signature)

    使用maven打包时一直报错,打包命令:mvn clean install -Dmaven.test.skip=true -P product 报错如下: 根据提示使用 -X 参数debug,命令:m ...

  4. maven打包报错scalac error: xxxx\target\classes does not exist or is not a director

    很简单,就是打包的工程路径里有中文,把中文去了,要全英路径!!!我竟然犯这种错误,太难了

  5. JavaScript高级语法打包 - babel插件安装配置报错!Error: Cannot find module ‘@babel/preset-preset.env‘

    目录 1. 插件安装和配置 2. 运行打包 - 报错信息 3. 解决办法 1. 插件安装和配置 安装babel转换器相关的包: npm i babel-loader @babel/core @babe ...

  6. vue打包报错 ERROR in static/js/0.4403c1dd262870db3c27.js from UglifyJs TypeError: Cannot read property ‘

    打包报错 ERROR in static/js/0.4403c1dd262870db3c27.js from UglifyJs TypeError: Cannot read property 'sec ...

  7. vue 项目打包报错 CSS minification error

    vue 项目打包报错 Error: CSS minification error: Lexical error 错误: CSS minification error: Lexical error on ...

  8. npm打包报错ERROR in ./src/main/webapp/app/core解决方法

    jenkins用webpack打前端的包,出现报错了,报错还不止一个,8个error,看的我疯狂以为是自己的问题,是不是要用npm下载很多的什么手脚架,插件之类的.. 问题: 主要报错: ERROR ...

  9. 解决React Native报错:Error:Found unexpected optical bounds (red pixel)

    问题背景 同样是在升级 gradle plugin V2.2.3 --> gradle plugin V3.0.1后,运行至打包APK期间报错: Error:found unexpected o ...

  10. 解决只读模式U盘保护格式化或者dd写报错:ERROR: failed to open ‘/dev/sdb‘ in read-write mode: Read-only file system.

    解决只读模式U盘保护格式化或者dd写报错:ERROR: failed to open '/dev/sdb' in read-write mode: Read-only file system. 或者: ...

最新文章

  1. wcf服务和寄主的关系
  2. eclipse常用以及实用的快捷键
  3. Scala中zip或者zipWithIndex的计数器用法
  4. CDOJ 1805 矩阵 数学
  5. linux man命令原理,Linux命令之man详解
  6. Unity3d学习日记(四)
  7. C语言编程一个人活了多少天,来用代码算一算在这个世界上活了多少天吧
  8. mathematica 如何在数组中等间隔插入元素
  9. linux dhcpv6 客户端,Linux(RedHat6.4)下配置radvd和dhcpv6
  10. 关于EMS,邮政快递包裹,邮政标准快递,邮政小包,EMS经济快递
  11. 安装scipy报错的解决方案
  12. 【VBA宏编程】——Excel操作
  13. 百词斩不复习_不背单词,墨墨背单词和百词斩哪个好啊?
  14. 统计学基础——方差、协方差、标准差(标准偏差/均方差)、标准误、均方误差、均方根误差(标准误差)的区别
  15. PON光模块相关知识
  16. android svg格式图片,Android工程使用SVG图片
  17. PHP项目集成支付宝PC端扫码支付API(国内支付)
  18. evplayer android闪退,Evplayer优弊端汇总
  19. 苹果App被置病毒 网友:安卓无压力
  20. win7下ie6兼容测试之Windows7(win7)下 XP Mode 下载、安装、设置完全图解

热门文章

  1. win10需要修复计算机,超好用!Win10自带修复系统 隐藏太深
  2. 中兴机顶盒刷机后服务器连接失败,(四川高安)中兴ba860av2.1t强刷安卓固件包解决刷机到7出错问题...
  3. 《30天自制操作系统》学习笔记--第11天
  4. 从网页浏览器跳转到微信打开公众号关注界面的解决方案
  5. ARC093 F Dark Horse——容斥
  6. Qt QSetting 读写ini配置文件(简单明了,多图)
  7. linux终端怎么复制粘贴某一行_如何在Linux终端中复制和粘贴文本、文件和文件夹...
  8. andserver FileBrowser 图片浏览
  9. 4G车载信息终端TBOX车联网数据采集智能网联解决方案
  10. oracle 10g 10053事件