一、前言
在開發RN專案時,經常會要使用這樣的方式(../../../)來引入元件,感覺非常繁瑣,如果專案結構層級比較多,引入的頭部更加分不清. 那有沒有一種方案和vue專案一樣,經過配置後簡寫路徑,在引入的時候,直接使用,例如vue專案中 @ 符號表示 src目錄. 經過百度後,發現還是有這種類似的配置. 但嘗試過網上的幾種方案,都沒起作用,主要是由於我的專案是基於 RN(0.59.5) + TypeScript搭建的。
二、嘗試過的錯誤方案
1. 在資料夾中加入 package.json
例如你想引入utils裡面的檔案,不想../../../..,這樣引入,而是想@utils/.....這樣引入,那麼你就可以在utils檔案中放一個package.json,裡面如下:
- {
- name:"@utils"
- }
該方案,我嘗試之後沒有成功,專案中的 ts檔案有規則校驗,會有錯誤提示,找不到該模組。 如果不是用TypeScript構建的專案,我想是可以的。
2. 安裝 babel-plugin-root-import
這種方案,網上搜尋是最多的. 網上所描述的具體實現,這裡不撰寫了,反正我按照網上的步驟配置,沒有成功。估計也是隻適合於ES6構建的專案。
以上兩種方案,參考 react-native 相對專案路徑匯入元件, 感謝暖暖的風兒 給我提供了些思路
3. 使用@providesModule
在檔案的頂部,巢狀一個多行註釋,把@providesModule放在註釋裡,@providesModule後新增類名,以後就直接使用類名就能匯入了。
注意,帶有@providesModule的多行註釋,一定要是檔案的第一個多行註釋。如:
- /**
- * @providesModule Common
- */
- import {
- Dimensions
- } from 'react-native';
- export default class Common {
- static bgColor = 'rgb(232,232,232)';
- static screenW = Dimensions.get('window').width;
- static screenH = Dimensions.get('window').height;
- }
外部使用Common
- // 以前需要這樣
- // import Common from './../Common/Common'
- // 現在可以直接用類名
- import Common from 'Common'
嘗試之後,ts的校驗,還是會報錯. 這種方案主要是參考ReactNative之解決檔案匯入路徑問題, 這篇文章中有介紹@providesModule的原理,有興趣的同學,請拜讀。
4. 使用typescript path mapping設定相對路徑
因為專案是用TypeScript構建的,在嘗試幾種錯誤思路後,然後想TypeScript是不是本來就支援路徑設定?確實,TypeScript是支援設定相對路徑的. 網上提供的方案
在 tsconfig.json 中設定
- {
- "baseUrl": "./",
- "path": {
- "@http/*": ["src/http/*"],
- "@utils/*": ["src/utils/*"]
- }
- }
這樣在 import 的時候就不用使用一長串的 ../../../.. 這種形式了,直接使用相對短路徑
- 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 增加如下配置
- module.exports = {
- plugins: [
- [
- 'babel-plugin-root-import',
- {
- rootPathPrefix: '~', // `~` 預設
- rootPathSuffix: 'src'
- }
- ]
- ]
- }
這裡,我嘗試過rootPathPrefix 用 @ , 在編譯的時候會報錯。所以不得不放棄使用@ (有些強迫症,想要用@, 因為vue專案中就是@表示src目錄)
3.執行npm start -- --reset-cache命令
已有專案,記得執行此命令清理快取,這點非常重要,我在除錯的過程中,變更過幾次符號的配置,如果變更配置後沒有執行該命令,則配置不起作用
4. 設定typescript相對路徑
在 tsconfig.json 中設定
- {
- "baseUrl": "./",
- "path": {
- "~/*": ["src /*"],
- }
- }
注意:變更設定之後,最好重啟下VSCode
至此,我們在專案中引入檔案可以用以下優雅的方式
- import { UserAccount } from '~/constants/const'
- import MyTheme from '~/assets/commonStyle'
四、總結
專案是使用 TypeScript + Dva構建的RN專案,該問題網上給出的一些方案都是基於 ES6構建的RN專案,所以之前的解決方案,都不適應。再加上我學習TypeScript 和 RN的時間不長,很多理論知識學習不到位。所以花了比較長的時間。我正在搭建基於TypeScript + Dva + RN + React-Navigation 的App開發框架,歡迎有興趣的同學一起交流。後續,也會把我搭建的專案框架,進行開源, 目前還只實現了一些基礎建設,哈哈~~。
以下是我專案框架的目錄: