【问题标题】:ES6 import from root从根目录导入 ES6
【发布时间】:2023-04-08 03:56:01
【问题描述】:

我目前正在玩 React Native。我正在尝试构建我的应用程序,但是它开始对导入变得混乱。

--app/
    -- /components
        -- Loading.js
    -- index.ios.js

现在,在我的index.ios.js 内,我可以简单地做:

import Loading from './components/Loading';

但是,当我开始创建更多组件时,具有更深的目录结构,它开始变得混乱:

import Loading from '.../../../../components/Loading';

我知道首选的解决方案是为事物制作私有 npm 模块,但这对于小型项目来说太过分了。

您可以在浏览器上执行global.requireRoot 类型的解决方案,但是如何通过导入来实现呢?

【问题讨论】:

  • 这似乎与 React 或 ES6 无关。
  • Alias,你找到解决办法了吗?
  • 我没有...我似乎找到的唯一答案是“更好地构建您的应用程序”,但这并不总是一种选择。我刚结束使用 require....
  • 这里使用 require 和使用 import 有何不同?
  • 也许可以尝试NODE_PATH='./app' npm start,然后需要import Loading from 'components/Loading'之类的东西,但我自己还没有尝试过......

标签: javascript node.js import


【解决方案1】:

React 文档解释了如何做到这一点: https://create-react-app.dev/docs/importing-a-component/#absolute-imports

只需在您的项目根目录中添加一个 jsconfig.json:

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

【讨论】:

    【解决方案2】:

    如果您使用的是Create-React-App,您只需更改环境变量NODE_PATH 以包含项目的根目录。

    在运行 react-scripts 命令之前,在您的 config.json 中进行以下更改以设置此变量:

    "scripts": {
      "start": "cross-env NODE_PATH=. react-scripts start",
      "build": "cross-env NODE_PATH=. react-scripts build",
      "test": "cross-env NODE_PATH=. react-scripts test",
      "eject": "react-scripts eject"
    },
    

    我们正在使用 npm 库 cross-env,因为它适用于 unix 和 windows。语法是cross-env var=value command

    现在我们可以用import module from 'src/my/module'代替import module from '../../my/module'

    更多实施细节

    需要注意的是,cross-env 的作用域仅限于它执行的命令,所以cross-env var=val command1 && command2 只会在 command1 期间设置 var。如果需要,请通过 cross-env var=val command1 && cross-env var=val command2 修复此问题

    create-react-app 将 node_modules/ 中的文件夹优先于 NODE_PATH 中的文件夹,这就是我们将 NODE_PATH 设置为“.”的原因。而不是“./src”。使用 ”。”要求所有绝对导入都以“src/”开头,这意味着永远不会有名称冲突,除非您使用的是一些名为 src 的 node_module。

    (注意:上述解决方案替换变量 NODE_PATH。理想情况下,如果它已经存在,我们将附加到它。NODE_PATH 是一个“:”或“;”分隔的路径列表,取决于它是 unix 还是 windows。如果有人找到跨平台解决方案来执行此操作,我可以编辑我的答案。)

    【讨论】:

      【解决方案3】:

      如果您使用 Create React App,您可以在 config/webpack.config.dev.jsconfig/webpack.config.prod.js 中添加 paths.appSrcresolve.modules

      发件人:

      resolve: {
          modules: ['node_modules', paths.appNodeModules].concat(...
      

      收件人:

      resolve: {
          modules: [paths.appSrc, 'node_modules', paths.appNodeModules].concat(...
      

      然后你的代码就可以工作了:

      import Loading from 'components/Loading';
      

      【讨论】:

        【解决方案4】:

        我刚刚检查了一个超过 6 个月的 React 项目,由于某些原因,我的导入不再有效。我尝试了第一个答案:

        import 'foo' from '~/components/foo.js';
        

        很遗憾,这不起作用。

        我在项目的根目录中添加了一个.env 文件,与我的package.json 处于同一级别。我在该文件中添加了以下行,这修复了我在项目中的导入。

        NODE_PATH=src/
        

        【讨论】:

        • 它是import 'foo' from 'components/foo.js';。也添加这个。
        【解决方案5】:

        Webpack 3 中配置略有不同:

        import webpack from 'webpack';
        import {resolve} from 'path';
        

        ...

        module: {
            loaders: [
                {
                    test: /\.js$/,
                    use: ["babel-loader"]
                },
                {
                    test: /\.scss$|\.css$/,
                    use: ["style-loader", "css-loader", "sass-loader"]
                }
            ]
        },
        resolve: {
            extensions: [".js"],
            alias: {
                ["~"]: resolve(__dirname, "src")
            }
        },
        

        【讨论】:

          【解决方案6】:

          使用 webpack,您还可以使以 ~ 开头的路径解析为根目录,因此您可以使用 import Loading from '~/components/Loading';

          resolve: {
            extensions: ['.js'],
            modules: [
              'node_modules', 
              path.resolve(__dirname + '/app')
            ],
            alias: {
              ['~']: path.resolve(__dirname + '/app')
            }
          }
          

          诀窍是使用 javascript 括号语法来分配属性。

          【讨论】:

          • 我怀疑括号在这里有什么作用。括号用于允许将变量作为键传递。只需在键周围加上引号就可以了。
          【解决方案7】:

          如果您使用的是 Webpack,您可以通过 resolve 属性对其进行配置,以解析您的导入路径。

          Webpack 1

          resolve: {
            root: [
              path.resolve(__dirname  + '/src')
            ]
          }......
          

          Webpack 2

          resolve: {
            modules: [
              path.resolve(__dirname + '/src'),
              path.resolve(__dirname + '/node_modules')
            ]
          }.....
          

          之后就可以使用了

          import configureStore from "store/configureStore";
          

          而不是:

          import configureStore from "../../store/configureStore";
          

          Webpack 将根据传递的解析参数配置您的导入路径。

          您可以使用 System.js 加载器执行相同的操作,但使用它自己的配置参数(可以是 mappath。请查看 System.js 文档) (如果您想使用它。它主要用于 Angular 2 案例。但我建议:即使您正在使用 ng2,也不要使用标准 System.js。Webpack 更好)。

          【讨论】:

          • 如果示例 import 语句使用操作问题中的路径/文件,则此答案会更好。
          • 这似乎不适用于 css 或图像文件。我在src/assets 中有我的资产,我从反应中得到一个 Module not found 错误,说我正在尝试导入不属于 src 目录的内容。 YMMV。
          【解决方案8】:

          React 也有同样的问题。 所以我为 babel 编写了一些插件,它可以从根的角度导入模块 - 路径并不短 - 但很清楚你导入的内容。

          所以而不是:

          import 'foo' from '../../../components/foo.js';
          

          你可以使用:

          import 'foo' from '~/components/foo.js';
          

          Here is the Plugin (tested and with a clear README)

          【讨论】:

          • 谢谢!非常有用:)
          • 这个很有用
          • 如何让 eslint 不抱怨找不到导入? (注意:尝试在 Nodejs 应用程序中使用它,而不是 React)
          猜你喜欢
          • 2015-09-13
          • 1970-01-01
          • 2018-06-10
          • 2014-07-21
          • 2017-11-14
          • 2019-04-09
          • 1970-01-01
          • 2012-08-31
          • 1970-01-01
          相关资源
          最近更新 更多