javascript - Konvertera closure till ES6-modul
Jag använder en JavaScript-byggmiljö som stöder ES6-moduler (med es6-module-transpiler), så du kan helt enkelt importera saker mellan olika filer.
Nu har jag ett tredjepartsbibliotek som jag skulle vilja kunna "importera".
Biblioteket fyller sitt funktionalitet på detta sätt:
(function () {/*...*/}).call(this);
Skulle det vara säkert att utelämna stängningen och omvandla det till:
export default function () {/* ... */};
Eller finns det ett bättre sätt?
Tack i förväg!
Svar #1
Den ursprungliga koden du visar anropar den anonyma funktionen, som för att ha någon mening måste definiera en global variabel, medan den andra kodfragmentet du visar bara exporterar funktionen, vilket är en annan sak.
För diskussionsändamål, låt oss anta att den ursprungliga koden definierar en global variabel på detta sätt:
// my-third-party-module.js
(function() {
let myVar = 22;
window.MyThirdPartyModule = { log: function() { console.log(myVar); } };
}.call(this);
och du använder den så här:
// app.js
MyThirdPartyModule.log();
Du skulle kunna skriva om detta som
// my-third-party-module.js
let myVar = 22;
export default { log: function() { console.log(myVar); } };
// app.js
import MyThirdPartyModule from `my-third-party-module';
MyThirdPartyModule.log();
Observera att vi har flyttat variabeln myVar som var lokal för den anonyma funktionen till den översta modullnivån.
Men beroende på dina preferenser, istället för att exportera ett stort objekt, vilket är en typ av för-modul-tänkande, kanske du vill exportera dess API:er individuellt:
// my-third-party-module.js
let myVar = 22;
export function log { console.log(myVar); }
// app.js
import {log} from `my-third-party-module';
log();
eller om du föredrar
// app.js
import * as MyThirdPartyModule from `my-third-party-module';
MyThirdPartyModule.log();
Men alla dessa tillvägagångssätt förutsätter att du kan och är villig att redigera källkoden för det tredjepartsbiblioteket. Om det inte är fallet, kan du skriva en liten bit limkod, såsom
// my-third-party-module-interface.js
import 'my-third-party-module'; // This will run the module.
export default MyThirdPartyModule; // Export the global it defined.
// app.js
import MyThirdPartyModule from 'my-third-party-module-interface';
Om du återigen skulle föredra att exportera individuella API:er, kan du utöka klisterlaget för att återexportera var och en av dem:
// my-third-party-module-interface.js
import 'my-third-party-module'; // This will run the module.
const {log, otherAPI, ...} = MyThirdPartyModule;
export {log, otherAPI, ...};
// app.js
import {log} from 'my-third-party-module-interface';
Svar #2
Konverteringen av äldre beroenden är fortfarande ett problem. Och det hemska arbetsflödet de använder gör saker mycket svårare, genom att prefixa den faktiska koden med browserify- och webpack-löjligheter.
Så vad ska man göra? Existentiellt sett garanterar biblioteket endast att sätta in en global i fönstret, men på obskyra och konstiga sätt. Och alla är något olika.
Så låt arvet helt enkelt göra vad det är tänkt att göra för dig, men inpackat i en modul så att du kan importera det istället för att använda en script-tagg:
https://medium.com/@backspaces/es6-modules-part-2-libs-wrap-em-up-8715e116d690
