【异常】记一次前端因资源无法加载导致白屏异常问题

news2024/11/26 21:51:13

一、背景

自从运维同事强烈要求前端的环境要使用多套的,参考文章
【项目】参考若依的前端框架去多环境
于是一番捣鼓与改造之后,看似已经顺利了
在这里插入图片描述
但运维说,前端还是有问题,需要他帮我改下,于是改了如下内容
在这里插入图片描述
什么嘛,为啥要帮我加上web?然后说还剩下最后一个问题,留给我慢慢改(自行解决)。
内心崩溃,为啥不一起改了呢??于是让我们来分析到底问题出在了哪里???

二、异常截图

2.1 页面:沙箱环境的前端页面显示了白屏

在这里插入图片描述

2.1 F12查看 控制台输出

F12一查看,错误的内容提示如下红色的部分,提示的意思是说以下JS的资源找不到
在这里插入图片描述
放大一点点看
在这里插入图片描述
在这里插入图片描述

这些文件都是哪里产生的呢?404就是提示找不到文件路径的报错嘛明显是~

前端大神说这个 web 目录,webpack 不会自动帮你生成的,需要自己在服务器创建 web 目录
然后把所有的资源文件,放在 web 目录下,其实是一个道理嘛。详细是以下代码进行dist的移动工作的
在这里插入图片描述

运维的很明白,因为加了web目录文件,前端打包完的dist文件是放在web目录下的。
因此,需要 解决的问题是 把这些JS等资源文件都要移动到 web路径,但是应该怎么实现呢?
在这里插入图片描述

三、问题排查与修复

3.1 定位错误代码, 查看configureWebpack

首先怀疑的是就是这个内容,发现以下的写法,我也看不懂啊。
在这里插入图片描述
这一段是对输出output进行配置,对文件名进行加version之类的吧?
version是一个变量,变量值的话,在前面有定义过
const version = new Date().getTime() + '-' + process.env.VERSION
原来写这一块的前端同事反馈,这个是因为某个项目出现过缓存没有及时更新的问题,于是需要加上这个配置
但是这里明显是有问题,从输出来看,web前缀,并没有帮我加上?那问题究竟出在哪?

一轮百度以及请教了前端大神之后发现,以下的写法确实是有问题的~大家的通用做法是这样的。
参考以下配置,我们开始了调试之旅

output: {
    filename: '[name].[chunkhash].js',
    chunkFilename: '[name].[chunkhash].js',
    publicPath: publishPath.publishPath + publishPath.prefix +'/'
  },

3.1.1 尝试1:加上前缀/web (无效)

试着加上前缀

        output: {
            filename: `/web/js/[name].${version}.js`,
            chunkFilename: `/web/js/[name].${version}.js`
        },

3.1.2 尝试2: 增加process.env.VUE_APP_CONTEXT_PATH前缀

        output: {
            filename: `${process.env.VUE_APP_CONTEXT_PATH}js/[name].${version}.js`,
            chunkFilename: `${process.env.VUE_APP_CONTEXT_PATH}js/[name].${version}.js`
        }

3.1.3 尝试3:注释掉output(无效)

        //output: {
            // filename: `${process.env.VUE_APP_CONTEXT_PATH}js/[name].${version}.js`,
            // chunkFilename: `${process.env.VUE_APP_CONTEXT_PATH}js/[name].${version}.js`
       //}

3.1.4 尝试4: 删除version (无效)

          output: {
            filename: `/web/js/[name].js`,
            chunkFilename: `/web/js/[name].js`
         },

3.1.5 尝试5:增加publishPath和path (无效)

         output: {
            filename: `/web/js/[name].js`,
            chunkFilename: `/web/js/[name].js`
            publishPath: 'web/',
            path: path.resolve(__dirname, "dist"), // string
         },

3.1.6 经过多轮尝试与请教后,最后的正确版本是

const isDev = process.env.ENV === 'development'
 output: {
            filename: isDev ? `[name].js` : `[name].[chunkhash].js`,
            chunkFilename:  isDev ? `[name].js` :`[name].[chunkhash].js`,
 },

看到这,你肯定会有以下的疑问?

  • (1)为啥要加上isDev
    参考一下文章:
    【异常】Cannot use [chunkhash] or [contenthash] for chunk in ‘[name].[chunkhash].js‘

  • (2)chunkhash的作用是啥?
    后面的文章会讲到, 反正最后是配置了这个,这个是请教了前端大佬给的建议

  • (3)为什么去掉了publishPath?
    因为vue对webpack进行重写了,publishPath提前写了。
    在这里插入图片描述
    在这里插入图片描述

3.2 尝试在本地进行prod脚本的构建

听前端大神的,可以先排除一下自己编译出来的文件有没有问题,那就本地先build起来啊!
本地能build,服务器也肯定能build的啊,然后看一下生成的 dist 目录里有啥先。

于是现在对本地进行调试吧 ,本地build一下先,但是本地遇到了不能build 情况, 如果本地都不能 build,那么部署是不会成功的

3.2.1 configuration.output.chunkFilen iame: A relative path is expected.

本地的构建过程中,得到过这个错误提示
什么相对路径的问题?看来还不能乱配置 斜杠啊。

 - configuration.output.chunkFilename: A relative path is expected. However, the provided value "/web/js/[name].1673275185922-1.0.0.js" is an absolute path!
   -> The filename of non-entry chunks as relative path inside the `output.path` directory.
WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.

在这里插入图片描述
在这里插入图片描述

3.2.2 npm run build:prod的编写

以下这个是不会进行构建的npm run prod
正确的应该是npm run build:prod,因为里面必须要是有build
在这里插入图片描述
注意:要有类似于以下的输出,才算是真正的build了哦!

在这里插入图片描述
build后,会出现这个dist文件。
在这里插入图片描述
打开的index文件都带有web前缀。难怪找不到文件。。
在这里插入图片描述

什么情况,这个build:prod 的script竟然会写错了?
在这里插入图片描述
这个问题运维也没有发现,其实在Jenkins的构建日志中也是可以看到是没有输出结果的。
因为Jenkins只保留最近几次的构建,历史的已经很难看到了,无法截图输出了。
在这里插入图片描述

3.2.3 在开发环境的也试着加入web前缀

在这里插入图片描述
发现资源文件还是没有找,最后,要将dev的脚本改成如下,才能够正常访问业务。
在这里插入图片描述

四、 看看还有没有其他改动点?

4.1 终于不会白屏啦

终于,通过以上修改,至少不会白屏了。。。终于剩下最后一个问题了啦,这个问题好解决,之前解决过嘿嘿。
在这里插入图片描述

4.2 参考别的项目的配置

运维反馈,这个问题是因为环境配置里的 VUE_APP_BASE_API 没生效
说罢给了以下截图,让我参考
在这里插入图片描述
在这里插入图片描述

4.3 你确定你的Nginx配置没有问题?

于是先怀疑,Nginx的反向代理没有配置或者是配置有错?运维说, 不可能!

4.4 提示了不同的错误码了哦

于是我继续排查,试着加上了web作为前缀,发现还是不行,还是提示错误
不过!!!现在提示502了???有进展!
在这里插入图片描述

4.5 代码重定向的逻辑排查

从异常来看,是 直接进行了代码重定向
在这里插入图片描述
那是那段逻辑进行了重定向呢??于是,便利了代码后锁定以下代码
在这里插入图片描述
让我们详细看看,这一段代码逻辑

import { showSpin, hideSpin } from '@/utils/baseTool'
import axios from 'axios'
import store from '../store'
import { getToken, removeToken } from '../utils/cookie'

// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: '/api/',
  // 超时
  timeout: 100000,
  headers: {
    get: {
      'Content-Type': 'application/json;charset=utf-8'
    }
  }
})

// request拦截器
service.interceptors.request.use(
  config => {
    // 登录界面
    if (config.url.indexOf('/login') !== -1) {
      config.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'
      config.headers.Accept = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
    } else if (getToken()) {
      config.headers.Authorization = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
    }
    showSpin()
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  res => {
    hideSpin()
    const code = res.data.resultCode
    if (code) {
      if (code === 401) {
        store.dispatch('LogOut').then(() => {
          location.href = '/#/login' // 为了重新实例化vue-router对象 避免bug
        })
      } else if (code === 1005) { // 用户未登录
        removeToken()
        location.href = '/#/login'
      } else if (code !== 0) {
        const errorMsg = res.data.resultDesc
        return Promise.reject(new Error(errorMsg))
      }
    } else {
      return res.data
    }
  },
  error => {
    hideSpin()
    return Promise.reject(error)
  }
)

export default service

在创建 创建axios实例的时候,使用了baseURL: '/api/',

这是不是就是我要的呢?我希望在所有的请求前面都加上/web的前缀 啊。

4.6 代码逻辑调整

于是做了如下代码的调整

(1)定义前缀变量

const prefix = process.env.VUE_APP_CONTEXT_PATH

(2)baseURL的修改

// 创建axios实例
const service = axios.create({
    // axios中请求配置有baseURL选项,表示请求URL公共部分
    baseURL: process.env.VUE_APP_BASE_API,
    // 超时
    timeout: 100000,
    headers: {
        get: {
            'Content-Type': 'application/json;charset=utf-8'
        }
    }
})

(3)使用前缀变量

           if (code === 401) {
                store.dispatch('LogOut').then(() => {
                    location.href = prefix + '#/login' // 为了重新实例化vue-router对象 避免bug
                })
            } else if (code === 1005) { // 用户未登录
                removeToken()
                location.href = prefix + '#/login'
            } else if (code !== 0) {
                const errorMsg = res.data.resultDesc
                return Promise.reject(new Error(errorMsg))
            }

5、验证

最后,终于是可以进入了,总结为啥会有这此问题吧,

(1)对npm的构建不熟悉,导致了scripts脚本都会写错。
(2)对webpack不熟悉,不懂构建webpack是如何控制构建结果的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/153706.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常用的git管理逻辑

//首先创建新的分支 git branch new_branch//切换到另一个分支 git checkout new_branch//修改代码,添加新的文件 git add .//查看文件的状态 git status//打包自己的改变 git commit -m "comment"//推到远程服务器上 git push origin new_branch// 拉远程…

2022年度打印机行业数据报告:十大热门品牌销量排行榜

随着5G技术的发展,越来越多的设备与人员将通过网络实现互联互通,打印的输入端口与输出端口变得多样与兼容,打印机也在越来越多的领域发挥着强大的作用。并且,随着电子化教学的不断推进以及普及,加之线上办公等场景的需…

Hudi系列2:Hudi安装

文章目录编译环境准备一. 下载并解压hudi二. maven的下载和配置2.1 maven的下载和解压2.2 添加环境变量到/etc/profile中2.3 修改为阿里镜像三. 编译hudi3.1 修改pom文件3.2 修改源码兼容hadoop33.3 手动安装Kafka依赖3.4 解决spark模块依赖冲突3.4.1 修改hudi-spark-bundle的p…

LeetCode 3. 无重复字符的最长子串

🌈🌈😄😄 欢迎来到茶色岛独家岛屿,本期将为大家揭晓LeetCode 3. 无重复字符的最长子串,做好准备了么,那么开始吧。 🌲🌲🐴🐴 目录 一、题目名称…

(02)Cartographer源码无死角解析-(48) 2D点云扫描匹配→暴力搜索匹配原理讲解,扫面匹配总体框架梳理

讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解(02)Cartographer源码无死角解析-链接如下: (02)Cartographer源码无死角解析- (00)目录_最新无死角讲解:https://blog.csdn.net/weixin_43013761/article/details/127350885 文末…

2022消费市场并未降级?麦肯锡调研报告解读

近日全球知名咨询公司麦肯锡发布《2023中国消费者报告》,重磅发布重塑中国消费市场的五大趋势。 趋势一:中等收入人群继续壮大 MGI数据显示,2019~2021年,年收入超过16万元人民币(2.18万美元)的中国城镇家…

nacos配置动态刷新及监听到变化触发一些方法

介绍在使用spring 时,动态更新配置是常见的,属性值更新,但是需要开启支持刷新功能,一个是spring.cloud.nacos.config.isRefreshEnabledtrue; 这个值一般是默认的,可以在nacosConfigProperties这个类中看到。还要在扩展…

【C++】list介绍及使用模拟实现对比vector

文章目录1. list的介绍及使用1.1 list的介绍1.2 list的使用1.2.1 list的构造1.2.2 list iterator以及insert和erase的使用1.2.3 list的迭代器失效2. list的模拟实现2.1 模拟实现list3.(本文精华)list与vector的对比1. list的介绍及使用 1.1 list的介绍 …

图像识别AI程序(数据集管理/训练/预测)

出于对Python中AI智能识别程序的兴趣,对照AI智能识别程序应该具有的主要功能:数据集管理(加载/移除/重命名)、模型训练(可实时监测训练进度、最终训练参数输出)、模型预测,使用Python/Keras编制…

open-local本地存储使用

Open-local使用指南架构组成1. scheduler-extender: 作为 kube-scheduler 的扩展组件,通过 Extender 方式实现,扩展了原生调度器对本地存储资源的感知,以实现对包括磁盘容量、多盘感知、磁盘介质(ssd or hdd&#xff0…

数据分析-深度学习Day5

Backpropagation反向传播我们上节课学习了深度学习,也知道采用梯度下降优化我们的各神经元参数,以语音识别为例,一个输入特征量1000多项,8层隐层,大致需要的w,b参数有数百万项,这样我们梯度下降的计算量是非…

记一次部署在docker环境项目发送邮件出现No appropriate protocol

前言 部门有个项目涉及到邮件发送,发送功能在本地测试可以成功发送,但是打包部署到docker环境中,却出现 No appropriate protocol (protocol is disabled or cipher suites are inappropriate)后面在网上搜索了一下,查到了这篇文…

技术分享 | 测试平台开发-前端开发之Vue.js 框架的使用

首先将 Vue.js 下载到本地,本章就以本地的 Vue.js 为例。在本地创建一个工作区即创建一个文件夹,使用 vscode 打开,将 Vue.js 放到工作区目录下。 创建挂载元素 首先创建一个 index.html 的文件,使用 加载 vue.js,这…

NAT模式虚拟机能ping通宿主机但是telnet不通 教你如何设置网关走出误区

今天跟大家聊聊如何正确配置NAT模式下虚拟机的网关。 如标题所言,我一开始在设置网关的时候一直存在着误区,而这个误区也导致标题中的问题:虚拟机能ping通宿主机,但是telnet不通,这就很奇葩了。 如下网络拓扑图。 虚…

Linux ALSA 之五:ALSA Proc Info

ALSA Proc Info一、概述二、Proc Files of Alsa Driver1、/proc/asound/xxx 简述2、创建 /proc/asound 目录树2.1 /proc/asound/version 文件2.2 /proc/asound/devices 文件2.3 /proc/asound/cards 文件2.4 /proc/asound/cardx 目录2.5 /proc/asound/pcm 文件一、概述 Linux系…

企业不可忽视的舆情监测管理办法,TOOM舆情监控工作总结?

企业做好舆情监控以及舆情管理是对企业负责,在企业发展过程中不可能是一帆风顺的,少不了各种各样的流言蜚语,像舆情监控管理监测早知早解决。接下来我们简单了解企业不可忽视的舆情监测管理办法,TOOM舆情监控工作总结? 一、企业…

【NI Multisim 14.0原理图设计基础——调整元器件位置】

目录 序言 一、调整元器件位置 🍊1.元器件的移动 🍊2.元器件的旋转 🍊3.元器件的对齐 序言 NI Multisim最突出的特点之一就是用户界面友好。它可以使电路设计者方便、快捷地使用虚拟元器件和仪器、仪表进行电路设计和仿真。 首先启动NI…

【自学Python】Python print()函数

Python print()函数 Python print()函数教程 在 Python 中,print() 函数用于打印相应的信息到终端控制台,同时 print() 函数可以支持同时输出一个或多个 变量。 Python print()函数详解 语法 print(*objects, sep , end\n, filesys.stdout, flushFa…

线性代数 --- 投影Projection 六(向量在子空间上的投影)

向量b在多维子空间上的投影回顾:向量在向量上(直线上)的投影在研究向量在子空间上的投影前,先回顾一下前面学习的一个任意向量b在另一个向量a上的投影,共三个部分。1,求权重系数(A constant&…

2022 general purpose in-context learning by meta-learning transformers

wps: option left 回到上一个视图 Kirsch L, Harrison J, Sohl-Dickstein J, et al. General-purpose in-context learning by meta-learning transformers[J]. arXiv preprint arXiv:2212.04458, 2022. 目录Kirsch L, Harrison J, Sohl-Dickstein J, et al. General-purpose…