從入門到放棄——快應用踩坑之路

狗蛋404實驗室發表於2019-03-02

伴隨著我司快應用稽核通過、上線,此處應該有一篇快應用踩坑經歷。我司開發的快應用剛好涉及到音訊、視訊、Feeds流業務,下面我說分享一下我在開發中遇到的問題。

專案搭建

  hap init <project_name> // 生成一個快應用專案腳手架
  cd project_name
  npm install // 安裝依賴
  npm run build // 打包快應用,輸出build和dist資料夾
  npm run watch // 監測到變化後自動編譯
  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簽名,而正式釋出到應用市場是需要正式簽名

建立私鑰:
通過openssl命令等工具生成簽名檔案private.pem、certificate.pem,例如:
openssl req -newkey rsa:2048 -nodes -keyout private.pem -x509 -days 3650 -out certificate.pem
(金鑰長度,1024覺得不夠安全的話可以用2048,但是代價也相應增大)
在工程的sign目錄下建立release目錄,將私鑰檔案private.pem和證書檔案certificate.pem拷貝進去
Country Name (2 letter code) [XX]:CN   #國家程式碼(中國)
State or Province Name (full name) []:BeiJing   #省(北京)
Locality Name (eg, city) [Default City]:BeiJing   #市(北京)
Organization Name (eg, company) [Default Company Ltd]:gdlb  #公司名稱
Organizational Unit Name (eg, section) []:   #可不填
Common Name (eg, your name or your server`s hostname) []: #可不填
Email Address []: #郵箱
Please enter the following `extra` attributes
to be sent with your certificate request
A challenge password []:   #可不填
An optional company name []:   #可不填
在工程的sign目錄下建立release目錄,將私鑰檔案private.pem和證書檔案certificate.pem拷貝進去
複製程式碼

自定義根目錄配置

開發中可能需要引入js或者css檔案等,為了方便通常回會備置相對路徑,可以設定 alias (別名),來方便應用;具體的操作是,在 src 目錄下建立 config 資料夾,在其中建立 webpack.config.js 檔案,畢竟都是是用webpack,就像寫vue專案一樣。

const path = require(`path`)
module.exports = {
postHook: function(webpackConf, options){
  webpackConf.resolve.alias = Object.assign(webpackConf.resolve.alias || {}, {
    `@src`: path.join(process.cwd(), `src`)
  })
}
}

複製程式碼

開發中遇到的問題

佈局樣式

  初寫快應用,因為之前是開發過小程式,再到快應用特別不適應。
  1.首頁面佈局預設的就是flex,其他的浮動佈局啥的都沒有。
  2.css 習慣連寫,突然不能連寫很不適應。
  3. 不支position要實現z-index的圖層效果請使用stack元件。
  4.大量的css樣式不支援,如bulr、box-shadow要實現只能用背景圖。
  5.background-image 1030 以下版本不支援網路路徑
  6. 華為平臺對svg 和 動畫有相容性問題。
  7. border-radius 如果是gif圖片不生效。
  8.自定義字型樣式 1030+ 才支援font-face定義字型樣式。
複製程式碼
元件
  • list-item
作為使用率最高的元件之一,list-item元件型別不一致時,一定要給type="***"
不同命名來區別,否則也會閃退。
解決方法:
<list-item type="{{index}}">
複製程式碼
  • swiper
swiper也是作為出現頻率非常高元件,但是字實際使用中,雖然bug不多,但是開放的功能太少,如vertical設定滑動方向都不支援。
順便教大家自定義dots(皮膚指示點)
  <div class="swiper-container">
    <stack>
      <swiper class="swiper" autoplay="true" indicator="false" interval="2000" loop="true" onchange="swiperChange">
        <block for="(index, item) in data">
          <image class="wrap-img" src="{{item.image}}" onclick="bindViewTap(item)" />
        </block>
      </swiper>
      <div class="dots">
        <block for="(index, item) in data">
          <div class="dot {{index === swiperCurrent ? `active` : ``}}"></div>
        </block>
      </div>
    </stack>
  </div>
  <script>
    export default {
        swiperChange(e) {
            this.swiperCurrent = e.index
        }
    }
  </script>
  利用onchange事件去做修改
複製程式碼
  • tabs
    tabs內不能再巢狀tabs,如有此類需求,外部需要div元件模擬選項卡
    複製程式碼
  • slider
這個也是一個特別坑爹的元件
slider 元件只有滑動結束後end才有回撥,進行中沒有回撥,改變value值也會觸發change事件,無法判斷change是人為滑動觸發,還是改變資料觸發的。官方demo竟然是有時差來區別。
複製程式碼
  • web
1.web元件使用網頁與原生通訊時(system.postMessage)。
 當頁面發生跳轉時,就無法再觸發通訊,如:
 www.xxx.com?id=1跳轉到www.xxx.com?id=2
 在華為機型上有更多蜜汁bug.
複製程式碼
  • video
    video元件,由於我用到了if渲染後,竟然不能立即呼叫它的方法,而且還列印是存在的,官方給出答覆,可能還沒準備就緒。
    this.$forceUpdate()
    /* 使用setTimeout解決蜜汁bug */
    // this.$element("video") && this.$element("video").pause()
    this.$element("video")&&setTimeout(()=>{this.$element("video").pause()},30);
複製程式碼

還有很坑爹的事情,如元件竟然沒有onDestroy鉤子,據說以後會增加。

介面

  • 音訊介面
    音訊介面特別坑爹。
    1.沒有獲取當前播放狀態的介面,據說1050才會加入。
        audio.ontimeupdate = () => {
          this.isplaying = true
          // 由於快用還沒提供獲取播放狀態的介面,暫時啊這樣解決了。
        }
    2.在通知欄中點選關閉音樂觸發onpause完之後,ontimeupdate沒有立即停止。
        audio.onpause = () => {
          /* 我使用通知欄上的音樂通知欄,直接點選關閉,觸發onpause完之後,ontimeupdate沒有立即停止,用clearTimeout解決 */
          let globalTime = this.$app.$def.globalTime
          clearTimeout(globalTime)
          globalTime = setTimeout(() => {
            this.isplaying = false
          }, 20)
        }
    3.當頁面觸發onDestroy,onHide一定要記得銷燬不必要的回撥。
複製程式碼
  • $watch
此方法儘量避免使用,因為他在1020和1030中是有差異的,在 1030 上的 watcher 的響應確會存在滯後,相比於 1020(牽扯到的程式碼都是同步邏輯)
複製程式碼
  • $forceUpdate()
this.$forceUpdate()有點類似與vue的this.$nextTick(),
若開發者期望資料更新時立即執行相應的 DOM 操作,可使用:this.$forceUpdate();一般不推薦使用
複製程式碼
  • 被禁用的 new Function,eval
    eval這些容易注入惡意程式碼,所以小程式,快應用禁用了。
    其實就是怕你怕你熱更新,繞開稽核,進行為所欲為的操作。
    但是你確實想用eval,也可以自己實現一個。
    參照-《前端與編譯原理——用JS寫一個JS直譯器》
    https://segmentfault.com/a/1190000017241258
    
複製程式碼

相關文章