请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册
搜索

交流分享 【征文】从入门到放弃——快应用踩坑之路

0
回复
139
查看
[复制链接]

1

主题

2

帖子

15

积分

 楼主| 2018-12-26 00:26:44 显示全部楼层 |阅读模式
本帖最后由 狗蛋实验室 于 2018-12-29 12:48 编辑

未标题-2(1).jpg

伴随着我司快应用审核通过、上线,此处应该有一篇快应用踩坑经历。我司开发的快应用刚好涉及到音频、视频、Feeds业务,下面我说分享一下我在开发中遇到的问题。

项目搭建
  1. hap init <project_name> // 生成一个快应用项目脚手架
  2.     cd project_name
  3.     npm install // 安装依赖
  4.     npm run build // 打包快应用,输出build和dist文件夹
  5.     npm run watch // 监测到变化后自动编译
  6.     npm run server // 在另起一个终端开启server
复制代码


如果node版本用的是8以上的话,在运行完npm install后再运行npm run build时可能会报Cannot find module .../webpack.config.js异常,请重新执行一次hap update --force。这是由于高版本的npm在npm install时,会校验并删除了node_modules下部分文件夹,导致报错。而hap update --force会重新复制hap-toolkit文件夹到node_modules

  项目发布
  由于我们在开发环境下是用的debug签名,而正式发布到应用市场是需要正式签名
  1. 创建私钥:
  2. 通过openssl命令等工具生成签名文件private.pem、certificate.pem,例如:
  3. openssl req -newkey rsa:2048 -nodes -keyout private.pem -x509 -days 3650 -out certificate.pem
  4. (密钥长度,1024觉得不够安全的话可以用2048,但是代价也相应增大)
  5. 在工程的sign目录下创建release目录,将私钥文件private.pem和证书文件certificate.pem拷贝进去
  6. Country Name (2 letter code) [XX]:CN   #国家代码(中国)
  7. State or Province Name (full name) []:BeiJing   #省(北京)
  8. Locality Name (eg, city) [Default City]:BeiJing   #市(北京)
  9. Organization Name (eg, company) [Default Company Ltd]:gdlb  #公司名称
  10. Organizational Unit Name (eg, section) []:   #可不填
  11. Common Name (eg, your name or your server's hostname) []: #可不填
  12. Email Address []: #邮箱
  13. Please enter the following 'extra' attributes
  14. to be sent with your certificate request
  15. A challenge password []:   #可不填
  16. An optional company name []:   #可不填
  17. 在工程的sign目录下创建release目录,将私钥文件private.pem和证书文件certificate.pem拷贝进去
复制代码


  自定义根目录配置
  开发中可能需要引入js或者css文件等,为了方便通常回会备置相对路径,可以设置 alias (别名),来方便应用;具体的操作是,在 src 目录下建立 config 文件夹,在其中创建 webpack.config.js 文件,毕竟都是是用webpack,就像写vue项目一样。
  1. const path = require('path')
  2. module.exports = {
  3.   postHook: function(webpackConf, options){
  4.     webpackConf.resolve.alias = Object.assign(webpackConf.resolve.alias || {}, {
  5.       '@src': path.join(process.cwd(), 'src')
  6.     })
  7.   }
  8. }
复制代码


开发中遇到的问题
布局样式
  1.     初写快应用,因为之前是开发过小程序,再到快应用特别不适应。
  2.     1.首页面布局默认的就是flex,其他的浮动布局啥的都没有。
  3.     2.css 习惯连写,突然不能连写很不适应。
  4.     3. 不支position要实现z-index的图层效果请使用stack组件。
  5.     4.大量的css样式不支持,如bulr、box-shadow要实现只能用背景图。
  6.     5.background-image 1030 以下版本不支持网络路径
  7.     6. 华为平台对svg 和 动画有兼容性问题。
  8.     7. border-radius 如果是gif图片不生效。
  9.     8.自定义字体样式 1030+ 才支持font-face定义字体样式。
复制代码


组件
- list-item

  1. 作为使用率最高的组件之一,list-item组件类型不一致时,一定要给type="***"
  2. 不同命名来区别,否则也会闪退。
  3. 解决方法:
  4. <list-item type="{{index}}">
复制代码

- swiper
  1. swiper也是作为出现频率非常高组件,但是字实际使用中,虽然bug不多,但是开放的功能太少,如vertical设置滑动方向都不支持。
  2. 顺便教大家自定义dots(面板指示点)
  3.   <div class="swiper-container">
  4.     <stack>
  5.       <swiper class="swiper" autoplay="true" indicator="false" interval="2000" loop="true" onchange="swiperChange">
  6.         <block for="(index, item) in data">
  7.           <image class="wrap-img" src="{{item.image}}" onclick="bindViewTap(item)" />
  8.         </block>
  9.       </swiper>
  10.       <div class="dots">
  11.         <block for="(index, item) in data">
  12.           <div class="dot {{index === swiperCurrent ? 'active' : ''}}"></div>
  13.         </block>
  14.       </div>
  15.     </stack>
  16.   </div>
  17.   <script>
  18.     export default {
  19.         swiperChange(e) {
  20.             this.swiperCurrent = e.index
  21.         }
  22.     }
  23.   </script>
  24.   利用onchange事件去做修改
复制代码


- tabs

  1. tabs内不能再嵌套tabs,如有此类需求,外部需要div组件模拟选项卡
复制代码
- slider
  1. 这个也是一个特别坑爹的组件
  2. slider 组件只有滑动结束后end才有回调,进行中没有回调,改变value值也会触发change事件,无法判断change是人为滑动触发,还是改变数据触发的。官方demo竟然是有时差来区别。
复制代码


- web

  1. 1.web组件使用网页与原生通信时(system.postMessage)。
  2. 当页面发生跳转时,就无法再触发通信,如:
  3. www.xxx.com?id=1跳转到www.xxx.com?id=2
  4. 在华为机型上有更多蜜汁bug.
复制代码



- video

  1. video组件,由于我用到了if渲染后,竟然不能立即调用它的方法,而且还打印是存在的,官方给出答复,可能还没准备就绪。
  2.     this.$forceUpdate()
  3.     /* 使用setTimeout解决蜜汁bug */
  4.     // this.$element("video") && this.$element("video").pause()
  5.     this.$element("video")&&setTimeout(()=>{this.$element("video").pause()},30);
复制代码



还有很坑爹的事情,如组件没有onDestroy钩子,据说以后会增加。

接口
- 音频接口
  1.     音频接口特别坑爹。
  2.     1.没有获取当前播放状态的接口,据说1050才会加入。
  3.         audio.ontimeupdate = () => {
  4.           this.isplaying = true
  5.           // 由于快用还没提供获取播放状态的接口,暂时啊这样解决了。
  6.         }
  7.     2.在通知栏中点击关闭音乐触发onpause完之后,ontimeupdate没有立即停止。
  8.         audio.onpause = () => {
  9.           /* 我使用通知栏上的音乐通知栏,直接点击关闭,触发onpause完之后,ontimeupdate没有立即停止,用clearTimeout解决 */
  10.           let globalTime = this.$app.$def.globalTime
  11.           clearTimeout(globalTime)
  12.           globalTime = setTimeout(() => {
  13.             this.isplaying = false
  14.           }, 20)
  15.         }
  16.     3.当页面触发onDestroy,onHide一定用销毁不必要的回调。
复制代码


- $watch

  1. 此方法尽量避免使用,因为他在1020和1030中是有差异的,在 1030 上的 watcher 的响应确会存在滞后,相比于 1020(牵扯到的代码都是同步逻辑)
复制代码


- $forceUpdate()
  1. this.$forceUpdate()有点类似与vue的this.$nextTick(),
  2. 若开发者期望数据更新时立即执行相应的 DOM 操作,可使用:this.$forceUpdate();一般不推荐使用
复制代码


- 被禁用的 new Function,eval
  1. eval这些容易注入恶意代码,所以小程序,快应用禁用了。
  2.     其实就是怕你怕你热更新,绕开审核,进行为所欲为的操作。
  3.     但是你确实想用eval,也可以自己实现一个。
  4.     参照-《前端与编译原理——用JS写一个JS解释器》
  5.     https://segmentfault.com/a/1190000017241258
复制代码



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册