绝对导入:React 和 Typescript
Posted
技术标签:
【中文标题】绝对导入:React 和 Typescript【英文标题】:Absolute Imports: React and Typescript 【发布时间】:2020-07-28 09:16:29 【问题描述】:背景
我有一个使用 create-react-app
和 typescript 引导的 React 应用程序。随着应用程序的增长,(目标)我想实现绝对导入。我正在使用 VS Code (Visual Studio Code),只需很少的配置,就可以让 TS 和 VS Code 识别我的绝对导入。
对于 TS,我在tsconfig.json
中采取了以下步骤:
"baseUrl": "client"
将“客户”添加到我的include
密钥:"include": ["./**/*.ts", "./**/*.tsx", "client"]
对于 VS Code,我更改了用户设置:Typescript -> Preferences: Import Module Specifier -> non-relative
效果很好。我所有的导入都使用绝对导入,没有错误。但是,当我运行应用程序时,我收到一个错误:Error: Cannot find module "component"
我希望看到我的应用程序,就像我在绝对导入之前所做的那样。
我尝试了什么
想通了,错误是 webpack 或 babel 问题。
已创建env
文件
将以下内容添加到应用根目录中的 env 文件(与我的 package.json 相同的位置)
NODE_PATH=client/
那没有用。同样的错误:Error: Cannot find module "components"
。还尝试将 NODE_PATH 更改为 REACT_APP_NODE_PATH 也不起作用。
修改 Babel 配置
添加了带有yarn add -D babel-plugin-module-resolver
的 babel 插件模块解析器。然后将我的babel.config.js
修改为:
module.exports =
env ...,
plugins: [
[
'module-resolver',
cwd: 'babelrc',
extensions: ['.ts', '.tsx', '.js'],
alias:
client: './client',
,
,
],
]
返回相同的错误。 (每次更改配置文件后,我都会重新启动服务器)
引用的资源 我使用了很多不同的文章来试图弄清楚。以下是一些:
Kyle Truong (here) 使用 Create React App 实现绝对导入 Michael Bednarz (here) 在 Create React App 中的绝对导入 Justin Noel (here) 为 TypeScript 配置 React 绝对导入 在 React 组件中使用绝对路径 (***) 如何在 React 应用程序的 typescript 文件中导入 js 模块(带绝对路径)?还有很多其他的。这些都没有奏效。
项目结构
我的项目结构有点“非传统”或不是我的典型模式,这可能会导致问题。
└── root dir
├── assets
│ └── client
│ ├── assets
│ ├── components
│ ├── hooks
│ └── ...
│ └── babel.config.js
│ └── .babelrc
│ └── webpack.config.js
│ └── package.json
└── server files (no server dir)
所以client
就像我在典型的反应应用程序中的src
。 assets
是我的服务器的“入口目录”,位于 root dir
中。
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:TypeScript 的 React 绝对导入 以下是它的工作原理。将您的 tsconfig.json 文件修改为如下所示:
"compilerOptions":
...
"baseUrl": "src"
,
"include": ["src"]
【讨论】:
【参考方案2】:我的解决方案是使用 babel-plugin-module-resolver。为什么?因为它允许我这样做。
import Comp1 from 'components/comp1';
import AnotherAppComp from '@app/anotherComp';
它的配置更加灵活,允许别名,或者直接访问。
在babel.config.js中,添加这个插件:
plugins: [
[
require.resolve('babel-plugin-module-resolver'),
cwd: 'babelrc',
extensions: [
'.js',
'.jsx',
'.ts',
'.tsx',
'.android.js',
'.android.tsx',
'.ios.js',
'.ios.tsx',
],
root: ['.'],
alias:
'@app': './another-app', // path to your app folder
,
,
],
...
]
然后在tsconfig.json中,将compilerOptions改为:
"compilerOptions":
...
"baseUrl": ".", /* Base directory to resolve non-absolute module names. */
"paths":
"@app/*": ["./another-app/*"],
"*": ["./src/*"],
,
...
我必须重新启动我的 vscode 才能让它第一次工作。之后,当我编辑时,我不必再重新启动了。
【讨论】:
【参考方案3】:找到答案。不需要env
文件。只需要修改tsconfig.json
和webpack.config.js
文件即可。
TS 配置
添加了两个键:baseUrl
和 paths
。将baseUrl
设置为src
或client
目录。 paths
键将包含一个对象,其中包含您要在绝对路径中引用的任何内容。
"compilerOptions":
...
"baseUrl": "./client",
"paths":
"client/*": ["./client/*"]
,
...
,
"include": ["./**/*.ts", "./**/*.tsx"]
Webpack 配置
为“src”添加了一个别名(在我的例子中是“client”)。
module.exports = (env, options) => (
...
resolve:
alias:
client: path.resolve(__dirname, 'client/') // added this
,
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json']
)
用法 现在要导入一些东西,我可以用“客户端”替换相对导入。 这个:
import TableHeader from '../../../components/Table/TableHeader'
变成这样:
import TableHeader from 'client/components/Table/TableHeader'
如果有更好的方法,请发布您的解决方案。 ?
【讨论】:
无论我做什么,我都无法让它工作:(我不确定 babel 是否会妨碍我以上是关于绝对导入:React 和 Typescript的主要内容,如果未能解决你的问题,请参考以下文章
React Monorepo 纱线工作区 + 打字稿 + 绝对导入
使用react + webpack时如何使用绝对路径导入自定义scss?