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

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

  • 相关阅读:
    121.买卖股票 求最大收益1 Best Time to Buy and Sell Stock
    409.求最长回文串的长度 LongestPalindrome
    202.快乐数 Happy Number
    459.(KMP)求字符串是否由模式重复构成 Repeated Substring Pattern
    326.是否为3的平方根 IsPowerOfThree
    231.是否为2的平方根 IsPowerOfTwo
    461.求两个数字转成二进制后的“汉明距离” Hamming Distance
    206.反转单链表 Reverse Linked List
    448. 数组中缺少的元素 Find All Numbers Disappeared in an Array
    常见表单元素处理
  • 原文地址:https://www.cnblogs.com/xyb0226/p/10986338.html
Copyright © 2011-2022 走看看