zoukankan      html  css  js  c++  java
  • 解决基于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开发框架,欢迎有兴趣的同学一起交流。后续,也会把我搭建的项目框架,进行开源, 目前还只实现了一些基础建设,哈哈~~。

    以下是我项目框架的目录:

  • 相关阅读:
    AdaBoost学习笔记
    隐马尔科夫模型(HMM)学习笔记二
    隐马尔可夫模型(HMM)学习笔记一
    k-means学习笔记
    pandas练习(四)--- 应用Apply函数
    pandas练习(三)------ 数据分组
    pandas练习(二)------ 数据过滤与排序
    pandas练习(一)------ 了解数据
    Android Studio Error:CreateProcess error=216
    玩QQ游戏,见到好几个图像是美女的QQ,就不始玩
  • 原文地址:https://www.cnblogs.com/xyb0226/p/10986338.html
Copyright © 2011-2022 走看看