Bagaimana Anda mengelola variabel / konstanta konfigurasi untuk lingkungan yang berbeda?
Ini bisa menjadi contoh:
API istirahat saya dapat dijangkau localhost:7080/myapi/
, tetapi teman saya yang bekerja pada kode yang sama di bawah kontrol versi Git telah menggunakan API di Tomcat-nya.localhost:8099/hisapi/
.
Andaikata kita memiliki sesuatu seperti ini:
angular
.module('app', ['ngResource'])
.constant('API_END_POINT','<local_end_point>')
.factory('User', function($resource, API_END_POINT) {
return $resource(API_END_POINT + 'user');
});
Bagaimana cara saya menyuntikkan nilai akhir API yang benar secara dinamis, tergantung pada lingkungannya?
Dalam PHP saya biasanya melakukan hal-hal semacam ini dengan config.username.xml
file, menggabungkan file konfigurasi dasar (config.xml) dengan file konfigurasi lingkungan lokal yang dikenali oleh nama pengguna. Tapi saya tidak tahu bagaimana cara mengatur hal semacam ini di JavaScript?
sumber
'ngconstant:development'
di'serve'
- jika Anda memasukkannya ke dalam config menonton di bawah'gruntfile'
sepertitasks: ['ngconstant:development']
- Anda tidak perlu me-restartgrunt serve
ketika Anda memperbarui variabel pembangunan di gruntfile tersebut.package: grunt.file.readJSON('development.json')
Satu solusi keren mungkin memisahkan semua nilai spesifik lingkungan menjadi beberapa modul sudut terpisah, yang bergantung pada semua modul lainnya:
Kemudian modul Anda yang membutuhkan entri tersebut dapat mendeklarasikan ketergantungan padanya:
Sekarang Anda bisa memikirkan hal-hal keren lainnya:
Modul, yang berisi konfigurasi dapat dipisahkan menjadi configuration.js, yang akan disertakan di halaman Anda.
Script ini dapat dengan mudah diedit oleh Anda masing-masing, asalkan Anda tidak memeriksa file terpisah ini menjadi git. Tetapi lebih mudah untuk tidak memeriksa konfigurasi jika ada dalam file terpisah. Anda juga bisa bercabang secara lokal.
Sekarang, jika Anda memiliki sistem build, seperti ANT atau Maven, langkah lebih lanjut Anda dapat menerapkan beberapa placeholder untuk nilai API_END_POINT, yang akan diganti selama waktu build, dengan nilai spesifik Anda.
Atau Anda memiliki
configuration_a.js
danconfiguration_b.js
dan memutuskan di backend yang akan dimasukkan.sumber
Untuk pengguna Gulp , gulp-ng-constant juga berguna dikombinasikan dengan gulp-concat , event-stream, dan yargs .
Dalam folder konfigurasi saya, saya memiliki file-file ini:
Kemudian Anda dapat menjalankan
gulp config --env development
dan itu akan membuat sesuatu seperti ini:Saya juga punya spec ini:
sumber
Untuk mencapai itu, saya sarankan Anda untuk menggunakan AngularJS Environment Plugin: https://www.npmjs.com/package/angular-environment
Ini sebuah contoh:
Dan kemudian, Anda dapat memanggil variabel dari pengontrol Anda seperti ini:
Semoga ini bisa membantu.
sumber
angular-environment
mendeteksi lingkungan? yaitu apa yang perlu Anda lakukan pada mesin / server web lokal Anda sehingga tahu bahwa itu adalah dev / prod masing-masing?envServiceProvider.check()
... akan secara otomatis mengatur lingkungan yang sesuai berdasarkan domain yang diberikan". Jadi saya rasa itu mendeteksi domain saat ini dan mengatur lingkungan dengan tepat - waktu untuk mengujinya!Anda dapat menggunakan
lvh.me:9000
untuk mengakses aplikasi AngularJS Anda, (lvh.me
hanya menunjuk ke 127.0.0.1) dan kemudian tentukan titik akhir yang berbeda jikalvh.me
tuan rumah:Dan kemudian menyuntikkan layanan Konfigurasi dan menggunakan di
Configuration.API
mana pun Anda perlu mengakses API:Agak kikuk, tetapi bekerja dengan baik untuk saya, meskipun dalam situasi yang sedikit berbeda (API endpoint berbeda dalam produksi dan pengembangan).
sumber
window.location.host
lebih dari cukup bagi saya.Kita juga bisa melakukan hal seperti ini.
Dan di Anda
controller/service
, kami dapat menyuntikkan dependensi dan memanggil metode get dengan properti yang akan diakses.$http.get(env.get('apiroot')
akan mengembalikan url berdasarkan lingkungan host.sumber
Pertanyaan bagus!
Salah satu solusinya adalah dengan terus menggunakan file config.xml Anda, dan memberikan informasi titik akhir api dari backend ke html yang Anda hasilkan, seperti ini (contoh dalam php):
Mungkin bukan solusi yang bagus, tetapi itu akan berhasil.
Solusi lain mungkin untuk menjaga
API_END_POINT
konstan seperti yang seharusnya dalam produksi, dan hanya memodifikasi file host Anda untuk mengarahkan url ke api lokal Anda saja.Atau mungkin solusi yang digunakan
localStorage
untuk mengganti, seperti ini:sumber
Sangat terlambat ke utas, tetapi teknik yang saya gunakan, pra-Angular, adalah untuk mengambil keuntungan dari JSON dan fleksibilitas JS untuk referensi kunci koleksi yang dinamis, dan menggunakan fakta lingkungan yang tidak dapat dicabut (nama server host, bahasa browser saat ini) , dll.) sebagai input untuk secara selektif membedakan / memilih nama kunci yang suffixed dalam struktur data JSON.
Ini tidak hanya menyediakan konteks lingkungan penerapan (per OP) tetapi konteks sewenang-wenang (seperti bahasa) untuk memberikan i18n atau varian lain yang diperlukan secara bersamaan, dan (idealnya) dalam manifes konfigurasi tunggal, tanpa duplikasi, dan jelas terlihat.
DALAM TENTANG 10 LINES VANILLA JS
Contoh yang terlalu sederhana tetapi klasik: URL dasar endpoint API dalam file properti berformat JSON yang bervariasi per lingkungan di mana (natch) server host juga akan bervariasi:
Kunci ke fungsi diskriminasi adalah hanya nama host server dalam permintaan.
Ini, secara alami, dapat dikombinasikan dengan kunci tambahan berdasarkan pada pengaturan bahasa pengguna:
Cakupan diskriminasi / preferensi dapat terbatas pada kunci individual (seperti di atas) di mana kunci "dasar" hanya ditimpa jika ada kunci yang cocok + akhiran untuk input ke fungsi - atau seluruh struktur, dan struktur itu sendiri diuraikan secara rekursif untuk mencocokkan sufiks / preferensi preferensi:
SO, jika pengguna yang mengunjungi situs web produksi memiliki pengaturan preferensi bahasa Jerman ( de ), konfigurasi di atas akan runtuh ke:
Seperti apa fungsi penulisan ulang preferensi / diskriminasi JSON? Tidak banyak:
Dalam implementasi kami, yang mencakup situs web Angular dan pra-Angular, kami cukup mem-bootstrap konfigurasi jauh di depan panggilan sumber daya lainnya dengan menempatkan JSON dalam penutupan JS yang dapat dieksekusi sendiri, termasuk fungsi prefer (), dan memasukkan properti dasar dari nama host dan kode bahasa (dan menerima sufiks arbitrer tambahan apa pun yang mungkin Anda butuhkan):
Situs pra-Angular sekarang akan memiliki jendela collapsed (no @ suffixed keys ) .app_props untuk merujuk.
Situs Angular, sebagai langkah bootstrap / init, cukup menyalin objek prop yang mati ke $ rootScope, dan (secara opsional) menghancurkannya dari ruang lingkup global / jendela
untuk selanjutnya disuntikkan ke pengendali:
atau disebut dari binding dalam tampilan:
Peringatan? Karakter @ tidak valid penamaan variabel / kunci JS / JSON, tetapi sejauh ini diterima. Jika itu adalah deal-breaker, gantikan konvensi yang Anda suka, seperti "__" (double garis bawah) selama Anda tetap menggunakannya.
Teknik ini bisa diterapkan di sisi server, porting ke Java atau C # tetapi efisiensi / kekompakan Anda mungkin bervariasi.
Bergantian, fungsi / konvensi dapat menjadi bagian dari skrip kompilasi front-end Anda, sehingga JSON lengkap semua-lingkungan / semua-bahasa tidak pernah dikirimkan melalui kabel.
MEMPERBARUI
Kami telah mengembangkan penggunaan teknik ini untuk memungkinkan beberapa sufiks pada kunci, untuk menghindari dipaksa menggunakan koleksi (Anda masih bisa, sedalam yang Anda inginkan), dan juga untuk menghormati urutan sufiks yang disukai.
Contoh (juga lihat jsFiddle yang berfungsi ):
1/2 (penggunaan dasar) lebih suka kunci '@dev', buang semua kunci sufiks lainnya
3 lebih suka '@dev' daripada '@fr', lebih suka '@ dev & fr' daripada yang lainnya
4 (sama dengan 3 tetapi lebih suka '@fr' daripada '@dev')
5 tidak ada sufiks pilihan, tetes SEMUA properti sufiks
Ini mencapai ini dengan mencetak setiap properti suffix dan mempromosikan nilai properti suffix ke properti non-suffix ketika iterating atas properti dan menemukan akhiran skor yang lebih tinggi.
Beberapa efisiensi dalam versi ini, termasuk menghilangkan ketergantungan pada JSON untuk menyalin dalam, dan hanya berulang ke objek yang bertahan dari putaran penilaian di kedalamannya:
sumber
Jika Anda menggunakan Brunch , plugin Constangular membantu Anda mengelola variabel untuk lingkungan yang berbeda.
sumber
Sudahkah Anda melihat pertanyaan ini dan jawabannya?
Anda dapat menetapkan nilai yang berlaku secara global untuk aplikasi Anda seperti ini:
dan kemudian menggunakannya dalam layanan Anda. Anda bisa memindahkan kode ini ke file config.js dan menjalankannya pada pemuatan halaman atau momen lain yang nyaman.
sumber