typescript - Ako štruktúrovať NPM balík s všeobecnými utilitami
Potrebujem vytvoriť balík NPM pre niektorú bežnú funkcionalitu používanú rôznymi frontendovými projektmi v našej spoločnosti, ale nie som si celkom istý, ako to správne urobiť. Používame Typescript a tsdx sa zdá riešiť niekoľko vecí, s ktorými si nie som istý, ako ich správne spraviť, ale nič sa nezmieňuje o tom, ako štruktúrovať balík typu „utilities“.
Čomu nerozumiem je, na čo by malo "main" v package.json odkazovať, keď neexistuje logický jediný export/trieda/funkcia, ktorá by dávala zmysel v balíku?
Mal by jednoducho exportovať každú jednu „verejnú“ funkciu v celom balíku? A ak áno, ako by to ovplyvnilo tree-shaking (ktorý momentálne až tak dobre nechápem) a podobné veci?
A ak by nemalo, na čo by mal "main" ukazovať a ako by sa mali veci exportovať a importovať? Chcel by som napríklad byť schopný import foobar from '@org/common/category/foobar, ale spôsob, akým sú balíky vytvárané npm, zdá sa, že cestu v balíku často skončí obsahovať dist alebo lib alebo niečo podobné, čo naozaj nechcem.
Ako by mal byť štruktúrovaný "multifunkčný balík NPM", aby boli možné čisté importy, fungujúce tree-shaking a ďalšie dobré veci?
A má niekto dobré, čisté, jednoduché príklady knižníc ako tieto na GitHube alebo inde? Snažil som sa pozrieť projekty ako lodash, ale často nie sú napísané v TypeScripte a často sa zdajú mať pomerne zložité nastavenia s mono-repos, pracovnými priestormi, vlastnými build skriptmi atď...
Odpoveď č. 1
Ako by mal niekto štruktúrovať „multi-funkčný balík NPM“, aby získal zároveň čisté importy, funkčný tree-shaking a ďalšie dobré veci?
Publikovať moderné ES moduly
pre moderné knižnice (ako pre Node, tak pre prehliadač), by ste mali svoje zdrojové kódy vytvárať v TypeScripte a poskytovať distribúciu vo forme ES-modulu
táto stratégia nasleduje filozofiu, že nové knižnice by mali byť moderné, štíhle a minimalistické -- vaša knižnica by mala byť len verejne dostupným adresárom modulov ES
váš súbor package.json by mal obsahovať
"type": "module",
"main": "dist/main.js",
"module": "dist/main.js",
"files": [
"dist",
"source"
],
"scripts": {
"prepare": "tsc",
"watch": "tsc -w",
},
"devDependencies": {
"typescript": "typescript": "^3.8.3"
},
a možno aj váš tsconfig.json s položkami ako tieto
"baseUrl": ".",
"rootDir": "source",
"outDir": "dist",
"target": "esnext",
"lib": ["esnext", "dom"],
"module": "esnext",
"experimentalDecorators": true,
"sourceMap": true,
"declaration": true,
všetky otázky optimalizácie - to znamená: zoskupovanie, minimalizáciu, tree-shaking, transpiláciu, polyfilling atď. - všetky tieto otázky sú už riešené spotrebiteľskými aplikáciami (je to zbytočné nafúknutie, ak knižnice poskytujú riešenia pre tieto otázky)
Dedičné aplikácie common-js môžu ľahko použiť adaptér esm na využitie distribúcie es modulov
ak to absolútne musíte (prosím, zvážte inak), môžete urobiť z vášho balíka hybridný balík dual esm+cjs: stačí spustiť paralelný krok zostavenia tsc -- --module=commonjs --outDir dist-cjs a potom nastaviť v package.json "main": "dist-cjs/main.js", a môžete podporovať súčasne aj commonjs aj esm
Konkrétne odpovede
Potrebujem vytvoriť balík NPM pre niektorú bežnú funkcionalitu používanú v rôznych frontendových projektoch v našej spoločnosti, ale nie som si celkom istý, ako to správne spraviť. Používame Typescript a tsdx sa zdá riešiť niekoľko vecí, v ktorých si nie som istý, ako ich správne spraviť, ale nič sa nezmieňuje o tom, ako štruktúrovať balík typu „utilities“.
preto odporúčam stratégiu esm: funguje skvele pre izomorfný kód, teda knižnica funguje bez problémov na frontendových projektoch aj na backendových node projektoch
Čo nechápem, je, na čo by mal v package.json ukazovať "main", keď neexistuje žiaden logický jediný export/trieda/funkcia, ktorý by dával zmysel v balíku?
Polia "main" a "module" v súbore package.json sú voliteľné - preskočte ich
Myslím si, že je to najlepšia prax: nešpecifikujte jediný vstupný bod ako svoj „hlavný“ - namiesto toho by ste mali povzbudzovať používateľov, aby si výslovne vybrali moduly, ktoré chcú.
import {makeLogger} from "authoritarian/dist/toolbox/logger/make-logger.js"explicitné importy ako vyššie sú lepšie ako index, ktorý znovu exportuje veľký strom pravdepodobne nepoužitých modulov, najlepšie je úplne sa vyhnúť potrebe tree-shakingu tým, že importujete iba to, čo potrebujete
Mal by jednoducho exportovať každú jednu „verejnú“ funkciu v celom balíku? A ak áno, ako by to ovplyvnilo tree-shaking (ktorý momentálne až tak dobre nechápem) a podobné veci?
chcete si jednoducho nastaviť pole "files" vo svojom package.json, aby ste npm povedali, aby publikoval adresár "dist" plný es-modulov - a tiež publikovať "source", aby mali používatelia pri ladení čohokoľvek v knižnici dobrý zážitok so sourcemapmi
povzbudzovanie používateľov, aby priamo importovali moduly, eliminuje problém s tree-shaking -- pretože nepoužívate indexový súbor na agregáciu potenciálne nežiaducich modulov, nemusíte ich odstraňovať -- je to tak či tak záležitosť konzumenta, ako spravovať balíky, ktoré používajú objemné indexové moduly
[...] zdá sa, že zabalená cesta často skončí vrátane dist alebo lib alebo niečoho podobného, čo naozaj nechcem.
áno, toto ma esteticky tiež rušilo, ale prekonal som to
teraz sa mi to páči, balíčky sú jednoduché, od koreňa, a je tu rozdiel medzi dist a source (napríklad pri prístupe k sourcemapám na ladenie atď.), takže toto rozlíšenie je oprávnené
Ako by mal niekto štruktúrovať „multi-funkčný balík NPM“, aby získal zároveň čisté importy, funkčný tree-shaking a ďalšie dobré veci?
Myslím, že stratégia tejto odpovede poskytne to, čo hľadáte
A má niekto dobré, čisté, jednoduché príklady knižníc ako tieto na GitHube alebo inde? Snažil som sa pozrieť na projekty ako lodash, ale často nie sú napísané v TypeScripte a často sa zdá, že majú dosť komplikované nastavenia s mono-repami, pracovnými priestormi, vlastnými build skriptami a podobne...
Ešte som nevytvoril populárne balíčky (zatiaľ, muahaha!), ale moja knižnica Authoritarian walking the walk.. poslednú dobu som produkujem veľa knižníc a vyššie uvedené princípy, ktoré kážem, sú to, čo si myslím, že som sa naučil: Renraku je moja izomorfná JSON-RPC knižnica, Metalshop je moja knižnica webových komponentov, Shopper je moje používateľské rozhranie košíka Shopify
iné knižnice, ktoré som nevytvoril, ale sú celkom dobré, zahŕňajú lit-element.. väčšina knižníc nie je nová a je čiastočne uviaznutá vo svete commonjs
