Masukkan Password
85 Mengatur File dalam Folder
Lecture ini sebenarnya adalah lanjutan langsung dari lecture sebelumnya tentang namespace, tetapi sekarang ada satu langkah tambahan:
Bukan hanya memecah TypeScript menjadi banyak file, tetapi file-file tersebut juga dikelompokkan ke dalam folder berdasarkan jenis/tanggung jawabnya.
Kalau lecture sebelumnya fokus pada:
Banyak kode
↓
Banyak file
↓
namespace
lecture ini menambahkan:
Banyak file
↓
Kelompokkan file ke folder
↓
Struktur project lebih rapi
Mari kita bedah pelan-pelan.
1. Masalahnya: Banyak file juga bisa berantakan
Sebelumnya kita sudah belajar memecah kode:
src/
├── app.ts
└── user-action.ts
Ini sudah lebih baik daripada satu file besar.
Tapi bayangkan project semakin besar.
Misalnya ada 100 file:
src/
├── app.ts
├── user.ts
├── task.ts
├── product.ts
├── order.ts
├── user-action.ts
├── product-action.ts
├── task-action.ts
├── validation.ts
├── formatting.ts
├── ...
└── ...
Walaupun sudah dipisah menjadi banyak file, masih terasa berantakan.
Pertanyaannya:
user.tsitu termasuk model, utility, service, atau apa?
validation.tsharus dicari di mana?
task.tsberada di mana?
Maka kita bisa menggunakan folder untuk mengelompokkan file yang berhubungan.
2. Folder membantu membuat struktur project
Lecture membuat dua folder:
src/
├── models/
└── user-utils/
Tujuannya:
models
Untuk menyimpan file yang berisi model.
Misalnya:
models/
├── user.ts
├── task.ts
├── product.ts
└── order.ts
user-utils
Untuk menyimpan utility yang berkaitan dengan user.
Misalnya:
user-utils/
├── user-action.ts
├── user-validation.ts
└── user-formatting.ts
Jadi folder juga digunakan untuk mengelompokkan tanggung jawab.
3. Analogi sederhana: Lemari dan laci
Bayangkan kamu memiliki banyak dokumen.
Awalnya:
Semua dokumen
├── KTP
├── invoice
├── laporan
├── kontrak
├── surat
├── ...
Semuanya bercampur.
Kemudian kamu membuat folder:
Documents/
│
├── Finance/
│ ├── invoice
│ └── laporan
│
├── Legal/
│ └── kontrak
│
└── Personal/
└── surat
Sekarang ketika mencari invoice:
“Oh, cari di
Finance.”
Hal yang sama terjadi pada source code.
src/
├── models/
│ └── user.ts
│
└── user-utils/
└── user-action.ts
Developer langsung tahu:
“Kalau mencari model User, lihat
models.”
4. Struktur project dalam lecture
Awalnya kira-kira:
src/
├── app.ts
└── user-action.ts
Kemudian dibuat:
src/
├── app.ts
│
├── models/
│ └── user.ts
│
└── user-utils/
└── user-action.ts
Sekarang kode sudah lebih terorganisasi.
5. Memindahkan User ke models/user.ts
Sebelumnya class User berada di:
user-action.ts
Kemudian lecture memindahkannya ke:
models/user.ts
Kenapa?
Karena User merupakan model.
Jadi struktur yang lebih masuk akal:
models/
└── user.ts
dan isi:
namespace App {
export class User {
constructor(
public name: string,
public age: number,
public gender: string
) {}
}
}
6. Kenapa User di-export?
Karena sekarang User berada di:
models/user.ts
tetapi akan digunakan oleh:
user-utils/user-action.ts
Maka:
export class User
berarti:
Userboleh digunakan oleh bagian lain dari namespace.
Tanpa export, kode dari luar tidak dapat menggunakannya seperti yang diharapkan dalam pola namespace lecture ini.
7. Sekarang user-action.ts membutuhkan User
File:
user-utils/user-action.ts
memerlukan:
models/user.ts
Karena createUser() melakukan:
const user = new User(name, age, gender);
Jadi kita perlu memberitahu TypeScript:
“UserAction membutuhkan
Userdarimodels/user.ts.”
8. Menggunakan /// <reference path="..." />
Seperti lecture sebelumnya, kita menggunakan:
/// <reference path="../models/user.ts" />
Perhatikan sekarang path-nya berbeda.
Kenapa?
Karena posisi file sudah berubah.
9. Memahami ../
Ini bagian yang sangat penting.
Sekarang struktur kita:
src/
├── app.ts
│
├── models/
│ └── user.ts
│
└── user-utils/
└── user-action.ts
Kita sedang berada di:
user-utils/user-action.ts
Tetapi file yang ingin kita akses berada di:
models/user.ts
Bagaimana cara menuju ke sana?
10. Arti ..
Dalam path:
..
berarti:
Naik satu folder ke parent folder.
Misalnya kita sedang di:
src/user-utils/
Kemudian:
..
berarti naik ke:
src/
Kemudian kita masuk:
models/
Kemudian:
user.ts
Jadi:
../models/user.ts
berarti:
user-utils/
↑
│ ..
│
src/
│
└── models/
│
└── user.ts
11. Bedakan ./ dan ../
Ini wajib dipahami.
./
Berarti:
Folder saat ini.
Misalnya:
src/
├── app.ts
└── user-action.ts
Dari app.ts menuju user-action.ts:
./user-action.ts
../
Berarti:
Naik satu folder.
Misalnya:
src/
├── models/
│ └── user.ts
│
└── user-utils/
└── user-action.ts
Dari:
user-utils/user-action.ts
menuju:
models/user.ts
gunakan:
../models/user.ts
12. Analogi alamat rumah 🏠
Bayangkan kamu berada di:
Rumah A
└── Lantai 1
└── Kamar
Kamu ingin pergi ke:
Rumah A
└── Lantai 1
└── Ruang tamu
Cukup:
./RuangTamu
Tetapi kalau ingin keluar dari Kamar, naik satu level:
../RuangTamu
Itulah konsep ../.
13. Memindahkan user-action.ts
Lecture kemudian memindahkan:
user-action.ts
ke:
user-utils/user-action.ts
Sekarang struktur:
src/
├── app.ts
├── models/
│ └── user.ts
└── user-utils/
└── user-action.ts
Ini menyebabkan beberapa path harus diperbarui.
14. Path dari user-action.ts ke user.ts
Sekarang:
user-action.ts
berada di:
user-utils/
sedangkan:
user.ts
berada di:
models/
Keduanya sibling folder:
src/
├── models/
│ └── user.ts
│
└── user-utils/
└── user-action.ts
Jadi dari user-utils:
../
naik ke src.
Kemudian:
models/user.ts
Gabung:
/// <reference path="../models/user.ts" />
15. Path dari app.ts ke user-action.ts
Sekarang app.ts masih berada di:
src/app.ts
Sedangkan user-action.ts berada di:
src/user-utils/user-action.ts
Dari app.ts, kita tidak perlu naik folder.
Kita hanya masuk ke:
user-utils/
Kemudian:
user-action.ts
Jadi:
/// <reference path="./user-utils/user-action.ts" />
16. Visualisasi semua path
Ini yang paling mudah untuk dipahami:
src/
│
├── app.ts
│ │
│ │ ./user-utils/user-action.ts
│ ↓
│
├── user-utils/
│ │
│ └── user-action.ts
│ │
│ │ ../models/user.ts
│ ↓
│
└── models/
│
└── user.ts
Jadi:
Dari app.ts:
./user-utils/user-action.ts
Dari user-action.ts:
../models/user.ts
17. Namespace tetap harus konsisten
Lecture masih menggunakan namespace:
namespace App {
}
Di beberapa file:
user.ts
namespace App {
export class User {}
}
user-action.ts
namespace App {
export function createUser() {}
}
app.ts
namespace App {
// menggunakan createUser
}
Karena semuanya menggunakan:
App
mereka dianggap sebagai bagian dari namespace yang sama.
18. Jadi folder dan namespace memiliki fungsi berbeda
Ini penting.
Jangan menganggap:
“Folder = namespace.”
Bukan.
Mereka dua hal berbeda.
Folder
Mengatur struktur file secara fisik.
models/
user-utils/
Namespace
Mengatur pengelompokan kode secara logis.
namespace App {
}
Jadi bisa dibayangkan:
FOLDER
↓
mengatur lokasi file
NAMESPACE
↓
mengatur grouping kode
19. Folder tidak mengubah namespace
Misalnya:
models/user.ts
bisa berisi:
namespace App {
export class User {}
}
Sedangkan:
user-utils/user-action.ts
bisa juga:
namespace App {
export function createUser() {}
}
Walaupun mereka berada di folder berbeda, keduanya masih berada di:
App
namespace yang sama.
20. Mengapa struktur folder penting untuk team?
Bayangkan kamu masuk ke project yang belum pernah kamu lihat.
Kamu diminta:
“Cari model
Task.”
Kalau struktur seperti ini:
src/
├── app.ts
├── user.ts
├── task.ts
├── product.ts
├── ...
└── ...
Kamu harus mencari.
Tetapi kalau:
src/
├── models/
│ ├── user.ts
│ ├── task.ts
│ └── product.ts
│
└── user-utils/
└── ...
Kamu langsung tahu:
Task
↓
models/
↓
task.ts
Ini meningkatkan discoverability kode.
21. Kalau ada model baru?
Lecture memberikan contoh:
Misalnya kita punya model
Task.
Kita tidak menaruh sembarangan:
src/task.ts
Tetapi:
src/models/task.ts
Jadi:
models/
├── user.ts
└── task.ts
Kemudian kalau ada model lain:
models/
├── user.ts
├── task.ts
├── product.ts
├── order.ts
└── customer.ts
Sekarang folder models punya arti yang jelas:
Semua file model aplikasi ada di sini.
22. Ini disebut separation of concerns
Konsep yang lebih besar di balik ini adalah:
Separation of concerns
Artinya:
Pisahkan kode berdasarkan tanggung jawabnya.
Misalnya:
models/
↓
data/model aplikasi
services/
↓
business logic / service
utils/
↓
fungsi bantuan
components/
↓
UI components
Dengan demikian kita tidak mencampur semuanya.
23. Contoh struktur project yang lebih besar
Misalnya project Todo App:
src/
│
├── app.ts
│
├── models/
│ ├── user.ts
│ ├── task.ts
│ └── category.ts
│
├── user-utils/
│ ├── user-action.ts
│ ├── user-validation.ts
│ └── user-formatting.ts
│
├── task-utils/
│ ├── task-action.ts
│ └── task-validation.ts
│
└── services/
├── api-service.ts
└── storage-service.ts
Developer baru bisa lebih mudah memahami:
models
→ model
user-utils
→ utilitas user
task-utils
→ utilitas task
services
→ service aplikasi
24. Hubungkan dengan lecture sebelumnya
Lecture sebelumnya:
Satu file besar
↓
Multiple files
↓
namespace
↓
outFile
↓
bundle.js
Lecture sekarang:
Multiple files
↓
Kelompokkan berdasarkan folder
↓
namespace
↓
reference path
↓
outFile
↓
bundle.js
Jadi lecture ini bukan konsep baru yang benar-benar terpisah.
Ini adalah penyempurnaan struktur project.
25. Alur lengkap project sekarang
Misalnya:
src/
│
├── app.ts
│
├── models/
│ └── user.ts
│
└── user-utils/
└── user-action.ts
Hubungannya:
app.ts
│
│ reference
↓
user-utils/user-action.ts
│
│ reference
↓
models/user.ts
Kemudian semuanya menggunakan:
namespace App
Setelah compile dengan outFile:
TypeScript
│
┌──────────┼──────────┐
↓ ↓ ↓
app.ts user-action.ts user.ts
│ │ │
└──────────┼──────────┘
↓
compiler
↓
bundle.js
HTML kemudian:
<script src="bundle.js"></script>
26. Perhatikan perubahan path dengan teliti
Ini mungkin bagian yang paling sering membuat pemula bingung.
Awalnya:
src/
├── app.ts
└── user-action.ts
Dari app.ts:
./user-action.ts
Kemudian menjadi:
src/
├── app.ts
├── models/
│ └── user.ts
└── user-utils/
└── user-action.ts
Maka:
app.ts → user-action.ts
./user-utils/user-action.ts
user-action.ts → user.ts
../models/user.ts
27. Cara membaca relative path
Kalau kamu melihat:
./
baca:
“Mulai dari folder saya sekarang.”
Kalau:
../
baca:
“Naik satu folder.”
Kalau:
../../
baca:
“Naik dua folder.”
Contoh:
../../models/user.ts
berarti:
naik 2 folder
↓
masuk models
↓
user.ts
28. Hal penting: folder tidak hanya untuk estetika
Kadang pemula berpikir:
“Folder cuma supaya kelihatan rapi.”
Sebenarnya manfaatnya lebih besar.
Folder membantu:
1. Menemukan kode
models → cari model
2. Memahami architecture
Dari struktur folder saja kita bisa mendapat gambaran aplikasi.
3. Memudahkan teamwork
Developer A mengerjakan:
models/
Developer B:
services/
4. Mengurangi kebingungan
Tidak perlu melihat 500 file dalam satu folder.
5. Mempermudah scaling
Ketika project berkembang dari:
10 files
menjadi:
500 files
struktur folder menjadi sangat penting.
29. Tapi jangan membuat folder terlalu dalam
Ada juga prinsip yang perlu kamu pahami.
Kita memang ingin rapi, tetapi jangan sampai:
src/
└── app/
└── features/
└── users/
└── management/
└── actions/
└── create/
└── handlers/
└── ...
Terlalu dalam juga menyulitkan.
Tujuannya adalah:
Struktur yang masuk akal, bukan struktur yang sebanyak mungkin.
30. Hubungan export dan reference
Mari kita satukan.
Misalnya user.ts:
namespace App {
export class User {
// ...
}
}
Kemudian user-action.ts:
/// <reference path="../models/user.ts" />
namespace App {
export function createUser() {
return new User(...);
}
}
Ada dua hal berbeda:
reference
/// <reference path="../models/user.ts" />
memberitahu TypeScript:
“Saya membutuhkan file ini.”
export
export class User
memberitahu:
“Class ini boleh digunakan oleh kode lain.”
Jadi:
reference
↓
menghubungkan file
export
↓
membuka sesuatu agar dapat digunakan
31. Analogi perpustakaan 📚
Bayangkan:
Perpustakaan
│
├── Models
│ ├── User
│ └── Task
│
└── Utils
└── UserAction
models/user.ts seperti buku:
“Buku User tersedia.”
export seperti:
“Buku ini boleh dipinjam.”
reference seperti:
“Saya ingin mengakses buku yang ada di rak Models.”
Namespace seperti:
“Semua buku ini berada dalam kategori
App.”
Folder seperti:
“Buku ini disimpan di rak mana.”
32. Apakah namespace dan folder harus mempunyai nama yang sama?
Tidak.
Misalnya:
models/user.ts
boleh menggunakan:
namespace App {
}
Sedangkan:
user-utils/user-action.ts
juga:
namespace App {
}
Folder:
models
dan:
user-utils
adalah struktur file.
Namespace:
App
adalah grouping kode.
Keduanya independen.
33. Kenapa lecture menggunakan namespace App?
Karena semua kode ingin dianggap sebagai bagian dari satu logical namespace:
App
├── User
├── createUser()
├── getUsers()
└── ...
Walaupun secara fisik file-file tersebut berada di folder berbeda:
models/user.ts
user-utils/user-action.ts
app.ts
Secara logis semuanya:
App
34. Kekurangan pendekatan namespace ini
Ini juga bagus untuk kamu ketahui agar tidak mengira ini adalah cara modern satu-satunya.
Lecture ini menggunakan:
namespace
+
/// <reference path>
+
outFile
Ini adalah pendekatan legacy/lebih lama.
Dalam TypeScript modern, kita lebih sering menggunakan:
ES Modules
+
import/export
+
bundler
Contohnya:
// user.ts
export class User {}
dan:
// user-action.ts
import { User } from "../models/user";
Ini jauh lebih familiar dengan ecosystem JavaScript modern.
Tetapi untuk mengikuti course ini, kamu perlu memahami namespace terlebih dahulu.
35. Perbedaan besar dengan ES6 Modules
Nanti ketika masuk ES6 Modules, kamu akan melihat:
Namespace
/// <reference path="../models/user.ts" />
namespace App {
export function createUser() {}
}
ES6 Module
import { User } from "../models/user";
export function createUser() {}
Jadi ES6 Modules tidak menggunakan:
namespace App
sebagai mekanisme utama.
36. Ringkasan struktur yang dibuat lecture
Pada akhirnya kira-kira:
src/
│
├── app.ts
│
├── models/
│ └── user.ts
│
└── user-utils/
└── user-action.ts
Dengan hubungan:
app.ts
│
│ reference
↓
user-utils/user-action.ts
│
│ reference
↓
models/user.ts
Dan semuanya menggunakan namespace:
App
Kemudian:
TypeScript files
↓
compile
↓
outFile
↓
bundle.js
↓
HTML
37. Mental model yang paling gampang 🧠
Ingat 4 lapisan:
LAPIS 1
File
↓
Memecah kode
LAPIS 2
Folder
↓
Mengelompokkan file
LAPIS 3
Namespace
↓
Mengelompokkan kode secara logis
LAPIS 4
outFile
↓
Menggabungkan hasil compile menjadi bundle
Jadi:
File memecah kode.
Folder mengelompokkan file.
Namespace mengelompokkan kode.
exportmembuka kode untuk digunakan bagian lain.
referencememberi tahu TypeScript tentang file yang dibutuhkan.
outFilemenggabungkan hasil compile menjadi satu JavaScript file.
38. Cheat sheet path
Ini juga sangat penting:
./file.ts
= file di folder yang sama.
./folder/file.ts
= masuk ke subfolder.
../file.ts
= naik satu folder, lalu cari file.
../folder/file.ts
= naik satu folder, masuk folder, cari file.
../../file.ts
= naik dua folder.
Kesimpulan
Lecture ini sebenarnya ingin mengajarkan satu prinsip sederhana:
Semakin besar aplikasi, semakin penting struktur project.
Kita tidak cukup hanya memecah:
app.ts
menjadi:
app.ts
user.ts
task.ts
product.ts
...
Tetapi kita juga perlu mengelompokkannya:
src/
│
├── models/
│ ├── user.ts
│ ├── task.ts
│ └── product.ts
│
├── user-utils/
│ ├── user-action.ts
│ └── user-validation.ts
│
└── app.ts
Dan karena lecture masih menggunakan namespace, file-file tersebut dihubungkan menggunakan /// <reference path="..." />, kemudian hasil akhirnya bisa digabung menggunakan outFile menjadi:
bundle.js
Kalimat hafalan paling penting:
File memisahkan kode, folder mengelompokkan file, namespace mengelompokkan kode secara logis, dan
outFilemenggabungkan hasil compile menjadi satu bundle.
Setelah ini course masuk ke ES6 Modules, dan di sana kamu akan melihat cara yang lebih modern menggunakan import dan export.