Masukkan Password
24 Opsi rootDir & outDir
Di lecture ini kita masuk ke dua compiler option yang sangat penting ketika project TypeScript mulai besar, yaitu:
rootDiroutDir
Keduanya sebenarnya sangat mudah kalau kita melihatnya dari sudut pandang “file masuk dari mana?” dan “hasil compile keluar ke mana?”
1. Gambaran Besar Dulu
Misalkan project kita awalnya seperti ini:
my-project/
│
├── app.ts
├── config.ts
├── user.ts
├── index.html
└── tsconfig.json
Ketika kita menjalankan:
tsc
TypeScript akan mengubah:
app.ts → app.js
config.ts → config.js
user.ts → user.js
Secara default, hasil .js biasanya diletakkan relatif terhadap lokasi file sumber.
Akibatnya project bisa menjadi berantakan:
my-project/
│
├── app.ts
├── app.js
├── config.ts
├── config.js
├── user.ts
├── user.js
├── index.html
└── tsconfig.json
Bayangkan kalau project punya 100 file TypeScript.
Akan sangat sulit membedakan:
“Mana source code saya?” “Mana hasil compile?”
Karena itu biasanya project dibuat seperti:
my-project/
│
├── src/
│ ├── app.ts
│ ├── user.ts
│ └── config/
│ └── config.ts
│
├── dist/
│ ├── app.js
│ ├── user.js
│ └── config/
│ └── config.js
│
├── index.html
└── tsconfig.json
Nah, di sinilah rootDir dan outDir berperan.
2. Apa Itu rootDir?
rootDir berasal dari:
root directory
Sederhananya:
rootDirmemberitahu TypeScript: “Source code TypeScript saya berada di folder mana?”
Misalnya:
my-project/
│
├── src/
│ ├── app.ts
│ ├── user.ts
│ └── config.ts
│
└── tsconfig.json
Kita bisa memberi tahu TypeScript:
{
"compilerOptions": {
"rootDir": "./src"
}
}
Artinya:
“Anggap
srcsebagai root directory dari source code saya.”
3. Analogi Sederhana rootDir
Bayangkan kamu punya sebuah gudang besar:
my-project/
Di dalamnya ada banyak barang:
my-project/
├── src/
├── dist/
├── images/
├── docs/
└── index.html
Kamu bilang kepada TypeScript:
“Barang yang ingin kamu proses ada di
src.”
Maka:
"rootDir": "./src"
Kurang lebih artinya:
my-project
│
▼
┌─────────┐
│ src │ ← rootDir
└─────────┘
│ │ │
▼ ▼ ▼
app user config
4. Default rootDir
Kalau kita tidak menentukan rootDir, TypeScript akan menentukan root directory berdasarkan file-file yang termasuk dalam proses compilation.
Dalam contoh sederhana lecture:
my-project/
├── app.ts
├── config.ts
├── user.ts
└── tsconfig.json
maka secara praktis project root menjadi bagian dari source root.
Ketika kita mengubah struktur menjadi:
my-project/
├── src/
│ ├── app.ts
│ ├── config.ts
│ └── user.ts
│
└── tsconfig.json
kita dapat secara eksplisit mengatakan:
{
"compilerOptions": {
"rootDir": "./src"
}
}
5. Tapi Ada Hal Penting: rootDir Bukan Filter File
Ini bagian yang sangat penting.
Banyak pemula mengira:
"rootDir": "./src"
berarti:
“TypeScript hanya akan compile file yang ada di
src.”
Tidak selalu begitu.
rootDir terutama menentukan root dari source/output structure, bukan menentukan file mana saja yang boleh masuk compilation.
Untuk menentukan:
“File mana yang harus di-compile?”
kita menggunakan:
includeexcludefiles
Misalnya:
{
"compilerOptions": {
"rootDir": "./src"
},
"include": ["src"]
}
Sekarang:
rootDir
↓
“Source root saya adalah src.”
include
↓
“File yang saya masukkan ke compilation adalah src.”
Jadi keduanya punya pekerjaan berbeda.
6. rootDir vs include
Ini sering membingungkan.
rootDir
Menentukan root struktur source.
"rootDir": "./src"
Artinya:
“Anggap
srcsebagai root directory source.”
include
Menentukan file/folder yang ikut compilation.
"include": ["src"]
Artinya:
“Compile file yang ada di
src.”
Jadi:
rootDir
↓
menentukan struktur/root source
include
↓
menentukan file yang ikut compile
7. Contoh rootDir + include
Misalnya:
my-project/
│
├── src/
│ ├── app.ts
│ ├── user.ts
│ └── config.ts
│
├── demo.ts
│
└── tsconfig.json
Kita menggunakan:
{
"compilerOptions": {
"rootDir": "./src"
},
"include": ["src"]
}
Maka:
src/app.ts
src/user.ts
src/config.ts
yang masuk compilation.
Sedangkan:
demo.ts
tidak ikut karena tidak termasuk include.
8. Sekarang Masuk ke outDir
Kalau rootDir menjawab:
“Source code ada di mana?”
maka outDir menjawab:
“Hasil JavaScript-nya mau diletakkan di mana?”
outDir berasal dari:
output directory
Misalnya kita punya:
src/
├── app.ts
├── user.ts
└── config.ts
Kita ingin hasil compile masuk ke:
dist/
Maka:
{
"compilerOptions": {
"outDir": "./dist"
}
}
9. Analogi outDir
Kalau rootDir adalah:
“Barang masuk dari gudang mana?”
maka outDir adalah:
“Barang hasil proses disimpan di gudang mana?”
Visualnya:
SOURCE
│
│
▼
┌────────┐
│ src/ │
└────────┘
│
│ tsc
▼
┌────────┐
│ dist/ │
└────────┘
OUTPUT
Jadi:
rootDir → tempat source
outDir → tempat hasil compile
10. Contoh Paling Sederhana
Struktur awal:
my-project/
│
├── src/
│ ├── app.ts
│ └── user.ts
│
├── dist/
│
└── tsconfig.json
tsconfig.json:
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src"]
}
Kemudian:
tsc
TypeScript akan menghasilkan:
my-project/
│
├── src/
│ ├── app.ts
│ └── user.ts
│
├── dist/
│ ├── app.js
│ └── user.js
│
└── tsconfig.json
Jadi:
src/app.ts → dist/app.js
src/user.ts → dist/user.js
11. Yang Sangat Menarik: Folder Structure Dipertahankan
Ini salah satu poin terpenting dari lecture.
Misalnya source kita seperti ini:
src/
│
├── app.ts
├── user.ts
│
└── config/
├── database.ts
└── environment.ts
Kita menggunakan:
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src"]
}
Setelah compile:
dist/
│
├── app.js
├── user.js
│
└── config/
├── database.js
└── environment.js
Perhatikan polanya:
src/
│
├── app.ts
│
└── config/
└── database.ts
menjadi:
dist/
│
├── app.js
│
└── config/
└── database.js
Struktur foldernya tetap sama.
Yang berubah terutama adalah:
.ts → .js
12. Kenapa TypeScript Melakukan Ini?
Karena kita ingin hubungan source dan output tetap mudah dipahami.
Misalnya:
src/services/user.ts
akan menjadi:
dist/services/user.js
Bukan semuanya dilempar ke satu folder:
dist/
├── user.js
├── product.js
├── order.js
└── ...
Struktur project tetap terjaga.
13. rootDir dan outDir Bekerja Bersama
Sekarang kita bisa memahami keduanya sebagai pasangan.
Misalnya:
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
}
}
Artinya:
SOURCE ROOT
src/
│
│
│ TypeScript Compiler
▼
OUTPUT ROOT
dist/
Atau:
src/
│
├── app.ts
├── user.ts
└── config/
└── database.ts
│
│ tsc
▼
dist/
│
├── app.js
├── user.js
└── config/
└── database.js
14. Cara Mengingatnya
Saya sarankan mengingat dengan kalimat ini:
rootDir= dari mana source code berasal.outDir= ke mana hasil compile pergi.
Atau lebih pendek:
rootDir → INPUT
outDir → OUTPUT
Walaupun secara teknis rootDir bukan penentu utama file input, untuk mental model sederhana ini cukup membantu.
Kalau ingin lebih presisi:
include / files / exclude
↓
“File mana yang ikut compile?”
rootDir
↓
“Source root-nya di mana?”
outDir
↓
“Hasil compile diletakkan di mana?”
15. Kenapa Project Besar Membutuhkan Ini?
Bayangkan project kecil:
project/
├── app.ts
├── config.ts
├── app.js
└── config.js
Masih bisa dimengerti.
Tapi project besar:
project/
├── app.ts
├── app.js
├── user.ts
├── user.js
├── product.ts
├── product.js
├── order.ts
├── order.js
├── database.ts
├── database.js
├── ...
Akan semakin berantakan.
Dengan src dan dist:
project/
│
├── src/
│ ├── app.ts
│ ├── user.ts
│ ├── product.ts
│ ├── order.ts
│ └── database.ts
│
└── dist/
├── app.js
├── user.js
├── product.js
├── order.js
└── database.js
Jauh lebih jelas.
16. Kenapa Namanya dist?
dist biasanya singkatan dari:
distribution
Biasanya folder ini berisi hasil yang sudah siap digunakan/didistribusikan.
Misalnya:
src/
berisi:
TypeScript source code
sedangkan:
dist/
berisi:
compiled JavaScript
Dalam project lain, nama folder output bisa saja:
dist/
build/
lib/
output/
Tidak wajib bernama dist.
Kita sendiri yang menentukan:
"outDir": "./dist"
atau:
"outDir": "./build"
17. Hubungannya dengan index.html
Ini juga penting dari contoh lecture.
Awalnya browser mungkin mencari:
<script src="app.js"></script>
Tetapi setelah kita menggunakan:
"outDir": "./dist"
hasil compile menjadi:
dist/app.js
Maka HTML harus mengarah ke lokasi tersebut:
<script src="dist/app.js"></script>
Kalau file ada di:
dist/config/config.js
maka path-nya juga harus sesuai:
<script src="dist/config/config.js"></script>
Jadi setelah memindahkan output JavaScript, referensi HTML terhadap file JS juga harus disesuaikan.
18. Kesalahan yang Sering Terjadi
Misalnya kita punya:
src/
└── app.ts
dist/
└── app.js
Tetapi index.html masih:
<script src="app.js"></script>
Browser akan mencari:
project/app.js
Padahal file sebenarnya:
project/dist/app.js
Akibatnya JavaScript tidak ditemukan.
Harus:
<script src="dist/app.js"></script>
19. rootDir Bukan Berarti “Folder yang Harus Dicari”
Ada satu koreksi kecil terhadap cara lecture menjelaskan konsep ini.
Lecture mengatakan kurang lebih:
rootDirmemberitahu TypeScript folder tempat mencari TypeScript files.
Untuk pemahaman awal, ini boleh digunakan sebagai gambaran.
Tetapi secara teknis lebih tepat mengatakan:
rootDirmenentukan root directory yang digunakan TypeScript untuk mempertahankan struktur folder pada output.
Sedangkan untuk menentukan file yang benar-benar dikompilasi, kita lebih tepat menggunakan:
include
exclude
files
Contohnya:
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src/**/*.ts"]
}
Di sini:
include
↓
menentukan file yang masuk
rootDir
↓
menentukan source root
outDir
↓
menentukan output root
20. Hubungkan dengan Option yang Sudah Kita Pelajari
Sekarang banyak compiler option sudah mulai saling terhubung.
Misalnya:
{
"compilerOptions": {
"target": "ES2016",
"lib": ["ES2016", "DOM"],
"rootDir": "./src",
"outDir": "./dist",
"sourceMap": true,
"declaration": true
},
"include": ["src"]
}
Kita bisa membacanya seperti ini:
target
JavaScript output-nya mau menggunakan versi apa?
lib
API/type declaration apa yang dikenali TypeScript?
rootDir
Source root saya di mana?
outDir
Hasil compile disimpan di mana?
include
File mana yang ikut compilation?
sourceMap
Buat mapping agar debugging source TypeScript lebih mudah.
declaration
Buat file .d.ts.
21. Gambaran Besar Compilation Project
Dengan konfigurasi seperti ini:
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src"]
}
alur project kita menjadi:
tsconfig.json
│
▼
TypeScript Compiler
│
┌──────────────┴──────────────┐
│ │
rootDir include
│ │
▼ ▼
src/ file yang ikut compile
│
│
▼
TypeScript
files
│
│ tsc
▼
dist/
│
▼
JavaScript files
Atau versi super sederhana:
src/
│
│ .ts
▼
tsc
│
│ .js
▼
dist/
22. Contoh Project yang Lebih Realistis
Misalnya project kita:
my-project/
│
├── src/
│ ├── app.ts
│ ├── models/
│ │ └── user.ts
│ ├── services/
│ │ └── userService.ts
│ └── config/
│ └── database.ts
│
├── dist/
│
├── index.html
├── package.json
└── tsconfig.json
Konfigurasi:
{
"compilerOptions": {
"target": "ES2016",
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src"]
}
Setelah:
tsc
hasilnya:
my-project/
│
├── src/
│ ├── app.ts
│ ├── models/
│ │ └── user.ts
│ ├── services/
│ │ └── userService.ts
│ └── config/
│ └── database.ts
│
├── dist/
│ ├── app.js
│ ├── models/
│ │ └── user.js
│ ├── services/
│ │ └── userService.js
│ └── config/
│ └── database.js
│
├── index.html
├── package.json
└── tsconfig.json
Perhatikan:
src/models/user.ts
↓
dist/models/user.js
dan:
src/services/userService.ts
↓
dist/services/userService.js
Struktur foldernya dipertahankan.
23. Cheat Sheet
| Option | Fungsi sederhana |
|---|---|
rootDir | Menentukan source root |
outDir | Menentukan folder output |
include | Menentukan file/folder yang ikut compile |
exclude | Menentukan file/folder yang dikecualikan |
files | Menentukan file secara eksplisit |
target | Menentukan versi JavaScript output |
lib | Menentukan API/type declaration yang dikenali TS |
sourceMap | Membantu debug source asli |
declaration | Membuat file .d.ts |
24. Cara Paling Mudah Mengingat
Bayangkan kita punya sebuah pabrik:
TYPEScript Factory
SOURCE OUTPUT
│ │
▼ ▲
┌───────┐ ┌───────┐
│ src │ ─────── tsc ───────→ │ dist │
└───────┘ └───────┘
▲ ▲
│ │
rootDir outDir
Jadi:
rootDir= “bahan mentah saya ada di mana?”
outDir= “hasil produksinya mau disimpan di mana?”
Sedangkan:
include= “bahan mentah mana yang boleh diproses?”
Ini adalah tiga konsep yang sebaiknya jangan tertukar:
include
↓
FILE MANA yang diproses?
rootDir
↓
SOURCE ROOT-nya di mana?
outDir
↓
OUTPUT-nya disimpan di mana?
Inti lecture ini
Kalau project TypeScript masih kecil, kita mungkin bisa membiarkan .ts dan .js berdampingan.
Tetapi ketika project membesar, pola yang jauh lebih rapi adalah:
project/
│
├── src/ ← TypeScript source
│
├── dist/ ← compiled JavaScript
│
└── tsconfig.json
dengan:
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src"]
}
Sehingga alurnya menjadi:
src/*.ts
│
│ TypeScript Compiler
▼
dist/*.js
rootDir mengatur sisi source, outDir mengatur sisi output, dan include mengatur file mana yang ikut dikompilasi.