在 React CRA 项目中使用 Alias 简化模块导入

问题

在使用 Create-React-App (CRA) 工具创建 React 项目后,我们常常会按照自己的风格,在 src 目录中组织目录结构。有时简单的项目,目录层级只有 1 级或者 2 级,那么在导入依赖组件时,可以写为:

1
2
import Nav from "./_partial/Nav";
import PostRepository from "../Repository/PostRepository";

这样看起来似乎没什么问题。

但是当项目变得复杂后,要么,所有的文件都平铺在一个目录中;要么,就会出现多级嵌套的目录结构,导入模块就可能演变成:

1
import Footer from "../../../component/_partial/Footer";

导入模块变得越来越复杂,而问题似乎又不可避免。

那么有没有什么方式可以让我们简化导入语句,同时又不影响对依赖模块的查找呢?

这就是 alias 可以发挥作用的时候了。


解决方法

默认情况下,使用 Create-React-App 创建的项目是使用 webpack 进行打包的,在 webpack 的配置中,我们可以设置 alias 项,通过一个简单符号替换公共的路径前缀,比如 ~

我们需要在项目根目录的 config/webpack.config.js 中修改这个配置项,但是 config 目录默认是不存在的,需要先在项目的根目录下运行,将 webpack 所有的配置项生成到 config 目录中。

1
$ npm run eject

如果项目存在未提交的内容,根据提示,需要先进行 commit,然后才能继续运行此命令.

关于 npm run eject 命令,请查看官方文档

执行完成后,就可以在项目的根目录下看到 config 子目录了。

然后打开 config/webpack.config.js 文件,在变量声明区域追加一行

1
const basePath = path.resolve(__dirname, "../src");

通常 path 模块已经被导入了,不过最好还是再进行一下确认

然后我们在向外暴露的函数中,找到最后 return 的巨大 object 里面的 resolve.alias 一项,向里面添加一组键值对。

1
2
3
4
5
6
...
alias: {
"~": basePath, // 添加这一行
...
}
...

修改后,就可以使用 ~ 作为前缀去导入内部组件了。

1
import Footer from "~/component/_partial/Footer";

上述的修改,会让 webpack 在打包时,使用 basePath 的值(我这里使用的是 src 目录的绝对路径)替换 ~ 符号,然后使用绝对路径去寻找依赖的组件。

这样就解决了导入路径繁琐的问题。