Apakah masuk akal untuk menggunakan Require.js dengan Angular.js? [Tutup]

443

Saya seorang pemula untuk Angular.js dan mencoba memahami perbedaannya dari Backbone.js ... Kami dulu mengelola dependensi paket kami dengan Require.js saat menggunakan Backbone. Apakah masuk akal untuk melakukan hal yang sama dengan Angular.js?

Franck
sumber
Proyek blog dan seed lain: startersquad.com/blog/angularjs-requirejs
iwein
19
Tidak - Jangan gunakan require.js ATAU peramban dengan Angular.JS sama sekali tidak perlu melakukan itu - AngularJS memiliki sistem modul dan menggunakan sistem modul lain di atasnya akan membuat hidup Anda terlalu sulit. Saya telah mengikuti jawaban di utas ini dan menghabiskan terlalu banyak waktu untuk sesuatu yang sama sekali tidak perlu. Silakan baca artikel ini yang menjelaskan mengapa tidak: medium.com/@dickeyxxx/…
VitalyB
Baca ini untuk memahami perbedaan antara sudut dan memerlukan modul juristr.com/blog/2014/07/lazy-angular-modules
pilavdzice
1
di sini adalah video yang bagus yang menjelaskan mengapa itu adalah ide yang bagus dan menunjukkan bagaimana cara menggunakan requireJS dengan angularJS youtube.com/watch?v=4yulGISBF8w#t=142
gskalinskii
2
@VitalyB Artikel bagus! Saya suka memuat aplikasi dalam jumlah kecil. Tidak akan ada biaya segera . Heck, tidak ada biaya untuk saya sekarang.
dsign

Jawaban:

224

Ya itu masuk akal untuk digunakan angular.jsbersama dengan di require.jsmana Anda dapat menggunakan require.jsuntuk memodulasi komponen.

Ada proyek benih yang digunakan both angular.js and require.js.

Anshu
sumber
108
Proyek unggulan yang disebutkan di atas belum tersentuh selama satu tahun jadi saya telah membuat yang baru menggunakan AngularJS dan RequireJS terbaru dengan dukungan penuh untuk pengujian yang digerakkan oleh pengujian.
tnajdek
2
@tnajdek, saya memperbarui tautan dalam jawaban Anshu untuk menunjuk ke yang Anda sarankan.
David Rivers
7
Perhatikan bahwa tak satu pun dari proyek-proyek unggulan tersebut didukung oleh tim Angular. Wajib adalah pola yang lebih masuk akal dalam konteks lain, dan menyulapnya ke Angular bukanlah, IMHO, praktik terbaik.
XML
2
Buku O'Reilly AngularJS karya Brad Green & Shyam Seshadri (dirilis April tahun ini) juga merekomendasikan penambahan Persyaratan di awal pertumbuhan proyek Angular, dan menjabarkan rinciannya dengan sangat jelas.
bjorke
1
Saya lebih suka melakukan semuanya pada waktu build 1. browserify.org 2. npmjs.org/package/gulp-angular-filesort
A-Dubb
150

Untuk menyatakan kembali apa yang saya pikirkan pertanyaan OP sebenarnya:

Jika saya sedang membangun aplikasi terutama di Angular 1.x, dan (secara implisit) melakukannya di era Grunt / Gulp / Brokoli dan Bower / NPM, dan saya mungkin memiliki beberapa dependensi perpustakaan tambahan, apakah Perlu menambahkan lebih jelas, spesifik nilai melebihi apa yang saya dapatkan dengan menggunakan Angular tanpa Membutuhkan?

Atau, dengan kata lain:

"Apakah vanilla Angular perlu Diperlukan untuk mengelola pemuatan komponen Angular dasar secara efektif, jika saya memiliki cara lain untuk menangani pemuatan skrip dasar? "

Dan saya percaya jawaban dasar untuk itu adalah: "tidak kecuali Anda memiliki sesuatu yang sedang terjadi, dan / atau Anda tidak dapat menggunakan alat yang lebih baru, lebih modern."

Mari kita perjelas sejak awal: RequireJS adalah alat yang hebat yang memecahkan beberapa masalah yang sangat penting, dan memulai langkah kita, menuju aplikasi Javascript yang lebih skalabel dan lebih profesional. Yang penting, ini adalah pertama kalinya banyak orang menemukan konsep modularisasi dan mengeluarkan sesuatu dari ruang lingkup global. Jadi, jika Anda akan membangun aplikasi Javascript yang perlu ditingkatkan, maka Memerlukan dan pola AMD bukanlah alat yang buruk untuk melakukan itu.

Tetapi, apakah ada sesuatu yang khusus tentang Angular yang membuat Require / AMD sangat cocok? Tidak. Faktanya, Angular memberi Anda modulasi dan pola enkapsulasi sendiri, yang dalam banyak hal menjadikan fitur modularisasi AMD yang berlebihan. Dan, mengintegrasikan modul Angular ke dalam pola AMD bukan tidak mungkin, tapi agak ... rewel. Anda pasti akan menghabiskan waktu untuk mengintegrasikan kedua pola dengan baik.

Untuk beberapa sudut pandang dari tim Angular itu sendiri, ada ini , dari Brian Ford, penulis Angular Batarang dan sekarang menjadi anggota tim inti Angular:

Saya tidak merekomendasikan menggunakan RequireJS dengan AngularJS. Meskipun tentu saja mungkin, saya belum melihat contoh di mana RequireJS bermanfaat dalam praktik.

Jadi, pada pertanyaan AngularJS yang sangat spesifik: Angular dan Require / AMD adalah ortogonal, dan di beberapa tempat tumpang tindih. Anda dapat menggunakannya bersama-sama, tetapi tidak ada alasan khusus yang terkait dengan sifat / pola Angular itu sendiri.

Tetapi bagaimana dengan manajemen dasar ketergantungan internal dan eksternal untuk aplikasi Javascript yang dapat diskalakan? Tidak Perlu melakukan sesuatu yang sangat penting bagi saya di sana?

Saya merekomendasikan memeriksa Bower dan NPM, dan terutama NPM. Saya tidak mencoba memulai perang suci tentang manfaat komparatif dari alat-alat ini. Saya hanya ingin mengatakan: ada cara lain untuk menguliti kucing itu, dan cara-cara itu mungkin bahkan lebih baik daripada AMD / Membutuhkan. (Mereka tentu memiliki momentum yang jauh lebih populer di akhir 2015, khususnya NPM, dikombinasikan dengan modul ES6 atau CommonJS. Lihat pertanyaan SO terkait .)

Bagaimana dengan pemuatan malas?

Perhatikan bahwa memuat malas dan mengunduh malas berbeda. Pemuatan malas Angular tidak berarti Anda menariknya langsung dari server. Dalam aplikasi bergaya Yeoman dengan otomatisasi javascript, Anda menggabungkan dan memperkecil keseluruhan shebang menjadi satu file. Mereka hadir, tetapi tidak dieksekusi / dipakai sampai diperlukan. Peningkatan kecepatan dan bandwidth yang Anda dapatkan dari melakukan ini sangat, jauh lebih besar daripada perbaikan yang dituduhkan dari mengunduh malas pengontrol 20-line tertentu. Bahkan, latensi jaringan yang terbuang dan overhead transmisi untuk pengontrol itu akan menjadi urutan besarnya lebih besar dari ukuran pengontrol itu sendiri.

Tetapi katakanlah Anda benar-benar perlu mengunduh dengan malas, mungkin untuk aplikasi Anda yang jarang digunakan, seperti antarmuka admin. Itu kasus yang sangat sah. Membutuhkan memang bisa melakukan itu untuk Anda. Tetapi ada juga banyak lainnya , berpotensi lebih fleksibel pilihan yang mencapai hal yang sama. Dan Angular 2.0 tampaknya akan menangani ini untuk kita, built-in ke router . ( Detail .)

Tapi bagaimana dengan selama pengembangan di kotak dev lokal saya?

Bagaimana saya bisa mendapatkan semua lusinan file skrip saya dimuat tanpa perlu melampirkan semuanya ke index.html secara manual?

Lihatlah sub-generator dalam generator-angular Yeoman, atau pada pola otomasi yang terkandung dalam generator-gulp-angular , atau pada otomatisasi Webpack standar untuk React. Ini memberi Anda cara yang bersih dan dapat diskalakan untuk: secara otomatis melampirkan file pada saat komponen-komponennya dirancah, atau hanya mengambil semuanya secara otomatis jika mereka ada dalam folder tertentu / cocok dengan pola-glob tertentu. Anda tidak perlu lagi memikirkan pemuatan skrip Anda sendiri setelah mendapatkan opsi yang terakhir.

Intinya?

Membutuhkan adalah alat yang hebat, untuk hal-hal tertentu. Tetapi pergi dengan gandum jika memungkinkan, dan pisahkan kekhawatiran Anda bila memungkinkan. Biarkan Angular khawatir tentang pola modularisasi Angular sendiri, dan pertimbangkan untuk menggunakan modul ES6 atau CommonJS sebagai pola modularisasi umum. Biarkan alat otomatisasi modern khawatir tentang pemuatan skrip dan pengelolaan ketergantungan. Dan atasi async lazy-loading dengan cara granular, bukan dengan menyibukkannya dengan dua masalah lainnya.

Yang mengatakan, jika Anda mengembangkan aplikasi Angular tetapi tidak dapat menginstal Node pada mesin Anda untuk menggunakan alat otomatisasi Javascript karena beberapa alasan, maka Membutuhkan mungkin merupakan solusi alternatif yang baik. Dan saya telah melihat pengaturan yang sangat rumit di mana orang ingin secara dinamis memuat komponen Angular yang masing-masing menyatakan dependensi mereka sendiri atau sesuatu. Dan sementara saya mungkin akan mencoba untuk memecahkan masalah itu dengan cara lain, saya dapat melihat manfaat dari gagasan itu, untuk situasi yang sangat khusus itu.

Tetapi sebaliknya ... ketika mulai dari awal dengan aplikasi Angular baru dan fleksibilitas untuk menciptakan lingkungan otomasi modern ... Anda punya banyak pilihan lain yang lebih fleksibel dan lebih modern.

(Diperbarui berulang kali untuk mengikuti perkembangan adegan JS.)

XML
sumber
1
Proyek seed NG-Boilerplate ( github.com/ngbp/ngbp ) juga membuat webapp halaman tunggal dengan satu file js. Menggunakan manifes HTML5 memastikan file ini hanya dimuat sekali per versi.
Federico Elles
2
Padahal, seperti biasa, <i> ini tergantung </i>. Banyak orang menggunakan Persyaratan untuk seluruh arsitektur mereka, dan perlu mengintegrasikan Angular ke ekosistem itu. Ini adalah situasi yang sangat berbeda daripada ketika Anda membangun aplikasi secara terpisah.
Dave Nichol
2
Sepakat. Tetapi dorongan OP tampaknya adalah: "Jika saya membangun aplikasi terutama di Angular, dan (secara implisit) melakukannya di era Grunt, dan saya mungkin memiliki beberapa dependensi perpustakaan tambahan, apakah Perlu menambahkan nilai yang jelas, spesifik di luar apa yang saya dapatkan dengan menggunakan Angular tanpa Membutuhkan? " Dan saya percaya, jawabannya adalah: tidak. Jika Anda memiliki aplikasi besar dengan 40 dependensi luar, atau Anda tidak dapat mengontrol lingkungan CI Anda, atau bos Anda memujanya, atau Anda memujanya, atau Angular hanya satu bagian dari aplikasi yang lebih besar, dll., Dll., Maka YMMV.
XML
1
Tetapi karena dia tampaknya tidak mengajukan pertanyaan-pertanyaan itu, dan karena dia hanya menyebutkan konteks alternatif dari aplikasi Backbone, dia tampaknya bertanya: "apakah vanila Angular perlu Diperlukan untuk mengelola komponen-komponennya secara efektif?" Dan jawabannya adalah: "tidak, kecuali Anda memiliki sesuatu yang terjadi." Selain itu, pertanyaan ini muncul pada puncak gerakan Javascript CI, di mana kami mendapat banyak cara yang lebih baik untuk menangani 'pemuatan skrip' dasar dan fisik. Jika Anda memiliki masalah yang diselesaikan, pada dasarnya diperlukan tentang pencocokan dependensi dan enkapsulasi. Angular melakukan keduanya untuk Anda.
XML
Google menggunakan lazy-loading di beberapa proyek AngularJS-nya, karena jika tidak, pengguna akan mengunduh 24mb file di halaman pertama (dan ini dengan file-file yang di-uglified dan digabungkan). Jadi ya, dalam aplikasi yang kompleks itu tidak membuat hanya menyatukan semua bagian, ketika ada bagian pengguna tidak akan membuka dengan setiap kunjungan.
ngDeveloper
136

Ya, itu masuk akal.

Modul sudut tidak mencoba untuk memecahkan masalah pemesanan pemuatan skrip atau pengambilan skrip yang malas. Sasaran-sasaran ini ortogonal dan kedua sistem modul dapat hidup berdampingan dan memenuhi tujuan mereka.

Sumber: situs web resmi Angular JS

Tiago Reis
sumber
6
Jika Anda menggunakan satu modul per file js Anda dapat memuat modul sudut Anda pada urutan apa pun. Tetapi jika Anda ingin memberikan contoh layanan yang berbeda dalam file js yang berbeda tetapi Anda ingin melampirkannya pada modul sudut yang sama Anda harus memuat deklarasi modul sebelum deklarasi layanan. Jadi ini adalah keputusan arsitektur.
Matohawk
@Tiago: Berikan tautan ke lokasi asal Anda ini. Saya tidak dapat menemukannya di mana pun. Saya menduga bahwa itu berasal dari versi sebelumnya dari dokumen Angular, sebelum pola Angular menjadi mapan, dan sebelum menjadi jelas bahwa ada keuntungan yang signifikan untuk menghindari Membutuhkan, setidaknya untuk komponen Angular.
XML
@XMLilley: dapatkah Anda memberikan tautan yang menjelaskan keuntungan menghindari Membutuhkan saat menggunakan Angular? Saya memutuskan untuk menggunakan atau tidak Membutuhkan dalam proyek saya dan ini kedengarannya akan sangat membantu.
Trevor
1
Saya tidak jelas dalam bahasa saya di sini: ada keuntungan yang signifikan untuk memanfaatkan modul-loaders bawaan Angular sendiri, dan sesuai dengan pola pola Angular. Pertanyaannya adalah bukan apakah harus menghindari Membutuhkan, melainkan apakah ada nilai untuk menambahkan lapisan kompleksitas tambahan. Yang jelas adalah bahwa pola bawaan Angular akan dengan mudah dan elegan mengatasi kebutuhan untuk memuat modul Angular sendiri. Jika Membutuhkan melayani tujuan untuk memuat modul di luar konteks Angular, maka jadilah itu. Tetapi menggunakan Require for Angular itu asing.
XML
6
@XMLilley yang dilakukan Angular hanyalah memberi Anda injeksi ketergantungan. Pemuatan modul yang sebenarnya adalah tanggung jawab Anda. Anda dapat melakukan ini dengan menambahkan tag skrip, memiliki skrip build atau menggunakan requirejs. Sistem modul Angulars tidak memiliki pendapat tentang ini.
gillesruppert
57

Ini saya percaya adalah pertanyaan subyektif, jadi saya akan memberikan pendapat subyektif saya.

Angular memiliki mekanisme modularisasi bawaan. Saat Anda membuat aplikasi, hal pertama yang akan Anda lakukan adalah

var app = angular.module("myApp");

lalu

app.directive(...);

app.controller(...);

app.service(...);

Jika Anda melihat sudut-seed yang merupakan aplikasi starter yang rapi untuk angle, mereka telah memisahkan arahan, layanan, controller dll menjadi modul yang berbeda dan kemudian memuat modul-modul tersebut sebagai dependancies pada aplikasi utama Anda.

Sesuatu seperti :

var app = angular.module("myApp",["Directives","Controllers","Services"];

Angular juga malas memuat modul-modul ini (ke dalam memori) bukan file skrip mereka.

Dalam hal malas memuat file skrip, sejujurnya kecuali Anda menulis sesuatu yang sangat besar itu akan menjadi berlebihan karena sifatnya sendiri mengurangi jumlah kode yang Anda tulis. Aplikasi tipikal yang ditulis di sebagian besar kerangka kerja lain dapat mengharapkan pengurangan sekitar 30-50% dalam LOC jika ditulis dalam sudut.

Ganaraj
sumber
5
Memang, lebih baik mengkonfigurasi layanan di Angular.js daripada memuat modul dengan Require.js. Ini membuatnya lebih mudah untuk bermain dengan $ scope dan layanan, karena saya bermain dengan Socket.io
Marco Godínez
33

Menggunakan RequireJS dengan AngularJS masuk akal tetapi hanya jika Anda memahami bagaimana masing-masing bekerja mengenai injeksi dependensi , seolah- olah keduanya menyuntikkan dependensi, mereka menyuntikkan hal yang sangat berbeda.

AngularJS memiliki sistem ketergantungannya sendiri yang memungkinkan Anda menyuntikkan modul AngularJS ke modul yang baru dibuat untuk menggunakan kembali implementasi. Katakanlah Anda membuat modul "pertama" yang mengimplementasikan filter "sambutan" AngularJS:

angular
  .module('first', [])
  .filter('greet', function() {
    return function(name) {
      return 'Hello, ' + name + '!';
    }
  });

Dan sekarang katakanlah Anda ingin menggunakan filter "sapaan" di modul lain yang disebut "kedua" yang mengimplementasikan filter "selamat tinggal". Anda dapat melakukannya dengan menyuntikkan modul "pertama" ke modul "kedua":

angular
  .module('second', ['first'])
  .filter('goodbye', function() {
    return function(name) {
      return 'Good bye, ' + name + '!';
    }
  });

Masalahnya adalah bahwa untuk membuat ini berfungsi dengan benar tanpa RequireJS, Anda harus memastikan bahwa modul AngularJS "pertama" dimuat pada halaman sebelum Anda membuat modul AngularJS "kedua". Dokumentasi kutipan:

Tergantung pada modul yang menyiratkan bahwa modul yang diperlukan perlu dimuat sebelum modul yang diperlukan dimuat.

Dalam hal ini, di sinilah RequireJS dapat membantu Anda karena RequireJS menyediakan cara yang bersih untuk menyuntikkan skrip ke halaman membantu Anda mengatur ketergantungan skrip antara satu sama lain.

Kembali ke modul AngularJS "pertama" dan "kedua", berikut adalah bagaimana Anda dapat melakukannya menggunakan RequireJS memisahkan modul pada file yang berbeda untuk meningkatkan pemuatan dependensi skrip:

// firstModule.js file
define(['angular'], function(angular) {
  angular
    .module('first', [])
    .filter('greet', function() {
      return function(name) {
        return 'Hello, ' + name + '!';
      }
    });
});
// secondModule.js file
define(['angular', 'firstModule'], function(angular) {
  angular
    .module('second', ['first'])
    .filter('goodbye', function() {
      return function(name) {
        return 'Good bye, ' + name + '!';
      }
    });
});

Anda dapat melihat bahwa kita bergantung pada file "firstModule" yang akan disuntikkan sebelum konten dari panggilan balik RequireJS dapat dieksekusi yang membutuhkan modul AngularJS "pertama" yang akan dimuat untuk membuat modul AngularJS "kedua".

Catatan: Menyuntikkan file "angular" pada file "firstModule" dan "secondModule" karena ketergantungan diperlukan untuk menggunakan AngularJS di dalam fungsi panggil balik RequireJS dan harus dikonfigurasi pada config RequireJS untuk memetakan "angular" ke kode perpustakaan. Anda mungkin memiliki AngularJS dimuat ke halaman secara tradisional juga (tag tag) meskipun mengalahkan manfaat RequireJS.

Rincian lebih lanjut tentang memiliki dukungan NeedeJS dari inti AngularJS dari versi 2.0 di posting blog saya.

Berdasarkan posting blog saya "Memahami Persyaratan dengan AngularJS" , inilah tautannya .

leog
sumber
2
Sebenarnya yang terbaik, ketika menyertakan tautan, untuk meringkas isi tautan di sini di Stack Overflow. Jika tautan Anda pernah putus, tautan mana yang dilakukan di Internet, jawaban Anda di sini tidak akan berguna bagi pengunjung masa depan. Pertimbangkan hasil edit untuk menghasilkan ringkasan dan perbaiki pos ini. Semoga berhasil!
jmort253
3
Ini dia, terima kasih jmort253.
leog
Terima kasih telah melakukan pengeditan ini dan menjelaskan bagaimana RequireJS dapat membantu mengelola dependensi untuk menghindari masalah dengan Angular yang mencoba memuat sesuatu yang belum ada.
jmort253
Saya sepenuhnya setuju, yang terbaik adalah menggunakan pendekatan ini untuk aplikasi besar jika tidak, Anda akan memiliki beberapa tag <script> dalam aplikasi Anda.
I.Tyger
21

Seperti @ganaraj disebutkan, AngularJS memiliki injeksi ketergantungan pada intinya. Ketika membangun aplikasi benih mainan dengan dan tanpa RequireJS, saya pribadi menemukan RequireJS mungkin berlebihan untuk kebanyakan kasus penggunaan.

Itu tidak berarti RequireJS tidak berguna karena kemampuan memuat skrip dan menjaga basis kode Anda tetap bersih selama pengembangan. Menggabungkan pengoptimal r.js ( https://github.com/jrburke/r.js ) dengan almond ( https://github.com/jrburke/almond ) dapat membuat kisah pemuatan skrip yang sangat tipis. Namun karena fitur manajemen ketergantungannya tidak sepenting dengan sudut pada inti aplikasi Anda, Anda juga dapat mengevaluasi sisi klien lain (HeadJS, LABjs, ...) atau bahkan sisi server (MVC4 Bundler, ...) solusi pemuatan skrip untuk aplikasi khusus Anda.

johlrich
sumber
17

Ya, tentu saja, khusus untuk SPA yang sangat besar.

Dalam beberapa skenario, RequireJS adalah suatu keharusan. Misalnya, saya mengembangkan aplikasi PhoneGap menggunakan AngularJS yang juga menggunakan Google Map API. Tanpa AMD loader seperti RequireJS, aplikasi hanya akan mogok saat diluncurkan saat offline karena tidak dapat sumber skrip Google Map API. AMD loader memberi saya kesempatan untuk menampilkan pesan kesalahan kepada pengguna.

Namun, integrasi antara AngularJS dan RequireJS agak rumit. Saya membuat angularAMD untuk menjadikan ini proses yang tidak terlalu menyakitkan:

http://marcoslin.github.io/angularAMD/

marcoseu
sumber
7

Ya, masuk akal untuk menggunakan JJ dengan Angular, saya menghabiskan beberapa hari untuk menguji beberapa solusi teknis.

Saya membuat Seed Angular dengan RequireJS di Server Side. Sangat sederhana. Saya menggunakan notasi SHIM tanpa modul AMD dan bukan AMD karena saya pikir sangat sulit untuk berurusan dengan dua sistem injeksi Ketergantungan yang berbeda.

Saya menggunakan grunt dan r.js untuk menggabungkan file js di server tergantung pada konfigurasi SHIM (dependensi) file. Jadi saya merujuk hanya satu file js di aplikasi saya.

Untuk informasi lebih lanjut, buka Benih Angular github saya: https://github.com/matohawk/angular-seed-requirejs

Matohawk
sumber
3

Saya akan menghindari menggunakan Require.js. Aplikasi yang pernah saya lihat yang melakukan ini mengacaukan banyak jenis arsitektur pola modul. AMD, Revealing, berbagai rasa IIFE, dll. Ada cara lain untuk memuat berdasarkan permintaan seperti loadOnDemand Angular mod . Menambahkan hal-hal lain hanya mengisi kode Anda yang penuh dengan cruft dan membuat rasio signal to noise yang rendah dan membuat kode Anda sulit dibaca.

Julia Anne Jacobs
sumber
0

Saya pikir itu tergantung pada kompleksitas proyek Anda karena sudut cukup banyak termodulasi. Pengontrol Anda dapat dipetakan dan Anda hanya dapat mengimpor kelas-kelas JavaScript di halaman index.html Anda.

Tetapi jika proyek Anda menjadi lebih besar. Atau Anda mengantisipasi skenario seperti itu, Anda harus mengintegrasikan sudut dengan needsejs. Pada artikel ini Anda dapat melihat aplikasi demo untuk integrasi tersebut.

lastboy
sumber