vuepress打包部署踩坑及解决

目录
  • vuepress打包部署踩坑记录
  • vuepress打包报错:error Error rendering /:
    • 问题
    • 方案1
    • 方案2

vuepress打包部署踩坑记录

官网教程

官网给了多种部署方案,这里我才用的是部署到github上

在你的项目中,创建一个如下的 deploy.sh 文件(请自行判断去掉高亮行的注释):

#!/usr/bin/env sh
# 确保脚本抛出遇到的错误
set -e
# 生成静态文件
npm run docs:build
# 进入生成的文件夹
cd docs/.vuepress/dist
# 如果是发布到自定义域名
# echo 'www.example.com' > CNAME
git init
git add -A
git commit -m 'deploy'
# 如果发布到 https://<USERNAME>.github.io
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git main
# 如果发布到 https://<USERNAME>.github.io/<REPO>
/**这个地方换成自己的github地址和仓库地址**/
git push -f git@github.com:FightingN/vue-common-vuepress.git master:gh-pages
cd -

然后需要注意的是 .vuepress/config.js文件的base需要修改一下

base: '/vue-common-vuepress/',

然后运行npm run deploy就可以正常打包到github托管中了

vuepress打包报错:error Error rendering /:

问题

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

方案1

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

内容链接

当然,如果不需要组件预览效果,及:::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 = dialogDom
      this.headerDom = dialogDom.querySelector(".ant-modal-header")
      this.footerDom = dialogDom.querySelector(".ant-modal-footer")
    })
  }
  /**
   * 获取窗口尺寸
   * @private
   */
  private getWindowSize():void {
    const that = this as any
    this.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-cropper
            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"
          >
          </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"
  >
        <component
              v-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"
  >
        <component
              v-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
        }
     ...
      })
    },
}

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • VuePress使用Algolia实现全文搜索

    目录 引言 确认眼神 申请授权 实施部署 调试爬取 总结回顾 引言 Algolia 为构建者提供构建世界级体验所需的搜索和推荐服务.Algolia 是一个数据库实时搜索服务,能够提供毫秒级的数据库搜索服务,并且其服务能以 API 的形式方便地布局到网页.客户端.APP 等多种场景. VuePress 官方文档就有 Algolia 搜索插件,可以直接安装使用,使用 Algolia 搜索最大的好处就是方便,它会自动爬取网站的页面内容并构建索引,你只用申请一个 Algolia 授权服务,在网站上添加一

  • 解决VuePress页面乱码问题

    目录 VuePress页面乱码问题 官方步骤 VuePress 初探 建立文件夹 安装 vuepress 初始化 新建文件夹 配置页面 启动 乱码 VuePress页面乱码问题 公司有一个业务场景,需要用到VuePress,所以我这边就研究了一下.VuePress的官方文档写得很详细,步骤也很清晰. 官方步骤 # 创建文件夹 mkdir vuepress-starter cd vuepress-starter # 初始化 git init npm init # 安装Vue Press npm i

  • Vuepress使用vue组件实现页面改造

    目录 引言 前置环境 使用 vue 组件 安装插件 配置插件 创建 vue 组件 使用 vue 组件 引言 只是单纯的用 vuepress 写个 markdown 文档,的确会处处受限,满足不了定制化的样式和功能,有时只是简单的修改下某个页面,或者做些组件演示的内容,而不是开发一整套主题.所以研究下如何在项目中使用 vue 组件还有非常有必要的,毕竟也没那么难. 前置环境 node 环境 node v16.13.0 VuePress 版本 VuePress v2.0.0-beta.48 每个版本

  • 关于vuepress部署出现样式的问题及解决

    目录 vuepress部署出现样式问题 vuepress个人博客部署遇到的一些问题 1.js和css出现404问题 2.每次都要重复操作打包.运行.上传github很麻烦怎么办? 3.github.io无法打开怎么办? vuepress部署出现样式问题 以前在安装hexo的时候出了样式问题,现在用vuepress也出现了相同的问题. 本地测试完全可以 然而打包之后就彻底乱了 即使是自己本地打包成dist之后也会出现相同的问题 有点困扰,应该是打包配置的问题 通过修改index.html里的内容.

  • 解决Vuepress码云部署及自动跳转404的问题

    目录 Vuepress码云部署及自动跳转404 介绍 部署 GitHub 页面 推到你仓库的的 gh-page 分支 码云页面-Gitee Pages Vuepress的简单使用 安装 Vuepress码云部署及自动跳转404 介绍 VuePress 由两部分组成:一个以 Vue 驱动的主题系统的简约静态网站生成工具,和一个为编写技术文档而优化的默认主题.它是为了支持 Vue 子项目的文档需求而创建的. 由 VuePress 生成的每个页面,都具有相应的预渲染静态 HTML,它们能提供出色的加载

  • vuepress实现自定义首页的样式风格

    目录 vuepress自定义首页的样式风格 正文 vuepress2.x修改默认样式的小技巧 详解 vuepress自定义首页的样式风格 如何自定义vuepress的首页设计风格呢?比如,我希望首页下面的红框内容是可点击的: 请看正文步骤 正文 在docs -> .vuepress下新建theme文件夹,再在theme文件夹下新建components -> Home.vue, 将vuepress -> packages -> @vuepress -> theme-defaul

  • Vuepress生成文档部署到gitee.io的注意事项及说明

    目录 Vuepress生成文档部署到gitee.io注意事项 在gitee中部署VuePress博客问题 Vuepress生成文档部署到gitee.io注意事项 1.静态资源要放在.vuepress/public目录下,比如创建一个assets/img/目录.把图片文件放在目录下面. 2.本地开发的时候,每次更新文件后,需要运行 vuepress dev .命令重新发布. 3.运行vuepress build .命令会编译出来一个静态文件的dist目录.只要把这个目录的东西push到gitee.

  • vuepress打包部署踩坑及解决

    目录 vuepress打包部署踩坑记录 vuepress打包报错:error Error rendering /: 问题 方案1 方案2 vuepress打包部署踩坑记录 官网教程 官网给了多种部署方案,这里我才用的是部署到github上 在你的项目中,创建一个如下的 deploy.sh 文件(请自行判断去掉高亮行的注释): #!/usr/bin/env sh # 确保脚本抛出遇到的错误 set -e # 生成静态文件 npm run docs:build # 进入生成的文件夹 cd docs/

  • Vite vue3多页面入口打包以及部署踩坑实战

    目录 为什么需要多入口? 一.改造项目 二.vite.config.ts配置 三.部署 总结 为什么需要多入口? 公司原生的移动端上需要用webview引入一些性能要求不高的H5页面,初步考虑后选择用vue试个水,前期页面跳转选择使用vue-router,测试过程中在安卓高版本下右滑返回效果尚可,ios端初步尝试使用的最左侧touch事件移动距离检测以及router判断index添加过场动画,但是整体的效果依然达不到下图的效果. 原先项目中是使用多个html页面以及原生自带的协议去打开html,

  • 基于IOS端微信分享失效的踩坑及解决方法

    最近的一个公众号是基于vue的spa应用,在接入微信分享和微信语音的时候出现了:在Android上一切正常,但是在ios端调用wx.config的时候总是失败,去翻了官方文档也并没有找到解决方案,最后在测试中发现是因为初始化的时候传入的URL的问题.具体过程如下: 微信config接口配置,官方文档如下: 所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支

  • spring-cloud-gateway启动踩坑及解决

    目录 spring-cloud-gateway启动踩坑 1.webflux与mvc不兼容 2.webflux使用netty作为容器 3.后来实验了下 很坑得spring cloud gateway 异常 spring-cloud-gateway启动踩坑 本人使用的版本是2.1.2,以下只记录几个小问题,但确实实实在在的把个人恶心的要死要活的找不到办法,几经挣扎,最终解决. 更可恨的是开发的过程中,没有出现异常,后来由于项目组其它人加了依赖,不知不觉对项目的兼容造成了英雄,真的是被撞的头破血流,才

  • Spring数据库连接池url参数踩坑及解决

    目录 Spring数据库连接池url参数踩坑 遇到的问题 报错情况 解决 修改数据库连接池的url后,还是连接原先的url 问题 例如 Spring数据库连接池url参数踩坑 遇到的问题 报错情况 解决 & ' 字符在xml需要转义为 ' & ' 修改数据库连接池的url后,还是连接原先的url 问题 当修改连接池url之后,访问的还是原来的数据库. 例如 原来: url=jdbc:mysql://192.168.250.227:3306/myshop?characterEncoding=

  • nuxt使用vuex存储及获取用户信息踩坑的解决

    目录 一.背景 二.具体使用方法以及遇到的问题 三.解决办法 一.背景 按公司要求做一个电商网站,考虑到seo,所以用的是nuxt进行开发. 登录之后记录用户信息(user)使用cookie+vuex模式. 二.具体使用方法以及遇到的问题 1.无法解码导致无法转化为对象且不支持中文: 使用nuxt的nuxtServerInit在在服务端的cookie里获取用户信息,但是user在存储时使用js-cookie,客户端已对数据进行编码且可能包含中文,在使用JSON.parse进行string转化为对

  • springboot整合freemarker的踩坑及解决

    目录 springboot整合freemarker踩坑 报错 问题原因 解决方法 springboot freemarker基础配置及使用 1.基础配置 2.基础使用 springboot整合freemarker踩坑 报错 2021-04-23 02:01:18.148 ERROR 9484 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatc

  • 记VUE3+TS获取组件类型的方法踩坑及解决

    目录 VUE3+TS获取组件类型的方法踩坑 遇到的坑 问题原因 解决办法 VUE3+TS获取组件ref实例 如何获取组件的类型呢? 总结 VUE3+TS获取组件类型的方法踩坑 获取组件类型的方法 const AccountRef = ref<InstanceType<typeof LoginAccount>>() 遇到的坑 typeof LoginAccount一直报红线提示错误 LoginAction: () => vo...' provides no match for

  • Vue3+Tsx给路由加切换动画时的踩坑及解决

    目录 项目场景 样式文件 步骤 最终代码 总结 项目场景 用最新的技术栈Vue+Tsx给后台管理系统路由加动画时,语法上与模板语法有些许不同,记录下自己的踩坑记录 样式文件 新建文件transition.scss,这里用的是若依框架人家写好的样式,写好之后在全局引入该样式文件 // global transition css /* fade */ .fade-enter-active, .fade-leave-active { transition: opacity 0.28s; } .fade

  • FastJSON字段智能匹配踩坑的解决

    背景 2021年第一天早上,客户突然投诉说系统的一个功能出了问题,紧急排查后发现后端系统确实出了bug,原因为前端传输的JSON报文,后端反序列化成JavaBean后部分字段的值丢失了. 查看git提交历史记录,前端和后端近期并未对该功能的接口字段做任何修改,联想到上个版本升级了后端的FastJSON的版本,怀疑是后端系统对FastJSON升级导致的问题. 复现 @Data static class Label { @JSONField(name = "label_id") priva

随机推荐