<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【Taro】1246- Taro 3 與原生小程序混合開發(fā)實踐

          共 7456字,需瀏覽 15分鐘

           ·

          2022-03-03 17:29

          前言

          最近接到一個項目需求,是要做出一套頁面,不僅應(yīng)用在小程序的環(huán)境中,也要應(yīng)用在 H5 里面,并同時兼容兩端原有的邏輯不變。最終經(jīng)過我們的調(diào)研梳理,決定使用當(dāng)前最新版本的 Taro 3,來實現(xiàn)多端統(tǒng)一開發(fā)的訴求。

          那這里我們?yōu)槭裁催x擇 Taro 呢,我認(rèn)為有以下幾點好處

          • 京東凹凸實驗室開發(fā),框架穩(wěn)定性較高
          • 與 Taro 1、2 相比,Taro 3 開發(fā)體驗幸福度更高,與使用 React 或者 Vue 開 web 體驗無差
          • 相比 UniApp 框架,Taro 靈活度高可配置性強,可選用的開發(fā)框架也更多
          • Taro 社區(qū)活躍度較高、周邊物料庫豐富

          項目痛點

          1.通過 Taro3 進(jìn)行多端開發(fā),代碼怎樣做到兼容,可以適配到 H5 和小程序,并保證在多端順利啟動。

          2.由于原生小程序端有一套自己的代碼邏輯,H5 端有一套自己的代碼邏輯,并且兩端邏輯毫不相關(guān)。怎樣做到一套代碼開發(fā)出來的頁面,同時插入 H5 或者小程序中,可以順利兼容到兩端的原有邏輯流程。

          3.打造一套通用框架,可以快速高效的接入其他多端頁面,實現(xiàn)降本提效。

          Taro架構(gòu)的演變

          在動手開發(fā)前,我覺得還是非常有必要先了解下 Taro 的架構(gòu)演進(jìn)的心路歷程。做到一個基本的了解。

          Taro 1/2(重編譯)

          在 Taro 1 與 Taro 2 階段,編譯階段起到了重要的部分。簡單來講,主要是將 Taro 代碼通過代碼編譯,轉(zhuǎn)換為各個端(各類小程序、RN、H5 等)可以運行的代碼。再通過輕量的運行時進(jìn)行適配,用 Taro 的組件庫、運行時的框架以及 API 進(jìn)行差異磨平,來解決多端差異性。

          Taro3(重運行)

          這一次的架構(gòu)全新升級,可以理解為重新站在瀏覽器的角度來思考前端的本質(zhì):無論開發(fā)用的是什么框架,React ,Vue 也好,jQuery 也罷,最終代碼經(jīng)過運行之后都是調(diào)用了瀏覽器的那幾個 BOM/DOM 的 API ,如:createElementappendChildremoveChild 等,那么在小程序端我們也可以模擬實現(xiàn) DOM、BOM API 來讓前端框架直接運行在小程序環(huán)境中。

          那么對于生命周期、組件庫、API、路由等差異,我們依然可以通過定義統(tǒng)一標(biāo)準(zhǔn)(如標(biāo)準(zhǔn)組件庫、標(biāo)準(zhǔn) API 等),各端負(fù)責(zé)各自實現(xiàn)的方式來進(jìn)行抹平。

          Taro v3.1 開放式架構(gòu)

          Taro 核心維護(hù)的平臺只有 6 個(微信、支付寶、百度、頭條、QQ、京東小程序),那么常常會有用戶對于其他平臺也需要進(jìn)行及時的支持和維護(hù)。因為對于單一平臺的兼容性代碼,涉及編譯和運行時的部分,改動起來復(fù)雜度高,且社區(qū)難以參與貢獻(xiàn)。于是便打造了一個開放式的框架,通過插件的形式擴(kuò)展 Taro 的端平臺支持能力:

          • 插件開發(fā)者無需修改 Taro 核心庫代碼,即可編寫出一個端平臺插件。
          • 插件使用者只需安裝、配置端平臺插件,即可把代碼編譯到指定平臺。
          • 開發(fā)者可以繼承現(xiàn)有的端平臺插件,然后對平臺的適配邏輯進(jìn)行自定義。

          那么基于此,Taro 也是根據(jù)開放式架構(gòu),進(jìn)行了調(diào)整,把內(nèi)置支持的 6 個平臺封裝成了插件,CLI 默認(rèn)會全部加載這些插件。封裝的過程中,也是檢索了各小程序最新的組件、API,并進(jìn)行更新與支持,對齊各小程序最新的能力。

          項目開發(fā)搭建過程

          架構(gòu)的演變簡單了解了下,下面讓我們開始項目開發(fā)搭建~

          1.Taro3 項目安裝

          CLI 工具安裝

          yarn?global?add?@tarojs/cli

          項目初始化

          2.原生小程序和 Taro 的目錄對比

          首先我們先對比下兩者目錄結(jié)構(gòu)的差異,其實兩者結(jié)構(gòu)并沒有太大的不同,也很容易看懂和上手。

          3.H5和小程序的打包運行分析

          1)scripts 腳本配置

          我們先看一下項目初始化后的 scripts 腳本:

          使用 Taro 的 build 命令可以把 Taro 代碼編譯成不同端的代碼:

          Taro 編譯分為 devbuild 模式:

          • dev 模式(增加 --watch 參數(shù)) 將會監(jiān)聽文件修改。
          • build 模式(去掉 --watch 參數(shù)) 將不會監(jiān)聽文件修改,并會對代碼進(jìn)行壓縮打包。
          • dev 模式生成的文件較大,設(shè)置環(huán)境變量 NODE_ENVproduction 可以開啟壓縮,方便預(yù)覽,但編譯速度會下降。
          "build:weapp":?"taro?build?--type?weapp",?//?微信小程序
          "build:swan":?"taro?build?--type?swan",??//?百度小程序
          "build:alipay":?"taro?build?--type?alipay",?//?支付寶小程序
          "build:tt":?"taro?build?--type?tt",?//?字節(jié)跳動小程序
          "build:h5":?"taro?build?--type?h5",?//?H5
          "build:rn":?"taro?build?--type?rn",?//?React?Native
          "build:qq":?"taro?build?--type?qq",?//?qq小程序
          "build:jd":?"taro?build?--type?jd",?//?京東小程序
          "build:quickapp":?"taro?build?--type?quickapp",?//?快應(yīng)用端

          2)如何支持編譯其他小程序呢

          前面也講過,Taro 為了支持編譯其他端的小程序更加的方便,進(jìn)行了架構(gòu)調(diào)整為開放式架構(gòu),并通過插件的形式擴(kuò)展 Taro 的端平臺支持能力,這里以企業(yè)微信小程序舉例:

          安裝插件
          yarn?add?@tarojs/plugin-platform-weapp-qy
          配置插件
          //?config/index.js
          config?=?{
          ??//?...
          ??plugins:?[
          ????"@tarojs/plugin-platform-weapp-qy"
          ??]
          }
          打包編譯
          npm?run?build:qywx
          注意:

          Taro v3.1 + 開始支持

          3)小程序 Taro 打出來的包怎么進(jìn)行預(yù)覽呢

          h5 打包預(yù)覽和我們平常的方式?jīng)]有任何區(qū)別,那么小程序又該如何操作呢?這里以微信小程序舉例:


          這個時候下載并打開微信開發(fā)者工具,然后導(dǎo)入項目根目錄的 dist 包即可,即可看到界面:

          4.Taro 3 開發(fā)過程中一些細(xì)節(jié)點

          這里還是推薦大家先將官方文檔簡單梳理一遍,了解下 Taro 的一些官方 api,組件庫的使用,這里就不再一一列舉。下面筆者會直接講一些開發(fā)過程中的遇到的一些踩坑點和我覺得比較重要的部分,避免大家走一些彎路。

          1)使用路由

          在 Taro3 中使用的路由的方式,與之前的版本會有所不同,無論是獲取項目傳入?yún)?shù)還是頁面入?yún)ⅲ际峭ㄟ^ getCurrentInstance().router 來獲取的,具體使用如下。

          import?Taro,?{?getCurrentInstance?}?from?"@tarojs/taro"
          import?React,?{?Component?}?from?"react"

          export?default?class?Index?extends?Component?{
          ??componentDidMount?()?{
          ????console.log(getCurrentInstance().router.params)
          ??}
          }

          2)打包新增版本號

          在h5編譯打包的時候,如果想要增加版本號,就需要在 config 目錄下 prod.js 文件進(jìn)行配置,這里會暴露一個專屬于 H5 的配置供大家使用。這里以設(shè)置輸出解析文件的目錄和拓展 Webpack 的 output 選項舉例:

          var?config?=?require("../package.json")
          var?path?=?require("path")
          module.exports?=?{
          ??env:?{
          ????NODE_ENV:?"production"
          ??},
          ??defineConstants:?{
          ??},
          ??mini:?{},
          ??h5:?{
          ????publicPath:config.publicPath+config.version,
          ????output:?{
          ??????path:?path.resolve(__dirname,?`../dist/${config.version}`),?
          ????},
          ????/**
          ?????*?如果h5端編譯后體積過大,可以使用 webpack-bundle-analyzer 插件對打包體積進(jìn)行分析。
          ?????*?參考代碼如下:
          ?????*?webpackChain?(chain)?{
          ?????*???chain.plugin('analyzer')
          ?????*?????.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin,?[])
          ?????*?}
          ?????*/

          ??}
          }

          3)接口請求

          對于網(wǎng)絡(luò)請求,Taro 封裝了一套自己的 API,比如說我這邊用的是 async/await 用法:

          const?options?=?{
          ??method:?requestType,?//?"GET"或者"POST"
          ??url,
          ??data:?param,
          ??credentials:?"include"?as?credentialsType,
          ??timeout:?1000?*?30,
          ??header:?h,
          };
          const?res?=?await?Taro.request(options)

          注意:

          小程序的環(huán)境下,接口 url 的請求一定是 https

          項目難點攻克

          對于這次需求來說,最需要做的事情,就是如何借助 Taro3 開發(fā)一套頁面,同時去兼容兩端(微信小程序端和 H5 端)的流程。并且將微信小程序環(huán)境下打包出來的 dist 目錄,插入到原生的小程序中,實現(xiàn)混合開發(fā)。

          1.兼容兩端流程搭建

          這里我們首先需要封裝函數(shù)來區(qū)分不同環(huán)境,封裝在 utils 目錄中。

          const?Utils?=?{
          ??isH5()?{
          ????return?process.env.TARO_ENV?===?"h5"
          ??},
          ??isWeapp()?{
          ??return?process.env.TARO_ENV?===?"weapp"
          ?},
          }
          export?default?Utils

          這樣我們在開發(fā)過程中,比如點擊提交按鈕,區(qū)分出是 h5 環(huán)境下,便處理 h5 的邏輯。區(qū)分出是微信小程序的邏輯,便處理微信小程序的邏輯。

          2.混合開發(fā)

          現(xiàn)在我們面臨這樣一個場景,就是在此 Taro 項目框架,區(qū)分出是微信小程序的環(huán)境下了,現(xiàn)在我們需要跳轉(zhuǎn)到原生小程序的某個頁面,比如說喚起原生的登陸打通,那么我們又該如何實現(xiàn)呢?

          讓我們思考下,即使只開發(fā)了一個頁面,小程序打出的包 dist,也是一整個小程序。那我們現(xiàn)在想要將打出的包插入到原生小程序中去實現(xiàn),那么我們需要打包成一個單獨的分包。

          1)以混合模式進(jìn)行打包

          非常幸運的一點是,Taro 3 官方提供了混合開發(fā)的功能,可以讓原生小程序項目和打包出來的項目進(jìn)行混合開發(fā)使用,通過 --blended 命令。

          taro?build?--type?weapp?--blended

          這個時候,在打包出來的 app.js 中會暴露出 taroApp,供我們在原生小程序的 app.js 頁面下去調(diào)用其生命周期。

          但是存在這樣一個問題,在執(zhí)行我們的原生小程序項目時,我們通過引用在原生項目下的 app.js 里引入 Taro 項目的入口文件,來提前初始化一些運行時的邏輯,因此要保證 Taro 項目下的 app.js 文件里的邏輯能優(yōu)先執(zhí)行。所以說只是 --blended 命令這種,只適合主包的頁面,分包的話,沒法優(yōu)先執(zhí)行。

          2)解決分包開發(fā),引入 @tarojs/plugin-indie 插件

          先進(jìn)行安裝

          yarn?add?--dev?@tarojs/plugin-indie

          然后引入插件配置

          //?config/index.js
          const?config?=?{
          ??//?...
          ??plugins:?[
          ????"@tarojs/plugin-indie"
          ??]?
          ??//?...
          }

          簡單來說,就是在編譯代碼時,對頁面下的 js chunk 文件進(jìn)行 require 引入的目錄調(diào)整,增加對應(yīng)的 module 的 sourceMap 映射。這樣在訪問到我們 Taro 下的分包頁面時,就可以做到優(yōu)先執(zhí)行了。

          3)手寫 @tarojs/plugin-mv 插件,自動化挪動打包后的文件

          在處理好分包的打包流程后,我們在原生小程序的 pages 頁面下建立一個頁面文件夾 taroMini,為了導(dǎo)入我們 Taro 項目下打包出的分包頁面。然后在原生小程序的 app.json 中,引入分包的路徑配置。

          {
          ??"subPackages":?[
          ????{
          ??????"root":?"pages/taroMini/pages/riskControlAnswer",
          ??????"pages":?[
          ????????"index"
          ??????]
          ????}
          ??]
          }

          現(xiàn)在就是我們手動把 Taro 打包出來的文件夾,拖動到原生小程序的 taroMini 目錄下就可以運行我們的頁面了。如圖:

          這個時候,我們又要思考下了,每次打包出來的 dist 文件夾,都要手動拖入到原生小程序的項目中么,有沒有一種自動化的方式,讓其自己挪動呢。這里我們就要開始手寫一個插件了:

          //?plugin/index.js
          const?fs?=?require("fs-extra")
          const?path?=?require("path")

          export?default?(ctx,?options)?=>?{
          ??ctx.onBuildFinish(()?=>?{
          ????const?blended?=?ctx.runOpts.blended?||?ctx.runOpts.options.blended
          ????
          ????if?(!blended)?return

          ????console.log("編譯結(jié)束!")

          ????const?rootPath?=?path.resolve(__dirname,?"../..")
          ????const?miniappPath?=?path.join(rootPath,?"jdc_wx_ecard")
          ????const?outputPath?=?path.resolve(__dirname,?"../dist")

          ????//?taroMini是你在京東有禮小程序項目下的路由文件夾
          ????const?destPath?=?path.join(miniappPath,?`./pages/taroMini`)

          ????console.log("outputPath",?outputPath)
          ????console.log("destPath",?destPath)

          ????if?(fs.existsSync(destPath))?{
          ??????fs.removeSync(destPath)
          ????}
          ????fs.copySync(outputPath,?destPath)

          ????console.log("拷貝結(jié)束!")
          ??})
          }

          其實代碼仔細(xì)看一下,實現(xiàn)思想就是進(jìn)行一個文件夾的自動挪動腳本。然后我們把我們手寫好的這個插件,引入到我們的 Taro 項目中

          //?config/index.js
          const?config?=?{
          ??//?...
          ??plugins:?[
          ????"@tarojs/plugin-indie",
          ????path.join(process.cwd(),?"/plugin/index.js")
          ??]?
          ??//?...
          }

          4)應(yīng)用

          那么上面所提到的,在 Taro 項目中跳轉(zhuǎn)到原生小程序的某個頁面中,就可以在我們的本地 Taro 項目中(區(qū)分好是微信小程序的環(huán)境下)正常書寫了。

          const?{?orderId?}?=?param
          const?fromPageType?=?""
          const?returnPage?=?encodeURIComponent(`/pages/taroMini/pages/riskControlAnswer/index?orderId=${orderId}`)
          const?url?=?`/pages/login/index/index?returnPage=${returnPage}&pageType=${fromPageType}&noWXinfo=1`
          Taro.redirectTo({?url?})

          其他調(diào)用原生小程序的功能也可以正常開發(fā)了。

          項目總結(jié)

          這樣我們就實現(xiàn)了最開始我們提到的一些需求點,實現(xiàn)了原生小程序和 Taro 項目的混合開發(fā),也實現(xiàn)了 Taro 項目端和原生小程序端兩個項目之間的自動化打通。其實對于 Taro 3 進(jìn)行深挖,還有很多可以值得探索梳理的地方,后續(xù)有機會再和大家分享下~

          參考資料

          1. JavaScript 重溫系列(22篇全)
          2. ECMAScript 重溫系列(10篇全)
          3. JavaScript設(shè)計模式 重溫系列(9篇全)
          4.?正則 / 框架 / 算法等 重溫系列(16篇全)
          5.?Webpack4 入門(上)||?Webpack4 入門(下)
          6.?MobX 入門(上)?||??MobX 入門(下)
          7. 120+篇原創(chuàng)系列匯總

          回復(fù)“加群”與大佬們一起交流學(xué)習(xí)~

          點擊“閱讀原文”查看 130+ 篇原創(chuàng)文章

          瀏覽 122
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  五月天成人综合 | 国产又粗又大又爽视频 | 日韩久久久 | 狠狠躁日日躁夜夜躁 | a篇,乱伦,欧美,国产 |