解決基于TypeScript 的 RN項目相對路徑引入組件的問題

一、前言

在開發RN項目時,經?;嵋褂謎庋姆絞?../../../)來引入組件,感覺非常繁瑣,如果項目結構層級比較多,引入的頭部更加分不清. 那有沒有一種方案和vue項目一樣,經過配置后簡寫路徑,在引入的時候,直接使用,例如vue項目中 @ 符號表示 src目錄. 經過百度后,發現還是有這種類似的配置. 但嘗試過網上的幾種方案,都沒起作用,主要是由于我的項目是基于 RN(0.59.5) + TypeScript搭建的。

二、嘗試過的錯誤方案

1. 在文件夾中加入 package.json

例如你想引入utils里面的文件,不想../../../..,這樣引入,而是想@utils/.....這樣引入,那么你就可以在utils文件中放一個package.json,里面如下

  1. {
  2. ?????name:"@utils"
  3. }

該方案,我嘗試之后沒有成功,項目中的 ts文件有規則校驗,會有錯誤提示,找不到該???。 如果不是用TypeScript構建的項目,我想是可以的。

2. 安裝?babel-plugin-root-import

這種方案,網上搜索是最多的. 網上所描述的具體實現,這里不撰寫了,反正我按照網上的步驟配置,沒有成功。估計也是只適合于ES6構建的項目。

以上兩種方案,參考 react-native 相對項目路徑導入組件, 感謝暖暖的風兒 給我提供了些思路

3. 使用@providesModule

在文件的頂部,嵌套一個多行注釋,把@providesModule放在注釋里,@providesModule后添加類名,以后就直接使用類名就能導入了。

注意,帶有@providesModule的多行注釋,一定要是文件的第一個多行注釋。如:

  1. /**
  2. ?* @providesModule Common
  3. ?*/
  4. import {
  5. ????Dimensions
  6. } from 'react-native';
  7. export default class Common {
  8. ????static bgColor = 'rgb(232,232,232)';
  9. ????static screenW = Dimensions.get('window').width;
  10. ????static screenH = Dimensions.get('window').height;
  11. }

外部使用Common

  1. // 以前需要這樣
  2. // import Common from './../Common/Common'
  3. ? ?
  4. // 現在可以直接用類名
  5. import Common from 'Common'

    嘗試之后,ts的校驗,還是會報錯. 這種方案主要是參考ReactNative之解決文件導入路徑問題, 這篇文章中有介紹@providesModule的原理,有興趣的同學,請拜讀。

4. 使用typescript path mapping設置相對路徑

因為項目是用TypeScript構建的,在嘗試幾種錯誤思路后,然后想TypeScript是不是本來就支持路徑設置?確實,TypeScript是支持設置相對路徑的. 網上提供的方案

在?tsconfig.json?中設置

  1. {
  2. ??"baseUrl": "./",
  3. ??"path": {
  4. ????"@http/*": ["src/http/*"],
  5. ????"@utils/*": ["src/utils/*"]
  6. ??}
  7. }

這樣在?import?的時候就不用使用一長串的?../../../..?這種形式了,直接使用相對短路徑

  1. import {AuthService} from '@http/Auth';

    采用這種方案之后,在ts文件中的校驗不報錯了,也能直接鏈接到對應的申明。但編譯為javascript后,路徑并沒有映射過去,生成apk的時候報錯,提示找不到對應的???。

    至此,我已發現,只要解決此編譯問題,那么就能解決了。但是發現沒有這么簡單,后又嘗試了引入 module-alias, tsmodule-alias等插件來解決此編譯問題都沒有成功,估計是沒有用正確。

三、最終方案

輪番嘗試以上的幾種錯誤方案后,反復搞了一天,心累了。哎,還好沒有最終放棄,在上述的第2種方案中,我引入了babel-plugin-root-import插件, 發現可以使用某個符號替代路徑.

1.安裝?babel-plugin-root-import

npm install babel-plugin-root-import --save-dev   yarn add babel-plugin-root-import –dev

? ?

如果 npm 沒有安裝成功,就用 yarn (我是使用yarn 才安裝成功)

2.babel.config.js 增加如下配置

  1. module.exports = {
  2. ??plugins: [
  3. ????[
  4. ??????'babel-plugin-root-import',
  5. ??????{
  6. ????????rootPathPrefix: '~', // `~` 默認
  7. ????????rootPathSuffix: 'src'
  8. ??????}
  9. ????]
  10. ??]
  11. }

這里,我嘗試過rootPathPrefix 用 @ , 在編譯的時候會報錯。所以不得不放棄使用@ (有些強迫癥,想要用@, 因為vue項目中就是@表示src目錄)

3.執行npm start -- --reset-cache命令

已有項目,記得執行此命令清理緩存,這點非常重要,我在調試的過程中,變更過幾次符號的配置,如果變更配置后沒有執行該命令,則配置不起作用

4. 設置typescript相對路徑

在?tsconfig.json?中設置

  1. ?{
  2. ?"baseUrl": "./",
  3. ??"path": {
  4. ????"~/*": ["src /*"],
  5. ??}
  6. }

注意:變更設置之后,最好重啟下VSCode

至此,我們在項目中引入文件可以用以下優雅的方式

  1. import { UserAccount } from '~/constants/const'
  2. import MyTheme from '~/assets/commonStyle'

? ?

四、總結

項目是使用 TypeScript + Dva構建的RN項目,該問題網上給出的一些方案都是基于 ES6構建的RN項目,所以之前的解決方案,都不適應。再加上我學習TypeScript 和 RN的時間不長,很多理論知識學習不到位。所以花了比較長的時間。我正在搭建基于TypeScript + Dva + RN + React-Navigation 的App開發框架,歡迎有興趣的同學一起交流。后續,也會把我搭建的項目框架,進行開源, 目前還只實現了一些基礎建設,哈哈~~。

以下是我項目框架的目錄:

posted @ 2019-06-06 18:04 沉淀的風 閱讀(...) 評論(...) 編輯 收藏