Flutter 导入:相对路径还是包?

Aug*_*n R 56 dart flutter flutter-provider

在 Flutter 中,为了在我们自己的包的 lib 目录中导入库,我们是否应该使用相对导入

import 'foo.dart'
Run Code Online (Sandbox Code Playgroud)

或包导入?

import 'package:my_app/lib/src/foo.dart'
Run Code Online (Sandbox Code Playgroud)

Dart 指南提倡使用相对导入:

在您自己的包的 lib 目录中导入库时,首选相对路径。

Provider包说总是使用包导入

  • 始终使用包导入。例如:import 'package:my_app/my_code.dart';

除了简洁之外还有区别吗?为什么包导入会减少相对导入的错误?

Tar*_*eem 33

从相同的Dart 指南中,进一步给出了相对导入的原因:

没有什么重要的理由更喜欢前者——它只是更短,而且我们希望保持一致。

就我个人而言,我更喜欢绝对方法,尽管它更冗长,因为这意味着当我从不同的 dart 文件(在其他文件夹中)导入时,我不必计算要导入的文件的位置,相对于当前文件。编造示例:

我有两个 dart 文件,位于不同的文件夹级别,需要导入themes/style.dart

一种是widgets/animation/box_anim.dart,相对路径导入的位置是:

import '../../themes/style.dart';
Run Code Online (Sandbox Code Playgroud)

另一个是screens/home_screen.dart相对导入:

import '../themes/style.dart';
Run Code Online (Sandbox Code Playgroud)

这可能会让人感到困惑,所以我发现最好在两个文件中都使用绝对值,并保持一致:

import 'package:myapp/themes/style.dart';
Run Code Online (Sandbox Code Playgroud)

并且始终坚持该规则。所以,基本上,无论你使用什么方法 - 一致性是关键!

Dart包的Linter也对此有话要说,但更多的是关于“/lib”文件夹中混合的注意事项

避免对 lib/ 中的文件进行相对导入。

当混合相对导入和绝对导入时,可能会混淆以两种不同方式导入相同的成员。避免这种情况的一种简单方法是确保您的路径中没有包含 lib/ 的相对导入。


Aug*_*n R 11

TLDR;选择你喜欢的一个,注意在官方Effective Dart 指南中推荐prefer_relative_imports

首先,正如在这个答案中提到的,Provider 不再推荐包导入。

Dart linter提供了一个规则列表,包括一些预定义的规则集:

进口规则

关于进口,实际上有两个以上对立的规则:

  • pedanticlints规则集中启用的avoid_relative_lib_imports基本上建议避免在其路径中包含“lib”的导入。

以下两个是您提到的一个:

我应该选择哪一个?

选择你想要的规则!它不会导致任何性能问题,并且没有任何规则可以减少另一个错误。多亏了 Dart linter,只需选择一个就可以使您的导入在您的所有项目中保持一致

我个人更喜欢使用prefer_relative_imports,这是 Dart 团队推荐的,使用这个 VSCode 扩展可以自动修复和排序我的导入。


Rém*_*let 10

提供程序不再需要包导入。

这是一个旧的 Dart 错误的解决方法:Flutter: Retrieving top-level state from child returns null

TL;DR,通过混合相对和绝对导入,有时 Dart 会创建类定义的副本。

这导致了荒谬的路线:

import 'package:myApp/test.dart' as absolute;
import './test.dart' as relative;

void main() {
  print(relative.Test().runtimeType == absolute.Test().runtimeType); // false
}
Run Code Online (Sandbox Code Playgroud)

既然provider依赖于runtimeType解析对象,那么这个bug使得provider在某些情况下无法获取对象。

  • 但何时使用哪种导入方式的问题仍然悬而未决。是否有规则或最佳实践,何时以一种方式进行,何时以另一种方式进行? (26认同)
  • 你用的是过去时态,这个bug现在解决了吗? (2认同)

Dan*_*Dan 8

我对这个主题的 5 美分是,当您决定重新组织/清理项目结构时,绝对 ( package:my_app/etc/etc2...) 导入比相对导入 ( ../../etc/etc2...) 造成的麻烦要少得多,因为每当您将文件从一个目录移动到另一个目录时,您都会更改“起始点”该文件使用的每个相对导入的“因此破坏了移动文件内的所有相对导入......

由于这个原因,我个人总是更喜欢绝对路径而不是相对路径