1. 程式人生 > >小程式雲開發:菜鳥也能全棧做產品

小程式雲開發:菜鳥也能全棧做產品

我想獨立實現一個全棧產品為什麼這麼難

日常生活中,我們會使用很多軟體產品。在使用這些產品的時候,我們看得見的東西稱為“前端介面”如一個輸入框、一個按鈕,點選按鈕之後發生的一切看不見的東西稱為“後端服務”。與之對應的創造者分別稱為“前端程式設計師”、“後端程式設計師”,然而,一個完整產品的開發不僅僅是隻有前端和後端,還有設計師,架構師,運維等。有沒有可能這些所有的事情都一個人幹呢?有可能,事實上如今就有很多的“全棧工程師”,他們身兼數職,是多面手。能獨立完成一個產品的方方面面。這種人固然十分了得,他們通常具有多年的經驗,涉獵廣泛,是老手,也是高手,當有一個產品想法的時候,他們可以用自己的全面專業技能,盡情的發揮去實現自己的想法。所以,從某種意義上講“全棧也是一種自由”,你可以自由的實現你的想法,這簡直太美妙了!

然而,很多時候當我們有一個產品想法的時候,我們往往發現,前端寫完了,後端怎麼搞?資料庫怎麼搞?域名怎麼搞?域名還要備案?應用部署怎麼搞?我的買什麼樣的伺服器啊?靜態資源 CDN 怎麼搞?檔案上傳伺服器怎麼搞?萬一訪問使用者多了能撐住嗎?等等……問題很多,導致你的一個個想法,都只是在腦海中曇花一現,從來都無法將她們實現,或者說你激情飽滿的實現了其中自己最擅長的一部分,當碰到其他難題的時候就止步了。於是仰天長嘯:我就想獨立做一個完整的產品為什麼這麼難?年輕人,這一切都不怪你……

破局:小程式雲開發

為什麼使用小程式雲開發來破局?

為啥是用“小程式雲開發”來破局?首先,我們的目的是全棧實現一個產品。全棧可以有多種技術方案,你可用任何你能會的技能來達到全棧的目的。你可以開發安卓,IOS,或者 PC 站,然而小程式是最實際的!為啥?手機上能做的事情為啥要用 PC 版?OK,既然手機版比較好,那能不能再簡單一點?能,就是小程式,不需要開發IOS,安卓兩個版本。可以快速產出,快速試錯。

其次,前面說到了,全棧實現一個產品並不容易,對很多人來說甚至是巨難!選擇了小程式已經是比較划算的方案。而再整合雲開發,全棧立馬就有了。這就是為什麼選擇“小程式雲開發”來破局。

小程式雲開發是什麼?

小程式雲開發是什麼?官方文件是這麼說的:開發者可以使用雲開發開發微信小程式、小遊戲,無需搭建伺服器,即可使用雲端能力。雲開發為開發者提供完整的原生雲端支援和微信服務支援,弱化後端和運維概念,無需搭建伺服器,使用平臺提供的 API 進行核心業務開發,即可實現快速上線和迭代,同時這一能力,同開發者已經使用的雲服務相互相容,並不互斥。

看完上面的描述,也許你仍然無法非常清楚的知道什麼是“小程式雲開發”,沒關係,你只需要注意加粗的部分,大概知道它“無需搭建伺服器”,從傳統觀念將,這個似乎“毀三觀”咋可能沒伺服器啊?是的,可以沒有傳統意義上的伺服器,這種模式是 serveless 的。

那麼,小程式雲開發提供了哪些東西來破局呢?且看下面的表格:

能 力 作 用 說 明
雲函式 無需自建伺服器 在雲端執行的程式碼,微信私有協議天然鑑權,開發者只需編寫自身業務邏輯程式碼
資料庫 無需自建資料庫 一個既可在小程式前端操作,也能在雲函式中讀寫的 JSON 資料庫
儲存 無需自建儲存和 CDN 在小程式前端直接上傳/下載雲端檔案,在雲開發控制檯視覺化管理
雲呼叫 原生微信服務整合 基於雲函式免鑑權使用小程式開放介面的能力,包括服務端呼叫、獲取開放資料等能力

上面的表格中提到了“雲開發”中的一些能力:“雲函式”,“資料庫”,“儲存”,“雲呼叫”,我們可以將這些詞帶入你曾經開發過的應用,看看它們分別代表了哪些部分。對於程式設計師來說,如果有疑問的話,沒有什麼是一個 helloword 解決不了的。

實戰:獨立開發一個簡易的零售小程式

哆嗦再多,不如實戰。下面我們就來使用小程式雲開發實現一個簡單的零售小程式。

專案構思

既然是一個零售小程式,那麼我們可以思考一下零售小程式的大致業務流程,以及粗略的梳理一下,其功能點。現根據自己的想法,大致畫一下草圖,如果沒有靈感可以參考一下別的 APP 是如何設計的。

我根據自己的想法設計之後是這樣的:

功能模組:首頁,商品列表頁,購物車,確認訂單,個人中心,個人訂單,管你模組(商品新增,分類新增)其中商品需要上傳圖片。

梳理完功能之後,我們對於要實現的東西已經有個初步的概念了。接下來,我們需要大概畫一下頁面設計、及功能流轉。初次設計可能沒有太多經驗,沒關係,開始做就行了,做著做著就會想法越來越多,然後優化的越來越好。。我也是經過了多番修改調整,最終找到了一些思路。我的(拙劣)設計如下,圖片如果看不清楚可複製圖片連結在新視窗開啟檢視:

說明,以上圖片是根據成品(我真的開發了一個雲小程式並上線使用了)截圖的,而實際我再設計的時候也是經過幾番修改才最終定成這樣。

同時,補充說明一下,這裡前端頁面使用的是 vant-weapp控制元件,非常好用。推薦!如果你和我一樣是一個純後端程式設計師,建議使用 vant-weapp 來作為 ui,非常方便。否則自己寫頁面樣式的話可能就做不出來了。全棧不是那麼好乾的啊。選擇自己能駕馭的,能實現最終功能,就是一個合格的全棧。

建立小程式雲開發專案

我們先下載微信小程式開發工具,下載地址在這裡,安裝好了之後,新建專案,介面如下,APPID 需要你自己去註冊一個。然後注意,選擇“小程式雲開發”,如下圖所示:

建立好了之後,專案目錄如下,先看 1 標註的地方:

如果你曾經有過小程式的開發經驗,那麼miniprogram資料夾下面的結構你肯定熟悉了,miniprogram下面的子目錄分別是小程式對應的元件、圖片、頁面、樣式以及app.js,app.json,sitemap.json,其中components下面的vant-weapp就是上面提到的 ui 元件。

最後一個比較重要的資料夾就是cloudfunctions,這個目錄是用來存放“雲函式的”,雲函式就是我們的後端。每一個雲函式提供一個服務。一個個的雲函式組成了我們整體的後端服務。雲函式可以看做是 FaaS(function as a service)。途中,2 標記的位置的“雲開發”按鈕,我們點進去,就可以看到“雲開發的控制檯”,如下圖所示:

如果上圖看不清楚,可以複製連結到新的瀏覽器視窗檢視,如圖,小程式雲開發預設的免費套餐有一定的額度可供使用。首頁便是使用統計。然後我們能看到,有“資料庫”,“儲存”,“雲函式”。

這裡的“資料庫”其實就是類似於一個 MongoDB,你可以點進去建立一個個的 collection(即:關係型資料庫中的table);這裡的“儲存”其實就是“資料夾”,我們可以通過微信提供的 api把圖片上傳到“儲存”中;這裡的“雲函式”就是我們需要實現的後端業務邏輯,他就是一個個的函式(函式由我們自己寫好後上傳)。一般開發過程中我們在開發者工具中的cloudfunctions目錄下建立雲函式(比方說是:user-add)開發完成之後在雲函式目錄點選右鍵——上傳即可。然後就可以在小程式的程式碼中呼叫這個user-add雲函式。

雲開發之——3 分鐘實現檔案上傳

注意:在開始雲開發之前,我們現在 小程式程式碼的 app.js 中加入wx.cloud.init,如下:

App({
  onLaunch: function () {
    if (!wx.cloud) {
      console.error('請使用 2.2.3 或以上的基礎庫以使用雲能力')
    } else {
      wx.cloud.init({
        // env 引數說明:
        //   env 引數決定接下來小程式發起的雲開發呼叫(wx.cloud.xxx)會預設請求到哪個雲環境的資源
        //   此處請填入環境 ID, 環境 ID 可開啟雲控制檯檢視
        //   如不填則使用預設環境(第一個建立的環境)
        env: 'your-env-id',
        traceUser: true,
      })
    }
    this.globalData = {}
  }
})

上面的圖中,我們已經看到了“商品新增”頁面的效果,它需要我們輸入商品名稱、價格、並上傳圖片,然後儲存。傳統架構中,上傳圖片需要前端頁面擺一個控制元件,然後後端提供一個 api用來接收前端傳來的檔案,通常來說這個後端 api 接收到圖片之後,會將圖片檔案儲存到自己的檔案伺服器或者是阿里雲端儲存、或者是七牛雲端儲存之類的。然後返回給你一個檔案連結地址。非常麻煩,然而,小程式雲開發上傳檔案超級簡單,上程式碼:

頁面程式碼:
<van-notice-bar
  scrollable="false"
  text="釋出商品"
/>
  <van-field
    value="{{ productName }}"
    required
    clearable
    label="商品名稱"
    placeholder="請輸入商品名稱"
    bind:change="inputName"
  />
    <van-field
    value="{{ productPrice }}"
    required
    clearable
    label="價格"
    icon="question-o"
     bind:click-icon="onClickPhoneIcon"
    placeholder="請輸入價格"
    error-message="{{phoneerr}}"
    border="{{ false }}"
    bind:change="inputPrice"
  />

<van-action-sheet
  required
  show="{{ showSelect }}"
  actions="{{ actions }}"
  close-on-click-overlay="true"
  bind:close="toggleSelect"
  bind:select="onSelect" cancel-text="取消"
/>
  <van-field
    value="{{ productCategory }}"
    center
    readonly
    label="商品分類"
    border="{{ false }}"
    use-button-slot
  >
    <van-button slot="button" size="small" plain type="primary"  
     bind:click="toggleSelect">選擇分類</van-button>
  </van-field>
  
  <van-button class="rightside" type="default" bind:click="uploadImage" >上傳商品圖片</van-button>
  <view class="imagePreview">
    <image src="{{productImg}}" />
  </view>
 <van-submit-bar
  price="{{ totalShow }}"
  button-text="提交"
  bind:submit="onSubmit"
  tip="{{ false }}"
 >
 </van-submit-bar> 
<van-toast id="van-toast" />
<van-dialog id="van-dialog" />

這裡有個控制元件,綁定了uploadImage方法,其程式碼為:

  uploadImage:function(){
    let that = this;
    wx.chooseImage({
      count: 1,
      sizeType: ['compressed'],
      sourceType: ['album', 'camera'],
      success(res) {
        wx.showLoading({
          title: '上傳中...',
        })
        const tempFilePath = res.tempFilePaths[0]
        const name = Math.random() * 1000000;
        const cloudPath = name + tempFilePath.match(/\.[^.]+?$/)[0]
        wx.cloud.uploadFile({
          cloudPath:cloudPath,//雲端儲存圖片名字
          filePath: tempFilePath,//臨時路徑
          success: res => {
            let fileID = res.fileID;
            that.setData({
              productImg: res.fileID,
            });
            wx.showToast({
              title: '圖片上傳成功',
            })
          },
          fail: e =>{
            wx.showToast({
              title: '上傳失敗',
            })
          },
          complete:()=>{
            wx.hideLoading();
          }
        });
      }
    })
  }

這裡,wx.chooseImage用於調起手機選擇圖片(相簿/相機拍照),然後wx.cloud.uploadFile用於上傳圖片到上面說到的雲開發能力之一的“儲存”中。上傳圖片成功之後返回一個檔案 ID,類似:

cloud://release-0kj63.7265-release-0kj63-1300431985/100477.13363146288.jpg  

這個連結可以直接在小程式頁面展示:

<image src="cloud://release-0kj63.7265-release-0kj63-1300431985/100477.13363146288.jpg  " />

也可以通過微信 api,裝換成 http 形式的圖片連結。

雲開發之——操作資料庫,1 分鐘寫完儲存商品到資料庫的程式碼

上面我們實現了商品圖片上傳,但是,商品圖片並沒有儲存到資料庫。正常錄入商品的時候,我們會填好商品名稱,價格等,然後上傳圖片,最終點選“儲存”按鈕,將商品儲存到資料庫。傳統模式下,前端仍然是需要呼叫一個後端介面,通過 post 提交資料,最終由後端服務(比如 java 服務)將資料儲存到資料庫。小程式雲開發使得操作資料庫十分簡單,首先我們在雲開發控制檯建立“商品表”,即一個 collection,取名為:products。然後我們就可以儲存資料到資料庫了,程式碼如下:

onSubmit:function(){
    // 校驗程式碼,略
    let product = {};
    product.imgId = this.data.productImg;
    product.name= this.data.productName;
    product.categoryId = this.data.productCategoryId;
    product.price = this.data.productPrice;
    // 其他賦值,略
    const db = wx.cloud.database();
    db.collection('products').add({
     data: product,
     success(res) {
       wx.showToast({
         title: '儲存成功',
       })
     }
   });
  }

以上就實現了資料入庫,就這點程式碼,超簡單,1 分鐘寫完,誠不欺我。其中這裡的products就是我們的“商品表”,之前說過,類似 MongoDB 資料庫,這裡操作的是db.collection,這和 MongoDB 的語法差不多。

雲開發之——使用雲函式完成後端業務邏輯,訂單建立

小程式雲開發提供了幾大能力:“資料庫”,“儲存”,“雲函式”,前兩項我們已經有所體會了。下面我們能建立一個雲函式來實現訂單建立。這裡說明,雲函式其實就是 一段JavaScript 程式碼,上傳至雲伺服器之後,最終也是執行在 nodejs 環境的,只是這一切,我們不需要關心。我們只需要關心我們這個雲函式提供的功能是什麼就可以了。

建立雲函式很簡單,直接在開發工具中右鍵“新建Node.js 雲函式”。然後以建立訂單為例,假設我們建立一個雲函式名為c-order-add,建立好了之後,目錄是這樣:

雲函式的主要程式碼在 index.js 中,其完整程式碼是這樣:

// 雲函式入口檔案
const cloud = require('wx-server-sdk')
cloud.init({
  env: 'release-xxx'// your-env-id
})
const db = cloud.database()

// 雲函式入口函式
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext();
  console.log("雲函式 c-order-add : ")  
  // 這裡是一些邏輯處理...
  
  return await db.collection('uorder').add({
    data: {
      openid: event.userInfo.openId,
      address: event.address,
      userName: event.userName,
      phone: event.phone,
      shoppingInfo: event.shoppingInfo,
      totlePrice: event.totlePrice,
      shoppingStr: event.shoppingStr,
      remark:event.remark,
      createTime: now,
      // ...
    }
  });
}

這個雲函式寫好之後,需要上傳到伺服器,直接在雲函式目錄點選右鍵,然後點選“上傳並部署”即可,這就相當於部署好了後端服務。前端小程式頁面呼叫的寫法是這樣的:

let orderData={};
orderData.userName = this.data.userName;
orderData.phone = this.data.phone;
orderData.address = this.data.address;
// ....
wx.cloud.callFunction({
      // 雲函式名稱
      name: 'c-order-add',
      // 傳給雲函式的引數
      data: orderData,
      complete: res => {
        Dialog.alert({
          title: '提交成功',
          message: '您的訂單成功,即將配送,請保持手機通暢。'
        }).then(() => {
          // ....
          wx.redirectTo({
            url: '../uorder/uorder'
          });
        });
      }
})

這裡,向程式前端,通過wx.cloud.callFunction完成了對雲函式的呼叫,也可以理解為對後端服務的呼叫。至此我們我們介紹完了,小程式雲開發的功能。雖然,我只貼出了少量的程式碼,即儲存商品,和提交訂單。由於時間和篇幅有限,我不可能把整個完整的程式程式碼貼出來。但是你可以參照這個用法示例,將剩下的業務邏輯補充完整,最終完成“專案構思”一節中展示的成品截圖效果。

小程式稽核的一點經驗

我開發的小程式稽核在提交稽核的時候遭遇了兩次退回,第一次是因為:“小程式具備電商性質,個人小程式號不支援”。所以,我只好申請了一個企業小程式號,使用的是超市的營業執照。服務類目的選擇也被打回了一次,最後選擇了食品還提交了食品經營許可證。第二次打回是因為:“使用者體驗問題”。其實就是“授權索取”的問題,微信不讓開啟首頁就“要求授權”,同時不能強制使用者接受授權,得提供拒絕授權也能使用部分功能。

上面兩條解決之後,更新新了好幾版,都沒有出現過被拒的情況。並且,有次我是夜晚 10 左右提價的稽核,結果10 點多就提示稽核通過,當時沒看具體時間,就是接盆水泡了個腳的時間稽核通過了。所以,我推斷小程式稽核初次稽核會比較嚴,之後如果改動不大應該直接機審就過了。

總結及對比

這裡我們可以對小程式雲開發和傳統模式做一個對比:

對比條目 傳統模式 雲開發
是否需要後端服務 需要 (如一個java應用部署在 Tomcat 中) 不需要 只需要“雲函式”
是否需要域名 需要 (還得在微信後臺的把域名加入安全域名) 不需要
是否需要購買伺服器 需要 (你得部署後端 Java 應用,還得安裝資料庫) 不需要
開通雲開發之後免費套餐夠用
不夠的話購買套餐按呼叫量計費
是否需要懂運維 需要
(你得會折騰伺服器,資料庫之類的
還得配置好相關的使用者,埠,啟動服務)
不需要
圖片上傳及 CDN 麻煩 簡單
獲取微信 openID 麻煩 超級簡單,雲函式中直接獲取
···

就對比這麼多吧,總之,我非常喜歡小程式雲開發,小程式真的可以讓你輕鬆幹全棧。或者咱們別動不動就提“全棧”,姑且說,小程式雲開發可以讓你更簡單、更快速、更便宜的實現你的產品落地。我自己開發的雲小程式上線之後,使用了一兩個月,沒出現任何問題。我也不用操心伺服器什麼的。所以,我已經給身邊很多人安利了小程式雲開發了。這裡我就不貼出我的小程式碼了,因為已經正式給我同學的超市使用了,所以不方便讓別人去產生測試資料。如果你感興趣想看的話,可以聯絡我