Rozhovor s Johnem Hannem, tvůrcem curl.js

Ve světě JavaScriptu je John Hann jedním z B.A.M.F. Jeho obvyklá rukojeť je nespisovatelná, ale to by mělo být to poslední, co by se mu mělo říkat. John vytvořil a přispěl k mnoha neuvěřitelným JavaScript nástrojům – jednoduše se podívejte na jeho stránku GitHub. Tento blog používá John's curljs, neuvěřitelně účinný a flexibilní zavaděč JavaScriptu. Chtěl jsem udělat rozhovor s Johnem o vytvoření nakladače:úskalí, rozdíly v prohlížečích a co ho čeká do budoucna.

Ahoj Johne! Pro ty, kteří vás neznají, dejte nám rychlý úvod a dejte nám vědět, na čem pracujete.

Ahoj, já jsem John. John Hann. "@unscriptable" na většině interwebů. Javascript píšu od roku 1995. Jako mnoho jiných jsem nebyl zpočátku nadšený. V roce 2005 jsem s ním byl natolik pohodlný, že jsem začal oceňovat jeho dobré části a začal jsem v něm výhradně kódovat.

Ha! Kolem toho je dobrý příběh. Udělám to rychle. V té době jsem vedl butikovou společnost zabývající se vývojem softwaru. V roce 2001 jsme měli 12 zaměstnanců na vrcholu, ale v roce 2005 se jejich počet snížil na 5. Internetová bublina:znáte to. Každopádně jsem svým zaměstnancům oznámil, že Javascript je cesta budoucnosti.

Hmmm. nech mě na chvíli zpátky. Měl bych zmínit, že jsem často předpovídal trendy vývoje softwaru a měl jsem obvykle pravdu. Například v den, kdy jsem slyšel o C#, jsem předpověděl, že zastíní všechny ostatní jazyky Microsoftu, a řekl jsem všem svým zaměstnancům, že se to potřebují naučit *teď*. Všichni vyhověli a byli jsme dlouhodobě velmi žádaný.

Když jsem však předpověděl, že další velkou věcí bude Javascript, všichni – do posledního z nich – pokrčili rameny a nesouhlasili. Prodal jsem společnost a nikdy jsem se neohlédl.

Každopádně do roku 2008 jsem napsal tři slušné Javascriptové frameworky od nuly pro různé soukromé projekty a byl jsem podrážděný, že většina průmyslu stále dělá věci, které jsem považoval za archaické. Nakonec jsem se v roce 2010 rozhodl přejít na open source. Tehdy vznikl cujo.js.

Začal jsem strukturováním cujo.js jako aplikačního rámce nad dojo. To vypadalo jako nejlepší způsob, jak začít:postavit se na ramena obrů. Zároveň jsem měl pocit, že necílím na tu správnou komunitu. Koneckonců, byli to lidé zaměření na jQuery, kteří potřebovali nejvíce vedení.

Náhodou jsem zjistil, že jeden z kolegů, kterého jsem nejvíce obdivoval, si také pohrával s podobnými nápady. Z diskuzí s Brianem Cavalierem později v roce 2010 jsme zjistili, že vůbec nechceme vytvářet další framework. Chtěli jsme vybudovat „architektonický rámec“ – kolekci architektonických nástrojů, které mohou fungovat společně nebo jako jednotlivé knihovny. Ještě důležitější je, že tyto nástroje musí fungovat i s dalšími populárními knihovnami.

cujo.js, jak ho známe dnes, ožil v roce 2011. To dělám teď. Pracuji s Brianem a některými dalšími pracovníky na částečný úvazek, aby byl cujo.js každý den úžasnější. Stále častěji to také dělám ve své každodenní práci ve SpringSource. Jsou tou nejlepší společností, se kterou jsem doposud spolupracoval.

O víkendech rád stavím věci se svými dětmi a zveřejňuji obrázky výsledků na Flickr.

Jste známým zastáncem formátu AMD. Co vedlo k vaší lásce k AMD? Proč je AMD nejlepší formát pro psaní JavaScriptu?

AMD jsem si zamiloval, když jsem si uvědomil, že je to první formát modulu Javascript, který není vázán na konkrétní knihovnu nebo společnost. Open source FTW!

Vážně. Oblíbil jsem si dojo.require(), ale opravdu jsem si přál, aby můj kód nebyl zapleten do dojo. dojo bylo – a stále je – jedním z nejúžasnějších frameworků Javascript, ale prostě mi nepřipadalo správné, že s ním byl můj kód neoddělitelně svázán. AMD byl první modulový formát – a jediný modulový formát v té době – který nezapletl můj kód s frameworkem.

Zde se budu věnovat tangentě, ale myslím, že je důležité zmínit:Javascript je komunita fanboyů. Neexistuje mnoho standardů, žádné univerzální best practices, žádné de facto frameworky na vysoké úrovni jako Java nebo C#. Nemáme jinou možnost, než se shromáždit kolem naší oblíbené knihovny nebo frameworku.

Navíc nejsme příliš vzdělaní. Mnoho z nás nemá diplomy z informatiky. Nemáme ani inženýrské vzdělání. Jsme jen hackeři, kteří milují to, co děláme. Takže když se objeví něco mocného, ​​a přesto jednoduchého a najednou nám to vybuchne z hlavy, PROSTĚ TO K SMRTI LÍBÍME.

AMD to udělalo za mě. Myšlenka, že bych mohl napsat modulární kód, který by byl zcela nezávislý na jakémkoli frameworku, ze mě okamžitě udělala fanouška.

Proč je tedy AMD nejlepším formátem pro Javascript? Hmm... Myslím, že jde o toto:je to nejjednodušší formát, který jsem viděl a který nevyžaduje krok sestavení. Byl navržen pro prohlížeče. S AMD můžete začít tím, že si stáhnete AMD loader a napíšete nějaký kód. Stiskněte F5 nebo Cmd-R a uvidíte načtení prvního modulu.

Když jste vytvořili curl.js, byly k dispozici další zavaděče. Jaká byla vaše inspirace při vytváření curl.js?

Heh. Dobře, tak jsem trochu soutěživý. Ne vyloženě, ale rozhodně konkurenceschopně. Když jsem poprvé vyzkoušel RequireJS, myslel jsem si, že je to opravdu skvělé, ale proč to bylo tak velké???? V té době byl RequireJS také dost nestabilní. Raději bych se spoléhal na svůj vlastní chybový kód než na kód někoho jiného, ​​protože rozumím tomu, jak opravit svůj vlastní kód.

Myslel jsem, že bych mohl vytvořit zavaděč AMD, který by byl menší a rychlejší. Ukázalo se, že jsem měl pravdu.

Abychom byli spravedliví, RequireJS má v sobě nějaký starší kód. To přidává trochu nadýmání. Mohl jsem začít od nuly. První verze curl.js měla asi 3,5 kB gzip, když RequireJS mělo asi 6 kB. RequireJS měl samozřejmě mnohem více funkcí.

Ale malá velikost curl.js mě motivovala. Byl jsem tím posedlý. Slíbil jsem, že to nikdy nenechám zvětšit. Dnes má stále kolem 3,5 KB a má podobnou sadu funkcí jako RequireJS.

Abychom byli spravedliví, RequireJS se nyní zdá velmi stabilní a má úžasnou testovací sadu.

Také mě napadlo, že je potřeba více implementací standardu, aby mohl být skutečně považován za standard. Cítil jsem, že AMD potřebuje být větší než jen RequireJS, aby se dalo brát vážně.

S jakými problémy jste se setkali při zahájení vývoje na curl.js? S jakými problémy jste nepočítali a jak jste je vyřešili?

CommonJS. Naprosto jsem nevěděl, co to sakra dělám, a nevěděl jsem *nic* o modulech CommonJS - nebo balíčcích - až do nedávné doby. Také:konfigurace. Stále nemohu uvěřit, kolik bajtů curl.js je spotřebováno při snaze zvládnout všechny způsoby, kterými mohou uživatelé nakonfigurovat curl.js. Teď už vím, proč lidé píší nepřátelská, nekonfigurovatelná API!

Ach. Předpokládám, že se pravděpodobně ptáte, na jaké překážky v prohlížeči jsem narazil? Páni! Spousty. Prohlížeče opravdu nestandardizovaly chování při načítání skriptů až do tohoto roku.

Naštěstí prohlížeče spadají do dvou táborů:IE a všechno ostatní. Počkat, ale pak je tu Opera, která je někde mezi, ale vlastně ani ne.

Trik načítání skriptu je znát přesný okamžik, kdy se skript provedl. V IE můžete zjistit aktuálně spouštěný skript tak, že projdete všechny nedávno vytvořené prvky skriptu a vyhledáte, který z nich má připravený stav „interaktivní“. Opera nás samozřejmě klame a říká, že nějaký zdánlivě náhodný skript je „interaktivní“, takže s tím musíme počítat.

Prohlížeče vyhovující standardům fungují trochu jinak. Zařazují spouštěcí skripty do fronty a spouštějí událost onload každého skriptu ihned *po* provedení. To samozřejmě vyžaduje úplně jiný algoritmus než IE.

Řešení chyb je jiná věc. IE a Opera stále nespouštějí událost onerror, pokud je prvek skriptu 404. Naštěstí můžeme zjistit, zda nebylo zavoláno AMD `define()`, a přesto vyvolat smysluplnou chybu.

Načítání CSS je vážná plechovka červů. curl.js zachází s CSS stejně jako s Javascriptem. Můžete jej načíst (a čekat) stejně jako Javascript. Problém je v tom, že i prohlížeče jako Chrome a Firefox až donedávna neměly adekvátní podporu pro onload a onerror handlery na odkazových prvcích. Kód pro manipulaci s CSS je prostě hrozný. Ale funguje to.

Která část vytváření zavaděče JavaScriptu je jednodušší, než si lidé mohou myslet?

Není to lehké. Nic z toho. Jakmile vytvoříte cokoliv, co zpracovává reálný kód, stane se to složité. Každý webový vývojář na této planetě chce dělat věci *po svém*. Nikdo nikdy nedělá věci úplně jako ten druhý.

Hmm...musí tam být něco, co není příliš složité. Přemýšlím... přemýšlím... Ne. Zapomeň na to. Není jediný řádek kódu, který by mě nestál hodiny testování, kousání nehtů nebo frustrace. Vážně.

Jak velký faktor hraje při vytváření nakladače moderní prohlížeč? Který prohlížeč byl nejjednodušší a který bylo nejobtížnější se přizpůsobit?

Moderní prohlížeče jsou samozřejmě mnohem lepší. Firefox byl zdaleka nejjednodušší. Další jsou Chrome a Safari. IE a Opera stále nepodporují základní zpracování chyb. Ve skutečnosti stále falešně deklarují úspěch, pokud skript 404. Skvělé.

Zdálo se, že Firefox byl vždy pilný ohledně načítání skriptů, dokonce ještě předtím, než se k Mozille přidal Kyle Simpson – kmotr načítání skriptů. Ach... odkaz se také načítá. Byli první, kdo implementoval funkční obslužné rutiny onload a onerror pro prvky skriptu *a*. Byli první, kdo také podporoval atribut async u prvků skriptu. Také se zdálo, že věděli, že pořadí vyhodnocování skriptů a událostí při načítání musí být předvídatelné dlouho před ostatními prohlížeči, pokud si dobře vzpomínám.

curl.js kvůli tomu dokonce funguje v Netscape 7. Hm... v poslední době jsem Netscape 7 netestoval. YMMV.

Výkon je důležitou součástí každé softwarové komponenty. Jaké kroky jste podnikli, aby byl curl.js efektivní a kompaktní?

Jak jsem již zmínil dříve, od prvního dne jsem posedlý velikostí kódu. To znamená, že si myslím, že curl.js potřebuje dietu. Jakmile budou vydány další velké funkce, podívám se na to, abych zjistil, co mohu upravit.

Velikost není jediným problémem. Jsem také posedlý výkonem http. Možná ne tak posedlý jako John-David Dalton (je blázen), ale natolik posedlý, že nepřijme kompromis.

Jedním z rozdílů mezi curl.js a jinými zavaděči, řekněme RequireJS, je to, že curl.js řeší své závislosti synchronně. V produkci, pokud jste správně zřetězili své moduly, rozlišení synchronizace nedělá velký rozdíl. Nicméně během vývoje – kdy je zřetězení zatěžující a zcela zbytečné – může mít průměrné 12ms zpoždění způsobené asynchronním rozlišením obrovský rozdíl. Jednou jsme pracovali na projektu, který měl 300+ modulů. To je 300 požadavků http! Čekali jsme celou věčnost - asi 30 sekund - na načtení aplikace v IE6. Ve skutečnosti bylo rychlejší spustit sestavení skriptu pro zřetězení modulů a poté načíst jeden soubor do IE.

Ahhhh! Právě jsem si vzpomněl. To byl další z důvodů, proč jsem napsal curl.js. RequireJS vypršel a vzdával se. I když jsme nastavili časový limit na 60 sekund, stále by zvracel. Byl jsem si jistý, že dokážeme napsat zavaděč, který nebude plýtvat 12 ms na modul jen tak, že sedí. Netušil jsem, že rozlišení asynchronního modulu je mnohem jednodušší než rozlišení synchronizačního modulu.

Časové limity jsou každopádně problematické. Není možné nastavit časový limit, který by fungoval ve všech prohlížečích a pro každou rychlost připojení. curl.js žádný nepoužívá. curl.js žádný nepotřebuje.

Také:pomalý IE6 je pomalý bez ohledu na to, co na něj hodíte. Pomocí curl.js jsme zkrátili dobu nezřetězeného načítání na polovinu, ale stále to bylo 6krát pomalejší než Firefox a Chrome.

Jak náročná byla implementace slibovaného rozhraní API pro curl.js?

Studna. Jakmile jsem implementoval chování podobné slibům uvnitř curl, nebylo těžké ho implementovat do API. Abychom byli spravedliví, curl.js neimplementuje úplný standard CommonJS Promises/A. Je to jen jako slib. Máme další knihovnu When.js, která je plně kompatibilní a také neuvěřitelně rychlá.

Jak obtížné je rozlišení cesty při vytváření zavaděče, když je možné nastavit aliasy, balíčky a adresy URL externích modulů?

Páni. Načtená otázka. Kde začít. Měl jsem v úmyslu o tom napsat další dokumentaci. Asi nejprve zmíním, že autoři zavaděčů AMD došli k závěru, že je důležité myslet na dvě různé fáze rozlišení adresy URL. Nejprve musíte normalizovat ID modulu. Poté můžete vyřešit adresu URL.

Rozlišení ID vyžaduje několik kroků. Nejprve musíte snížit úvodní tečky. Pokud například požadujete modul, který je o dvě složky výš než aktuální (nadřazený) modul, máte dvě úrovně dvojitých teček, které lze složit do ID nadřazeného modulu. V tuto chvíli už doufejme nemáte žádné tečky na začátku. Pokud máte úvodní tečky, pak je id modulu ve skutečnosti cesta adresy URL, a to je problematické, ale to zatím přeskočím.

Jakmile odstraníte všechny úvodní tečky, můžete provádět transformace ID. curl.js má v současné době dvě transformace ID modulu:1) transformaci ID modulu a 2) transformaci modulu "hlavního" balíčku. Oba tyto typy ID mají zkratkovou notaci. curl zkontroluje, zda modul, který požadujete, je zástupcem zásuvného modulu nebo hlavního modulu, a rozbalí je do dlouhých forem.

Ok, takže jakmile budete mít normalizované id, můžete vyhledat cestu url. curl.js používá velmi rychlý, regulárními výrazy řízený algoritmus, který umožňuje vývojářům vytvářet stále specifičtější transformace adres URL. Curl v podstatě třídí transformovanou adresu URL podle počtu lomítek v ní. Čím více lomítek, tím vyšší priorita. curl.js používá tento algoritmus k prohledávání konfigurace cest, aby zjistil, kam jste modul umístili. Nakonec curl připojí cestu k základní adrese URL a použije ji k načtení modulu.

curl.js je dodáván s mnoha pluginy, které umožňují základní vyžádání XHR, načítání souborů CSS, provádění zpětného volání domReady a další. V podstatě můžete načíst kompletní widget uživatelského rozhraní, například v rámci pole závislostí modulu. Jak obtížné bylo integrovat pluginy a máte další pluginy, které plánujete zahrnout v budoucnu?

James Burke navrhl velmi jednoduché plugin API skládající se z jedné funkce. S malou pomocí Rawlda Gilla ze slávy dojo a mě jsme dokončili kompletní, přesto stále jednoduché, run-time plugin API, které se skládá pouze ze dvou funkcí a vlastnosti. James a Rawld toto API trochu rozšířili, aby vyhovovalo určitým požadavkům. Všechno jsem však dokázal udělat s původním API.

Mezi hlavní případy použití zásuvných modulů patří načítání šablon HTML pomocí zásuvného modulu pro text a načítání lokalizačních souborů pomocí zásuvného modulu i18n. curl.js má také dvě varianty pluginu CSS. Jiní lidé vytvořili zásuvné moduly Coffeescript, zásuvné moduly CommonJS a zásuvné moduly pro další jazyky kompilující do JavaScriptu.

Naším oblíbeným vzorem je – jak jste řekl – vytvoření celé komponenty uživatelského rozhraní v modulu. Javascript, CSS, HTML, lokalizační soubory atd. vše v jedné složce. Spousta lidí nabízí widgety, ale způsob, jakým zacházíte s Javascriptem a CSS, je tak nesourodý. Když můžete společně najít Javascript a CSS, máte skutečně přenosný widget. curl.js to umí tak dobře.

Už máme dobrou sadu pluginů. Myslím, že se v budoucnu soustředíme na transpilátory. Od curl 0.8 budeme mít plnou podporu pro transpilery používající stejné staré plugin API, které používají běžné pluginy. Tento koncept nazýváme „Compile to AMD“ a je docela výkonný. Stačí najít nebo napsat plugin, který transpiluje váš preferovaný jazyk – Coffeescript, Haskell, Sybilant, TypeScript, cokoliv – a řeknete curl.js, že jej chcete použít k převodu sady modulů na AMD. Jiné moduly ve vašem projektu nepotřebují vědět, v jakém jazyce byly napsány jiné moduly. Všechny jsou převedeny na AMD buď za běhu, nebo během sestavení, ale pravděpodobně je nebudete chtít převést v době sestavení pro produkci. kód.

Určitě to vypadá jako budoucnost!

Jaké problémy se objevují z hlediska kódu a logiky při načítání jak asynchronních, tak synchronizovaných souborů v rámci stejného modulu?

Curl nenačte synchronizaci souborů. Měl bych říci, že *AMD* nenačte synchronizaci souborů. Můžete napsat kód, který předpokládá, že soubor bude načten synchronizovaně, ale zavaděč AMD to zjistí a předem načte soubor asynchronně.

Vzhledem k tomu, že AMD bylo napsáno pro prohlížeče, formát AMD vám umožňuje psát kód, jako by byly závislosti dostupné synchronně. Pokud chcete psát ve stylu modulů CommonJS, existuje specifický způsob, jak moduly zabalit, aby to fungovalo. Myslím, že James Burke tomu říká "Simplified CommonJS-wrapped modules". Stačí si to vygooglit a najdete na tom slušné dokumenty.

curl.js má ve skutečnosti způsob, jak načíst moduly CommonJS bez zalamování. Je to „experimentální“ funkce, která předvádí funkce „Compile to AMD“ přicházející ve verzi 0.8. Je to úžasné, protože získáte to nejlepší z obou světů. Říkám tomu „experimentální“, ale dnes to funguje skvěle. Jde jen o to, že se změní nastavení konfigurace.

Jaké problémy představovalo přidání podpory jQuery?

James udělal všechnu práci tím, že přiměl lidi z jQuery, aby podporovali AMD, ale způsob, jakým to implementovali, vyžadoval zavaděč, který řeší moduly asynchronně. curl.js řeší synchronizaci modulů, jak jsem již zmínil. První vydání jQuery s podporou AMD, 1.7, nepočítalo s rozlišením synchronizace. Verze 1.7.2 ano. Všechny následující verze fungují skvěle s curl.

jQuery však dělá něco jiného, ​​​​co vyžaduje zvláštní poznámku. *Jmenují* svůj modul. Definovat příkaz jQuery má v sobě pevně zakódované ID modulu. To umožňuje používat nástroje pro vytváření jiných výrobců ve spojení se zavaděčem AMD. Nemyslím si, že by to někdo ve skutečném světě dělal, ale my si s tím poradíme.

Jediný způsob, jak zpracovat pojmenované moduly, je zadat konfiguraci cesty pro modul. Stručně řečeno, musíte bezpodmínečně zadat mapování cesty pro jQuery v konfiguraci AMD. Podle mého názoru to není velký problém, protože si myslím, že vývojář by měl určit mapování cesty ke každému balíčku nebo knihovně ve své aplikaci. Může to prostě podrazit nováčky.

Máte nějaké malé, ale užitečné úryvky kódu z curl.js, které byste chtěli sdílet? (tj. existují nějaké úryvky detekce okrajových funkcí nebo „hacky“, které by někteří lidé neznali?)

Ach jo. Plugin css je plný hacků a okrajových případů. Myslím, že nejlepší je metoda, kterou používáme, abychom se vyhnuli limitu 31 stylů v IE6-9. Tato metoda také poskytuje podporu onerror, protože prvky odkazu IE normálně nevolají onerror, když je adresa URL 404. Funguje to takto:

Nejprve se vytvoří "sběratelský" list. Tato šablona stylů bude použita ke shromáždění prvních 31 šablon stylů. Do listu kolektoru přidáme obslužnou rutinu onload a onerror a vložíme první požadovanou šablonu stylů jako @import. Sběrný list spustí buď obslužnou rutinu onload nebo onerror, když se importovaný list načte nebo selže. Z nějakého důvodu se v tomto okamžiku obslužná rutina onerror stane nefunkční, takže ji musíme nahradit -- a obslužnou rutinu onload -- než se pokusíme načíst další šablonu stylů.

Neustále vyměňujeme obslužné nástroje a vkládáme @importy, dokud nedosáhneme limitu 31 listů. Při 31 listech vytvoříme nový sběratelský list a začneme počítat do 31 znovu.

Problém s tímto algoritmem je, že dokáže načíst pouze jeden list najednou. Abychom toto omezení obešli, vytváříme až 12 souběžných sběrných listů. Plugin css používá techniku ​​„round robin“, takže lze současně načíst až 12 listů. Protože limit požadavků HTTP IE9 je 12, funguje to dobře.

Pokud se dobře orientujete v sémantice CSS, právě teď vám v hlavě blikají červená světýlka a sirény. Algoritmus kruhové rotace, jako je tento, by jistě pokazil kaskádu CSS. Měli byste pravdu - pokud byste mysleli na chování *normálních prohlížečů*. IE není normální prohlížeč. Na rozdíl od všech ostatních prohlížečů tým IE interpretoval kaskádu odlišně. Rozhodli se, že o preferenci kaskády rozhoduje *časové* pořadí. Všechny ostatní prohlížeče rozhodují o preferenci kaskády podle pořadí *DOM*. Když na svou html stránku vložíte prvky statického odkazu, časové pořadí a pořadí DOM jsou stejné, takže jste si pravděpodobně nikdy nevšimli rozdílu.

Stručně řečeno, protože zajišťujeme, aby se šablony stylů CSS zpracovávaly ve správném časovém pořadí, vše funguje. Starší IE dokáže pomocí tohoto algoritmu načíst až 372 šablon stylů a je to zatraceně rychlé.

Jaké funkce předpokládáte přidání do curl.js v blízké budoucnosti?

No, zmínil jsem funkci "Compile to AMD". To bude horké.

Další hlavní funkcí je funkce „Portable AMD Bundle“. Sesterský projekt curl.js, cram.js, bude schopen zřetězit moduly do větších souborů. Není to nic ohromujícího, pokud jste již obeznámeni s nástrojem pro vytváření RequireJS, r.js. Existuje však několik zvratů. Za prvé, CSS může být také součástí souboru. Za druhé, bude existovat rozumný způsob, jak rozdělit soubory na logické části, které nazýváme „balíčky“. A konečně, soubory by mělo být možné načíst i těmi nejhloupějšími zavaděči AMD, protože budou kompilovány podle nejmenšího společného jmenovatele.

Můžete vzít tyto balíčky a hostit je někde na CDN, publikovat je na githubu nebo je prostě použít ve své vlastní organizaci. Nezáleží na tom, že jste k vytvoření balíčku použili některé super skvělé funkce curl.js, mělo by to fungovat prakticky kdekoli.

Můžete poskytnout nějaké tipy pro snazší ladění s moduly AMD?

Dobrý postřeh. Ladění asynchronního *cokoli* je těžké. ladicí modul curl je užitečný pro protokolování každého modulu při jeho zpracování. Ale je skoro stejně snadné jen sledovat konzoli a síťovou aktivitu. Zde je několik věcí, na které si dát pozor:

  1. Pokud je modul 404, podívejte se na adresu URL, kterou prohlížeč použil. Použili jste příliš mnoho navigací nadřazených cest se dvěma tečkami? Vypadá to, že curl nepoužil mapování cesty? Zkuste modul načíst z konzole zadáním `curl([], console.log.bind(console));` a uvidíte, co se stane.
  2. Pokud curl tiše selže a načítáte javascript jiného výrobce než AMD pomocí pluginu js, zkuste použít funkci `exports=` pluginu js. Tato funkce poskytuje explicitní zpětnou vazbu k chybám ve všech prohlížečích.
  3. Vytvořte testovací svazek a omezte rozsah problému. Sledování desítek asynchronních věcí je šíleně těžké. Omezujte rozsah problému, dokud nebudete mít přehled o tom, co se děje.

Další problémy:

  1. Dávejte pozor, abyste se nepokoušeli použít globální require() omylem. Na rozdíl od prostředí CommonJS neposkytují prostředí AMD automaticky kontextově citlivý require() (také znám jako „místní požadavek“). Globální požadavek nemůže přijít na to, jak najít relativní závislosti, což může vést k vážným WTF momentům. Ve výchozím nastavení curl.js selže brzy a hlasitě, pokud jste náhodou odkazovali na globální požadavek, protože vůbec nedeklaruje globální `require()` (pokud mu to neřeknete). Ujistěte se, že ve svých modulech vždy požadujete místní požadavek a nedeklarujte globální požadavek, pokud si nejste jisti, že se váš projekt nachází v 0,00001 % případů použití, které skutečně vyžadují globální požadavek.
  2. Nedovolte, aby se adresy URL vkradly do vašich ID modulů. Jakmile budete mít adresy URL ve svých ID modulů, vaše možnosti pro přesun souborů se omezí. Situace se zhorší, když zřetězíte soubory do svazků.
  3. Existují dva způsoby, jak se adresy URL vkrádají do ID modulů. O prvním jsem se již zmínil. Stává se to, když se pokusíte dostat na příliš mnoho úrovní.

    define(["../../util/foo"], function (foo) { /* create something epic */ });
    

    Obecně platí, že použití dvojitých teček v kódu aplikace je zápach kódu. Jediný případ, kdy byste kdy měli použít dvojité tečky, je odkazovat na související modul ve stejném balíčku. Vysoce modulární balíčky třetích stran jako dojo, wire.js, poly.js atd. často používají dvojité tečky. Pokud zjistíte, že je používáte ve své webové aplikaci, měli byste zvážit rozdělení aplikace do balíčků. Nemusíte z nich vytvářet legitimní balíčky pomocí package.json; stačí nakonfigurovat zavaděč, aby rozpoznal, že existuje logické uspořádání modulů.

    Vlastně si myslím, že adresy URL obecně jsou problematické. ID modulů jsou flexibilnější a jsou více v souladu se vzory CommonJS a node.js. Myslím, že by to mělo spočívat v tom, že byste měli používat funkce mapování cest a mapování balíčků vašeho zavaděče AMD. Pokud vaše ID modulů vypadají sofistikovaněji než „myFoo“ nebo „myPackage/foo“ – jinými slovy, pokud mají mnoho lomítek nebo dvojitých teček – pravděpodobně si hrajete s nožní zbraní.