React Native 項目 Web 端同構初探

      網友投稿 762 2025-04-02

      ?


      使用 JavaScript 來開發移動端 App 似乎是眾多小廠比較普遍的選擇,作為拷貝經驗豐富的 Copy 工程師,我所在的小作坊采用的是 React Native。盡管 React Native 已經進入開源的第 6 個年頭,距離發布 1.0 版本依舊是遙遙無期?!癓earn once, write anywhere”,完全不影響 React Native 淪為“不會 JavaScript 也能用”的框架,那如何將在 React Native 項目中引入 react-native-web 呢?

      React Native 項目 Web 端同構初探

      ?

      react-native-web 簡介

      倉庫地址: https://github.com/necolas/react-native-web

      react-native-web 是由 前 Twitter 現 Facebook 工程師 Nicolas Gallagher 實現并維護的開源項目,是一個使 React Native 組件和 API 能運行在 Web 上的庫,其和 React Native Windows, React Native macOS 等庫將 React Native 拓展到一個又一個新的平臺。目前推特、expo、大聯盟足球、Flipkart、優步、《泰晤士報》、DataCamp 以及我們小作坊都在生產中使用了 react-native-web。Chrome、Firefox、Edge,Safari 7 +、IE 10+都支持通過 react-native-web 構建的 web 應用。當然值得注意的是,官方文檔明確表示不支持 React Native 中不推薦使用的組件和 API,因此如果您項目中的某些功能依賴第三方庫,可能那部分的功能在 web 端同構時需要額外處理。

      淺顯地認為react-native-web就是把React Native的組件和API都用適用于Web的標簽和API再適配實現一遍,使其在Web上的行為和在原生應用上盡量保持一致,從文檔中提到的 Alert 和 Setting 模塊以及其對應的源碼中大概能感受到一二,比如TextInput:

      switch?(keyboardType)?{

      case?'email-address':

      type?=?'email';

      break;

      case?'number-pad':

      case?'numeric':

      inputMode?=?'numeric';

      break;

      case?'decimal-pad':

      inputMode?=?'decimal';

      break;

      case?'phone-pad':

      type?=?'tel';

      break;

      case?'search':

      case?'web-search':

      type?=?'search';

      break;

      case?'url':

      type?=?'url';

      break;

      default:

      type?=?'text';

      }

      if?(secureTextEntry)?{

      type?=?'password';

      }

      因此也借鑒了 React Native 的一些代碼,作為適配的依據。

      如果您想基于 React Native 實現多端統一化方案,可參考去哪兒前端團隊的實現方案:跨端開發, 倉庫地址:https://github.com/qunarcorp/qrn-remax-unir

      添加到React Native項目

      一般來說新建 React Native 項目時可以選用 expo-cli 或者 react-native-cli 來創建。expo-cli 中已經預置了對web的支持,如下圖所示.

      而我們實際開發中可能用 react-native-cli腳手架來構建項目比較多些,那么如何引入 react-native-web呢?

      我們先初始化項目:

      npx?react-native?init?rn_web

      #?當然也可以使用模板,如

      #?npx?react-native?init?rn_web?--template?react-native-template-typescript

      此時我們的項目并不支持在web中使用:

      為了項目能在web環境中運行,我們需要借助今天的主角--react-native-web,有請主角出臺:

      cd?rn_web

      yarn?add?react-native-web

      yarn?add?-D?babel-plugin-react-native-web?webpack?webpack-cli?webpack-dev-server?html-webpack-plugin?react-dom?babel-loader?url-loader?@svgr/webpack

      接著我們施展Copy大法,將我們初始化能用到的App.web.jsx、index.html、index.web.js、webpack.config.js這幾個文件一把 down下來:

      curl?-L?https://gist.github.com/hu-qi/bde8a6d2b45325d93b1665174f938faa/download?|?tar?-xvz?--strip-components=1

      react-native-web

      然后在package.json中添加build和web的腳本:

      "build":?"rm?-rf?dist/?&&?webpack?--mode=production?--config?webpack.config.js",

      "web":?"webpack?serve?--mode=development?--config?webpack.config.js"

      就和 expo-cli 初始化的項目一樣可以執行yarn web,這時會在本地8080端口運行一個服務,這時我們分別執行yarn ios 和 yarn android就能看到在ios模擬器和Android模擬器中顯示和web端一模一樣的頁面,一次 react-native-web 的多端同構 Hello World 就成功實現了,當然這也意味著我們還可能編譯成小程序,后續有機會一起探討探討!

      此處的注意點:

      代碼能得以成功拷貝全靠梯子,當然也可以選擇去網頁下載;

      Android能得以成功運行,全靠給權限sudo 755 android/gradlew;

      React Native 入口文件需修改為 App.web,不然只有Web端才能讀取App.web.js;

      適當執行./gradlew clean重新yarn android等多年經驗積累騷操作排除故障.

      探究代碼

      關鍵的操作在于那行Copy代碼的命令,那究竟上文中提到到下載了4的文件到底做了啥呢?Copy攻城獅心中也有一個大大的問號,Talk is cheap, show me the code,打開文件看看那些代碼吧!

      index.html 常見的單頁面應用入口,像下面代碼中的 div 我們稱其為“根” DOM節點,因為其中的所有內容都將由React DOM進行管理。在當前案例中,我們只是設置一些基本樣式以使主體div具有完整的高度和寬度:

      ...

      ...

      ?

      index.web.js

      使用index.web.js可以在Web和移動端之間區分開來,通過.web.js擴展名可以使該文件僅在Web上使用,其他一些可用的擴展如.native.js、.ios.js和.android.js適用于移動端。當然,如果您希望將本不同端的代碼都保存在一個index.js文件中,則可以使用import { Platform } from 'react-native'來按照條件區分不同平臺的代碼。可以參考React Native官方文檔中有關平臺特定代碼的更多信息。

      index.web.js:

      ...

      ...

      AppRegistry.runApplication(appName,{

      initialProps:{},

      rootTag:document.getElementById('app-root'),

      });

      這與我們移動端的index.js非常相似,不過它還將您的應用程序掛載到根目錄中index.html的div上。

      webpack.config.js

      webpack雖然是重點內容,但此處不過過多介紹,請前往官方文檔或掘金社區閱讀更加詳細的內容,此案例中我們用到了三個插件:

      HtmlWebpackPlugin創建HTML;

      HotModuleReplacementPlugin用于熱模塊重裝;

      DefinePlugin定義變量,例如__DEV__或NODE_ENV中react-native-web。

      使用 JavaScript 來開發移動端 App 似乎是眾多小廠比較普遍的選擇,作為拷貝經驗豐富的 Copy 工程師,我所在的小作坊采用的是 React Native。盡管 React Native 已經進入開源的第 6 個年頭,距離發布 1.0 版本依舊是遙遙無期。“Learn once, write anywhere”,完全不影響 React Native 淪為“不會 JavaScript 也能用”的框架,那如何將在 React Native 項目中引入 react-native-web 呢?

      react-native-web 簡介

      倉庫地址: https://github.com/necolas/react-native-web

      react-native-web 是由 前 Twitter 現 Facebook 工程師 Nicolas Gallagher 實現并維護的開源項目,是一個使 React Native 組件和 API 能運行在 Web 上的庫,其和 React Native Windows, React Native macOS 等庫將 React Native 拓展到一個又一個新的平臺。目前推特、expo、大聯盟足球、Flipkart、優步、《泰晤士報》、DataCamp 以及我們小作坊都在生產中使用了 react-native-web。Chrome、Firefox、Edge,Safari 7 +、IE 10+都支持通過 react-native-web 構建的 web 應用。當然值得注意的是,官方文檔明確表示不支持 React Native 中不推薦使用的組件和 API,因此如果您項目中的某些功能依賴第三方庫,可能那部分的功能在 web 端同構時需要額外處理。

      淺顯地認為react-native-web就是把React Native的組件和API都用適用于Web的標簽和API再適配實現一遍,使其在Web上的行為和在原生應用上盡量保持一致,從文檔中提到的 Alert 和 Setting 模塊以及其對應的源碼中大概能感受到一二,比如TextInput:

      switch?(keyboardType)?{

      case?'email-address':

      type?=?'email';

      break;

      case?'number-pad':

      case?'numeric':

      inputMode?=?'numeric';

      break;

      case?'decimal-pad':

      inputMode?=?'decimal';

      break;

      case?'phone-pad':

      type?=?'tel';

      break;

      case?'search':

      case?'web-search':

      type?=?'search';

      break;

      case?'url':

      type?=?'url';

      break;

      default:

      type?=?'text';

      }

      if?(secureTextEntry)?{

      type?=?'password';

      }

      因此也借鑒了 React Native 的一些代碼,作為適配的依據。

      如果您想基于 React Native 實現多端統一化方案,可參考去哪兒前端團隊的實現方案:跨端開發, 倉庫地址:https://github.com/qunarcorp/qrn-remax-unir

      添加到React Native項目

      一般來說新建 React Native 項目時可以選用 expo-cli 或者 react-native-cli 來創建。expo-cli 中已經預置了對web的支持,如下圖所示.

      而我們實際開發中可能用 react-native-cli腳手架來構建項目比較多些,那么如何引入 react-native-web呢?

      我們先初始化項目:

      npx?react-native?init?rn_web

      #?當然也可以使用模板,如

      #?npx?react-native?init?rn_web?--template?react-native-template-typescript

      此時我們的項目并不支持在web中使用:

      為了項目能在web環境中運行,我們需要借助今天的主角--react-native-web,有請主角出臺:

      cd?rn_web

      yarn?add?react-native-web

      yarn?add?-D?babel-plugin-react-native-web?webpack?webpack-cli?webpack-dev-server?html-webpack-plugin?react-dom?babel-loader?url-loader?@svgr/webpack

      接著我們施展Copy大法,將我們初始化能用到的App.web.jsx、index.html、index.web.js、webpack.config.js這幾個文件一把 down下來:

      curl?-L?https://gist.github.com/hu-qi/bde8a6d2b45325d93b1665174f938faa/download?|?tar?-xvz?--strip-components=1

      然后在package.json中添加build和web的腳本:

      "build":?"rm?-rf?dist/?&&?webpack?--mode=production?--config?webpack.config.js",

      "web":?"webpack?serve?--mode=development?--config?webpack.config.js"

      就和 expo-cli 初始化的項目一樣可以執行yarn web,這時會在本地8080端口運行一個服務,這時我們分別執行yarn ios 和 yarn android就能看到在ios模擬器和Android模擬器中顯示和web端一模一樣的頁面,一次 react-native-web 的多端同構 Hello World 就成功實現了,當然這也意味著我們還可能編譯成小程序,后續有機會一起探討探討!

      此處的注意點:

      代碼能得以成功拷貝全靠梯子,當然也可以選擇去網頁下載;

      Android能得以成功運行,全靠給權限sudo 755 android/gradlew;

      React Native 入口文件需修改為 App.web,不然只有Web端才能讀取App.web.js;

      適當執行./gradlew clean重新yarn android等多年經驗積累騷操作排除故障.

      探究代碼

      關鍵的操作在于那行Copy代碼的命令,那究竟上文中提到到下載了4的文件到底做了啥呢?Copy攻城獅心中也有一個大大的問號,Talk is cheap, show me the code,打開文件看看那些代碼吧!

      index.html 常見的單頁面應用入口,像下面代碼中的 div 我們稱其為“根” DOM節點,因為其中的所有內容都將由React DOM進行管理。在當前案例中,我們只是設置一些基本樣式以使主體div具有完整的高度和寬度:

      ...

      ...

      ?

      index.html 常見的單頁面應用入口,像下面代碼中的 div 我們稱其為“根” DOM節點,因為其中的所有內容都將由React DOM進行管理。在當前案例中,我們只是設置一些基本樣式以使主體div具有完整的高度和寬度:

      ...

      ...

      ?

      index.web.js

      使用index.web.js可以在Web和移動端之間區分開來,通過.web.js擴展名可以使該文件僅在Web上使用,其他一些可用的擴展如.native.js、.ios.js和.android.js適用于移動端。當然,如果您希望將本不同端的代碼都保存在一個index.js文件中,則可以使用import { Platform } from 'react-native'來按照條件區分不同平臺的代碼??梢詤⒖糝eact Native官方文檔中有關平臺特定代碼的更多信息。

      index.web.js:

      ...

      ...

      AppRegistry.runApplication(appName,{

      initialProps:{},

      rootTag:document.getElementById('app-root'),

      });

      這與我們移動端的index.js非常相似,不過它還將您的應用程序掛載到根目錄中index.html的div上。

      index.web.js

      使用index.web.js可以在Web和移動端之間區分開來,通過.web.js擴展名可以使該文件僅在Web上使用,其他一些可用的擴展如.native.js、.ios.js和.android.js適用于移動端。當然,如果您希望將本不同端的代碼都保存在一個index.js文件中,則可以使用import { Platform } from 'react-native'來按照條件區分不同平臺的代碼??梢詤⒖糝eact Native官方文檔中有關平臺特定代碼的更多信息。

      index.web.js:

      ...

      ...

      AppRegistry.runApplication(appName,{

      initialProps:{},

      rootTag:document.getElementById('app-root'),

      });

      這與我們移動端的index.js非常相似,不過它還將您的應用程序掛載到根目錄中index.html的div上。

      webpack.config.js

      webpack雖然是重點內容,但此處不過過多介紹,請前往官方文檔或掘金社區閱讀更加詳細的內容,此案例中我們用到了三個插件:

      HtmlWebpackPlugin創建HTML;

      HotModuleReplacementPlugin用于熱模塊重裝;

      DefinePlugin定義變量,例如__DEV__或NODE_ENV中react-native-web。

      webpack.config.js

      webpack雖然是重點內容,但此處不過過多介紹,請前往官方文檔或掘金社區閱讀更加詳細的內容,此案例中我們用到了三個插件:

      HtmlWebpackPlugin創建HTML;

      HotModuleReplacementPlugin用于熱模塊重裝;

      DefinePlugin定義變量,例如__DEV__或NODE_ENV中react-native-web。

      App.web.tsx

      該文件是臨時添加的文件,用于在使用React Native Web 同構之前驗證我們的設置是否正常運行。最終,您可以刪除此文件,因為App的入口js文件可以在移動端運行,也能在Web端運行。不過為了處理某些在Web上能運行而在移動端不能運行的業務,需要將代碼抽離出來存放在``.web.js`為后綴的文件中。

      App.web.tsx

      該文件是臨時添加的文件,用于在使用React Native Web 同構之前驗證我們的設置是否正常運行。最終,您可以刪除此文件,因為App的入口js文件可以在移動端運行,也能在Web端運行。不過為了處理某些在Web上能運行而在移動端不能運行的業務,需要將代碼抽離出來存放在``.web.js`為后綴的文件中。

      后記

      結合上述的簡單案例,在后續實際業務中,我們可以逐步嘗試同構業務到Web并逐步進行驗證。

      希望這篇文章對您有所啟發,也請各位大佬多多指教!評論區始終為您敞開!

      JavaScript React web前端 移動APP

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:提升開發效率和創新力,低代碼開發平臺功能特點
      下一篇:excel設計銷售漏斗圖技巧分享
      相關文章
      久久精品国产精品亚洲下载| 精品国产亚洲AV麻豆| 亚洲精品线路一在线观看| 亚洲AV无码XXX麻豆艾秋| 国产色在线|亚洲| 亚洲成人网在线观看| 亚洲日韩乱码中文无码蜜桃臀| 亚洲综合激情九月婷婷| 亚洲色欲或者高潮影院| 亚洲成人黄色在线| 亚洲va在线va天堂成人| 国产AV旡码专区亚洲AV苍井空| 精品亚洲成在人线AV无码| 亚洲午夜一区二区电影院| 亚洲av一本岛在线播放| 亚洲伦理中文字幕| 亚洲国产成人综合精品| 苍井空亚洲精品AA片在线播放 | 亚洲精品蜜夜内射| 亚洲第一成年免费网站| 国产亚洲美女精品久久久久| 亚洲人成电影在线播放| 91麻豆国产自产在线观看亚洲| 亚洲日韩一页精品发布| 婷婷亚洲综合五月天小说| 久久精品国产亚洲AV电影| 亚洲国产综合精品| 亚洲中文精品久久久久久不卡| 亚洲精品理论电影在线观看| 国产亚洲漂亮白嫩美女在线| 亚洲一区二区视频在线观看| 亚洲精品成人无码中文毛片不卡| 亚洲av无码专区在线播放 | 亚洲伊人久久大香线蕉苏妲己| 亚洲第一成年人网站| 亚洲综合av一区二区三区不卡 | 亚洲а∨天堂久久精品| 亚洲中文字幕在线第六区| 亚洲AV日韩精品久久久久| 亚洲熟妇无码爱v在线观看| 中文字幕亚洲综合久久综合|