Masukkan Password
90 Creating a Webpack Config File
Lecture ini adalah lanjutan langsung dari lecture sebelumnya. Kalau sebelumnya kita baru meng-install Webpack dan package pendukungnya, sekarang kita mulai mengatur bagaimana Webpack bekerja di project TypeScript kita.
Ada 4 hal besar yang dilakukan:
- Mengubah beberapa setting di
tsconfig.json - Membuat
webpack.config.js - Menentukan entry dan output Webpack
- Mengubah import agar Webpack nanti bisa mencari file
.ts
Dan di akhir lecture, Webpack belum bisa compile TypeScript sepenuhnya. Itu baru akan dikonfigurasi di lecture berikutnya dengan ts-loader.
1. Gambaran besar dulu
Sebelum konfigurasi:
TypeScript
│
↓
tsc
│
↓
JavaScript files
Sekarang kita ingin mengubah workflow menjadi:
TypeScript
│
↓
Webpack
│
├── compile TypeScript
├── follow imports
├── bundle
└── output JavaScript
│
↓
bundle.js
Tetapi Webpack perlu diberi tahu:
“File mana yang harus mulai dibaca?”
“Hasilnya mau disimpan di mana?”
“Kalau ketemu
.ts, harus diproses bagaimana?”
Lecture ini baru menjawab dua pertanyaan pertama.
2. Perubahan pertama: tsconfig.json
Lecture mulai dengan membuka:
tsconfig.json
Kemudian ada 3 perubahan utama:
1. target
2. module
3. rootDir
Mari kita bahas satu per satu.
3. target: JavaScript versi berapa yang ingin dibuat?
Misalnya di TypeScript kita menulis:
const user = new User("John", 25, "male");
TypeScript perlu tahu:
“JavaScript versi berapa yang harus menjadi target output?”
Itulah fungsi:
"target": "es2015"
4. Apa itu ES5, ES6, ES2015?
Ini adalah versi/standar JavaScript.
Secara sederhana:
ES5
↓
lebih lama
↓
dukungan browser lama lebih luas
ES6 / ES2015
↓
lebih modern
↓
fitur JavaScript lebih baru
Perlu diingat:
ES6 dan ES2015 pada dasarnya adalah nama untuk generasi standar JavaScript yang sama.
Jadi:
ES6 ≈ ES2015
5. Kenapa target harus diperhatikan?
Karena tidak semua browser mendukung fitur JavaScript modern.
Misalnya kita menulis TypeScript menggunakan fitur modern.
TypeScript bisa menghasilkan JavaScript yang sesuai dengan target yang kita pilih.
Contohnya secara konseptual:
TypeScript
↓
target ES5
↓
JavaScript lebih kompatibel dengan browser lama
atau:
TypeScript
↓
target ES2015
↓
JavaScript lebih modern
Jadi:
targetmenentukan versi JavaScript yang menjadi tujuan hasil compile.
6. Kenapa lecture memilih ES2015?
Lecture mengatakan:
target bisa ES5, ES2015, atau ES6 tergantung browser yang ingin didukung.
Jadi kalau aplikasi kita harus mendukung browser yang sangat lama, kita mungkin memilih target yang lebih lama.
Kalau browser modern menjadi target utama:
"target": "es2015"
bisa digunakan.
7. Perubahan kedua: module
Kemudian lecture mengatakan:
"module": "es2015"
Kenapa?
Karena project kita menggunakan ES6/ES2015 Modules.
Sebelumnya kita belajar:
import User from "./models/user.js";
dan:
export default class User {
...
}
Itu adalah ES Modules.
Jadi TypeScript perlu diberi tahu:
“Pertahankan sistem module ES ini.”
Secara sederhana:
TypeScript
↓
module: ES2015
↓
ES Modules
↓
import / export
8. Jangan tertukar target dan module
Ini salah satu bagian yang sering membingungkan pemula.
Keduanya berbeda.
target
Menentukan:
JavaScript versi apa yang dihasilkan?
Contoh:
"target": "es2015"
module
Menentukan:
sistem module apa yang digunakan oleh output?
Contoh:
"module": "es2015"
Jadi:
target
↓
versi/sintaks JavaScript
module
↓
cara module diorganisasi
(import/export, CommonJS, dll.)
9. Perubahan ketiga: rootDir
Sebelumnya kita menggunakan sesuatu seperti:
"rootDir": "./src"
Tetapi sekarang lecture meminta agar ini di-comment.
Kenapa?
Karena sekarang:
Webpack yang akan mengatur struktur input dan output build.
Sebelumnya kita menggunakan TypeScript compiler secara langsung:
tsc
↓
TypeScript menentukan output
Sekarang kita ingin:
Webpack
↓
mengatur proses build
Jadi Webpack akan mengambil alih sebagian tanggung jawab tersebut.
10. Analogi rootDir
Bayangkan kamu memiliki:
src/
├── app.ts
├── models/
│ └── user.ts
└── user-utils/
└── user-action.ts
rootDir sebelumnya seperti mengatakan kepada TypeScript:
“Anggap folder
srcsebagai root/source utama project.”
Tetapi ketika Webpack digunakan sebagai build tool, Webpack akan menentukan:
“Saya mulai dari entry file ini dan mengikuti dependency-nya.”
Jadi lecture menghapus rootDir agar tidak terjadi tumpang tindih tanggung jawab.
11. Setelah perubahan tsconfig.json
Secara konsep, bagian pentingnya menjadi:
{
"compilerOptions": {
"target": "es2015",
"module": "es2015"
}
}
Dan:
"rootDir": "./src"
di-comment/dihapus sesuai konfigurasi lecture.
12. Sekarang membuat webpack.config.js
Ini bagian terpenting dari lecture.
Kita membuat file:
webpack.config.js
di root project.
Struktur sederhananya:
project/
├── src/
│ ├── app.ts
│ ├── models/
│ │ └── user.ts
│ └── user-utils/
│ └── user-action.ts
│
├── package.json
├── tsconfig.json
└── webpack.config.js
13. Kenapa namanya harus webpack.config.js?
Karena Webpack secara default akan mencari file konfigurasi dengan nama tersebut.
Jadi ketika kita menjalankan Webpack, Webpack bisa menemukan:
webpack.config.js
dan membaca:
“Oh, ini adalah aturan bagaimana project ini harus di-build.”
14. webpack.config.js adalah file JavaScript
Ini menarik.
Kita sedang mengatur project TypeScript.
Tetapi file:
webpack.config.js
adalah JavaScript, bukan TypeScript.
Kenapa?
Karena file konfigurasi tersebut akan dijalankan oleh:
Node.js
Jadi Webpack configuration adalah kode JavaScript yang digunakan oleh Node.js.
15. Apa maksud module.exports?
Lecture memberikan contoh:
module.exports = {
...
};
Ini adalah syntax module dari Node.js/CommonJS.
Artinya kira-kira:
“Export object konfigurasi ini supaya bisa digunakan oleh program yang membacanya.”
Webpack nantinya membaca object tersebut.
Contohnya:
module.exports = {
entry: "...",
output: {
...
}
};
Bisa kita bayangkan seperti:
webpack.config.js
│
↓
object configuration
│
↓
Webpack
│
↓
menjalankan build
16. Kenapa Node.js bisa menjalankan file ini?
Karena Node.js sudah kita install sejak awal course.
Jadi:
webpack.config.js
↓
Node.js
↓
membaca/menjalankan config
↓
Webpack
Ini berbeda dengan source code aplikasi kita.
Source code:
.ts
akan diproses melalui pipeline TypeScript/Webpack.
Sedangkan:
webpack.config.js
adalah file konfigurasi yang digunakan dalam lingkungan Node.js.
17. Konsep penting: entry
Sekarang kita masuk ke konfigurasi:
entry: "./src/app.ts"
Entry = titik awal Webpack membaca aplikasi.
Ini sangat penting.
Misalnya:
app.ts
↓
user-action.ts
↓
user.ts
Kita tidak perlu memberikan semua file kepada Webpack satu per satu.
Kita cukup mengatakan:
Entry = app.ts
Kemudian Webpack akan mengikuti import yang ada di dalamnya.
18. Analogi entry
Bayangkan kamu masuk ke sebuah gedung besar.
Kamu tidak perlu memberitahu satpam:
“Ini pintu A, kemudian lorong B, lalu ruangan C, lalu ruangan D…”
Kamu cukup bilang:
“Saya masuk dari pintu utama.”
Webpack juga begitu.
Kita memberikan:
entry
↓
app.ts
Kemudian Webpack mengikuti dependency.
Misalnya:
app.ts
│
├── import user-action
│
│ └── import User
│
│ └── user.ts
│
└── dependency lainnya
Webpack akan menelusuri graph tersebut.
19. Kenapa app.ts menjadi entry?
Karena app.ts adalah file utama aplikasi.
Misalnya:
import { createUser, getUsers }
from "./user-utils/user-action.js";
const U1 = createUser("John", 28, "male");
const U2 = createUser("Mary", 30, "female");
app.ts mengimpor file lain.
Jadi:
app.ts
↓
user-action.ts
↓
user.ts
Cukup mulai dari app.ts.
20. Konsep kedua: output
Setelah Webpack tahu:
“Saya mulai membaca dari mana?”
Webpack juga harus tahu:
“Hasil build harus ditaruh di mana?”
Itulah fungsi:
output: {
...
}
21. output.filename
Lecture memilih:
filename: "bundle.js"
Artinya hasil bundle akan diberi nama:
bundle.js
Nama tersebut tidak wajib.
Kita bisa saja menggunakan:
app.js
atau:
index.js
atau nama lain.
Tetapi:
bundle.js
cukup umum dan mudah dipahami karena file tersebut berisi hasil bundling.
22. output.path
Kemudian ada:
path: ...
Ini menentukan:
folder tempat
bundle.jsdibuat.
Lecture ingin:
dist/
└── bundle.js
Jadi output-nya:
src/
↓
Webpack
↓
dist/bundle.js
23. Kenapa path harus absolute path?
Lecture menekankan:
output
pathharus berupa absolute path.
Misalnya:
C:\Projects\my-app\dist
atau di Linux/macOS:
/home/user/my-app/dist
Itu adalah absolute path.
Sedangkan:
./dist
adalah relative path.
Untuk konfigurasi output.path, Webpack mengharapkan absolute path.
24. Bagaimana mendapatkan absolute path?
Di sinilah Node.js path module digunakan.
Lecture membuat:
const path = require("path");
path adalah module bawaan Node.js.
Jadi kita tidak perlu meng-install package path secara terpisah untuk penggunaan dasar ini.
25. Apa fungsi path?
Module path membantu kita bekerja dengan path/folder/file.
Misalnya:
path.resolve(...)
digunakan untuk menghasilkan absolute path.
Jadi:
Node.js
↓
path module
↓
path.resolve(...)
↓
absolute path
26. Apa itu __dirname?
Ini juga penting.
Lecture menggunakan:
__dirname
__dirname adalah nilai yang menunjuk ke directory tempat file JavaScript yang sedang dijalankan berada.
Misalnya:
project/
└── webpack.config.js
Saat webpack.config.js dijalankan, secara sederhana:
__dirname
↓
/path/to/project
Jadi kita bisa menggunakan:
path.resolve(__dirname, "dist")
untuk mendapatkan:
/path/to/project/dist
27. Kenapa tidak langsung menulis path komputer?
Misalnya kita bisa saja menulis:
path: "C:/Users/John/project/dist"
Tetapi itu buruk.
Karena ketika project dipindahkan ke komputer lain:
John's computer
❌ path berbeda
Jane's computer
❌ path berbeda
Dengan:
path.resolve(__dirname, "dist")
path menjadi relatif terhadap lokasi project/config file.
Jadi lebih portable.
28. Memahami path.resolve(__dirname, "dist")
Mari pecah:
path.resolve(__dirname, "dist")
Bagian 1
__dirname
= lokasi folder project/config.
Bagian 2
"dist"
= tambahkan folder dist.
resolve
= gabungkan dan ubah menjadi absolute path.
Jadi:
__dirname
+
dist
↓
absolute path ke dist
29. Bentuk konfigurasi Webpack yang sedang dibangun
Secara konsep, lecture sedang menuju konfigurasi seperti:
const path = require("path");
module.exports = {
entry: "./src/app.ts",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
}
};
Catatan: lecture berikutnya kemungkinan akan menambahkan module.rules dan ts-loader, sehingga konfigurasi akhirnya akan lebih lengkap.
30. Apa yang terjadi ketika Webpack menjalankan konfigurasi ini?
Bayangkan Webpack membaca:
entry: "./src/app.ts"
Webpack berpikir:
“Oke, saya mulai dari
app.ts.”
Kemudian:
app.ts
↓
Webpack membaca import
↓
user-action.ts
↓
Webpack membaca import
↓
user.ts
Kemudian Webpack menghasilkan:
dist/
└── bundle.js
Jadi:
src/app.ts
│
↓
Webpack dependency graph
│
↓
dist/bundle.js
31. Perubahan import: kenapa .js dihapus?
Ini bagian yang mungkin terasa aneh.
Sebelumnya kita punya:
import { createUser }
from "./user-utils/user-action.js";
Lecture sekarang meminta menjadi:
import { createUser }
from "./user-utils/user-action";
Begitu juga:
import User from "../models/user.js";
diubah menjadi:
import User from "../models/user";
Kenapa?
Karena sekarang Webpack nanti akan dikonfigurasi agar bisa mencari file TypeScript.
32. Kenapa sebelumnya .js, sekarang dihapus?
Ini berkaitan dengan perbedaan antara browser dan Webpack.
Sebelumnya browser secara langsung menjalankan JavaScript module.
Misalnya:
<script type="module" src="app.js"></script>
Kemudian:
import User from "./user.js";
Browser membutuhkan file JavaScript yang benar-benar ada.
Jadi .js masuk akal.
Sekarang kita punya:
TypeScript source
↓
Webpack
↓
JavaScript bundle
↓
Browser
Browser nantinya tidak akan membaca semua file .ts tersebut secara langsung.
Webpack yang akan membaca source TypeScript.
Karena itu Webpack nanti perlu dikonfigurasi agar dapat menyelesaikan import TypeScript.
33. Contoh dependency setelah .js dihapus
app.ts:
import { createUser }
from "./user-utils/user-action";
user-action.ts:
import User from "../models/user";
Jadi graph-nya:
app.ts
│
↓
user-action.ts
│
↓
user.ts
Webpack kemudian akan mengetahui:
"Ah, dependency ini adalah file TypeScript."
Tetapi…
belum otomatis tahu cara compile TypeScript.
Dan inilah yang akan dibahas di lecture berikutnya.
34. Ini poin yang sangat penting: Webpack belum tahu TypeScript
Lecture menekankan:
“by default webpack does not know what it has to do with .ts file”
Ini penting sekali.
Webpack adalah bundler.
Jangan menganggap:
Webpack = TypeScript compiler
Tidak.
Secara sederhana:
Webpack
= bundler
Sedangkan:
TypeScript
= compiler
35. Jadi kenapa kita membutuhkan ts-loader?
Ingat lecture sebelumnya kita sudah install:
ts-loader
Sekarang kita tahu alasan sebenarnya.
Kita ingin:
.ts
↓
TypeScript processing
↓
JavaScript
↓
Webpack bundle
Webpack perlu diberi aturan:
“Kalau kamu menemukan file
.ts, gunakants-loader.”
Konfigurasi tersebut belum dibuat di lecture ini.
Itu akan dilakukan di lecture berikutnya.
36. Apa yang sebenarnya sudah bisa dilakukan setelah lecture ini?
Setelah lecture ini, Webpack sudah diberi tahu:
1. Mulai dari mana?
./src/app.ts
2. Output namanya apa?
bundle.js
3. Output ditaruh di mana?
dist/
Tetapi belum:
“Bagaimana cara memproses
.ts?”
Itulah pekerjaan berikutnya.
37. Analogi lengkap
Bayangkan Webpack seperti sebuah pabrik.
Kita punya bahan baku:
src/
├── app.ts
├── user.ts
└── user-action.ts
Kita memberi instruksi:
entry
“Mulai ambil bahan dari gudang ini.”
src/app.ts
output.filename
“Produk akhirnya beri nama ini.”
bundle.js
output.path
“Simpan produk di gudang ini.”
dist/
Tetapi pabrik masih bertanya:
“Bahan
.tsini harus diproses dengan mesin apa?”
Nah, ts-loader adalah salah satu bagian yang akan menjawab pertanyaan itu.
38. Alur sebelum dan sesudah Webpack
Sebelumnya
Kita menggunakan:
.ts files
↓
tsc
↓
.js files
↓
browser
Sekarang
Kita ingin:
.ts files
↓
Webpack
↓
ts-loader
↓
JavaScript
↓
Webpack bundling
↓
bundle.js
↓
browser
Dengan demikian Webpack mengambil alih proses build yang sebelumnya kita lakukan secara terpisah.
39. Kenapa tsc watch mode dihentikan?
Di lecture sebelumnya terminal menjalankan:
tsc --watch
Sekarang lecture menghentikannya dengan:
Ctrl + C
Kenapa?
Karena kita tidak ingin lagi mengandalkan tsc --watch sebagai pipeline utama.
Sekarang kita ingin Webpack yang mengurus proses build.
Jadi sebelumnya:
tsc --watch
↓
compile TS
Sekarang nantinya:
Webpack Dev Server / Webpack
↓
ts-loader
↓
compile TS
↓
bundle
40. Diagram keseluruhan lecture
Kalau dirangkum:
tsconfig.json
│
┌──────────┼──────────┐
↓ ↓ ↓
target module rootDir
ES2015 ES2015 removed
│
│
↓
webpack.config.js
│
├── entry
│ ↓
│ src/app.ts
│
└── output
├── filename
│ ↓
│ bundle.js
│
└── path
↓
dist/
Kemudian nanti lecture berikutnya menambahkan:
webpack.config.js
│
↓
module.rules
│
↓
.ts
│
↓
ts-loader
│
↓
JavaScript
│
↓
Webpack
│
↓
bundle.js
41. Ringkasan tsconfig.json vs webpack.config.js
Ini juga wajib kamu pahami.
| File | Tugas |
|---|---|
tsconfig.json | Mengatur bagaimana TypeScript diproses |
webpack.config.js | Mengatur bagaimana Webpack melakukan build/bundling |
package.json | Mencatat metadata dan dependency project |
node_modules/ | Tempat package yang di-install |
Jadi jangan menganggap semua konfigurasi berada di satu tempat.
42. Perbedaan tsconfig.json dan webpack.config.js
Cara gampang mengingat:
tsconfig.json
Menjawab:
“TypeScript harus dikompilasi seperti apa?”
Contoh:
{
"compilerOptions": {
"target": "es2015",
"module": "es2015"
}
}
webpack.config.js
Menjawab:
“Webpack harus mengambil, memproses, dan menghasilkan file seperti apa?”
Contoh:
module.exports = {
entry: "./src/app.ts",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
}
};
43. Kenapa Webpack perlu entry, padahal sudah ada rootDir?
Karena keduanya punya konsep yang berbeda.
rootDir:
“Di mana source TypeScript saya berada?”
entry:
“Dari file mana Webpack harus mulai membangun dependency graph?”
Misalnya:
src/
├── app.ts ← entry
├── models/
│ └── user.ts
└── utils/
└── helper.ts
Webpack tidak harus memulai dari semua file.
Dia bisa mulai:
app.ts
lalu mengikuti:
import
yang digunakan.
44. Konsep dependency graph
Ini sebenarnya konsep inti Webpack.
Misalnya:
app.ts
│
├──── import ────→ user-action.ts
│ │
│ └── import → user.ts
│
└──── import ────→ helper.ts
Webpack melihat ini sebagai graph:
app.ts
/ \
↓ ↓
user-action.ts helper.ts
│
↓
user.ts
Webpack mulai dari:
entry = app.ts
Kemudian menelusuri seluruh dependency yang dibutuhkan.
45. Apa output akhirnya?
Secara sederhana:
src/
├── app.ts
├── models/
│ └── user.ts
└── user-utils/
└── user-action.ts
↓
Webpack
↓
dist/
└── bundle.js
Jadi browser nantinya tidak perlu mengetahui struktur source TypeScript kita.
Browser cukup menerima hasil build.
46. Hal yang paling penting untuk diingat
Kalau kamu hanya ingin mengingat 7 poin dari lecture ini, ingat ini:
① target
Menentukan versi JavaScript output.
Contoh:
ES5
ES2015
② module
Menentukan sistem module.
Lecture menggunakan:
ES2015
③ rootDir
Tidak lagi menjadi fokus karena Webpack mengambil alih proses build.
④ webpack.config.js
File konfigurasi Webpack.
⑤ entry
Titik awal Webpack.
Dalam project:
./src/app.ts
⑥ output
Menentukan hasil build:
filename → bundle.js
path → dist/
⑦ ts-loader
Belum dikonfigurasi di lecture ini, tetapi nanti bertugas membantu Webpack memproses:
.ts → JavaScript
47. Mental model terakhir 🧠
Bayangkan seluruh project seperti ini:
SOURCE CODE
│
↓
src/app.ts
ENTRY
│
↓
Webpack
│
┌──────────┴──────────┐
↓ ↓
ikuti import proses .ts
│
↓
ts-loader
│
↓
JavaScript
│
↓
BUNDLING
│
↓
dist/bundle.js
Sedangkan konfigurasi yang mengatur prosesnya:
tsconfig.json
│
├── target
├── module
└── compiler settings
webpack.config.js
│
├── entry
├── output
└── nanti: rules/loader
🎯 Inti lecture dalam satu kalimat:
Kita sedang memindahkan tanggung jawab build dari
tsclangsung ke Webpack:tsconfig.jsonmengatur sisi TypeScript, sedangkanwebpack.config.jsmemberi tahu Webpack mulai dari mana (entry) dan menyimpan hasil ke mana (output); pada lecture berikutnya barulah kita memberitahu Webpack bagaimana menangani file.tsmenggunakants-loader.