Saya memiliki fungsi IIFE untuk beberapa kode perpustakaan dalam aplikasi lawas yang perlu bekerja untuk IE10 + (Tidak memuat modul ES6, dll).
Namun, saya mulai mengembangkan aplikasi Bereaksi yang akan menggunakan ES6 dan TypeScript dan saya ingin menggunakan kembali kode yang sudah saya miliki tanpa menduplikasi file. Setelah sedikit riset, saya menemukan bahwa saya ingin menggunakan pola UMD untuk memungkinkan file-file perpustakaan ini berfungsi baik sebagai <script src=*>
impor dan untuk memungkinkan aplikasi React untuk mengimpornya melalui pemuatan modul ES6.
Saya datang dengan konversi berikut:
var Utils = (function(){
var self = {
MyFunction: function(){
console.log("MyFunction");
}
};
return self;
})();
untuk
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.Utils = {})));
}(this, (function (exports) {
exports.MyFunction = function(){
console.log("MyFunction");
};
})));
Ini akan memungkinkan pemuatan melalui Import Utils from './Utils.js'
perintah dan juga memungkinkannya untuk dimasukkan menggunakan tag skrip<script src='Utils.js'></script>
Namun, beberapa IIFE saya menggunakan IIFE lain sebagai ketergantungan (buruk yang saya tahu tetapi kenyataan).
var Utils = Utils; // Used to indicate that there is dependency on Utils
var RandomHelper = (function(){
var self = {
DoThing: function(){
Utils.MyFunction();
}
};
return self;
})();
Jika diubah dengan benar RandomHelper
dan Utils
menjadi file yang dapat diimpor, aplikasi Bereaksi tidak kompatibel dengan teknik ini. Melakukan secara sederhana
Import Utils from './Utils.js'
Import RandomHelper from './RandomHelper.js'
tidak berfungsi karena saya percaya Utils tidak dilingkupi jendela. Ini akan memuat tanpa masalah tetapi RandomHelper.DoThing()
akan melemparkan bahwa Utils tidak didefinisikan.
Di aplikasi lawas
<script src='Utils.js'></script>
<script src='RandomHelper.js'></script>
bekerja dengan sempurna.
Bagaimana saya bisa membuat RandomHelper dapat menggunakan Utils dalam aplikasi Bereaksi, menjaganya agar tetap kompatibel dengan IE dan ES5 tetapi masih berfungsi sebagai reaksi. Mungkin entah bagaimana mengatur variabel jendela / global?
PS: Saya mengerti inti dari pemuatan modul ES6 adalah untuk menangani dependensi dan IIFE saya saat ini tidak ideal. Saya berencana untuk akhirnya beralih kelas es6 dan kontrol ketergantungan yang lebih baik tetapi untuk sekarang saya ingin menggunakan whats yang tersedia tanpa menulis ulang
sumber
Jawaban:
Mari kita selesaikan dulu, fitur modul, jika tidak diekspor secara eksplisit, dicakup secara pribadi ke modul yang menentukan . Anda tidak dapat menyiasati fakta ini. Tetapi ada beberapa opsi penyelesaian yang dapat Anda pertimbangkan.
1. Dengan asumsi modifikasi kode legacy yang minimal dapat diterima
Cara mengatasinya dengan perubahan minimal pada kode lawas Anda adalah dengan hanya menambahkan
Utils
danRandomHelper
kewindow
objek. Misalnya, ubahvar Utils = (...)();
kewindow.Utils = (...)();
. Akibatnya, objek akan dapat diakses dari objek global dengan kode legacy (dimuat viaimport
) dan basis kode yang lebih baru.2. Dengan asumsi sama sekali tidak ada modifikasi dalam kode warisan dapat ditoleransi
Modul ES6 baru harus dibuat sebagai proksi untuk memuat skrip lawas:
Akhirnya, Anda dapat mengimpor
Utils
danRandomHelper
darilegacy-main.js
saat diperlukan:sumber
Salah satu pendekatan yang dapat Anda pertimbangkan adalah beberapa bentuk injeksi ketergantungan : minta aplikasi Bereaksi Anda menerima RandomHelper, atau beberapa propertinya, dari dunia luar. Kemudian Anda bisa melepasnya saat Anda siap memotong kabelnya.
sumber