Taro 2.0:擁抱社區,擁抱變化

image

緣起

Taro 1.x 版本自去年 9 月份發佈以來,已經陪伴你們度過了一年多的時間,在此期間 Taro 一直保持高速成長,發佈了多個具備重大意義的版本,讓 Taro 成爲現在一個功能完善,擁有衆多忠實擁躉的多端統一開發框架。css

儘管 Taro 一直保持超高的迭代速度,Taro 的總體架構設計沒有發生太大變化,這讓 Taro 在這個時刻在變化的時代稍顯佛系,且對於一個時刻想要突破本身的技術團隊來講,常規性質的維護工做,顯然沒法安撫咱們躁動的心,畢竟人的夢想,是永遠不會中止的,因此咱們決定啓動一系列的顛覆式重構設計html

2.0

咱們首先從 CLI 開始入手進行改造,你們都知道,原來 Taro CLI 的編譯構建系統是自研的,整個構建系統邏輯複雜,要考慮的邊際條件衆多,這就致使瞭如下問題:前端

  • 維護困難,每次須要新增一個功能,例如支持解析 Markdown 文件,就須要直接改動 CLI,不夠靈活
  • 難以共建,CLI 的代碼很是複雜,並且邏輯分支衆多,讓不少想要一塊兒共建的人難以入手
  • 可擴展性偏低,自研的構建系統,設計之初沒有考慮到後續的擴展性,致使開發者想要添加自定義的功能無從下手

基於以上問題,咱們決定使用 Webpack 來實現編譯構建,因而誕生了 2.0。webpack

Taro 2.0 的 CLI 將會變得很是輕量,只會作區分編譯平臺、處理不一樣平臺編譯入參等操做,隨後再調用對應平臺的 runner 編譯器 作代碼編譯操做,而原來大量的 AST 語法操做將會改形成 Webpack Plugin 以及 Loader,交給 Webpack 來處理。ios

taro-cli 2.0

相較於舊的構建系統,新的小程序編譯帶來了如下優點:git

  • 利於維護,大量的邏輯交由 Webpack 來處理,咱們只須要維護一些插件
  • 更加穩定,相較於自研的構建系統,新的構建會更加穩定,下降一些奇怪錯誤的出現機率
  • 可擴展性強,能夠經過自行加入 Webpack Loader 與 Plugin 的方式作本身想要的擴展
  • 各端編譯統一,接入 Webpack 後,Taro 各端的編譯配置能夠實現很是大程度的統一

能夠看到新的構建系統會有很大的進步。同時,更重要的是,基於 Webpack,咱們能夠在小程序中嘗試更多的特性與技術,例如經過 tree shaking) 來優化代碼包大小等等,讓小程序開發更加與業界發展同步,讓 Taro 更加擁抱社區。github

Migrate to 2.0

編譯配置調整

2.0 總體上與 1.0 是徹底兼容的,可是在基於 Webpack 重構後,咱們對部分編譯配置作了優化調整,因此若是想要將基於 1.x 的舊項目遷移至 2.0,首先須要對編譯配置進行調整。web

const config = {
  projectName: 'taro-framework',
  date: '2019-11-2',
  designWidth: 750,
  deviceRatio: {
    640: 2.34 / 2,
    750: 1,
    828: 1.81 / 2
  },
  sourceRoot: 'src',
  outputRoot: 'dist',
  // babel、csso、uglify 等配置從 plugins 配置中移出來
  babel: {
    sourceMap: true,
    presets: [['env', { modules: false }]],,
    plugins: [
      'transform-decorators-legacy',
      'transform-class-properties',
      'transform-object-rest-spread'
    ]
  },
  // 小程序配置從 weapp 改成 mini,能夠刪掉不少小配置
  mini: {
    webpackChain (chain, webpack) {},
    cssLoaderOption: {},
    postcss: {
      pxtransform: {
        enable: true,
        config: {}
      },
      url: {
        enable: true,
        config: {
          limit: 10240 // 設定轉換尺寸上限
        }
      }
    }
  },
  // 能夠刪掉不少小配置
  h5: {
    publicPath: '/',
    staticDirectory: 'static',
    webpackChain (chain, webpack) {},
    postcss: {
      autoprefixer: {
        enable: true,
        config: {
          browsers: [
            'last 3 versions',
            'Android >= 4.1',
            'ios >= 8'
          ]
        }
      }
    }
  }
}

module.exports = function (merge) {
  if (process.env.NODE_ENV === 'development') {
    return merge({}, config, require('./dev'))
  }
  return merge({}, config, require('./prod'))
}

具體編譯配置請參考 編譯配置文檔shell

異步編程調整

Taro 2.0 中開啓 async functions 支持再也不須要安裝 @tarojs/async-await,而是直接經過 babel 插件來得到支持。npm

在項目根目錄下安裝包 babel-plugin-transform-runtimebabel-runtime

$ yarn add babel-plugin-transform-runtime --dev
$ yarn add babel-runtime

隨後修改項目 babel 配置,配置插件 babel-plugin-transform-runtime

babel: {
  sourceMap: true,
  presets: [['env', { modules: false }]],
  plugins: [
    'transform-decorators-legacy',
    'transform-class-properties',
    'transform-object-rest-spread',
    ['transform-runtime', {
      "helpers": false,
      "polyfill": false,
      "regenerator": true,
      "moduleName": 'babel-runtime'
    }]
  ]
}

新特性嚐鮮

在基於 Webpack 改造後帶來全面提高的同時,2.0 也爲咱們帶來了如下新的特性。

主編譯流程鉤子

在 2.0 中,CLI 編譯的主流程已經基於 Tapable 進行改造,而且對外暴露了 hooks 以供使用,在 Taro 編譯配置中能夠經過 plugins 來配置編譯過程插件,調用這些 hooks 來實現本身的需求。

目前編譯主流程暴露了兩個鉤子 beforeBuildafterBuild,其中,beforeBuild 將在總體編譯前觸發,能夠獲取到編譯的相關配置,同時也能進行修改;afterBuild 將在 Webpack 編譯完後執行,能夠獲取到編譯後的結果。具體使用方式以下。

首先定義一個插件

class BuildPlugin {
  apply (builder) {
    builder.hooks.beforeBuild.tap('BuildPlugin', (config) => {
      console.log(config)
    })

    builder.hooks.afterBuild.tap('BuildPlugin', (stats) => {
      console.log(stats)
    })
  }
}

接下來在 plugins 字段中進行配置

const config = {
  ...
  plugins: [
    new BuildPlugin()
  ]
  ...
}

爲小程序編譯添加 Loader

咱們有時候可能會面臨在小程序中展現 Markdown 語法文件的需求,在 WEB 開發的時候咱們能夠藉助 Webpack 及其 Loader,實現直接引入 md 文件並讀取其內容,而在小程序開發中,經過藉助 Taro 2.0,咱們也能很輕鬆地實現這一需求。

通常咱們會以以下的方式,來引入一個 .md 文件。

import mdTxt from '../../some_markdown.md'

.md 文件默認是不能直接被識別的,咱們須要經過配置相應的 Loader 來實現對這類文件的加載解析,在 Taro 中能夠經過 mini.webpackChain 來爲小程序配置自定義 Webpack 配置,咱們也能夠經過它來配置 Loader。

const config = {
  mini: {
    webpackChain (chain) {
      chain.merge({
        module: {
          rule: {
            myloader: {
              test: /\.md$/,
              use: [{
                loader: 'raw-loader',
                options: {}
              }]
            }
          }
        }
      })
    }
  }
}

爲小程序編譯添加 Plugin

當咱們要把打包後的小程序進行發佈的時候,可能會遇到小程序過大的問題,那麼咱們確定迫切但願能夠看到究竟是哪些文件的大小形成了這個影響,咱們能夠經過使用 webpack-bundle-analyzer 插件對打包體積進行分析。

mini.webpackChain 中添加以下配置。

const config = {
  mini: {
    webpackChain (chain, webpack) {
      chain.plugin('analyzer')
        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [])
    }
  }
}

在運行以後,咱們就能在瀏覽器裏看到以下分析效果。

webpack-bundle-analyzer

Taro RN 依賴升級到 0.59.9

在 2.0 中咱們將 RN 端 React 依賴升級到 16.8.0,React Native 依賴升級到 0.59.9。主要緣由:

  • Google 要求全部 Google Play 應用支持 64 位 so 庫,而現有 RN 0.55.4 依沒法支持 64 位庫,爲配合 64 位升級,Taro RN 端的 React Native 依賴須要同步升級
  • React 16.8.0 是第一個支持 Hook 的版本,React Native 從 0.59 版本開始支持 Hook,此前社區一直在呼籲對 RN 0.55.4 進行升級以直接支持 Hook 的寫法

本次 RN 端屬於無縫升級,原有的寫法和配置均不變,若是使用 taro-native-shell 的,選擇 0.59.9 分支便可;在原生應用集成 RN 的,須要自行升級 React Native 依賴到 0.59.9。

將來與展望

正如前文所提到的,Taro 2.0 只是一個開始。

在 10 年代最後一場 GMTC 全球大前端技術大會上,Taro 團隊向你們展現了 小程序跨框架開發的探索與實踐 的艱辛旅程,同時也提早曝光了正在緊密開發中的 Taro Next

那是一個徹底區別於以往的版本,一條與如今 Taro 大相徑庭的道路,預示着 Taro 正在革本身的命。

節物風光不相待,桑田碧海須臾改。

20 年代呼嘯而來,下一個 10 年,不少框架都會死去,不少技術也會煥然而生,沒有什麼是不變的,惟一不變的只有變化,咱們能作的也只能是擁抱變化

歡迎關注凹凸實驗室博客:aotu.io

或者關注凹凸實驗室公衆號(AOTULabs),不定時推送文章:

image