赞
踩
在写这篇文章之前,写过一篇名为【React 项目中如何使用 easyPlayer-pro.js】的文章,大家可能会有些好奇,为什么在这里会提到另外一篇文章。
他们是有很强的关联性的,这篇文章主要是记录解决问题的过程,而【React 项目中如何使用 easyPlayer-pro.js】这篇文章是最终的结果。
因为印象深刻,所以专门为此写下一篇,算是对此次相关问题的一些概括总结。
因为一些原因,导致原本的视频播放插件不能继续支持项目需求,所以对视频播放插件进行更换,所以 easyPlayer.js
插件就承担起了本次视频播放的主角。
刚开始在开发环境中都挺顺利,但是当打包部署的时候就出现了一些问题,为解决这些问题花费了一些时间,解决过程有些波折,也是耗费很多心思,所以就打算给记录下来,算是一件小有感触的特殊事件。
因为有了 【React 项目中如何使用 easyPlayer-pro.js】 这篇文章,所以有些问题我就不继续在这里啰嗦,如有需要请前往查看。
因为本地运行正常,经过查看本地打包也正常,该有引入的文件也正常引入,该有的资源也有,但是为什么就不生效了,难道是远程打包失败了?
总结:正常引入,资源存在,没问题
本地没问题,那就远程有问题了?
如下操作:
查看打包资源地址,代码分支名称
查看远程打包命令
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 ..
因为项目的保密性,一些关键性的内容,就不展示了。
查看打包后的文件
总结:经查看,仓库地址,分支名称,运行命令,打包结果都没问题。
查看线上入口文件,是否有我引入的文件以及一些特殊标识。
打开后简直懵逼了有没有,打包的入口页呢?资源去哪儿呢?添加的一些特殊标识呢?
难道说不是用这个入口文件,用了其他的吗,还是说打包根据环境变量对 webpack 有特殊配置?
.env
打头的多个环境变量文件webpack
输出总结:webpack 与 环境变量没问题,并且本地与远程打包命令这些都一致
其实当到这里的时候,已经不知道怎么处理了,先休息一下吧,同时也因为其他工作的原因,只能先暂时搁置。
晚上下班回去一路上想着问题到底出在哪里,所以第二天到了工位后继续查看问题,问题一天没处理,心里就不踏实。
利用 Git
使用命令 md5sum
将远程的 index.html
文件与 本地打包的index.html
文件做对比。看看有没有不一致。
md5Sum index.html
如下显示:
通过前面的值是否完全相等来判断两个文件是否一致。
总结:完全一致!
当问题走到这里的时候,我已经不怀疑我的工程代码了,我得从网络层面考虑考虑,是不是中间有第三方页面利用 nginx
做了代理跳转。
但是怎么看呢,我没有对应的权限,只能找运维的同事帮忙查看了。
当付出我心爱的零食后,总算请动了大佬,经查,代理没问题,没有指向其他的地址
。
总结:代理没问题。
到这一步的时候,我就开始怀疑后端了,为啥要怀疑他们呢?
原因很简单,因为这个项目是前端和后端集中在一起部署的,不是单纯的前后端分开部署。
既然这样,那就拉后端同事一起看看,找了半天啥也没有找到,后端一口咬定是前端的问题,需要前端自行处理。
没办法,只能自己默默继续找问题。
一个上午就这样溜走了,吃过午饭后下午继续。
因为上午查看这个问题导致其他项目需求没有处理,下午只能是尽快处理完手中的活儿,接着看问题。
下午在写其他项目的时候,忽然想到既然线上入口有问题,那就直接到终端里面去查看入口文件长啥样。
这一看不要紧,一看就发现了问题,这个文件居然是存在的,为什么会存在呢?
经过一番排查,能够确定这个入口文件的来源了,一切问题都不再是问题。
是啥呢?
原来后端使用了一个模板引擎,在项目中配置了一个 idx.ftl
的文件,这个文件经过编译后就是测试环境线上的入口文件。
他长这样:
<#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 已定位。
针对引入文件丢失,标识丢失,只需要修改修改即可,如下:
<#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>
这个引入目录一致。
<#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再拿出来改吧改吧。
看到这个标题,很多的朋友脑海中自动回显一个 webpack 插件: 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或更早的版本。以下是一个兼容性的例子:
npm install copy-webpack-plugin@^5.0.0 --save-dev
如果你使用的是Webpack 5,copy-webpack-plugin的版本应该是6.x或更新版本:
npm install copy-webpack-plugin@^6.0.0 --save-dev
由于你的customize-cra版本是1.0.0,这个版本是针对Webpack 4的。因此,建议安装copy-webpack-plugin的5.x版本,这样可以确保兼容性:
npm install copy-webpack-plugin@5 --save-dev
在安装了合适的copy-webpack-plugin版本之后,你就可以按照前面提供的方法在config-overrides.js中配置它了。
问题得以解决,离成功又近了一步,再加上有了新思路,那心情是倍儿爽,内心有个声音告诉我:“这次一定能行”,经过一顿操作:
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
,惊不惊喜意不意外,当真是 【世事无常,大肠包小肠】。
以往的经验失效了,为啥呢?
经过 GPT 哥的讲解:
如果你在使用
CopyWebpackPlugin
时遇到错误信息[copy-webpack-plugin] patterns must be an array
,这意味着你提供给CopyWebpackPlugin
的patterns
选项不是一个数组。这个选项是用来指定文件拷贝规则的,它必须是一个包含至少一个对象的数组。
下面是一个
"正确"
的CopyWebpackPlugin
配置示例,它指定了一个patterns
数组:
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
,它应该看起来像下面这样:
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参数是一个对象
。
既然报错的根源已经找到,那就解决它,将参数给传正确。
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 是能够打印输出东西的,如下图所示:
这次问题的排查,耗费了我两天半的时间,虽然中间不可能完全一心一意的将所有时间用来排查这个任务,但总体来说,时间从开始到解决确实花费了这么多,但好在是总算得以解决,心里又得一个石头总算是落下了。
写到最后,这篇文章写的有些繁杂且内容有些偏长,但总体来说,这算是我遇到这个问题进行排查的一些心路历程,希望对一些朋友有所帮助,该借助的力量一定要用起来。
看到这里的朋友,耽搁您一些宝贵的时间,借助您的 黄金手指 多多 点赞,搜藏,评论。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。