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 是能够打印输出东西的,如下图所示:

最后

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

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

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

相关推荐
stayong12 小时前
市面主流跨端开发框架对比
前端
一米八二的矮个子12 小时前
JavaScript语法进阶(一)
javascript
庞囧12 小时前
大白话讲 React 原理:Scheduler 任务调度器
前端
liyi_hz200812 小时前
O2OA (翱途)开发平台新版本发布预告:架构升级、性能跃迁、功能全面进化
android·java·javascript·开源软件
东华帝君12 小时前
react 虚拟滚动列表的实现 —— 动态高度
前端
CptW12 小时前
手撕 Promise 一文搞定
前端·面试
温宇飞12 小时前
Web 异步编程
前端
腹黑天蝎座12 小时前
浅谈React19的破坏性更新
前端·react.js
东华帝君12 小时前
react组件常见的性能优化
前端
第七种黄昏12 小时前
【前端高频面试题】深入浏览器渲染原理:从输入 URL 到页面绘制的完整流程解析
前端·面试·职场和发展