패키지, 저장소 및 앱 카테고리 검색

패키지 상세v0.1.8+11

ft_cli

이 프로젝트는 Flutter와 Dart를 Clean Architecture와 통합하기 위한 CLI입니다

macOSWindowsLinux
30일 다운로드
33
좋아요
45
Pub 점수
120

패키지 설치

flutter pub add ft_cli

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

ft_cli는 플러터 및 다트 프로젝트를 클린 아키텍처와 통합하는 것을 간편하게 만드는 명령줄 도구입니다. 클린 아키텍처 원칙을 따르며 구조적이고 유지보수 가능한 코드베이스를 생성하기 위한 자동 스캐폴딩을 제공합니다. CLI는 엔티티, 리포지토리, 사용 사례, 프레젠테이션 레이어와 같은 계층적 구성 요소를 생성함으로써 프로젝트 설정을 단순화합니다. macOS, Windows, Linux에서의 크로스플랫폼 개발을 지원하여 플러터 애플리케이션 전반에 걸쳐 일관된 아키텍처를 적용하고자 하는 팀에게 이상적입니다.

사용 사례

  • 클린 아키텍처 프로젝트 설정 자동화
  • 계층적 코드 구조 생성
  • 일관된 프로젝트 구성 강제
  • 새로운 Flutter 프로젝트 초기화 가속화
  • 팀 전체 아키텍처 표준 지원

주요 기능

  • 클린 아키텍처 계층을 위한 자동 코드 생성
  • 크로스 플랫폼 CLI 지원 (macOS, Windows, Linux)
  • Flutter 및 Dart 워크플로우와의 통합
  • 도메인 주도 설계와 일치하는 스크래포드 프로젝트 구조
  • 빠른 개발을 위한 명령줄 인터페이스

적합한 대상

  • 클린 아키텍처를 채택하는 플러터 개발자
  • 표준화된 프로젝트 구조가 필요한 팀
  • 더 빠른 프로젝트 부팅을 원하는 개발자
  • 유지보수성과 확장성에 중점을 둔 프로젝트
  • 장기적인 코드 품질에 중점을 둔 엔지니어링 팀

고려 사항

  • 클린 아키텍처 원칙에 대한 이해 필요
  • 생성된 코드 구조에서의 맞춤 설정 제한
  • 업데이트를 위해 외부 GitHub 저장소에 의존합니다
  • 복잡한 프로젝트 설정을 위해 추가 구성이 필요할 수 있습니다
  • 신규 프로젝트 또는 대규모 리팩터링에 가장 적합

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

Flutter Arch CLI

Code generator to facilitate clean architecture

Documentation in pt-BR

Get Start:

dart pub global activate ft_cli

Or:

dart pub global activate --source path ./RepositoryProject
Overview

To make it easier and more intuitive to implement Uncle Bob's Clean Architecture. This CLI provides the base structure, where will dynamically generate the Classes as shown in the examples below.

You can also have the advantage of editing in an easy and dynamic way through the editing of template and triggers to apply replace in some piece of code and create new files from the commands.

Commands:
ft_cli init 

Create the configurable variables of your project, generating a basic structure, where will generate a .ft_cli folder.


# Generate Micro Frontend
ft_cli mf

Select the component you want to create and write the name in snakeCase.

Result
? Qual componente você deseja criar? › 
❯ micro_app
  micro_commons
  micro_core
  base_app


# Generate Layer
ft_cli g layer lib/app/module/home
# Or
ft_cli g l lib/app/module/home
Result


# Generate Page
ft_cli g page lib/app/module/home HomeCards
# Or
ft_cli g p lib/app/module/home HomeCards
Result
// presentation/ui/pages/home_cards/home_cards_page.dart
import 'package:flutter/material.dart';
import 'home_cards_controller.dart';

class HomeCardsPage extends StatefulWidget {

  @override
  _HomeCardsPageState createState() => _HomeCardsPageState();
}

class _HomeCardsPageState extends State<HomeCardsPage> {
  final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      appBar: const AppBar(),
      body: const Container(),
    );
  }
}
// presentation/ui/pages/home_cards/home_cards_controller.dart
class HomeCardsController {
  bool loading = false;

  void setLoading(bool value) {
    loading = value;
  }
}


# Generate Controller
ft_cli g controller lib/app/module/home HomeCards
# Or
ft_cli g c lib/app/module/home HomeCards
Result
// presentation/ui/pages/home_cards/home_cards_controller.dart
class HomeCardsController {
  bool loading = false;

  void setLoading(bool value) {
    loading = value;
  }
}


# Generate DataSource
ft_cli g datasource lib/app/module/home GetHomeCards
# Or
ft_cli g d lib/app/module/home GetHomeCards
Result
// data/datasources/get_home_cards_datasource.dart
abstract class GetHomeCardsDatasource {
  Future<void> call();
}
// external/datasources/get_home_cards_imp_datasource.dart
import '../../data/datasources/get_home_cards_datasource.dart';

class GetHomeCardsImpDatasource implements GetHomeCardsDatasource {
  @override
  Future<void> call() {
    // TODO: implement call
    throw UnimplementedError();
  }
}


# Generate Repository
ft_cli g repository lib/app/module/home GetHomeCards
# Or
ft_cli g repository lib/app/module/home GetHomeCards
Result
// domain/repositories/get_home_cards_repository.dart
abstract class GetHomeCardsRepository {
  Future<void> call();
}
// data/repositories/get_home_cards_imp_repository.dart
import '../../repositories/get_home_cards_repository.dart';

class GetHomeCardsImpRepository implements GetHomeCardsRepository {
  @override
  Future<void> call() {
    // TODO: implement call
    throw UnimplementedError();
  }
}


# Generate UseCase
ft_cli g usecase lib/app/module/home GetHomeCards
# Or
ft_cli g u lib/app/module/home GetHomeCards
Result
// domain/usecases/get_home_cards_usecase.dart
abstract class GetHomeCardsUsecase {
  Future<void> call();
}
// domain/usecases/get_home_cards_imp_usecase.dart
import 'get_home_cards_usecase.dart';

class GetHomeCardsImpUsecase implements GetHomeCardsUsecase {
  @override
  Future<void> call() {
    // TODO: implement call
    throw UnimplementedError();
  }
}
  


# Generate UseCase, Repository and DataSource
ft_cli g usecase lib/app/module/home GetHomeCards -r -d
# Or
ft_cli g u lib/app/module/home GetHomeCards -r -d
Result


# Generate Service
ft_cli g service lib/app/module/home HomeCards
# Or
ft_cli g s lib/app/module/home HomeCards
Result
// domain/services/home_cards_service.dart
abstract class HomeCardsService {
  Future<void> call();
}
// domain/services/home_cards_imp_service.dart
import 'home_cards_service.dart';

class HomeCardsImpService implements HomeCardsService {
  @override
  Future<void> call() {
    // TODO: implement call
    throw UnimplementedError();
  }
}
  


# Generate Entity
ft_cli g entity lib/app/module/home Home
# Or
ft_cli g e lib/app/module/home Home
Result
// domain/models/entities/home_entity.dart 
class HomeEntity {
  HomeEntity();
}


# Generate Dto
ft_cli g dto lib/app/module/home Home
Result
// domain/models/dtos/home_dto.dart
import '../../models/entities/home_entity.dart';

class HomeDto extends HomeEntity {
  HomeDto() : super();
}


-------------------------- HELPS --------------------------

i, init             Gera os arquivos configuraveis do projeto...
Exemplo: ft_cli init

mf, microfrontend   Seleciona a opção para criação de novos componentes de microfrontend...
Exemplo: ft_cli mf

l, layer            Gera a estrutura de pastas de um modulo...
Exemplo: ft_cli g l lib/app/modules/nome_modulo

p, page             Cria uma nova pagina com um controller...
Exemplo: ft_cli g p lib/app/modules/nome_modulo Nome

c, controller       Cria um novo controller...
Exemplo: ft_cli g c lib/app/modules/nome_modulo Nome

d, datasource       Cria a camada de busca dados de fontes externas...
Exemplo: ft_cli g d lib/app/modules/nome_modulo Nome

r, repository       Cria a camada para tratar os dados...
Exemplo: ft_cli g r lib/app/modules/nome_modulo Nome

u, usecase          Cria a camada para tratar as regras de negócio...
Exemplo: ft_cli g u lib/app/modules/nome_modulo Nome

s, service          Cria a camada para tratar os serviços...
Exemplo: ft_cli g s lib/app/modules/nome_modulo Nome

e, entity           Cria as entidades...
Exemplo: ft_cli g e lib/app/modules/nome_modulo Nome

dto                 Cria os dto para transferência de dados...
Exemplo: ft_cli g dto lib/app/modules/nome_modulo Nome

Reserved Words

The reserved words can be used in the templet files that are generated in .ft_cli/templete the reserved words must be used inside mustaches {{}} example {{name}}, can also be used in reserved words an extension, example {{name.pascalCase}} whose extension will format the word as needed, you can check the lists below for all reserved words and extensions.

  • Reserved words can be edited in my_project\.ft_cli\configs.json
Reserved Words Default
name Entrada pelo terminal, este valor é o último parâmetro da expressão para gerar os modelos
path Entrada pelo terminal, caminho onde o novo arquivo será gerado
module input input by the terminal, name of the module that will generate the new files
projectName Entrada do nome do projeto quando é criado um componente de microfrontend
projectNameComplete O nome do projeto concatenado com o padrão do modelo dos microfrontend
repositoryPathInterface domain/repositories
repositoryNameFileInterface {{name.snakeCase}}_repository
repositoryPath data/repositories
repositoryNameFile {{name.snakeCase}}_imp_repository
repositoryNameClassInterface {{name.pascalCase}}Repository
repositoryNameClass {{name.pascalCase}}ImpRepository
datasourcePathInterface data/datasources
datasourceNameFileInterface {{name.snakeCase}}_datasource
datasourcePath external/datasources
datasourceNameFile {{name.snakeCase}}_imp_datasource
datasourceNameClassInterface {{name.pascalCase}}Datasource
datasourceNameClass {{name.pascalCase}}ImpDatasource
usecasePathInterface domain/usecases
usecaseNameFileInterface {{name.snakeCase}}_usecase
usecasePath domain/usecases
usecaseNameFile {{name.snakeCase}}_imp_usecase
usecaseNameClassInterface {{name.pascalCase}}Usecase
usecaseNameClass {{name.pascalCase}}ImpUsecase
pagePath presentation/ui/pages/{{name.snakeCase}}
pageNameFile {{name.snakeCase}}_page
pageNameClass {{name.pascalCase}}Page
controllerPath presentation/ui/pages/{{name.snakeCase}}
controllerNameFile {{name.snakeCase}}_controller
controllerNameClass {{name.pascalCase}}Controller
Methods

The Methods can be used in triggers or templates, and work in sequence, example {{path.replace(str1,str2).replace(str3, str4)}}.

WARNING: If changing routes, use in Windows \\ and in Mac or Linux /.

Method Exemple
replace {{path.replace(string1,string2)}}
Extensions
Extension Exemple
camelCase testeCase
constantCase TESTE_CASE
sentenceCase Teste case
snakeCase teste_case
dotCase teste.case
paramCase teste-case
pathCase teste/case
pascalCase TesteCase
headerCase Teste-Case
titleCase Teste Case
Triggers

In .ft_cli/templete a {{term}}_replace_trigger.json file is generated where from your annotation it can apply a replace to any input expression, for example:

[
    {
        "pathFile": "{{path}}\\{{module}}_module.dart",
        "from": "//imports",
        "to": "//imports\nimport '{{controllerPath}}/{{controllerNameFile}}.dart';"
    },
    {
        "pathFile": "{{path}}\\{{module}}_module.dart",
        "from": "//Dependence",
        "to": "//Dependence\nfinal {{controllerNameClass.camelCase}} = {{controllerNameClass.pascalCase}};"
    }
]

Where will perform a replace on the pointed file, from the expression.

Generate new file

In .ft_cli / templete a file {{term}} _ new_file_trigger.json is generated where, from his annotation, he can create a new file with the pre-defined templete, for example:

Note, the generate variable must be true to generate the file.

[
    {
        "pathFile": "{{path}}\\{{module}}_module",
        "pathTemplete": ".ft_cli/template/layer/complete_new_file_exemple.template",
        "generate": true
    }
]
Templates

.ft_cli/template/layer/complete_new_file_exemple.template

class {{module.pascalCase}}Module extends Module {
  @override
  final List<Bind> binds = [
    //Usecases

    //Repositories

    //Datasources
      
    //Controllers
  ];

  @override
  final List<ModularRoute> routes = [
    //Pages
  ];
}

Where will generate a new file from the defined template.

Tests

To add tests, just create a template, example:

import 'package:flutter_test/flutter_test.dart';

import 'package:{{path.replace(\,/).replace(lib/,)}}/{{name.snakeCase}}';

void main() {
  test('adds one to input values', () {
    final calculator = Calculator();
    expect(calculator.addOne(2), 3);
    expect(calculator.addOne(-7), -6);
    expect(calculator.addOne(0), 1);
  });
}

Then add the path of the template in the trigger of creation of the class to be tested, making a replace of the path of this class, forwarding the test file to the tests folder, example:

[
    {
        "pathFile": "{{path.replace(lib/app,test)}}/{{name.snakeCase}}_test",
        "pathTemplete": ".ft_cli/template/example_test.template",
        "extension": "dart",
        "replaceOldFileWithNew": false,
        "generate": true
    }
]

Submit feature and bug requests to improve CLI report issues.

카테고리

의존성

의존성 목록 7 개

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.