使用绝对路径导入React组件

25

这是我的测试文件

// /imports/components/main.test.js
import React from 'react'
import { shallow, mount } from 'enzyme'
import Main from './main'
import TextInput from "/imports/ui/textInput"
...

并且main.js文件有

// /imports/components/main.js
import { action1 } from "/imports/actions/myAction"

但是当我运行测试时,它会抛出一个错误,内容为:

Cannot find module '/imports/actions/myAction' from 'main.js'

如果我注释掉 import './main', 用同样的方式导入 TextInput 也会发生相同的事情。我在导入 node_modules 中的模块方面没有问题。

我该如何告诉 Jest 或 webpack 从项目目录的绝对路径导入组件(即 import Foo from /imports/...)?


如果在您的测试文件同级目录下有一个名为imports的目录,则应该像这样添加点:**import TextInput from "./imports/ui/textInput"**。 - Hosar
抱歉,我错过了目录结构。我添加了组件和测试文件的位置路径,它们基本上也在 /imports 中。 - spondbob
你可以在 main.test.js 中像这样导入:import TextInput from "../ui/textInput",并且在 import { action1 } from "../actions/myAction" 中导入。如果你想使用绝对路径导入,则必须在 webpack.config 中进行别名设置,然后像这样导入:import { action1 } from "imports/actions/myAction" - Vikramaditya
../actions/myAction 是从 main.js 中导入的,而不是测试文件,并且在组件上运行得非常好。我不需要在测试文件中导入它。在测试文件中,我只需要导入 main.js 组件和用于测试浅渲染的 textInput。如果有什么让您感到困惑,我很抱歉。 - spondbob
https://github.com/tleunen/babel-plugin-module-resolver 对我有用。 - zeraien
@zeraien,对我也有效! - spondbob
7个回答

42
更好的解决相对路径导入问题的方法是创建 jsconfig.json 文件,将其放置在与 package.json 文件相邻的位置。
{
  "compilerOptions": {
    "baseUrl": "src"
  }
}

那么 import { action1 } from "actions/myAction"; 将会生效。


"plugins": ["@babel/plugin-proposal-export-default-from"],刚刚在 package.json#babel 中添加了这个插件。希望对你有用。 - nishit chittora
@Daniel的解决方案很好,不必为这样微不足道的事情再添加另一个插件。 - David Schumann
1
baseUrl 应该是 . 而不是所述的单词 "imports"。 - vsync
@vsync 感谢您的反馈,这是我的笔误。应该是您想要设置baseUrl的目录。在我的情况下,它是“src”。 - nishit chittora
2
您可能需要重新启动,例如 npm start - Chuan

29

如果你正在使用Create React App,你可以在项目根目录下的jsconfig.json(需要在一个新的JavaScript模板中创建)或者tsconfig.json(已经在TypeScript模板中创建)中设置绝对导入路径以在你的项目中使用。

例如:

{
  "compilerOptions": {
    "baseUrl": "src"
  },
  "include": ["src"]
}

官方文档:https://create-react-app.dev/docs/importing-a-component/#absolute-imports


7
另一种解决方案是在项目根目录中创建一个.env文件。 在其中添加NODE_PATH=src/即可。 保存文件并在终端中重新启动开发环境。 然后,您需要更新一些导入语句。

3
现在已经不建议使用这种方法,而是使用jsconfig.json文件:https://dev59.com/8FMI5IYBdhLWcg3wV6Fr - Ben

3

我的文件结构与你的完全相同。为了让 Jest 使用以 / 开头的导入语句,我使用了 babel-plugin-module-resolver 以及其方便的 root 选项。我的 Jest 的 .babelrc 如下:

{
  "presets": ["es2015", "meteor"],
  "plugins": [
    "transform-class-properties",
    "transform-react-constant-elements",
    "transform-react-inline-elements",
    "transform-react-remove-prop-types",
      ["module-resolver", {
      "root": ["../"],
      "alias": {
        "react-router-dom": "react-router-dom/umd/react-router-dom.min.js",
        "redux": "redux/dist/redux.min.js",
        "react-redux": "react-redux/dist/react-redux.min.js"
      }
    }]
  ]
}

我正在使用Meteor,该框架定制了根导入模块,因此我将我的Jest使用和配置隐藏在存储库根目录的.jest目录中,这样我就可以拥有一个特定的.babelrc文件,而不会冲突于Meteor的文件。


嘿,这看起来很有希望。我会在几天后试一试,并在此处更新。感谢您的意见! - spondbob
抱歉更新晚了,但这个解决方案非常有效!安装了resolver模块并设置了根目录,现在我可以使用import .. from '/imports/foo。谢谢。 - spondbob

2

使用webpack(v4)和babel,您可以在目录中提供绝对路径。按照以下步骤进行操作: 在.babelrc文件中,为插件添加此条目。确保在package.json中也有babel-plugin-root-import。

"plugins": [
    [
        "babel-plugin-root-import",
        {
          "paths": [
            {
              "rootPathPrefix": "~",
              "rootPathSuffix": "./"
            },
            {
              "rootPathPrefix": "@src",
              "rootPathSuffix": "src"
            },
            {
                "rootPathPrefix": "@any-other-folder",
                "rootPathSuffix": "src/client/../any-other-folder"
              }
          ]
        }
      ]
]

现在,如果你遇到eslint问题,可以在你的eslintrc中添加以下几行代码:
"settings": {
"import/resolver": {
  "babel-plugin-root-import": [
    {
      "rootPathPrefix": "@src",
      "rootPathSuffix": "src"
    },
    {
      "rootPathPrefix": "@any-other-folder",
      "rootPathSuffix": "src/client/../any-other-folder"
    }
  ]
 }
}

现在,为了让您的编辑器识别这些路径,您可以在jsconfig文件中创建此条目。
{
"compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~/*": ["/*"],
      "@src/*": ["src/*"],
      "@any-other-folder/*": ["src/client/../any-other-folder/*"] ==> absolute path to any other folder
    }
  },
  "exclude": ["node_modules"] 
}

希望这些条目能够帮到您。

1

我在 package.json 文件中的 "jest" 键下有一些 jest 配置。所以我只需在那里添加这一行:

"modulePaths": ["<rootDir>/src/"]

这对我很有效,希望能帮助其他人。


1
在你的jsconfig.json/tsconfig.json文件中添加以下内容。
{
  "compilerOptions": {
    "baseUrl": "src",
  },
  "include": ["src"],
  "exclude": ["node_modules", "build"]
}

假设文件夹结构如下:src->components->Header.tsx,那么你可以按照以下方式进行导入。

import Header from 'components/Header';

这是因为在tsconfig.json/jsconfig.json中的baseUrl被设置为src

注意:除非你想使用@/前缀的方式进行导入,否则不需要其他操作。如果你需要,请告诉我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接