React 项目中使用 `@` 符号代替 `src` 目录

7,108 阅读5分钟

开发日记 2020.10.16

怎么使用 @ 符号代替项目的 src 目录,用以避免类似 ../../../../ 的多重相对路径导入

最近在做毕设项目的时候,前端用到了 React + React-Redux + React-Router + TypeScript。jsx 的灵活性配合上 typescript 的类型安全简直美呆了。只不过经常会碰到一些在 vue 中的自带的功能,react 中却需要自己来实现。

比如我在 src/pages/user/login/login.tsx 中要调用到 src/store/useinfoSlice.ts 中的方法,写导入的时候就要这么写:

import { postLogin } from '../../../store/useinfoSlice'
// 万一多嵌套了几层
import { postLogin } from '../../../../../../store/useinfoSlice'
// 恐怖如斯

简直恶心有没有,我都必须通过编辑器(vscode)的智能提示来避免多输入了或者少输入了 ../ 符号。明明只需要很简单的一步就可以确认文件位置,却偏偏要搞得这么麻烦。要是像 vue 那样直接通过 @ 符号引入就好了。

于是我就查阅网上信息来完美解决了这个 shit 一般的多重 ../ 的写法,换成了简单的 @ 符号。

Step 1: 弹出 react 项目配置

create-react-app 默认是将配置文件隐藏起来的,现在首先需要弹出 react 的配置文件。

npm run eject
# or
yarn run eject

弹出 react 配置之后,我们才能继续下面的修改。

参考:

Step 2: 编辑 webpack 配置

编辑 config/webpack.config.js

// ...
// 我使用的 3.4.3 版本的 react-scripts 生成的代码,这一部分配置大约在 280 行左右
resolve {
    // 在 alias 下进行配置 more configuration
    alias: {
        // ...
        // 添加一行配置
        // paths.appSrc 就是 src 目录的路径
        '@': paths.appSrc
    }
}
// ...

编辑好之后,webpack 便能够解析 @ 符号了。

Step 3: 替换相对路径引用

现在可以将代码中的相对路径引用改成绝对路径引用。例如:

// src/index.tsx 中
import App from "./pages/App";
// == 修改成 ==>
import App from "@/pages/App";

Step 4: 解决 TS 找不到类型定义的报错(JS 用户请跳过)

完成以上步骤后,重新启动开发服务器还会遇到问题,发现编译不通过。

控制台报错信息如下

TypeScript error in <path/to/project>/src/index.tsx(7,17):
Cannot find module '@/pages/App' or its corresponding type declarations.  TS2307

     5 | import store from "./store/store";
     6 |
  >  7 | import App from "@/pages/App";
       |                 ^

tsc (Typescript 编译器)找不到对应的类型定义。

这是因为项目是用 Typescript 开发的,webpack 能够解析 @ 符号的路径替换了,但是 tsc 不能解析。所以会报出“找不到类型定义”的错误。

所以我们还需要编辑 tsconfig.json

{
  "compilerOptions": {
        // 在 compilerOptions 内添加如下配置
        "baseUrl": ".",
        "paths": {
        	// 注意哦,是 "@/*" 后面的 "/*" 不能少
            "@/*": [
                "src/*"
            ]
        }
    }
}

重新启动开发服务器后,不出意外的话,已经能够运行了。

如果你没有解决问题,或者解决了却觉得现在只是知其然不知其所以然,不如看一看下面几个关于 ts 的参考文档。

参考:

Step 5: 解决 eslint 找不到模块的报错(如果编辑器有错误提示再看)

上述步骤执行结束了,是能够运行了。但是我在 vscode 里进行编辑时,依然会看到“无法解析指定模块”的错误提示。一经探查,发现这是因为尽管 webpack 和 tsc 都能识别解析 “@” 符号了,但是 eslint 还不知道怎么解析,所以编辑器还是或弹出 eslint 的报错。

解决方案如下:

# 安装两个插件
# 其实还需要用到 eslint-plugin-import 的,但是 react 已经默认安装了,就不再另外安装了
# 如果发现 package.json 中没有,再另外安装
npm install eslint-import-resolver-webpack --save-dev
# or
yarn add eslint-import-resolver-webpack --dev

create-react-app 默认是将 eslint 配置写到了 package.json 里。所以成功后,需要编辑 package.json 中的 eslintConfig 属性(如果发现 eslint 配置不是在这里,那就写到对应的位置,配置的格式不一样,但内容都是一样的):

{
  "eslintConfig": {
    "extends": "react-app",
    "plugins": [
      "import" // 使用插件
    ],
    "settings": {
      "webpack": "./config/webpack.config.js",
      // import 插件配置
      "import/resolver": {
      	// 路径别名配置
        "alias": {
          "@": "src"
        }
      }
    }
  }
}

保存,看看 vscode 还有报错么?如果没有,万事大吉。如果有,试试重启编辑器让编辑器重新加载一遍 eslint 配置试试 [滑稽.jpg - 能重启解决的问题那都不叫问题]?

如果还有问题?看一看下面的几篇关于 eslint 的配置,万一有你想要的答案呢?

具体要为什么要这么配置,我就不来讲解了,班门弄斧就不好了,可以参考:

Step 6: jest 单元测试识别别名

updated: 2020.11.09 00:25

今天运行 yarn test 的时候,发现对组件进行单元测试时 jest 无法识别通过 @ 符号导入的包。仔细一看,原来 jest 也需要配置一下路径别名。

react-scripts 弹出的 相关配置大多数都在 package.json 里。jest 配置也在,我们在 jest 字段中内添加如下配置。

{
  "jest": {
  	// 省略无关部分 ...
    "moduleNameMapper": {
      "^react-native$": "react-native-web",
      "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy",
      "^@/(.*)$": "<rootDir>/src/$1" // 新增 用来映射 `@` 符号
    },
    "moduleFileExtensions": [
      "web.js",
      "js",
      "web.ts",
      "ts",
      "web.tsx",
      "tsx",
      "json",
      "web.jsx",
      "jsx",
      "node",
      "d.ts"    // 新增,不是 ts 用户不用添加,主要是因为配置了 moduleNameMapper 中的别名映射后, 
                // 别的文件能够识别到了,但 .d.ts 无法被识别
    ]
  	// 省略无关部分 ...
  }
}

OK!如果觉得有用的话,不妨动动鼠标点个赞吧~~