← all posts

Cerita di Balik Layar Menaklukkan Proyek Weather App di The Odin Project

7/8/2026

Cerita di Balik Layar Menaklukkan Proyek Weather App di The Odin Project

Membangun Aplikasi Cuaca dengan Webpack dan Vanilla JS

Sebagai bagian dari kurikulum The Odin Project, saya membangun sebuah aplikasi cuaca. Proyek ini bukan sekadar latihan mengambil data dari API, melainkan sebuah tantangan untuk mengintegrasikan berbagai praktik pengembangan web modern dalam satu proyek yang kohesif.

Dalam tulisan ini, saya akan membagikan pengalaman dan keputusan teknis di balik layar, mulai dari proses bundling aset dengan Webpack, strategi efisiensi saat mengambil data cuaca, hingga alur kerja Git yang saya terapkan.

Pendahuluan

Aplikasi ini dirancang untuk menampilkan informasi cuaca saat ini beserta prakiraan lima hari ke depan berdasarkan kota yang dicari pengguna. Tujuan utamanya adalah untuk mengasah tiga keterampilan fundamental dalam pengembangan web modern:

  1. Modern JavaScript Tooling: Menggunakan Webpack untuk mengelola assets (JavaScript, CSS) dan environment variables.
  2. Asynchronous JavaScript: Mengonsumsi beberapa endpoint API secara efisien tanpa mengorbankan pengalaman pengguna.
  3. Version Control: Menerapkan alur kerja Git yang bersih, termasuk penggunaan feature branch dan penanganan merge conflict.

Konfigurasi Webpack

Webpack adalah jantung dari proses build proyek ini. Konfigurasi yang tepat memastikan proses pengembangan berjalan lancar dan hasil produksi menjadi optimal. Berikut adalah poin-poin penting dari webpack.config.js yang saya gunakan:

  1. Entry dan Output: Titik masuk aplikasi adalah src/script.js, dan semua hasil bundle akan ditempatkan di direktori dist. Opsi output.clean: true saya aktifkan untuk membersihkan direktori dist setiap kali proses build dijalankan.
  2. Loaders: Saya menggunakan css-loader untuk membaca file CSS dan style-loader untuk menyuntikkannya ke dalam DOM. Urutan ['style-loader', 'css-loader'] penting, karena Webpack memproses loader dari kanan ke kiri.
  3. Plugins:
    • HtmlWebpackPlugin: Plugin ini secara otomatis membuat file index.html di dalam dist dan menyisipkan bundle JavaScript ke dalamnya. Ini menghilangkan kebutuhan untuk mengedit HTML secara manual setiap kali nama file bundle berubah.
    • Dotenv-webpack: Untuk mengelola API key tanpa menuliskannya langsung di dalam kode (hardcode), saya menggunakan plugin ini. Ia memuat variabel dari file .env dan membuatnya tersedia di dalam aplikasi melalui process.env.
  4. DevServer: webpack-dev-server sangat membantu selama pengembangan dengan fitur hot-reloading, yang secara otomatis memuat ulang halaman di browser setiap kali ada perubahan pada kode.

Berikut adalah cuplikan konfigurasi yang merangkum poin-poin di atas:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const Dotenv = require("dotenv-webpack");

module.exports = {
  mode: "development",
  entry: "./src/script.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
    clean: true,
  },
  module: {
    rules: [{ test: /\.css$/, use: ["style-loader", "css-loader"] }],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html", // Menggunakan src/index.html sebagai template
    }),
    new Dotenv(), // Memuat variabel dari file .env
  ],
  devtool: "source-map",
  devServer: {
    static: "./dist",
    hot: true,
    open: true,
  },
};

Tips praktis:

  • Pisahkan konfigurasi untuk development dan production bila perlu.
  • Gunakan plugins seperti HtmlWebpackPlugin untuk menyuntikkan bundle ke HTML secara otomatis.
  • Aktifkan caching dan minimization di production untuk performa.

Mengoptimalkan Pemanggilan API dengan Promise.all

Di aplikasi cuaca, saya perlu mengambil beberapa resource (mis. data cuaca saat ini, forecast, dan ikon) yang berasal dari beberapa endpoint. Mengambilnya satu-per-satu menambah latensi. Solusi yang saya pakai adalah Promise.all untuk menjalankan beberapa fetch secara paralel.

Contoh pola penggunaan:

const urls = [currentWeatherUrl, forecastUrl, iconsUrl];

Promise.all(urls.map((url) => fetch(url).then((res) => res.json())))
  .then(([current, forecast, icons]) => {
    // gunakan data secara bersamaan
  })
  .catch((err) => {
    // tangani error: jika salah satu gagal, Promise.all menolak
  });

Catatan penting:

  • Tangani kegagalan dengan try/catch atau fallback agar satu gagal tidak merusak seluruh UI.
  • Untuk permintaan yang bisa gagal tanpa menghentikan keseluruhan, gunakan Promise.allSettled.
  • Batasi paralelisme jika API rate-limited (mis. p-limit atau batch requests).

Visualisasi Alur Aplikasi

Untuk memberikan gambaran yang lebih jelas tentang bagaimana semua bagian bekerja sama—mulai dari interaksi pengguna hingga respons dari API—berikut adalah dua diagram yang menggambarkan alur kerja aplikasi.

Diagram Alur (Mermaid)

Diagram sekuens ini menunjukkan interaksi antara pengguna, browser (kode JavaScript Anda), dan OpenWeatherMap API. Ini secara efektif mengilustrasikan bagaimana Promise.all mengeksekusi dua permintaan API secara paralel.

sequenceDiagram
    participant User as Pengguna
    participant Browser as "Browser (script.js)"
    participant API as "OpenWeatherMap API"

    User->>Browser: Memasukkan nama kota & klik "Cari"
    activate Browser

    Browser->>Browser: Menampilkan spinner loading
    Browser->>Browser: Memanggil searchCity(city)

    par Permintaan Paralel
        Browser->>API: GET /weather?q={city}
    and
        Browser->>API: GET /forecast?q={city}
    end

    API-->>Browser: Respons: Data Cuaca Saat Ini (JSON)
    API-->>Browser: Respons: Data Prakiraan Cuaca (JSON)

    Browser->>Browser: Merender data cuaca saat ini ke UI
    Browser->>Browser: Merender kartu prakiraan cuaca ke UI
    Browser->>Browser: Menyembunyikan spinner loading

    deactivate Browser

Diagram Teks (ASCII)

Diagram berbasis teks ini memberikan pandangan langkah demi langkah yang lebih sederhana tentang proses yang sama.

[Pengguna] -> Masukkan "Jakarta", Klik "Cari"
    |
    v
[Browser: script.js]
    |
    +-- 1. Tampilkan spinner "Loading..."
    |
    +-- 2. Panggil searchCity("Jakarta")
    |      |
    |      +--> Promise.all() memulai dua permintaan secara paralel:
    |           |
    |           +-- A. fetch(currentWeatherUrl) ---> [OpenWeatherMap API]
    |           |
    |           +-- B. fetch(forecastUrl)     ---> [OpenWeatherMap API]
    |
    +-- 3. Tunggu hingga A dan B selesai
    |      |
    |      +--> [OpenWeatherMap API] ---> Mengembalikan data JSON untuk A
    |      |
    |      +--> [OpenWeatherMap API] ---> Mengembalikan data JSON untuk B
    |
    +-- 4. Terima [currentData, forecastData]
    |
    +-- 5. Render data ke UI
    |      - Perbarui bagian cuaca saat ini
    |      - Buat dan tambahkan kartu prakiraan cuaca
    |
    +-- 6. Sembunyikan spinner "Loading..."

Alur Kerja Git dan Penanganan Konflik

Selama pengembangan, saya menghadapi konflik merge ketika beberapa orang (atau branch) mengubah file yang sama. Langkah-langkah saya untuk menyelesaikannya:

  1. Tarik perubahan terbaru: git fetch dan git pull pada branch tujuan.
  2. Lakukan merge atau rebase dari branch sumber: git merge feature-branch atau git rebase feature-branch.
  3. Ketika terjadi konflik, Git menandai bagian yang bermasalah dalam file dengan <<<<<<<, =======, >>>>>>>.
  4. Buka file yang konflik, tinjau kedua bagian, dan pilih/menggabungkan perubahan yang benar secara manual.
  5. Jalankan tes atau build untuk memastikan tidak ada yang rusak setelah resolusi.
  6. Setelah bersih: git add <file>, git commit (atau lanjutkan rebase dengan git rebase --continue).

Praktik yang membantu mencegah konflik besar:

  • Lakukan commit kecil dan sering.
  • Tarik perubahan terbaru sebelum memulai pekerjaan baru.
  • Gunakan feature branch untuk setiap fitur atau perbaikan.
  • Komunikasi tim: koordinasikan perubahan pada file yang sensitif.

Kesimpulan

Membangun Odin Weather App memberi pengalaman praktis dalam konfigurasi bundler (Webpack), efisiensi pemanggilan API menggunakan Promise.all, dan keterampilan menyelesaikan konflik Git. Praktik-praktik ini penting untuk pengembangan web modern dan meningkatkan kualitas kode serta alur kerja tim.

Semoga catatan singkat ini berguna bagi siapa saja yang mengerjakan proyek serupa di The Odin Project.