Konfigurasi Aplikasi Angular
Kerangka sudut adalah pilihan sempurna untuk mengembangkan aplikasi perusahaan. Dalam produk seperti itu, Anda mungkin perlu menemukan solusi yang memungkinkan aplikasi bekerja secara berbeda berdasarkan konteks yang diberikan. Misalnya, logging panjang mungkin diperlukan selama pengembangan atau titik akhir API mungkin berbeda untuk setiap lingkungan penerapan. Selain itu, akses ke beberapa fitur/modul dapat dibatasi untuk kelompok pengguna tertentu, oleh karena itu konfigurasi khusus sesi juga diperlukan (misalnya penanda fitur).
Dalam posting blog ini, saya akan membahas berbagai sumber data konfigurasi dan menguraikan informasi mana yang harus menjadi milik masing-masing. Saya juga akan menganalisis cara untuk menyediakan file konfigurasi aplikasi dan mempertimbangkan ketersediaannya untuk blok penyusun aplikasi Angular.
The environment file
Saat Anda membuat proyek baru menggunakan Angular CLI, itu menghasilkan file lingkungan, yang ditukar dalam konfigurasi build tertentu berdasarkan pengaturan di file angular.json
Penting untuk diperhatikan bahwa Anda hanya dapat mengubah konfigurasi seperti itu selama waktu pembuatan. Oleh karena itu, ini bukan tempat yang tepat untuk mendefinisikan data yang berbeda berdasarkan lingkungan penyebaran. Sebagai aturan praktis, Anda harus dapat membangun aplikasi sekali dan menerapkannya di mana saja.
File lingkungan adalah tempat yang tepat untuk menyimpan data yang memungkinkan Anda membedakan antara versi pengembangan dan versi yang dikirimkan ke klien. Sebagian besar waktu itu cukup untuk tetap menggunakan flag produksi:
File lingkungan disertakan dalam bundel utama, sehingga dapat diakses secara sinkron, yang sangat nyaman.
Anda dapat menggunakan bendera produksi untuk memberikan implementasi layanan yang berbeda:(Diedit)Pulihkan teks asli
Sebagai alternatif, Anda dapat menukar file dengan kelas layanan dengan cara yang sama seperti lingkungan file:
Anda juga dapat secara kondisional mengaktifkan fitur tertentu yang terkait dengan pengalaman pengembang (DX) berdasarkan informasi dari file lingkungan:
Selain itu, Anda dapat memasukkan modul-modul tertentu secara kondisional:
Last but not least, merupakan ide bagus untuk menyediakan objek dari file lingkungan dengan bantuan token injeksi:
Ini sangat pas dengan ekosistem Angular dan menyederhanakan unit tes.
Anda bisa meletakkan placeholder di file lingkungan:
dan melakukan penggantian teks untuk artefak build tunggal. Namun, solusinya tampak sedikit hacky dan hash pada nama file tidak lagi sesuai dengan isinya.
File config.json
Jika Anda ingin memberikan konfigurasi yang berbeda untuk aplikasi Anda berdasarkan lingkungan penerapan, menggunakan file json yang disajikan sebagai aset statis adalah cara yang harus dilakukan. Informasi tersebut mungkin berisi titik akhir API, pengaturan server auth, level log, dll.
Anda hanya perlu membangun aplikasi Anda sekali dan Anda dapat menerapkannya di mana saja. Aplikasi ini dikonfigurasi dengan menukar file config.json statis. Hasilnya, artefak yang sama diterapkan ke produksi setelah diuji pada lingkungan pementasan.
Ini adalah solusi yang sangat skalabel, karena Anda tidak perlu membuat aplikasi untuk setiap konfigurasi yang memungkinkan, mis. versi demo/reguler/extended.
File config harus diambil dari server. Mari kita fokus pada dua solusi yang umum:
penyedia statis
Anda dapat mengambil file sebelum bootstrap aplikasi Angular dan mengirimkannya dengan token injeksi CONFIG:
Manfaat utama dari solusi di atas adalah Anda dapat mengakses data konfigurasi secara sinkron di dalam modul, layanan, komponen, dll. Namun, file tersebut harus dimuat di luar ekosistem Angular, oleh karena itu Anda tidak memiliki akses ke Mekanisme Injeksi Ketergantungan dan token bawaan, misalnya. Anda tidak dapat menentukan platform.
Token APP_INITIALIZER
File konfigurasi dapat diambil selama aplikasi inisialisasi dengan bantuan token APP_INITIALIZER.
Mari pertimbangkan layanan konfigurasi berikut:(Diedit)Pulihkan teks asli
Layanan ini dapat digunakan dalam fungsi inisialisasi yang tersedia di bawah token APP_INITIALIZER:
Di dalam fungsi yang disediakan, Anda dapat menggunakan mekanisme Injeksi Ketergantungan, yang merupakan keuntungan besar dibandingkan solusi dengan penyedia statis. Namun, data konfigurasi tidak akan tersedia secara sinkron untuk semua blok bangunan aplikasi, yaitu pembuatan modul dan layanan tidak ditunda hingga file konfigurasi diambil. Ini dapat menyebabkan bug yang sulit ditemukan, karena menyuntikkan layanan ke salah satu fungsi yang disediakan di bawah token APP_INITIALIZER (perhatikan bahwa ini adalah penyedia multi) akan memaksa pembuatan contoh sebelum memuat file konfigurasi. Faktanya, cukup jika sebuah layanan berada di suatu tempat dalam rantai dependensi dari layanan yang disuntikkan secara langsung. Oleh karena itu, layanan yang perlu dikonfigurasi oleh data jarak jauh harus berlangganan dan melakukan inisialisasi setelah konfigurasi tersedia alih-alih mengandalkan akses sinkron:
Atau, Anda dapat menyediakan layanan di bawah token injeksi WITH_CONFIG dan mengandalkan fungsi penginisialisasi konfigurasi untuk memanggil metode konfigurasi setelah file konfigurasi diambil:
Seperti yang sudah saya sebutkan, Anda bisa menyediakan beberapa fungsi penginisialisasi di bawah token APP_INITIALIZER. Mereka dijalankan secara paralel dan Anda tidak dapat mengonfigurasi perilaku tersebut. Dalam hal kinerja, ini adalah pendekatan yang masuk akal, namun ada situasi ketika salah satu dari fungsi tersebut memerlukan data yang disediakan oleh yang lain, misalnya. data konfigurasi. Bagaimana cara menunda eksekusi hingga file konfigurasi dimuat? Sekali lagi, akses data dengan cara yang tidak sinkron:
Sebagai alternatif, Anda dapat menyediakan fungsi penginisialisasi yang memerlukan akses ke data konfigurasi di bawah token injeksi APP_WITH_CONFIG_INITIALIZER dan bergantung pada fungsi penginisialisasi config untuk menjalankannya setelah file konfigurasi tersedia:
Kesimpulannya, yang terbaik adalah tidak membuat terlalu banyak asumsi tentang kapan modul atau layanan akan dipakai atau fungsi akan dipanggil. Solusi yang paling anti peluru, namun mudah, bergantung pada memperlakukan data konfigurasi sebagai informasi asinkron. Jika Anda membutuhkan konfigurasi, berlanggananlah dan tunda eksekusi logika hingga tersedia, sesederhana itu.
Namun, ada situasi di mana tidak mungkin melakukan inisialisasi/konfigurasi secara asinkron, mis. mengaktifkan pelacakan router Angular hanya di lingkungan pengujian. Dalam skenario seperti itu, Anda dapat mengandalkan penyedia statis atau memuat ulang aplikasi setelah Anda mengambil konfigurasi secara asinkron dan menyimpannya di penyimpanan browser (mis. penyimpanan lokal). Sebagai alternatif, data konfigurasi dapat disematkan dalam skrip sebaris di file index.html:
Ini dapat diakses dengan cara sinkron dan diekspos menggunakan token injeksi:
Terakhir, mari kita bahas cara menyediakan konten berbeda ke file config.json. Jika Anda menerapkan artefak build ke CDN secara manual, Anda cukup menukar file. Di sisi lain, jika Anda menjalankan aplikasi menggunakan image Docker, Anda memiliki dua opsi.
Solusi pertama bergantung pada substitusi variabel lingkungan saat wadah dimulai:
Dockerfile
config.template.json
terminal command
Jika Anda menyediakan data konfigurasi menggunakan skrip sebaris, Anda perlu mengganti variabel lingkungan di file index.template.html, bukan file config.template.json.
Cara lain untuk mencapai tujuan adalah dengan menggunakan volume Docker:
Dockerfile
external-config.json
terminal command
Titik akhir API info pengguna
Beberapa data konfigurasi terikat pada pengguna tertentu, mis. bendera fitur. Oleh karena itu, Anda perlu mengambil informasi tersebut dari titik akhir API berdasarkan cookie sesi atau token akses.
Contoh layanan dapat diimplementasikan sebagai berikut:
Data harus diambil setelah diverifikasi bahwa sesi pengguna aktif:
Akibatnya, info pengguna perlu diperlakukan sebagai data yang tidak sinkron.
Mari kita lihat sebuah penjaga yang membatasi akses berdasarkan flag fitur:
Karena, mungkin diperlukan di banyak tempat untuk mengakses data setelah dimuat, fungsi yang dapat digunakan kembali berikut ini sangat berguna:
Perhatikan bahwa beberapa data konfigurasi khusus pengguna juga diperlukan untuk halaman publik yang tidak memerlukan autentikasi. Oleh karena itu, sebaiknya simpan informasi seperti bahasa atau tema pilihan di penyimpanan browser, mis. penyimpanan lokal, sehingga data dapat diakses secara sinkron untuk setiap tampilan.
Data konfigurasi untuk aplikasi dapat dikirimkan dari sumber yang berbeda dan tidak ada satu tempat yang tepat untuk menyimpan semua informasi. Anda perlu memperhitungkan apakah sepotong data dapat diakses secara sinkron atau asinkron. Perlu diingat bahwa praktik terbaik adalah membuat aplikasi satu kali dan dapat menerapkannya di mana saja dengan konfigurasi yang sesuai.