使用react-scripts测试canvas的注意事项

本文档详细介绍了在React Scripts 3版本中遇到的Canvas测试问题以及CSS引用网络文件导致的编译问题。首先,由于jsdom版本过低,无法支持canvas测试,而升级到React Scripts 4虽然解决了Canvas问题,却又引入了CSS引用的bug。为在React Scripts 3中支持canvas测试,通过调整node_modules中jest配置,将jsdom版本提升到14.1.0,成功实现了测试需求,同时项目仍能正常编译运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结论

1、react-scripts3的最新版本是3.4.3,该版本的jsdom版本太低,不能支持对canvas进行测试,具体表现为执行document.createElement('canvas').getContext('2d')获得的返回值为undefined。虽然会提示安装canvas包可以解决问题,但由于jsdom版本太低实际上并不行。

2、react-scripts4的jsdom版本支持对canvas进行测试,在安装了canvas包后对canvas的相关函数有很好的支持。但react-scripts4版本无法解析在css、less等样式文件中使用url引用网络文件的方式,会导致使用了url引用文件的项目编译不通过,目前该bug还没有解决。

3、对react-scripts3版本下调整node_modules中的部分目录结构可以实现jsdom版本的升级从而实现在react-scripts3版本下也能支持canvas测试。

 

详细过程

发现getContext('2d')的返回值是null

        在一次编写测试用例的过程中发现报错:Cannot read property 'font' of null,定位发现是在document.createElement('canvas').getContext('2d')上取font属性时报的,也就是说getContext('2d')的结果是null。但是在浏览器中运行时该结果并不是null:

        通过在测试用例中打断点调试,发现在用例运行时,该函数的返回值确实是null,和浏览器中运行的结果不同:

        原因是react-scripts运行测试用例虽然是指定了运行环境是jsdom,但jsdom毕竟是类浏览器环境,和真实的浏览器环境还是有差别,在canvas上jsdom没有做到完全支持。

stackoverflow上对该问题的回答:https://stackoverflow.com/questions/33269093/how-to-add-canvas-support-to-my-tests-in-jest

jsdom官方提供的解决方案:https://github.com/jsdom/jsdom#canvas-support

 

安装了canvas但不生效

        按jsdom官方的说法,jsdom会去寻找canvas包是否安装,如果安装了就可以支持和canvas相关的API,没有安装就会把canvas标签当做div来处理。实际上在测试报错的位置也有相关的提示:

        但是在安装了canvas之后,还是有这个提示,并且getContext('2d')还是返回null。原因是jsdom在v13之后才支持和canvas包协同支持canvas特性,而且还要求canvas的版本>2。

        但是当前使用的react-scripts版本是3.4.3,跟随安装的jsdom的版本是11.12.0,因此即使安装了canvas也无法支持canvas特性:

 

更换了react-scripts4遇到了编译问题

        升级react-scrips到4.0.3之后运行canvas相关api可以得到正确的值了:

        但运行项目的时候遇到了问题:

        控制台提示无法解析,无法解析的代码是这一段,是通过URL网络请求获取图片:

        但是相同的代码在react-scripts3中是可以运行的,通过搜索,最终发现这是react-scripts4的一个bug:https://github.com/facebook/create-react-app/issues/9870,目前这个issue还没有关闭,这个问题应该还没有解决。如果为了解决canvas测试的问题而升级到react-scripts4,会导致项目的编译出问题。

 

如何在react-scripts3中测试canvas

        react-scripts3中的jsdom版本是11.12.0,jsdom支持canvas的版本是13之后,因此react-scripts3中的jsdom不支持对canvas进行测试。如果要支持,得把jsdom的版本单独升级上来。但是如果安装了新的jsdom,会破坏其他三方件的依赖关系,同时react-scripts运行时会提示有重复的jsdom存在,要求先卸载。因此也不能简单地升级。

        在项目中查看jsdom版本时可以看到其实当前项目中有两个jsdom:

        一个是react-scripts中依赖的jest带的jsdom,react-scripts运行单元测试时也是用的这个版本的jsdom。一个是react-scripts自己配置的依赖jest-environment-jsdom-fourteen带的jsdom,这个jsdom版本是14.1.0,满足>=13的要求。可以尝试把jest-config所依赖的jest-environment-jsdom换成jest-environment-jsdom-fourteen,从而实现jsdom版本的升级。

操作步骤(均在node_modules目录下进行):

  1. 重命名jest-environment-jsdom为jest-environment-jsdom-bak;
  2. 重命名jest-environment-jsdom-fourteen为jest-environment-jsdom;

 完成以上步骤后可以实现在react-scripts3下支持canvas测试,也可以正常编译运行项目。

        在查看jsdom版本时会有一些报错信息:

        这是因为修改了目录后部分依赖丢失了导致的,不影响项目运行和测试。

 

{ "name": "lowcode-demo", "version": "1.0.10", "description": "Low-Code Engine 低代码搭建引擎 Demo 项目", "scripts": { "eslint": "eslint \"./src/**/*.{vue,html,js,jsx,ts,tsx}\"", "build": "set NODE_OPTIONS=--openssl-legacy-provider && build-scripts build && sh ./scripts/delete.sh", "build:AUI": "set NODE_OPTIONS=--max_old_space_size=8096 && build-scripts build --config build.aurora-vue.json", "prepublishOnly": "npm run build", "pub": "node ./scripts/watchdog.js && npm pub", "start": "set NODE_OPTIONS=--max_old_space_size=9896 && build-scripts start --disable-reload --port 5556", "stylelint": "stylelint \"./src/**/*.{vue,htm,html,css,sss,less,scss,sass}\" --cache --cache-location node_modules/.cache/stylelint/", "analyz": "set NODE_ENV=production && set npm_config_report=true && npm run build" }, "main": "index.js", "files": [ "build" ], "dependencies": { "@aurora/service": "~2.5.0", "@aurora/vue": "5.0.38", "@aurora/vue-cli-plugin-aurora-theme": "~3.0.13", "@aurora/vue-icon": "~5.0.0", "@wecode/welink-wlkh5-sdk": "^1.0.1", "element-ui": "2.15.12", "html2canvas": "1.4.1", "jquery": "3.6.3", "lodash": "4.17.21", "uuid": "v10.0.0", "vue": "2.6.14" }, "devDependencies": { "@alib/build-scripts": "0.1.32", "@alilc/lowcode-engine": "1.1.6", "@alilc/lowcode-engine-ext": "1.0.5", "@alilc/lowcode-plugin-components-pane": "1.0.7", "@alilc/lowcode-plugin-inject": "1.2.2", "@alilc/lowcode-plugin-schema": "1.0.2", "@alilc/lowcode-types": "1.0.3", "@alilc/lowcode-utils": "1.1.6", "@ffe/engine-vue-utils": "2.0.23", "@ffe/eslint-config-ffe": "1.0.29", "@ffe/fcore-lowcode-env": "1.1.5", "@ffe/stylelint-standard": "^1.0.10", "@types/events": "^3.0.0", "@types/react": "16.8.6", "@types/react-dom": "16.8.4", "build-plugin-moment-locales": "^0.1.0", "build-plugin-react-app": "^1.1.2", "copy-webpack-plugin": "5.1.2", "cross-env": "7.0.3", "css-loader": "3.6.0", "eslint": "8.34.0", "eslint-plugin-import": "^2.29.1", "fs-extra": "^10.0.1", "husky": "^8.0.3", "less-loader": "^7.3.0", "moment": "2.29.4", "prettier": "^2.8.8", "prop-types": "^15.5.8", "react": "16.14.0", "react-dom": "16.14.0", "screenfull": "5.2.0", "tsconfig-paths-webpack-plugin": "3.2.0", "vue-clipboard2": "0.3.3", "vue-grid-layout": "2.4.0", "vue-i18n": "8.27.2", "vue-loader": "15.9.8", "vue-router": "3.6.5", "vue-style-loader": "^4.1.3", "vue-template-compiler": "2.6.14", "vuera": "^0.2.7", "webpack-bundle-analyzer": "^4.10.2", "xlsx": "0.17.0" }, "config": {}, "license": "MIT", "repository": "git@github.com:alibaba/lowcode-demo.git" } 上面是packetjson,这个项目的依赖还能做什么优化?
最新发布
06-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值