Imports e Exports no Dart | Dart
- Imports e Exports no Dart | Dart
O sistema de m ódulos do Dart é baseado em bibliotecas (libraries). Cada arquivo .dart é, por padrão, uma biblioteca. O controle de visibilidade, encapsulamento e composição de APIs ocorre por meio de:
importexportlibrarypart/part of
Este documento cobre todas as variações e combinações relevantes desses mecanismos.
1. import
Permite utilizar símbolos (classes, funções, variáveis, extensões, enums) definidos em outra biblioteca.
1.1 Import básico
import 'package:meu_app/utils/logger.dart';
Ou arquivo relativo:
import '../utils/logger.dart';
Ou biblioteca do SDK:
import 'dart:math';
import 'dart:convert';
1.2 Import com prefixo (as)
Evita colisão de nomes.
import 'dart:math' as math;
void main() {
print(math.pi);
}
Use quando:
- Há conflito de nomes
- Deseja deixar explícita a origem do símbolo
1.3 Import seletivo (show)
Importa apenas símbolos específicos.
import 'dart:math' show pi, Random;
Reduz superfície de exposição e melhora legibilidade.
1.4 Import com exclusão (hide)
Importa tudo, exceto símbolos específicos.
import 'dart:math' hide Random;
Útil quando há colisão de nomes.
1.5 Import condicional
Muito utilizado em Flutter Web / Mobile.
import 'src/io_stub.dart'
if (dart.library.io) 'src/io_impl.dart'
if (dart.library.html) 'src/web_impl.dart';
Baseado em environment libraries.
Principais condições:
dart.library.iodart.library.htmldart.library.jsdart.library.ffi
1.6 Deferred Import (Lazy Loading)
Carrega biblioteca sob demanda.
import 'package:meu_app/feature.dart' deferred as feature;
Future<void> loadFeature() async {
await feature.loadLibrary();
feature.run();
}
Restrições:
- Funciona principalmente no Flutter Web
- Não suporta
dart:mirrors - Necessita chamada explícita
loadLibrary()
2. export
Reexpõe símbolos de outra biblioteca.
Muito usado para criar barrel files.
2.1 Export simples
export 'src/models/user.dart';
export 'src/models/order.dart';
Arquivo models.dart:
export 'src/models/user.dart';
export 'src/models/order.dart';
Uso:
import 'package:meu_app/models.dart';
2.2 Export com show
export 'src/internal.dart' show PublicClass;
2.3 Export com hide
export 'src/internal.dart' hide InternalHelper;
2.4 Reexport encadeado
// a.dart
export 'b.dart';
// b.dart
export 'c.dart';
Ao importar a.dart, você obtém símbolos de c.dart.
3. library
Define explicitamente o nome da biblioteca.
library meu_app.utils;
Hoje é opcional na maioria dos casos. Útil principalmente com part.
4. part e part of
Permite dividir uma única biblioteca em múltiplos arquivos.
4.1 Arquivo principal
library user_module;
part 'user_model.dart';
part 'user_repository.dart';
4.2 Arquivo part
part of user_module;
class User {
final String name;
User(this.name);
}
Características importantes:
- Compartilham o mesmo namespace
- Membros privados (
_private) são acessíveis entre parts - Não é um import real
- Não gera biblioteca separada
5. Visibilidade e Encapsulamento
Dart usa privacidade por biblioteca, não por classe.
Símbolos iniciados com _ são privados à biblioteca.
class _InternalClass {}
Se você dividir código com part, o privado continua acessível.
Se usar import, o privado não é acessível.
6. Importando dart: Libraries
Principais bibliotecas nativas:
dart:core(import automático)dart:asyncdart:convertdart:collectiondart:mathdart:iodart:ffidart:isolatedart:html
Exemplo:
import 'dart:async';
import 'dart:isolate';
7. Importando pacotes (package:)
import 'package:http/http.dart';
Baseado no pubspec.yaml.
O Dart resolve via:
.dart_tool/package_config.json
8. Barrel Pattern (Arquitetura)
Estrutura recomendada:
lib/
├── src/
│ ├── service.dart
│ ├── repository.dart
│
└── feature.dart
feature.dart:
export 'src/service.dart';
export 'src/repository.dart';
Benefícios:
- API pública controlada
- Evita expor
src/ - Permite refatorar internamente sem quebrar consumidores
9. Resolução de Conflitos
Caso 1 – Mesmo nome
import 'a.dart';
import 'b.dart'; // ambos possuem class User
Erro: Ambiguous reference.
Solução:
import 'a.dart' as a;
import 'b.dart' as b;
a.User userA;
b.User userB;
Caso 2 – show + prefix
import 'a.dart' as a show User;
10. Best Practices
10.1 Use package: em vez de relativo para código público
Preferível:
import 'package:meu_app/utils.dart';
Evita problemas com reorganização de pastas.
10.2 Não exponha src/
Estrutura ideal:
lib/
├── src/ (privado)
└── meu_app.dart (API pública)
10.3 Evite uso excessivo de part
Use part apenas quando:
- Geradores de código (ex:
json_serializable,freezed) - Código altamente coeso
Evite para organização comum — prefira import.
11. Import em testes
Em testes:
import 'package:meu_app/src/internal.dart';
É permitido, mas viola encapsulamento lógico. Faça apenas quando necessário.
12. Imports implícitos
O Dart automaticamente importa:
import 'dart:core';
Sempre disponível:
StringintListMapFuture- etc.
13. Imports e Null Safety
Não há impacto direto no sistema de import/export. A null safety é analisada no nível de biblioteca durante compilação.
14. Casos Avançados
14.1 Import + extensão
import 'string_extensions.dart';
void main() {
print("hello".capitalize());
}
14.2 Import cíclico
// a.dart
import 'b.dart';
// b.dart
import 'a.dart';
Evite. Pode gerar inconsistências e acoplamento excessivo.
Solução:
- Extraia interfaces
- Crie camada intermediária
15. Fluxo de Resolução do Compilador
Ordem lógica:
- Resolve imports
- Aplica
show/hide - Mescla namespace
- Detecta conflitos
- Aplica prefixos
- Resolve exports transitivos
16. Resumo Técnico
| Recurso | Finalidade |
|---|---|
import | Consumir outra biblioteca |
as | Criar namespace |
show | Importar seletivamente |
hide | Excluir símbolos |
deferred | Lazy loading |
export | Reexpor API |
library | Nomear biblioteca |
part | Dividir mesma biblioteca |