티스토리 뷰
[ 문서 ]
- workshop > Bonus 2. Templates
[ tuist scaffold ]
tuist 는 tuist scaffold 라는 명령어를 제공하는데, 프로젝트 자동생성을 도와주는 명령어입니다.
tuist scaffold name_of_template --name Name
이 명령어는 Tuist/Templates 경로에 저장되어있는 템플릿을 사용하고,
템플릿은 manifest 파일과 Stencil file 을 결합하여 만듭니다.
자세히 말하자면,
1) Tuist/Templates 하위에 name_of_template 디렉토리 만들기.
2) 해당 디렉토리에 name_of_template.swift 파일 두기.
3) name_of_template.swift 는 템플릿을 describe 하는 manifest 파일입니다.
이 파일에 Template 을 구성하는데, 이 때 stencil 파일이 필요하다면 templatePath 로 연결합니다.
[ 예제 ]
tuist workshop 예제를 참고해서 feature module 을 만들어주는 템플릿을 작성해보겠습니다.
우선 tuist edit 을 실행해서 Tuist/Templates 아래에 feature 디렉토리를 만들어줍니다.
(이 디렉토리는 문서에서 가이드하지만 필수는 아님. 하지만 있어야 유지보수가 편함)
그리고 해당 디렉토리 밑에 manifest 파일인 feature.swift 를 만듭니다.
manifest 파일명이 tuist scaffold 명령어에서 name_of_template 에 해당되기 때문에, 저는 소문자로 시작하게 만들어줬어요.
tuist scaffold name_of_template --name Name
코드는 우선 이렇게만 작성해줍니다.
Attribute 는 template 으로 전달되는 값을 의미합니다. name 을 필수로 전달받게 합니다.
import ProjectDescription
let nameAttribute: Template.Attribute = .required("name")
let template = Template(
description: "Creates a new feature module",
attributes: [
nameAttribute,
]
)
그리고 이 모듈이 생기면 기본으로 생겨야하는 뼈대를 stencil 형태로 작성해줍니다.
참고로 이렇게 하위 폴더 (Feature, Sources) 로 묶지 않아도 됩니다.
Tuist 팀에서 자동생성될 모듈이랑 똑같은 디렉토리로 파일을 배치해둔게 좋아보여 따라한 것!
간단히 project.swift 파일이랑
import ProjectDescription
let project = Project(
name: "{{ name }}",
targets: [
.target(
name: "{{ name }}",
destinations: .iOS,
product: .framework,
bundleId: "io.tuist.{{ name }}",
deploymentTargets: .iOS("17.0"),
sources: ["Sources/**"],
dependencies: []
)
]
)
Sources 밑에 생겨야하는 샘플 파일을 작성해줍니다.
import Foundation
public class {{ name }} {
public init() {}
}
그리고 feature.swift 에 가서 items 를 작성해줍니다.
import ProjectDescription
let nameAttribute: Template.Attribute = .required("name")
let template = Template(
description: "Creates a new feature module",
attributes: [
nameAttribute,
],
✅ items: [
.file(path: "Projects/\(nameAttribute)/Project.swift", templatePath: "Feature/Project.stencil"),
.file(path: "Projects/\(nameAttribute)/Sources/\(nameAttribute).swift", templatePath: "Feature/Sources/Feature.stencil")
]
)
- path: Path where to generate file
- templatePath: Path of file where the template is defined
그리고 아래 명령어를 실행해보면
tuist scaffold feature --name Settings
해당 모듈이 잘 만들어지는 것을 볼 수 있습니다.
[ Stencil 필터 ]
stencil 필터를 같이 쓰면 좀 더 유용합니다.
예를들어 {{ name }} 이 아니라 {{ name | capitalize }} 를 쓰면 실수로 settings 를 입력해도 Settings 로 만들어지게 할 수 있어요. (대문자 카멜케이스 보장)
stencil 파일 뿐만아니라, manifest 파일에서도 stencil 문법을 쓸 수 있더라구요 ?
기존의 string interpolation 인 \(nameAttribute) 말고, {{ name | capitalize }} 를 사용한 코드 입니다.
import ProjectDescription
let template = Template(
description: "Creates a new feature module",
attributes: [
.required("name"),
],
items: [
✅ .file(path: "Projects/{{ name | capitalize }}/Project.swift", templatePath: "Feature/Project.stencil"),
✅ .file(path: "Projects/{{ name | capitalize }}/Sources/{{ name | capitalize }}.swift", templatePath: "Feature/Sources/Feature.stencil")
]
)
[ Template.Attribute ]
위에서 required 만 썼는데, optional 도 있습니다.
예를들어 이렇게 optional 과 default value 를 지정해줄 수 있습니다.
let template = Template(
description: "Creates a new feature module",
attributes: [
.required("name"),
✅ .optional("platform", default: "ios")
]
...
)
명시적으로 platform 을 넘기면 해당 platform 으로, 아니면 default value 로 지정되게 됩니다.
tuist scaffold name_of_template --name Name --platform macos
넘어오는 값을 보고 manifest 에서 템플릿을 분기해줄 수도 있고
stencil 파일에서 코드 분기를 태울 수도 있겠습니다.
자꾸 까먹는 stencil 분기문법,,
{% if condition1 %}
<!-- condition1이 참일 때 실행 -->
{% elif condition2 %}
<!-- condition1은 거짓이고 condition2가 참일 때 실행 -->
{% else %}
<!-- 모든 조건이 거짓일 때 실행 -->
{% endif %}
[ Template.Item ]
3가지 static 메소드가 제공됩니다.
위에서 사용한 file(path:templatePath:) 으로 템플릿을 복붙할 수 도 있고
- string(path:contents:) string 복붙
- directory(path:sourcePath:) 폴더 복붙
도 가능!
문서에는 template 이 가장 flexibility 가 높고 additional stencil filters 도 쓸 수있는 방법이라고 말합니다.
'🍏 > Tuist' 카테고리의 다른 글
[Tuist] StaticFramework 와 Preview (4) | 2024.04.09 |
---|---|
[Tuist] Cache (10) | 2024.04.08 |
[Tuist] iOS 에서 Dynamic Library (dylib) 를 직접 만들 수 있는가 ? (2) | 2024.03.29 |
[Tuist] 프로젝트 만들기 (4.7.0 버전) (7) | 2024.03.26 |
- Total
- Today
- Yesterday
- 장고 Custom Management Command
- Django Firebase Cloud Messaging
- flutter deep link
- github actions
- 플러터 얼럿
- Flutter 로딩
- Flutter Spacer
- Flutter Clipboard
- flutter dynamic link
- SerializerMethodField
- 장고 URL querystring
- flutter 앱 출시
- DRF APIException
- flutter build mode
- cocoapod
- PencilKit
- ribs
- Django Heroku Scheduler
- Flutter getter setter
- drf custom error
- ipad multitasking
- Flutter Text Gradient
- Django FCM
- 플러터 싱글톤
- METAL
- Watch App for iOS App vs Watch App
- 구글 Geocoding API
- Dart Factory
- Python Type Hint
- Sketch 누끼
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |