Jak vytvořit a publikovat modul Úhlové

Když jsem vytvořil lokální úložiště úhlové asynchronní, bylo snadné vytvořit modul úhlové a použít jej přímo v mé aplikaci. Ale protože to mohlo pomoci jiným vývojářům, chtěl jsem, aby to byl opakovaně použitelný modul, zabalený a spotřebovaný jako jakékoli jiné úhlové moduly.

S touto stavební částí jsem bojoval. Našel jsem téměř žádnou dokumentaci o tom, tak jsem se pokusil zkopírovat, jak funguje oficiální modul Http. Nyní je to hotovo, sdílím své zkušenosti s tím, jak sestavit a publikovat modul Angular.

Tento příspěvek je určen zkušeným vývojářům, kteří již znají základní pojmy Angular a jak vytvořit základní aplikaci. Francouzská verze tohoto příspěvku je k dispozici zde.

Aktualizace: Úhlová 6

Tento příspěvek již není relevantní. U Angular 6 je vytvoření Angular knihovny stejně jednoduché jako název knihovny ng g. Viz oficiální dokumentace CLI.

Od stejného autora

  • Rozšíření úhlových schémat pro VS kód: GUI pro úhlové příkazy CLI
  • @ ngx-pwa / local-storage: 1. Úhlová knihovna pro místní úložiště
  • Další úhlové knihovny: @ ngx-pwa / offline & @ ngx-pwa / ngsw-schema
  • Další populární úhlové příspěvky na médiu
  • Sleduj mě na Twitteru
  • Úhlová školení na místě (se sídlem v Paříži, takže web je ve francouzštině, ale moje anglické bio je zde a jsem otevřený cestování)

Vytvoření modulu Angular: úskalí

Tato část je zcela stejná jako vytvoření modulu v aplikaci: importujte potřebné moduly, deklarujte komponenty, direktivy nebo potrubí nebo poskytujte některé služby. Existuje jen několik bodů, které je třeba si uvědomit.

Za prvé, nikdy neimportujte BrowserModule. Váš modul je modul funkcí, pouze koncový uživatel by měl importovat modul BrowserModule do kořenového modulu aplikace. Pokud potřebujete společné směrnice (* ngIf, * ngFor…), importujte CommonModule.

Pokud se váš modul týká vytváření nových komponent, direktiv nebo potrubí, nezapomeňte je exportovat. Deklarované jsou přístupné pouze uvnitř vašeho modulu.

A co je nejdůležitější, nemíchejte komponenty / směrnice / potrubí a služby ve stejném modulu. Proč?

  • Služba poskytovaná v modulu bude k dispozici všude v aplikaci, takže váš modul by měl být importován pouze jednou v uživatelském kořenovém modulu aplikace (jako je modul Http).
  • Exportovaná komponenta / směrnice / potrubí bude k dispozici pouze v modulu importujícím váš, takže váš modul by měl být importován do každého uživatelského modulu (kořenové a / nebo funkční moduly), který je potřebuje (jako je CommonModule).

Pokud to pro vás není jasné, měli byste můj další příspěvek „Porozumění modulům úhlové (NgModule) a jejich rozsahům“, protože je to důležitý (a matoucí) bod v Angular.

Nakonec respektujte Angular pravidlo: nikdy nepoužívejte přímo API specifická pro prohlížeče (jako DOM). Pokud tak učiníte, váš modul nebude kompatibilní s vykreslením Universal serveru a dalšími pokročilými možnostmi Angular. Pokud opravdu potřebujete používat API specifická pro prohlížeč (localStorage…), měli byste zkusit / zachytit chyby.

Export veřejného API

Pokud používáte oficiální modul Angular, máte pouze jeden vstupní bod k importu všeho, co potřebujete (například „@ angular / http“).

Budete tedy muset vytvořit soubor index.ts a exportovat všechna veřejná rozhraní API vašeho modulu. Měl by obsahovat alespoň váš NgModule a vaše komponenty nebo služby (uživatel je bude muset importovat, aby je mohl vložit tam, kde jsou potřeba).

Komponenty / směrnice / roury nebudou importovány přímo uživatelem, ale musíte je exportovat, aby byly kompatibilní s AoT (díky této informaci Isaaca Manna).

Vytvářejte nástroje

Tam jsem začal bojovat. Podařilo se mi tedy zkopírovat, jak fungují oficiální moduly Angular, jako je HttpModule. Používají:

  • strojopis, pomocí úhlového kompilátoru (ngc), pro převádění,
  • rollupjs pro balení,
  • uglify-js pro minifikaci.
npm install @ angular / compiler @ angular / compiler-cli strojopis kumulativní uglify-js --save-dev

Konfigurace TypeScript

Tady je tsconfig.json mého modulu:

S vaším klasickým souborem tsconfig.json existují některé důležité rozdíly:

  • jsou potřeba explicitní „cesty“ k jiným modulům, které používáte, protože finální balíček je přímo nezahrnuje (více o tom později).
  • "angularCompilerOptions": {"strictMetadataEmit": true} musí být kompatibilní s AoT.
  • "prohlášení": true je důležité pro generování souborů s definicemi typů, takže uživatel bude mít pro váš modul Intellisense.
  • "noImplicitAny": true a "strictNullChecks": true se doporučuje, aby se zabránilo chybám a byly kompatibilní se všemi uživatelskými konfiguracemi. "noImplicitAny": true musí být respektováno od Angular 4.0 a "strictNullChecks": true od Angular 4.1.
  • "module": "es2015" je důležitý pro výkon a "sourceMap": true pro ladění, ale zde není nic konkrétního.
  • „stripInternal“: true se vyhněte zbytečným deklaracím pro interní API a „skipLibCheck“: true se vyhýbejte blokování (neškodnými) chybami v librairiích, které používáte.

Souhrnná konfigurace

Úhlové moduly jsou dodávány ve formátu UMD, takže by měl být nastaven váš rollup.config.js. Zde je příklad:

Vstupní skript je váš transpilovaný index.ts, takže by měl odpovídat vaší konfiguraci TypeScript. bundles / modulename.umd.js je konvenční cesta a název používaný Angular moduly.

Souhrn vyžaduje název modulu pro formát UMD. Bude to objekt JavaScript, proto nepoužívejte speciální znaky (žádné pomlčky).

Pak nastane důležitý bod. Váš modul používá úhlové věci (přinejmenším dekoratér NgModule), ale váš balíček by neměl zahrnovat Angular.

Proč? Úhel bude již součástí uživatelské aplikace. Pokud jej váš modul také obsahuje, bude tam dvakrát a budou existovat fatální (a nepochopitelné) chyby.

Musíte tedy nastavit Angular jako globální. A potřebujete znát název modulu UMD pro každý modul. Z toho vyplývá tato konvence: ng.modulename (ng.core, ng.common, ng.http ...).

Totéž platí pro RxJS, pokud jej váš modul používá. A názvy modulů jsou zde docela nepořádek. Pro třídy (pozorovatelné ...) je to Rx. Pro operátory (mapa, filtr…) je to Rx.Observable.prototype. Pro přímé metody tříd (z, odEvent ...) je to Rx.Observable.

Budování, konečně

Nyní můžete sestavit balíček modulů. Příkazové řádky můžete ukládat do skriptů npm:

Pak:

npm run build

Pamatujte, že převádění neprobíhá přímo TypeScript, měli byste použít kompilátor Angular (ngc): je to TypeScript s nějakou další kouzelnou kouzelnou čarou.

Publikování v npm

Nezveřejňujte vše na npm, pouze dist adresář.

Budete muset vytvořit nový a specifický dist / package.json. Například :

Některé konkrétní body:

  • "version" musí následovat sémantické verzování. Jakákoli zlomová změna znamená velký přírůstek čísla (i když je to malá změna). A když upravíte svůj modul tak, aby zůstal v aktuálním stavu s Angular, je to menší přírůstek čísla.
  • Pro import uživatelů jsou potřeba cesty „hlavní“ a „modul“. Cesta „typing“ je určena pro Intellisense.
  • "licence": "MIT": open-source licence je důležitá, nebo váš modul je k ničemu. Angular používá licenci MIT a měli byste se jí držet.
  • Úhlové moduly, které jste použili, budou uvedeny v seznamu vzájemných závislostí. Stále sledujte semver, se znaménkem ^, nebo váš modul bude zastaralý pokaždé, když se Angular upgraduje. U ostatních knihoven (RxJS, zone.js…) můžete vidět aktuální požadavky Angular zde.

Nezapomeňte napsat README s dokumentací vašeho API. Jinak je váš modul k ničemu. Knihovnu jako copyfiles můžete použít ke zkopírování README z kořenového adresáře projektu (zobrazeného v Githubu) do vašeho dist adresáře (zobrazeného v npm repozitáři).

A s nakonfigurovaným účtem npm nyní můžete modul publikovat:

CD dist
npm publikovat

A kdykoli budete potřebovat aktualizovat svůj modul, stačí znovu sestavit, změnit číslo verze, aktualizovat changelog a znovu publikovat.