绝对导入:React 和 Typescript

Ben*_*ves 1 typescript reactjs webpack babeljs

背景

我有一个使用create-react-app和打字稿引导的 React 应用程序。随着应用程序的增长,(目标)我想实现绝对导入。我正在使用 VS Code(Visual Studio Code)并且配置很少,我得到了 TS 和 VS Code 来识别我的绝对导入。

对于 TS,我采取了以下步骤tsconfig.json

  • 将“baseUrl”更改为“client”: "baseUrl": "client"
  • 将“客户端”添加到我的include密钥中:"include": ["./**/*.ts", "./**/*.tsx", "client"]

对于 VS Code,我更改了我的用户设置:Typescript -> Preferences: Import Module Specifier -> non-relative

那效果很好。我所有的进口都使用绝对进口,没有错误。但是,当我运行该应用程序时,出现错误:Error: Cannot find module "component"我希望看到我的应用程序,就像我在绝对导入之前所做的那样。

我试过的

想通了,错误是 webpack 或 babel 问题。

  1. 创建的env文件

    将以下内容添加到应用程序根目录中的 env 文件(与我的 package.json 相同的位置)

NODE_PATH=client/
Run Code Online (Sandbox Code Playgroud)

那没有用。同样的错误:Error: Cannot find module "components"。还尝试将 NODE_PATH 更改为 REACT_APP_NODE_PATH 也不起作用。

  1. 修改 Babel 配置

    添加了 babel 插件模块解析器yarn add -D babel-plugin-module-resolver。然后将我的修改babel.config.js为:

module.exports = { 
  env {...}, 
  plugins: [
    [
      'module-resolver',
      {
        cwd: 'babelrc',
        extensions: ['.ts', '.tsx', '.js'],
        alias: {
          client: './client',
        },
      },
    ],
  ]
}
Run Code Online (Sandbox Code Playgroud)

这将返回相同的错误。(每次更改我的配置文件后,我都会重新启动服务器)

参考资源 我使用了很多不同的文章来试图找到清晰的思路。这里有一些:

  • Kyle Truong 的 Create React App 的绝对导入(此处
  • Michael Bednarz 撰写的 Create React App 中的绝对导入(此处
  • 由 Justin Noel 为 TypeScript 配置 React 绝对导入(这里
  • 在 React 组件中使用绝对路径 ( StackOverflow )
  • 如何在 React 应用程序的打字稿文件中导入 js 模块(带绝对路径)?

还有许多其他人。这些都没有奏效。

项目结构

我的项目结构有点“非常规”,或者不是我的典型模式,这可能会导致问题。

??? root dir
    ??? assets
    ?   ??? client
    ?       ??? assets
    ?       ??? components
    ?       ??? hooks
    ?       ??? ...
    ?   ??? babel.config.js
    ?   ??? .babelrc
    ?   ??? webpack.config.js
    ?   ??? package.json
    ??? server files (no server dir) 
Run Code Online (Sandbox Code Playgroud)

所以,client就像我src在一个典型的反应程序。assets是我的服务器的“入口目录”,它位于root dir.

任何帮助,将不胜感激。

Ben*_*ves 9

找到了答案。不需要该env文件。只需要修改tsconfig.jsonwebpack.config.js文件。

TS配置

添加了两个键:baseUrlpaths。将 设置baseUrl为您的srcclient目录。该paths键将包含一个对象,其中包含您要在绝对路径中引用的任何内容。

{
  "compilerOptions": {
    ...
    "baseUrl": "./client",
    "paths": {
      "client/*": ["./client/*"]
    },
    ...
  },
  "include": ["./**/*.ts", "./**/*.tsx"]
}
Run Code Online (Sandbox Code Playgroud)

网络包配置

添加了“src”的别名(在我的例子中是“client”)。

module.exports = (env, options) => ({
  ...
  resolve: {
    alias: {
      client: path.resolve(__dirname, 'client/') // added this
    },
    extensions: ['.ts', '.tsx', '.js', '.jsx', '.json']
  }
})
Run Code Online (Sandbox Code Playgroud)

用法 现在要导入一些东西,我可以用“client”替换相对导入。这个:

import TableHeader from '../../../components/Table/TableHeader'
Run Code Online (Sandbox Code Playgroud)

变成这样:

import TableHeader from 'client/components/Table/TableHeader'
Run Code Online (Sandbox Code Playgroud)

如果有更好的方法来做到这一点,请发布您的解决方案。


归档时间:

查看次数:

6873 次

最近记录:

5 年,2 月 前