工作中的遇到的一些小知识 4
lottie production环境下bug修复总结
现象:
前段时间,用lottie-web做动画的时候,发现在有个别动画在本地测试时可以正常播放,打包上线后会报库代码内的错误
猜测原因:
打包过程中的uglify有损压缩了lottie-web的代码,导致部分特性的bug
修复方式:
- 在webpack配置中,为lottie-web专门指定一个chunk
- 在optimization中,指定一个lottie的cacheGroup,保证一个专门的chunk
- minimizer中uglifyJSConfig指定exclude为lottie的chunk名,避免被uglify
- resolve中,指定lottie-web resolve到’../node_modules/lottie-web/build/player/lottie.min.js’,使用压缩过的版本
大致像下面这样:
1 | module.exports = { |
结果:
问题解决。
Android机型下rem适配不准的问题
通过比较document.documentElement.style.fontSize
和window.getComputedStyle(document.documentElement)['font-size']
,假设前者是a,后者是b,a * a / b
计算得到和设计一致的尺寸。
3D旋转效果
利用CSS中的backface-visibility: hidden;
属性,实现在transform: rotateY(180deg)
时,页面翻转到不可见区域。
egret学习
场景:H5小游戏开发
投放场景:各种小游戏平台,也可以打包为Android、iOS、Windows Phone应用发布,甚至直接web访问H5页面
开发语言:TypeScript
开发方式:
- 类Java的代码组织方式,MVC分离项目代码,M和C开发体验类似“用JavaScript写Java项目”。在View部分开发体验类似于用
canvas API写页面结构
- 类Android的resource管理方式(定义json文件描述资源组和路径对应),在代码中用API动态分组或逐个load资源
- 单一入口,流程上在stage加载完成后,load资源(同时给出loading页面),之后执行游戏逻辑
- 使用dispatchEvent实现组件间的信息交流
项目结构
入口文件为index.html。在其中引入manifest.json。读入所需的库文件后,根据DOM容器的data-*
属性确定项目配置,以及项目入口*.ts
(一般是Main.ts
)。之后打包编译到bin-debug
。
业务逻辑放在/src
下,资源文件放在/resources
中,资源文件用类似于Android的形式进行存取管理。
视图
Displayable元素可以添加到容器中显示。包含下面基类。
- displayableContainer 视图元素容器
- stage
- scrollView
- sprite
- bitmap
- bitmapText
- textField
- movieClip
- shape
movieClip表示逐帧动画。生成方法如下:
RES.getRes
获取资源- 使用factory方法构造movieClipData
- 使用movieClipData构造movieClip
简单动画用tween来实现。
发布
egret publish
或run build。发布H5,runtime版本- 对应平台support工具,如Android、iOS、微信小程序
不过在最新的egret launcher下,项目本身已经提供的发布到原生的快捷入口,参考官方解释。
难点
和React如何结合开发?
View层通过canvas、WebGL实现,不适合和React结合。
部署方式如何结合在App里
小游戏可以发布到HTML5平台,之后类似老的webview页面开发方式,部署到离线包平台或在线页面即可。
SSO实现方案
SSO - Single Sign On 单一站点登录。由一个站点的登录状态实现关联网站免登录。
背景
由sso.xxx.com记录用户登录态,其他需要使用同一登录态的网站需要同步该域名下的登录态cookie到自己的独立域名下。
实际场景
一般公司内部的网站或ToC的集团网页间都有SSO控制,任意访问一个清除了所有cookie网页,观察network中开头的302报文即可发现实现SSO过程中的各跳转逻辑。
实际步骤因实现而异:
- (转让控制权)访问目标网页,302到SSO的跳转特定页面,如jump.sso.xxx.com
- (写入cookie)302回目标网页的特定页面,如sso.mysite.com。该域名CNAME到sso.xxx.com的服务器
- (写入cookie)sso.mysite.com写入cookie到自己的同域名下,再次302到目标网页,完成SSO过程
或者
- 同上
- (写入cookie)jump.sso.xxx.com做cookie的检查确认,通过url的方式写入回调的user session,再302回mysite.com。
- (写入cookie)mysite.com的后台对应路由根据URL里的回调写入cookie,302到目标页面
在写入cookie到新域名过程中,可以有不同的实现方式。
原理
第一步302到sso.xxx.com的时候已经可以带上xxx.com的cookie了,但是由于浏览器安全限制,并不能直接set cookie到独立域名下。需要再次302回原始域名,CNAME到sso的服务器,实现set cookie到独立域名。
为了保证安全性,CNAME到sso的sso.mysite.com所传递的参数需要有安全机制保证。如时间戳、秘钥等保证请求的完整性。避免中间人伪造域名下的请求。同时,链接本身也应有时效性,在超过时间范围失效,避免拦截链接,实现钓鱼网站获取sso.xxx.com的登录态。
具体步骤:
- 302到jump.sso.xxx.com后,进行权限检查判断域名是否允许同步,匹配SSO的cookie域名下的cookie取交集,得到需要同步的cookie。
- 通过以上两步后,302到sso.mysite.com,url中带上cookie和安全相关的参数
- 根据安全参数校验、target是否允许同步,决定返回403还是302。
- 通过校验后,同步登录态cookie,302到目标网页
清除登录态时,如何做到相关域名的同时清除,还需要额外设计。
当然,如果sso只在内网使用,在jump.sso.xxx.com做完安全验证后,通过url将结果交由sso.mysite.com设置登录态Cookie,要更为简洁。
git branch rename
如果分支在远端也有的话,工作需要分为本地和远端两部分。
- 重命名本地分支
- 如果就在该分支
1
git branch -m new-name
- 如果在其他分支
1
git branch -m old-name new-name
- 删除原分支,推送新分支
1
git push origin :old-name new-name
- 重置upstream设置
1
git push origin -u new-name
webpack无痛mock方案
使用webpack-api-mocker实现,对比axios-mock-adapter和其余方案有几个优势:
- mock部分代码和业务代码分离开,让网络请求部分代码(/apis)有清晰的逻辑,不混杂业务无关内容
- 热更新,保存即生效
- 本地dev环境无痛切换到production环境,无需修改任何代码
- 基于webpack-dev-server,和整个项目耦合,无需本地起服务
本地开发时,配置webpack.dev.config.js,在devServer部分的配置中加入apiMocker即可。
1 | const apiMocker = require("webpack-api-mocker"); |
更多使用,参考webpack-api-mocker文档。
webpack配置使用es6语法
如今现代的前端开发早已采用全es6的语法书写,然而webpack的配置文件需要通过node解析执行,一般还使用es5的语法书写。在需要使用import
,export
,数组、对象解构等最新特性时就很蛋疼。
比如在最近的开发中,使用webpack-api-mocker
时,希望拆分不同领域的接口到不同文件,最后通过对象结构的方式聚合在mocker的入口文件中。使用es5的语法就很麻烦。
实际上,让webpack使用babel解析配置文件分两步即可:
yarn add -D babel-register
,让webpack能够使用babel-loader转译配置文件- 修改配置文件后缀为,
webpack.config.babel.js
,webpack会使用.js
前的字符串作为loader
之后就可以愉快地使用es6语法写配置文件了。
autoprefixer remove -webkit-box-orient
解决方案
autoprefixer是postcss的插件,会根据browser list,删除一些autodated的样式,其中就包括-webkit-box-orient
这个用于hack实现多行省略号的CSS样式。
几种方法:
- 设置autoprefixer,
{remove: false}
,保留autodated的样式规则 - 添加flexbox 2009老旧浏览器到broswer list中
- 如下,通过注释临时disable autoprefixer
1 | /* autoprefixer: ignore next */ |