duxapp:基於Taro使用模塊化開發,提升開發效率

来源:https://www.cnblogs.com/shaogong/p/18427402
-Advertisement-
Play Games

duxapp是基於Taro二次開發的模塊化框架 使用這個框架,結合框架提供的UI庫和工具庫,能幫助你快速且高質量的完成項目,且能實現同時開發小程式、H5、APP(React Native),並且保證各個端的一致性 ...


duxapp是基於Taro二次開發的模塊化框架

使用這個框架,結合框架提供的UI庫和工具庫,能幫助你快速且高質量的完成項目,且能實現同時開發小程式、H5、APP(React Native),並且保證各個端的一致性

duxapp還針對APP開發(React Native)做了大量優化,大大降低了APP發開的難度,你可以閱讀React Native教程,瞭解詳情

下麵讓我來詳細介紹如何使用duxapp

何為模塊化

什麼是模塊化?就像npm包一樣,我們可以將一些通用的功能或頁面編寫在一個模塊內,提供給多個項目來使用,以提高代碼的復用性。

模塊的概念在很多後端框架中很常見,它們可以在應用商店通過安裝應用的方式來獲得新功能,在前端框架中確很少見到類似的設計方案,當然你其實也可以理解為發佈到npm就是一種模塊化的設計,但是在Taro中很多功能他並不能發佈到npm中,例如頁面。頁面需要放在項目中,當發佈到npm之後就會無法使用

在duxapp框架中的模塊化設計原理,和npm的依賴關係是類似的,每個模塊有一個配置文件app.json,裡面的依賴欄位dependencies,用來填寫我要用到的依賴,就像下麵ui庫示例這個模塊的配置

{
  "name": "duxuiExample",
  "description": "ui庫示例",
  "version": "1.0.13",
  "dependencies": [
    "duxui",
    "duxcms",
    "amap",
    "echarts",
    "wechat"
  ]
}

和npm依賴不一樣的是,這裡的依賴不包含版本信息。因為頁面等限制條件,你一個項目中,同一個模塊無法存在兩個不同的版本,因此並未設計指定版本號的功能

依賴關係是逐層查找的,就像npm一樣,例如這裡依賴的duxui模塊,他的模塊配置文件是這樣的

{
  "name": "duxui",
  "description": "DUXUI庫",
  "version": "1.0.42",
  "dependencies": [
    "duxapp"
  ],
  "npm": {
    "dependencies": {
      "b-validate": "^1.5.3",
      "react-native-view-shot": "~3.8.0",
      "react-native-fast-shadow": "~0.1.1",
      "array-tree-filter": "^2.1.0"
    }
  }
}

在duxui模塊中他又使用了duxapp這個依賴,通過每個模塊都去查找,我們最終整理出這樣的依賴關係圖

dependencies

那麼最終當我們使用下麵的命令編譯duxuiExample模塊的時候

# 調試小程式
yarn dev:weapp --app=duxuiExample
# 調試h5
yarn dev:h5 --app=duxuiExample

實際被編譯的模塊就包含下麵這些

  • duxuiExample
  • duxcms
  • amap
  • echarts
  • wechat
  • duxui
  • duxappReactNative
  • duxapp

使用duxapp

上面介紹了模塊化的原理,現在我們來看看,具體要怎麼使用這個框架

首先使用cli命令創建一個項目,中途會要求你選擇模板,你可以選擇 duxui 示例代碼(包含所有組件的示例代碼 支持RN端) 這個選項,和上面使用的示例一樣

npx duxapp-cli create projectName

在使用這個命令之前,確保全裝了以下工具和環境

安裝後會自動安裝項目依賴

進入項目目錄projectName,使用上面提到的命令 yarn dev:weapp --app=duxuiExample 或者 yarn dev:h5 --app=duxuiExample 編譯為小程式或者H5,使用開發者工具或者瀏覽器就能預覽

可以看到編譯命令是在Taro原有的命令基礎上增加了 --app= 參數,參數用來指定一個模塊,通常你都需要指定這個參數,因為你的項目中除了上面提到的模塊之外,大多是時候還會存在其他模塊,如果你不指定的話,他會把所有模塊都打包進去

通過上面的描述可以看出,其實在一個項目中不是真的只有一個項目,在我的實際開發經驗中,我是將很多項目放在一起開發的,我只需要通過 --app= 參數指定我的項目入口文件進行編譯,他就是不同的項目

多個項目同時存在,如何保持他們不混亂呢,例如第三方npm依賴,每個項目可能都有不同的npm依賴,這通過下麵的章節來介紹

模塊

在duxapp框架中,src目錄下每個文件夾將被識別為一個模塊,模塊一般是像下麵這樣設計結構的

├── duxapp                      模塊名稱
│   ├── components              模塊組件庫 
│   │   ├── ComponentName       組件
│   │   │   └── index.jsx
│   │   └── index.js            導出需要導出的組件
│   ├── config                  配置目錄 
│   │   ├── route.js            路由配置文件(路徑固定)
│   │   ├── theme.js            主題配置文件(路徑固定)
│   │   └── themeToScss.js      主題轉換函數(路徑固定)
│   ├── pages                   頁面放置文件夾
│   │   └── index               頁面文件夾
│   │       ├── index.jsx       頁面
│   │       └── index.scss
│   ├── utils                   工具庫
│   │   ├── index.js            導出工具庫
│   │   └── ...you util.js
│   ├── update                  模塊安裝目錄
│   │   ├── copy                需要複製到項目的文件(路徑固定)
│   │   │   └── ...             
│   │   └── index.js            安裝腳本 主要針對RN端 插件安裝方法(路徑固定)
│   ├── app.js                  模塊入口文件
│   ├── app.json                模塊配置文件 包括名稱 依賴等(必須)
│   ├── app.scss                全局樣式文件(次樣式文件無需導入到js文件中,會自動註入全局)
│   ├── changelog.md            更新日誌(必須 如果發佈)
│   ├── index.js                模塊出口文件 可以導出組件和方法給其他模塊使用
│   ├── index.html              如果是h5的項目可以自定義index.html,僅當作為入口模塊時可用
│   ├── app.config.js           用於覆蓋項目全局配置
│   ├── babel.config.js         babel配置文件
│   ├── metro.config.js         metro配置文件
│   ├── taro.config.js          Taro編譯配置文件
│   ├── taro.config.prod.js     Taro 發佈配置文件
│   ├── taro.config.dev.js      Taro 調試配置文件
│   └── readme.md               自述文件(必須 如果發佈)

關於模塊目錄的詳細內容查看這個 模塊結構 獲取

模塊配置

在duxui這個模塊中,它的配置文件是這樣的

{
  "name": "duxui",
  "description": "DUXUI庫",
  "version": "1.0.42",
  "dependencies": [
    "duxapp"
  ],
  "npm": {
    "dependencies": {
      "b-validate": "^1.5.3",
      "react-native-view-shot": "~3.8.0",
      "react-native-fast-shadow": "~0.1.1",
      "array-tree-filter": "^2.1.0"
    }
  }
}

我們看到,他有一個欄位 npm,它的內容和項目的 package.json 的配置是完全一樣的,在模塊中編寫這個內容,將會和項目的 package.json 進行覆蓋合併,那麼你就可以通過模塊來安裝當前模塊需要依賴了,每個模塊中都可以指定這個依賴,他們會合併在一起

當你指定了不同的 --app= 入口模塊之後,框架會根據你使用到的模塊中的第三方依賴自動重新安裝

在模塊中還有很多類似的設計,用來編寫配置或者文件,包括下麵這些

  • app.scss 編寫全局樣式
  • index.html 如果是h5的項目可以自定義index.html,僅當作為入口模塊時可用
  • app.config.js 用於覆蓋項目全局配置
  • babel.config.js babel配置文件
  • metro.config.js metro配置文件
  • taro.config.js Taro編譯配置文件

模塊路由

每個模塊中都可以編寫頁面,當然這不是必選項,這些頁面會被定義在自己的模塊中

通過 modeName/config/route.js 定義當前的模塊路由,例如 duxuiExample 的路由定義如下

/**
 * login:是否需要登錄
 * platform:支持的平臺(weapp, h5, rn)不配置支持所有
 * subPackage:是否將其設置為分包
 * home: 是否是主頁 是主頁的頁面將會被排在前面
 */
const config = {
  pages: {
    'duxuiExample/index': {
      pages: {
        index: {
          home: true
        }
      }
    },
    'duxuiExample/example': {
      pages: {
        Button: {},
        Cell: {},
        Grid: {},
        Divider: {},
        Space: {},
        // 更多未展示
      }
    }
  }
}

module.exports = config

路由的定義也是經過封裝的,配置的時候是將一個文件夾作為一個對象來處理,這樣我們能很方便的將某個文件夾進行分包等操作

使用UI庫和全局樣式編寫頁面

在基礎模塊 duxapp 中提供了可以用於快速佈局頁面的全局樣式,他就和 tailwindcss 類似,在結合UI組件,編寫頁面像下麵這樣的,可以看到我們不需要編寫 scss 文件就能完成頁面的編寫

import { Avatar, Card, ScrollView, Column, Divider, Header, Text, TopView, Row, px, Image, nav, Tag } from '@/duxui'
import { useRequest, CmsIcon, saleHook, Qrcode } from '@/duxcmsSale'
import { setClipboardData } from '@tarojs/taro'

export default function Sale() {

  const [{ info = {}, day = {}, money, total = {} }] = useRequest('sale/index')

  return <TopView>
    <Header absolute title='推廣中心' color='#FFFFFF' style={{ backgroundColor: 'transparent' }} />
    <Image style={{ height: px(396) }} className='w-full absolute' src={require('./images/tui_bag.png')} />
    <Row justify='between' items='center' style={{ marginTop: px(208) }} className='mt-3 ph-3'>
      <Row items='center' justify='start'>
        <Avatar url={info.avatar}>{info.nickname}</Avatar>
        <Column className='mh-3'>
          <Row items='center' className='gap-2'>
            <Text size={33} bold color='#FFFFFF' >{info.nickname}</Text>
            {!!info.level_name && <Tag type='primary' size='s'>{info.level_name}</Tag>}
          </Row>
          <Row className='mt-2'>
            <Text color='#FFFFFF' size={1}>邀請碼:{info.code}</Text>
            <CmsIcon className='mh-2' size={36} name='copy' color='#FFFFFF' onClick={() => setClipboardData({ data: info.code })} />
          </Row>
        </Column>
      </Row>
      <CmsIcon size={60} name='QRcode1' color='#FFFFFF' onClick={Qrcode.show} />
    </Row>
    <ScrollView className='mt-3'>
      <Card margin disableMarginTop>
        <Row jtems='center' justify='between' className='gap-3'>
          <Column justify='center' items='center' grow >
            <Text bold type='primary'>{total.order_num || 0}</Text>
            <Text color={2} size={2} className='mt-2'>直推訂單</Text>
          </Column>
          <Column justify='center' items='center' grow>
            <Text bold type='primary'>{total.user_num || 0}</Text>
            <Text color={2} size={2} className='mt-2'>直推客戶</Text>
          </Column>
        </Row>
        <Row className='mt-2' jtems='center' justify='between'>
          <Column justify='center' items='center' grow>
            <Text bold type='primary'>{total.month_sale_money || 0}</Text>
            <Text color={2} size={2} className='mt-2'>本月收益</Text>
          </Column>
          <Column justify='center' items='center' grow>
            <Text bold type='primary'>{total.sale_money || 0}</Text>
            <Text color={2} size={2} className='mt-2'>累計收益</Text>
          </Column>
        </Row>
      </Card>
      <Card shadow margin disableMarginTop onClick={() => nav('duxcmsAccount/cash/index')}>
        <Row items='center' justify='between'>
          <Text bold>佣金管理</Text>
          <CmsIcon name='direction_right' size={32} />
        </Row>
        <Row className='mt-3' items='baseline'>
          <Text size={2}>可提現佣金:</Text>
          <Text className='mh-3' bold size={50}>{money || 0}</Text>
        </Row>
      </Card>
      <Card margin disableMarginTop>
        <Row items='center' justify='around'>
          <Column items='center'>
            <Text size={2}>今日預估收益</Text>
            <Text className='mt-1' bold size={40} >{day.sale_money || 0}</Text>
          </Column>
          <Column items='center'>
            <Text size={2}>今日有效訂單</Text>
            <Text className='mt-1' bold size={40} >{day.order_num || 0}</Text>
          </Column>
          <Column items='center'>
            <Text size={2}>今日新增客戶</Text>
            <Text className='mt-1' bold size={40} >{day.user_num || 0}</Text>
          </Column>
        </Row>
      </Card>

      <Card margin className='gap-4'>
        <Text size={4} bold>其他操作</Text>
        <Row justify='between' items='center' onClick={() => nav('duxcmsSale/index/order')}>
          <Text size={2} className='mh-2' bold>推廣訂單</Text>
          <CmsIcon name='direction_right' size={32} />
        </Row>
        <Row justify='between' items='center' onClick={() => nav('duxcmsSale/index/customer')} >
          <Text size={2} className='mh-2' bold>我的客戶</Text>
          <CmsIcon name='direction_right' size={32} />
        </Row>
        <saleHook.Render mark='index.menus' />
      </Card>
      <Row style={{ height: px(16) }}></Row>
    </ScrollView >
  </TopView>
}

為何獲得更好的編輯體驗,需要在vscode中安裝 SCSS Everywhere 插件,他能識別到全局樣式並給出編寫提示

用戶配置

很多模塊都是通用的,那麼一些需要根據不同項目變化的內容,就不能寫在模塊中,而是要通過配置的形式來配置

項目配置放在項目根目錄下的 configs 目錄中,其中每個文件夾就是一個配置,文件中的index.js就是項目配置

像下麵這個duxuiExample的配置,其中option中的每一項就是對應模塊的配置

// import qiniu from './base/components/UploadFileManage/drive/qiniu'

const config = {
  // 覆蓋app.config.js 配置
  appConfig: {
    requiredPrivateInfos: [
      'chooseLocation',
      'getLocation',
      'onLocationChange',
      'startLocationUpdateBackground',
      'chooseAddress'
    ]
  },
  // 調試配置
  debug: {
    // 在h5端開啟vconsole調試功能
    vconsole: false
  },
  // 模塊配置 將會調用模塊生命周期的option,將對應模塊的參數傳入
  option: {
    // 基礎模塊
    duxapp: {
      theme: {
        primaryColor: '#E70012',
        secondaryColor: '#E84C00',
        successColor: '#34a853',
        warningColor: '#fbbc05',
        dangerColor: '#ea4335',
        pageColor: '#F7F9FC',

        textColor1: '#373D52',
        textColor2: '#73778E',
        textColor3: '#A1A6B6',
        textColor4: '#FFF',
        header: {
          color: '#fff', // 僅支持rgb hex值,請勿使用純單詞 設置為數組將顯示一個漸變按鈕
          textColor: '#000', // 文本顏色
          showWechat: false, // 微信公眾號是否顯示header
          showWap: true, // h5是否顯示header
        }
      }
    },
    codepush: {
      androidKey: '',
      iosKey: '',
    },
    wechat: {
      // 分享組件配置
      share: {
        open: true,
        // 開啟未定義的頁面分享
        pageSlef: {
          // 包含這些頁面分享自身 頁面路徑關鍵詞匹配 include 優先順序比 exclude 高,
          // 可以配置exclude為空數組表示支持所有頁面
          // pageSlef優先順序高於pageHome
          // include: ['page/test'],
          // 排除這些頁面 不進行分享
          exclude: []
        },
        // 開啟未定義的頁面分享到指定頁面
        pageHome: {
          path: '',
          params: {},
          // 包含這些頁面分享自身 頁面路徑關鍵詞匹配
          // include: [],
          // 排除這些頁面 不進行分享
          // exclude: []
        },
        // 公共分享參數
        common: {
          title: 'DUXUI',
          desc: '同時相容小程式、H5、RN',
          image: 'https://img.zhenxinhuixuan.com/weiwait/cropper/2lVCofRIu6Jl3jNebxCA6VkEMUeaobvLWFYMTiaG.jpg'
        },
        platform: {
          app: {
            // 配置分享到小程式的原始id 同時相當於開關
            weappUserName: '',
            // 配置分享到h5的url 同時相當於開關
            h5Url: 'https://duxui.cn',
          }
        }
      }
    },
    // 新php模塊化系統
    duxcms: {
      request: {
        origin: 'https://mock.dux.plus',
        path: 'api', // 功能變數名稱二級目錄
        secretId: '53368068',
        secretKey: '6c278fbf1791fbed3ae79197de03f65f',
        devOpen: false,
        devToken: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJtZW1iZXIiLCJpYXQiOjE2ODc5Mzg3NDEsImV4cCI6MTY5MDUzMDc0MSwiaWQiOjZ9.kCb82Y3bgUJWUo_WYsUPO1cLYzF1OJdEWTKAj9iNlF0'
      },
      // 登錄相關配置
      loginConfig: {
        // 手機號登錄
        phone: true,
        // 郵箱登錄
        email: false,
        // app微信登錄
        appWatch: true,
        // 小程式微信登錄
        weappWatch: true,
        // 名稱
        appName: 'duxui'
      }
    }
  }
}

export default config

後端框架

在我開發的項目中,後端框架是我的合伙人負責的,後端同樣也是採用模塊化的開發模式完成的,duxapp框架對後端框架已經打好了對接的基礎,如果你考慮進一步提升後端的開發效率,可以考慮使用

後端開發文檔:https://www.dux.cn/

總結

這一篇文章已經很長了,duxapp框架中還有很多內容,無法在這裡一一介紹,像下麵這些

  • 模塊主題
  • 模塊安裝與發佈
  • 快速開發APP(React Native)
  • 請求上傳
  • 路由系統
  • 開放模塊(用戶管理、微信、支付寶、頁面設計器等)
  • 等等

請前往開發文檔查看詳細教程

開發文檔:http://duxapp.cn/

GitHub:https://github.com/duxapp


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • title: Nuxt Kit 中的模板處理 date: 2024/9/20 updated: 2024/9/20 author: cmdragon excerpt: 摘要:本文詳細介紹了在Nuxt 3框架中,使用Nuxt Kit進行模板處理的方法,包括理解模板基本概念、使用addTemplate動 ...
  • title: Nuxt Kit 中的插件:創建與使用 date: 2024/9/19 updated: 2024/9/19 author: cmdragon excerpt: 摘要:本文介紹了在 Nuxt 3 框架中使用 Nuxt Kit 創建和管理插件的方法,包括使用addPlugin註冊插件、創 ...
  • ‍ 寫在開頭 點贊 + 收藏 學會 一.webpack和vite的區別 1.構建速度不同 Webpack: Webpack的構建速度相對較慢,尤其在大型項目中,因為它需要分析整個依賴圖,進行多次文件掃描和轉譯。 Vite: Vite以開發模式下的極速構建著稱。它利用ES模塊的特性 ...
  • 前言 在Vue3.5版本中響應式 Props 解構終於正式轉正了,這個功能之前一直是試驗性的。這篇文章來帶你搞清楚,一個String類型的props經過解構後明明應該是一個常量了,為什麼還沒丟失響應式呢?本文中使用的Vue版本為歐陽寫文章時的最新版Vue3.5.5 關註公眾號:【前端歐陽】,給自己一 ...
  • Pintree 是一個開源項目,旨在將瀏覽器書簽導出成導航網站。通過簡單的幾步操作,就可以將書簽轉換成一個美觀且易用的導航頁面。 ...
  • 隨著JavaScript在前後端開發中的廣泛應用,測試已成為保證代碼質量的關鍵環節。 為什麼需要單元測試 在我們的開發過程中,經常需要定義一些演算法函數,例如將介面返回的數據轉換成UI組件所需的格式。為了校驗這些演算法函數的健壯性,部分開發同學可能會手動定義幾個輸入樣本進行初步校驗,一旦校驗通過便不再深 ...
  • title: Nuxt Kit 中的頁面和路由管理 date: 2024/9/17 updated: 2024/9/17 author: cmdragon excerpt: 摘要:本文介紹了Nuxt Kit中頁面和路由管理的高級功能,包括extendPages自定義頁面路由、extendRouteR ...
  • title: Nuxt Kit 中的上下文處理 date: 2024/9/16 updated: 2024/9/16 author: cmdragon excerpt: Nuxt Kit 提供的上下文處理工具,尤其是 useNuxt 和 tryUseNuxt,為模塊化開發提供了極大的便利。通過這些函 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...