React项目中引用视频播出插件 easyPlayer.js 部署趟坑日志

目录

前文

在写这篇文章之前,写过一篇名为【React 项目中如何使用 easyPlayer-pro.js】的文章,大家可能会有些好奇,为什么在这里会提到另外一篇文章。

他们是有很强的关联性的,这篇文章主要是记录解决问题的过程 ,而【React 项目中如何使用 easyPlayer-pro.js 】这篇文章是最终的结果

因为印象深刻,所以专门为此写下一篇,算是对此次相关问题的一些概括总结。

记录背景

因为一些原因,导致原本的视频播放插件不能继续支持项目需求,所以对视频播放插件进行更换,所以 easyPlayer.js 插件就承担起了本次视频播放的主角。

刚开始在开发环境中都挺顺利,但是当打包部署的时候就出现了一些问题,为解决这些问题花费了一些时间,解决过程有些波折,也是耗费很多心思,所以就打算给记录下来,算是一件小有感触的特殊事件。

问题摸排:第一天

因为有了 【React 项目中如何使用 easyPlayer-pro.js】 这篇文章,所以有些问题我就不继续在这里啰嗦,如有需要请前往查看。

前端打包失败?

因为本地运行正常,经过查看本地打包也正常,该有引入的文件也正常引入,该有的资源也有,但是为什么就不生效了,难道是远程打包失败了?

总结:正常引入,资源存在,没问题

远程打包逻辑与本地打包逻辑不一致?

本地没问题,那就远程有问题了?

如下操作:

  1. 查看打包资源地址,代码分支名称

  2. 查看远程打包命令

    bash 复制代码
    dir=`pwd`
    npm config set registry=https://registry.npmmirror.com/
    rm -rf [文件夹名称]
    git clone -b [分支名] [仓库地址]
    mkdir -p output/bin/static
    cd [文件夹名称]
    npm config set unsafe-perm true
    npm cache clean -f
    rm -rf node_modules
    npm install
    npm run build:test || exit 1
    rm -rf $dir/output/bin/static/*
    cp -rf build/*   $dir/output/bin/static
    cd ..

    因为项目的保密性,一些关键性的内容,就不展示了。

  3. 查看打包后的文件

总结:经查看,仓库地址,分支名称,运行命令,打包结果都没问题。

远程入口页被篡改?

查看线上入口文件,是否有我引入的文件以及一些特殊标识。

打开后简直懵逼了有没有,打包的入口页呢?资源去哪儿呢?添加的一些特殊标识呢?

难道说不是用这个入口文件,用了其他的吗,还是说打包根据环境变量对 webpack 有特殊配置?

再次排查本地webpack打包逻辑

  1. 检查根目录下 .env 打头的多个环境变量文件
  2. 检查 webpack 输出

总结:webpack 与 环境变量没问题,并且本地与远程打包命令这些都一致

其实当到这里的时候,已经不知道怎么处理了,先休息一下吧,同时也因为其他工作的原因,只能先暂时搁置。

问题摸排:第二天

晚上下班回去一路上想着问题到底出在哪里,所以第二天到了工位后继续查看问题,问题一天没处理,心里就不踏实。

确认本地与远程打包一致

利用 Git 使用命令 md5sum 将远程的 index.html 文件与 本地打包的index.html 文件做对比。看看有没有不一致。

bash 复制代码
md5Sum  index.html

如下显示:

通过前面的值是否完全相等来判断两个文件是否一致。

总结:完全一致!

排查远程nginx代理

当问题走到这里的时候,我已经不怀疑我的工程代码了,我得从网络层面考虑考虑,是不是中间有第三方页面利用 nginx 做了代理跳转。

但是怎么看呢,我没有对应的权限,只能找运维的同事帮忙查看了。

当付出我心爱的零食后,总算请动了大佬,经查,代理没问题,没有指向其他的地址

总结:代理没问题。

定位问题 index.html 的所在

到这一步的时候,我就开始怀疑后端了,为啥要怀疑他们呢?

原因很简单,因为这个项目是前端和后端集中在一起部署的,不是单纯的前后端分开部署。

既然这样,那就拉后端同事一起看看,找了半天啥也没有找到,后端一口咬定是前端的问题,需要前端自行处理

没办法,只能自己默默继续找问题。

一个上午就这样溜走了,吃过午饭后下午继续。

因为上午查看这个问题导致其他项目需求没有处理,下午只能是尽快处理完手中的活儿,接着看问题。

下午在写其他项目的时候,忽然想到既然线上入口有问题,那就直接到终端里面去查看入口文件长啥样。

这一看不要紧,一看就发现了问题,这个文件居然是存在的,为什么会存在呢?

经过一番排查,能够确定这个入口文件的来源了,一切问题都不再是问题。

是啥呢?

原来后端使用了一个模板引擎,在项目中配置了一个 idx.ftl 的文件,这个文件经过编译后就是测试环境线上的入口文件。

他长这样:

java 复制代码
<#assign currentTime = "${.now?long?c}">

<!doctype html>
<html lang="en">
  <head>
    <meta name="thirdHomePage" content="${thirdHomePage}">
    <meta name="AppPublic" content=".">
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
    <meta charset="utf-8"/><meta name="AppPublic" content="不便展示">
    <link rel="icon" href="./favicon.ico?v=1" type="image/x-icon">
    <title>你的爱豆</title>
    <link href="./static/css/main.css?v=${currentTime}" rel="stylesheet">
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script src="./static/js/commons.js"></script>
    <script src="./static/js/main.js?v=${currentTime}"></script>
  </body>
</html>

这一切的一切都说的通了,index.html 已定位。

更改 index.html 中对依赖插件的引入

针对引入文件丢失,标识丢失,只需要修改修改即可,如下:

java 复制代码
<#assign currentTime = "${.now?long?c}">

<!doctype html>
<html lang="en">
  <head>
    <meta name="thirdHomePage" content="${thirdHomePage}">
    <meta name="AppPublic" content=".">
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
    <meta charset="utf-8"/><meta name="AppPublic" content="不便展示">
    <link rel="icon" href="./favicon.ico?v=1" type="image/x-icon">
    <title>你的爱豆</title>
    <link href="./static/css/main.css?v=${currentTime}" rel="stylesheet">
  </head>
  <body>
  	
  	<!-- 重要 -->
    <script src="./js/easyplayer-pro.js"></script>
    
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script src="./static/js/commons.js"></script>
    <script src="./static/js/main.js?v=${currentTime}"></script>
    
    <!-- 重要 -->
    <script>window.EasyPlayerPro = EasyPlayerPro</script>
    
  </body>
</html>

代码中标示 **【重要】**的部分就是本次需要添加的内容。

到这里基本问题不大,还是需要做进一步的验证。

资源加载失败?

本以为部署后,就没问题了,谁知道,资源居然加载不出来,不知道文件为啥不能指向 index.html 同级目录下的js文件夹下,但是可以访问 ./static/ 目录下的资源。

最终没办法继续修改为跟 <script src="./static/js/commons.js"></script> 这个引入目录一致。

java 复制代码
<#assign currentTime = "${.now?long?c}">

<!doctype html>
<html lang="en">
  <head>
    <meta name="thirdHomePage" content="${thirdHomePage}">
    <meta name="AppPublic" content=".">
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
    <meta charset="utf-8"/><meta name="AppPublic" content="不便展示">
    <link rel="icon" href="./favicon.ico?v=1" type="image/x-icon">
    <title>你的爱豆</title>
    <link href="./static/css/main.css?v=${currentTime}" rel="stylesheet">
  </head>
  <body>
  	
  	<!-- 重要:重新修改引入地址 -->
    <script src="./static/js/easyPlayerPro/easyplayer-pro.js"></script>
    
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script src="./static/js/commons.js"></script>
    <script src="./static/js/main.js?v=${currentTime}"></script>
    
    <!-- 重要 -->
    <script>window.EasyPlayerPro = EasyPlayerPro</script>
    
  </body>
</html>

然后将对应的资源手动拷贝到 /static/js/easyPlayerPro/ 目录下,再次重新打包部署。

成功了
惊不惊喜,太惊喜了。

引入成功

经过后端同事的重新部署,发现生效了,如下:


这都说明最重要的已经解决了,到此就算是前进了一大步。

可是这里虽然成功了,但是还是有问题,不能每次打包都要手动去拷贝一次资源吧,所以只能将webpack再拿出来改吧改吧。

目标:将 public 下的 js文件夹在打包的是拷贝到 static/js/ 目录下

看到这个标题,很多的朋友脑海中自动回显一个 webpack 插件: copy-webpack-plugin,这个是专门用于拷贝文件的插件,用着也很好用,这下按照以往的思路直接上手修改就行了。

下载 copy-webpack-plugin 插件

webapck 4 地址

对于customize-cra版本为1.0.0和react版本为16.13.1的项目,copy-webpack-plugin 的版本并没有特定的要求,因为它与customize-cra和react版本不直接相关。copy-webpack-plugin是一个Webpack插件,用于复制文件和目录,它的使用并不依赖于React或customize-cra的具体版本。

截至我知识更新的时间点(2023年),你通常可以使用copy-webpack-plugin的任何版本,只要它与你使用的Webpack版本兼容。copy-webpack-plugin的最新版本应该与Webpack 4和Webpack 5都兼容,但如果你使用的是较旧的Webpack版本,你可能需要选择一个对应的copy-webpack-plugin版本。

对于Webpack 4(这可能是与react版本16.13.1一起使用的Webpack版本),copy-webpack-plugin的版本可以是5.x或更早的版本。以下是一个兼容性的例子:

bash 复制代码
npm install copy-webpack-plugin@^5.0.0 --save-dev

如果你使用的是Webpack 5,copy-webpack-plugin的版本应该是6.x或更新版本:

bash 复制代码
npm install copy-webpack-plugin@^6.0.0 --save-dev

由于你的customize-cra版本是1.0.0,这个版本是针对Webpack 4的。因此,建议安装copy-webpack-plugin的5.x版本,这样可以确保兼容性:

bash 复制代码
npm install copy-webpack-plugin@5 --save-dev

在安装了合适的copy-webpack-plugin版本之后,你就可以按照前面提供的方法在config-overrides.js中配置它了。

本地修改打包逻辑

问题得以解决,离成功又近了一步,再加上有了新思路,那心情是倍儿爽,内心有个声音告诉我:"这次一定能行",经过一顿操作:

javascript 复制代码
module.exports = {
  	webpack: override(
  		// 输出文件配置
		appBuildOutput: (config) => {
			// 其他配置...
			config.plugins.push(
				new CopyWebpackPlugin({
					patterns: [
						{
							from: 'public/js/*.js', // 指定public目录下js文件夹中的所有.js文件
							to: 'static/js/easyPlayerPro/[name].[ext]', // 指定目标路径,[name]和[ext]是文件名和扩展名的占位符
						}
					]
				})
			);
			
			return  config;
		}
	)
}

修改后再次执行 npm run build,最终结果看这个篇幅也是显而易见的,居然报错:[copy-webpack-plugin] patterns must be an array,惊不惊喜意不意外,当真是 【世事无常,大肠包小肠】。

以往的经验失效了,为啥呢?

[copy-webpack-plugin] patterns must be an array?

经过 GPT 哥的讲解:

如果你在使用 CopyWebpackPlugin 时遇到错误信息 [copy-webpack-plugin] patterns must be an array,这意味着你提供给 CopyWebpackPluginpatterns选项不是一个数组。这个选项是用来指定文件拷贝规则的,它必须是一个包含至少一个对象的数组。
下面是一个 "正确"CopyWebpackPlugin 配置示例,它指定了一个 patterns 数组:

javascript 复制代码
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  // ...其他配置
  plugins: [
    new CopyWebpackPlugin({
      patterns: [
        {
          from: 'path/to/source/*', // 指定要复制的源文件或目录(支持glob语法)
          to: 'path/to/destination/[name][ext]', // 指定目标路径,[name]和[ext]是占位符
          // 可以添加更多配置选项,例如 noErrorOnMissing
          noErrorOnMissing: true,
        },
        // 如果需要,可以在这里添加更多的pattern对象
      ],
    }),
  ],
};

确保你的 patterns 属性是一个数组,并且每个元素都是一个对象,它描述了拷贝的规则。如果你在config-overrides.js 中使用 addWebpackPlugin 来添加 CopyWebpackPlugin,它应该看起来像下面这样:

javascript 复制代码
const { override, addWebpackPlugin } = require('customize-cra');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = override(
  addWebpackPlugin(
    new CopyWebpackPlugin({
      patterns: [
        // 确保这里是一个数组,包含至少一个pattern对象
        {
          from: 'public/js/*.js',
          to: 'static/js/[name][ext]',
        },
      ],
    })
  )
);

如果 patterns 不是数组或者数组中的对象不符合预期格式,就会导致出现错误。检查你的配置,确保每个 pattern 对象都有正确的属性和格式。

这个看着跟我写的基本没多大区别,那就再找找度娘看看,得到的结论基本一致,所以能够想象得到是行不通的。

实在没办法,那就只能查看 copy-webpack-plugin 是如何传参的,所以去看看他的源码是怎么写的,以下是他的源码内容:

进去一眼就看到这个错误(途中画红线的位置),再接着看接收参数的地方,发现定义的类 CopyPlugin 接收两个参数:patterns 和 options,patterns是一个数组,options是一个对象

要正确地使用这个类,需要确保传递给它的 patterns参数是一个数组,而 options参数是一个对象

既然报错的根源已经找到,那就解决它,将参数给传正确。

问题解决

javascript 复制代码
module.exports = {
  	webpack: override(
  		// 输出文件配置
		appBuildOutput: (config) => {
		
			// 其他配置...
			config.plugins.push(
				new CopyWebpackPlugin(
					[
						{
							from: 'public/js/*.js', // 指定public目录下js文件夹中的所有.js文件
							to: 'static/js/easyPlayerPro/[name].[ext]', // 指定目标路径,[name]和[ext]是文件名和扩展名的占位符
						}
					]
				)
			);
			
			return  config;
		}
	)
}

再次执行打包命令:npm run build,因为打包执行篇幅以及一些敏感信息,就不截全内容了,望大家理解。

到这里可以看到最后是成功打包,是否将 public 下的 js 文件成功的拷贝到 static/js/ 目录下,请看下面的截图:

到这一步,就算是前端打包工作内容部分结束了。可是就完全结束了吗,可以明确的说:还没有。还需要后端将 idx.ftl 文件中对 easyPlayer-pro.js 的引入地址再次修改一下。

经过后端同学的再次辛苦修改后,部署到测试环境,控制输入 window.EasyPlayerPro 是能够打印输出东西的,如下图所示:

最后

这次问题的排查,耗费了我两天半的时间,虽然中间不可能完全一心一意的将所有时间用来排查这个任务,但总体来说,时间从开始到解决确实花费了这么多,但好在是总算得以解决,心里又得一个石头总算是落下了。

写到最后,这篇文章写的有些繁杂且内容有些偏长,但总体来说,这算是我遇到这个问题进行排查的一些心路历程,希望对一些朋友有所帮助,该借助的力量一定要用起来

看到这里的朋友,耽搁您一些宝贵的时间,借助您的 黄金手指 多多 点赞,搜藏,评论

相关推荐
m0_748232922 分钟前
[项目][boost搜索引擎#4] cpp-httplib使用 log.hpp 前端 测试及总结
前端·搜索引擎
新中地GIS开发老师7 分钟前
《Vue进阶教程》(12)ref的实现详细教程
前端·javascript·vue.js·arcgis·前端框架·地理信息科学·地信
m0_7482495410 分钟前
前端:base64的作用
前端
html组态16 分钟前
web组态可视化编辑器
前端·物联网·编辑器·web组态·组态·组态软件
~央千澈~23 分钟前
如果你的网站是h5网站,如何将h5网站变成小程序-除开完整重做方法如何快速h5转小程序-h5网站转小程序的办法-优雅草央千澈
前端·apache
m0_7482398335 分钟前
基于web的音乐网站(Java+SpringBoot+Mysql)
java·前端·spring boot
时雨h39 分钟前
RuoYi-ue前端分离版部署流程
java·开发语言·前端
爱喝奶茶的企鹅43 分钟前
Next.js 14 性能优化:从首屏加载到运行时优化的最佳实践
react.js
Cachel wood1 小时前
Django REST framework (DRF)中的api_view和APIView权限控制
javascript·vue.js·后端·python·ui·django·前端框架
m0_748234081 小时前
Spring Boot教程之三十一:入门 Web
前端·spring boot·后端