Programavimas

Koduokite „JavaScript“ išmaniuoju, moduliniu būdu

Kai kurie žmonės vis dar atrodo nustebę, kad „JavaScript“ yra laikoma garbinga, užaugusia rimtų programų programavimo kalba. Tiesą sakant, „JavaScript“ kūrimas jau daugelį metų bręsta, o pavyzdys yra geriausia modulių kūrimo praktika.

Modulinio kodo rašymo pranašumai yra gerai dokumentuoti: didesnis palaikomumas, vengiant monolitinių failų ir kodo atsiejimas iš vienetų, kuriuos galima tinkamai išbandyti. Tiems iš jūsų, kurie norėtų greitai susigaudyti, pateikiame įprastas šiuolaikinių „JavaScript“ kūrėjų praktikas rašant modulinį kodą.

Modulio modelis

Pradėkime nuo pagrindinio dizaino modelio, vadinamo modulio modeliu. Kaip galite įtarti, tai leidžia mums rašyti kodą moduliniu būdu, leidžiant mums apsaugoti nurodytų modulių vykdymo kontekstą ir visame pasaulyje atskleisti tik tai, ką norime atskleisti. Šablonas atrodo maždaug taip:

(funkcija(){

// 'privatus' kintamasis

var orderId = 123;

// atskleisti metodus ir kintamuosius, juos pridedant

// į visuotinį objektą

window.orderModule = {

getOrderId: funkcija () {

// atnešė jums uždarymai

grąžinimo orderId;

}

};

})()

Anonimasfunkcija išraiška, veikianti kaip fabrikas šiuo atveju, parašoma ir nedelsiant paskambinama. Dėl greičio galite aiškiai perduoti kintamuosiusfunkcija skambinti, efektyviai susiejant tuos kintamuosius su vietine apimtimi. Kartais tai pamatysite kaip gynybinį manevrą bibliotekose, palaikančiose senas naršykles, kuriose tam tikros vertės (pvz.,neapibrėžtas) yra rašytinės savybės.

(funkcija (visuotinė, neapibrėžta) {

// kodas čia gali greitai pasiekti visuotinį objektą,

// ir „undefined“ tikrai bus „neapibrėžta“

// PASTABA: Šiuolaikinėse naršyklėse „undefined“ negalima rašyti,

// bet verta to nepamiršti

// rašant senų naršyklių kodą.

}) (tai)

Tai tik dizaino modelis. Naudojant šią techniką, norint rašyti modulinę „JavaScript“, nereikia įtraukti papildomų bibliotekų. Priklausomybių trūkumas yra didelis pliusas (arba kritinė misija) kai kuriuose nustatymuose, ypač jei rašote biblioteką. Pamatysite, kad dauguma populiarių bibliotekų naudos šį modelį, kad apjungtų vidines funkcijas ir kintamuosius, atskleisdami tik tai, kas būtina.

Tačiau jei rašote programą, yra keletas šio požiūrio trūkumų. Tarkime, kad sukuriate modulį, kuriame nustatomi keli metodailangas.pasakymai. Jei norite naudoti tuos metodus kitose programos dalyse, prieš paskambindami turite įsitikinti, kad modulis yra įtrauktas. Tada kode, į kurį skambinatelangas.orders.getOrderId, tu parašai kodą ir tikiesi, kad kitas scenarijus buvo įkeltas.

Atrodo, kad tai nėra pasaulio pabaiga, tačiau tai gali greitai tapti sudėtingų projektų nekontroliuojama, o scenarijų įtraukimo tvarkos valdymas tampa kančia. Be to, visi failai turi būti sinchroniškai įkeliami, kitaip pakviesite varžybų sąlygas, kad sugadintumėte savo kodą. Jei tik būtų būdas aiškiai deklaruoti modulius, kuriuos norite naudoti tam tikram kodo bitui ...

AMD (asinchroninio modulio apibrėžimas)

AMD atsirado dėl poreikio nurodyti aiškias priklausomybes, vengiant sinchroniško visų scenarijų įkėlimo. Tai lengva naudoti naršyklėje, bet nėra gimtoji, todėl turite įtraukti biblioteką, kuri įkelia scenarijus, pvz., „RequireJS“ arba „curl.js“. Štai kaip atrodo modulio apibrėžimas naudojant AMD:

// libs / order-module.js

apibrėžti (funkcija () {

// 'privatus' kintamasis

var orderId = 123;

// atskleiskite metodus ir kintamuosius juos grąžindami

grįžti {

getOrderId: funkcija () {

grąžinimo orderId;

}

});

Tai panašu į tai, su kuo susidūrėme anksčiau, išskyrus tai, kad užuot iškart iškvietę savo gamyklos funkciją, mes perduodame kaip argumentąapibrėžti. Tikroji magija prasideda, kai vėliau norite naudoti modulį:

define (['libs / order-module'], function (orderModule) {

orderModule.getOrderId (); // vertina iki 123

});

Pirmasis argumentasapibrėžti dabar yra priklausomybių masyvas, kuris gali būti savavališkai ilgas, o gamyklos funkcija pateikia oficialius tų priklausomybių parametrus, kurie bus prie jo prijungti. Dabar kai kurios jums reikalingos priklausomybės gali turėti atskiras priklausomybes, tačiau naudojant AMD nereikia to žinoti:

// src / utils.js

apibrėžti (['libs / pabraukimas'], funkcija (_) {

grįžti {

moduleId: „foo“,

_ : _

});

// src / myapp.js

apibrėžti ([

„libs / jquery“,

„libs / vairas“,

„src / utils“

], funkcija ($, vairas, įrankiai) {

// Naudokite kiekvieną iš nurodytų priklausomybių be

// neramu, ar jie ten, ar ne.

$ („div“). addClass („juosta“);

// Taip pat buvo pasirūpinta antrinėmis priklausomybėmis

Naudoja ._. Klavišus (langas);

});

Tai puikus būdas sukurti modulinę „JavaScript“, kai reikia spręsti daugybę judančių dalių ir priklausomybių. Atsakomybė už scenarijų užsakymą ir įtraukimą dabar tenka scenarijaus krautuvo pečiams, paliekant jums galimybę paprasčiausiai pasakyti, ko jums reikia, ir pradėti juo naudotis.

Kita vertus, yra keletas galimų problemų. Pirma, jūs turite papildomą biblioteką, kurią norite įtraukti ir išmokti naudotis. Neturiu patirties su curl.js, bet „RequireJS“ apima mokymąsi, kaip nustatyti jūsų projekto konfigūraciją. Tai užtruks kelias valandas, kol susipažinsite su nustatymais, o po to pradinės konfigūracijos rašymas turėtų užtrukti kelias minutes. Be to, modulių apibrėžimai gali ilgėti, jei jie sukurs priklausomybių krūvą. Štai pavyzdys, paimtas iš šios problemos paaiškinimo „RequireJS“ dokumentuose:

// Iš RequireJS dokumentacijos:

// //requirejs.org/docs/whyamd.html#sugar

apibrėžti ([„reikalauti“, „jquery“, „ašmenys / objektas“, „ašmenys / fn“, „rdapi“,

„oauth“, „blade / jig“, „blade / url“, „išsiuntimas“, „sąskaitos“,

„saugykla“, „paslaugos“, „valdikliai /„ AccountPanel ““, „valdikliai /„ TabButton ““,

"valdikliai / AddAccount", "mažiau", "osTheme", "jquery-ui-1.8.7.min",

"jquery.textOverflow"],

funkcija (reikalauti, $, objektas, fn, rdapi,

oauth, jig, url, išsiuntimas, sąskaitos,

saugykla, paslaugos, „AccountPanel“, „TabButton“,

AddAccount, less, osTheme) {

});

Oi! „RequireJS“ pateikia tam tikrą sintaksinį cukrų, kuris yra gana panašus į kitą populiarią modulinio kūrimo API „CommonJS“.

CJS („CommonJS“)

Jei kada nors parašėte serverio „JavaScript“ naudodami „Node.js“, naudojote „CommonJS“ modulius. Kiekvienas jūsų parašytas failas nėra įpakuotas įmantrumu, tačiau turi prieigą prie vadinamojo kintamojoeksportas kuriam galite priskirti viską, ko norite, kad modulis veiktų. Štai kaip tai atrodo:

// „privatus“ kintamasis

var orderId = 123;

export.getOrderId = funkcija () {

grąžinimo orderId;

};

Tada, kai norite naudoti modulį, paskelbiate jį tiesioginiu:

// orderModule gauna „eksporto“ vertę

var orderModule = reikalauti ('./ order-module');

orderModule.getOrderId (); // vertina iki 123

Sintaksiniu požiūriu tai man visada atrodė geriau, daugiausia dėl to, kad tai nereiškia, kad kitose mūsų aptariamose parinktyse yra švaistomas įdubimas. Kita vertus, jis labai skiriasi nuo kitų tuo, kad yra skirtas sinchroniniam priklausomybių pakrovimui. Tai logiškiau serveryje, bet tai nebus daroma iš priekio. Sinchroninis priklausomybės įkėlimas reiškia ilgesnį puslapio įkėlimo laiką, o tai nepriimtina žiniatinkliui. Nors CJS yra neabejotinai mano mėgstamiausios modulio sintaksė, turiu ją naudoti tik serveryje (ir rašydama mobilias programas naudodama „Appcelerator“ „Titanium Studio“).

Vienas valdyti juos visus

Dabartinis šeštojo „ECMAScript“ leidimo (ES6) projektas, specifikacija, iš kurios įdiegta „JavaScript“, papildo savąją modulių palaikymą. Specifikacija vis dar yra juodraščio forma, tačiau verta pažvelgti į tai, kokia ateityje gali atrodyti modulinė plėtra. ES6 specifikacijose (dar vadinamose „Harmony“) naudojama nemažai naujų raktinių žodžių, iš kurių keli naudojami su moduliais:

// libs / order-module.js

var orderId = 123;

eksportuoti var getOrderId = funkcija () {

grąžinimo orderId;

};

Vėliau galite paskambinti keliais būdais:

importuoti {getOrderId} iš „libs / order-module“;

getOrderId ();

Aukščiau galite pasirinkti, kurį modulio eksportą norite susieti su vietiniais kintamaisiais. Arba galite importuoti visą modulį taip, lyg jis būtų objektas (panašus įeksportas objektas CJS moduliuose):

importuoti „libs / order-module“ kaip orderModule;

orderModule.getOrderId ();

ES6 modulių yra daug daugiau (daugiau rasite Dr. Axelio Rauschmererio tinklaraštyje „2ality“), tačiau pavyzdys turėtų parodyti keletą dalykų. Pirma, mes turime sintaksę, panašią į CJS modulius, o tai reiškia, kad papildomos įtraukos niekur negalima rasti, nors taip nėra visada, kaip rasite aukščiau esančioje nuorodoje „2ality“. Kas nėra akivaizdu žiūrint į pavyzdį, ypač todėl, kad jis panašus į CJS, yra tai, kad importo sakinyje išvardyti moduliai įkeliami asinchroniškai.

Galutinis rezultatas yra lengvai skaitoma CJS sintaksė, susimaišiusi su asinchronišku AMD pobūdžiu. Deja, praeis šiek tiek laiko, kol jie bus visiškai palaikomi visose dažniausiai taikomose naršyklėse. Be to, „kurį laiką“ vis trumpėjo, nes naršyklių pardavėjai sugriežtino savo išleidimo ciklus.

Šiandien šių įrankių derinys yra kelias, kai reikia kurti modulinę „JavaScript“. Viskas priklauso nuo to, ką darai. Jei rašote biblioteką, naudokite modulio dizaino modelį. Jei kuriate naršyklės programas, naudokite AMD modulius su scenarijų krautuvu. Jei esate serveryje, pasinaudokite CJS modulių pranašumais. Galų gale, žinoma, ES6 bus palaikomas visoje erdvėje - tada jūs galite padaryti ES6 būdus, o likusius atsisakyti!

Turite klausimų ar minčių? Nedvejodami palikite komentarų skiltyje pateiktą žinutę arba susisiekite su manimi „Twitter“, @ freethejazz.

$config[zx-auto] not found$config[zx-overlay] not found