Miałem właśnie zamiar opublikować moduł w NPM, kiedy myślałem o przepisaniu go w ES6, aby był zarówno przyszłościowy, jak i nauczony ES6. Użyłem Babel do transpozycji do ES5 i uruchomienia testów. Ale nie jestem pewien, jak postępować:
- Czy transpiluję i publikuję folder wynikowy / wyjściowy w NPM?
- Czy dołączam folder wyników do mojego repozytorium Github?
- A może utrzymuję 2 repozytoria, jedno z kodem ES6 + skryptem gulp dla Github, a drugie z transpilowanymi wynikami + testami dla NPM?
W skrócie: jakie kroki muszę wykonać, aby opublikować moduł napisany w ES6 w NPM, jednocześnie pozwalając ludziom przeglądać / rozwidlać oryginalny kod?
javascript
node.js
npm
ecmascript-6
babeljs
Podróżujący Technik
źródło
źródło
Odpowiedzi:
Wzorzec, który widziałem do tej pory, polega na przechowywaniu plików es6 w
src
katalogu i budowaniu swoich rzeczy w prepublimie npm wlib
katalogu.Będziesz potrzebował pliku .npmignore, podobnego do .gitignore, ale
src
zamiast tego ignorujlib
.źródło
./node_modules/babel-cli/bin/babel.js -s inline -d lib -w src
. Powinno to zapewnić, że instalacje nie zakończą się niepowodzeniem podczas wdrażania w nowych środowiskach..npmignore
możesz użyćfiles
pola w package.json . Pozwala dokładnie określić pliki, które chcesz opublikować, zamiast szukać losowych plików, których nie chcesz publikować.Podoba mi się odpowiedź José. Zauważyłem, że kilka modułów już podąża za tym wzorem. Oto, jak możesz łatwo zaimplementować to za pomocą Babel6. Instaluję
babel-cli
lokalnie, więc kompilacja nie zepsuje się, jeśli kiedykolwiek zmienię moją globalną wersję babel..npmignore
.gitignore
Zainstaluj Babel
package.json
źródło
scripts
testamencie zostałynode_modules/.bin
dodane do ich,$PATH
a ponieważbabel-cli
instaluje plik binarny,node_modules/.bin/babel
nie ma potrzeby odwoływania się do polecenia według ścieżki.prepublish
jest to problematyczne, ponieważ może działać w czasie instalacji ( github.com/npm/npm/issues/3059 ), wolę bardziej idiomatyczny punktversion
zaczepienia skryptu ( docs.npmjs.com/cli/version )prepublish
nadal występuje. W tej chwili myślę, że ręcznie skompilujsrc
katalog inpm publish
jest do zrobienia.prepublishOnly
podpięcia skryptu (patrz docs.npmjs.com/misc/scripts#prepublish-and-prepare ). Zauważ, że w wersji 5 npm powinno to działać zgodnie z oczekiwaniami, ale na razie (zakładając, że używasz npm v4 +) powinno to działać.prepublish
działa przedpublish
(obv.), Co przesyła rzeczy do npm (lub gdziekolwiek skonfigurujesz). A więc służy do budowania tego, co znajduje się w pakiecie NPM, nawet jeśli nie jest on zarejestrowany.TL; DR - Nie, dopóki ~ października 2019 roku node.js Moduły Zespół został poproszony :
Aktualizacja z maja 2019 r
Od 2015 roku, kiedy zadano to pytanie, obsługa JavaScript dla modułów znacznie się rozwinęła i miejmy nadzieję, że w październiku 2019 będzie oficjalnie stabilna. Wszystkie inne odpowiedzi są teraz przestarzałe lub zbyt skomplikowane. Oto aktualna sytuacja i najlepsze praktyki.
Obsługa ES6
99% ES6 (aka 2015) jest obsługiwanych przez Node od wersji 6 . Aktualna wersja Node to 12. Wszystkie wiecznie zielone przeglądarki obsługują zdecydowaną większość funkcji ES6. ECMAScript jest teraz w wersji 2019 , a schemat wersjonowania faworyzuje teraz używanie lat.
Moduły ES (aka moduły ECMAScript) w przeglądarkach
Wszystkie przeglądarki wiecznie zostały wspieranie
import
-ing moduły ES6 od 2017. import dynamiczne są obsługiwane przez Chrome (+ widły jak Opera i Samsung Internet) i Safari. Obsługa Firefoksa jest przewidziana w następnej wersji, 67.Nie potrzebujesz już Webpack / rollup / Parcel itp., Aby załadować moduły. Mogą być nadal przydatne do innych celów, ale nie są wymagane do ładowania kodu. Możesz bezpośrednio importować adresy URL wskazujące na kod modułów ES.
Moduły ES w Node
Moduły ES (
.mjs
pliki zimport
/export
) były obsługiwane od wersji 8.5.0 Node przez wywołanienode
z--experimental-modules
flagą. Node v12, wydany w kwietniu 2019 r., Przepisał obsługę modułów eksperymentalnych. Najbardziej widoczną zmianą jest to, że rozszerzenie pliku musi być określone domyślnie podczas importowania:Zwróć uwagę na obowiązkowe
.mjs
rozszerzenia w całym tekście. Uruchom jako:Wydanie Node 12 ma miejsce również wtedy, gdy zespół Modules poprosił programistów, aby nie publikowali pakietów modułów ES przeznaczonych do użytku przez Node.js, dopóki nie zostanie znalezione rozwiązanie do korzystania z pakietów za pośrednictwem obu
require('pkg')
iimport 'pkg'
. Nadal można publikować natywne moduły ES przeznaczone dla przeglądarek.Wsparcie ekosystemu natywnych modułów ES
Od maja 2019 r. Obsługa ekosystemu dla modułów ES jest niedojrzała. Na przykład struktury testowe, takie jak Jest i Ava , nie obsługują
--experimental-modules
. Musisz użyć transpilera, a następnie zdecydować, czy użyć nazwanejimport { symbol }
składni import ( ) (która jeszcze nie będzie działać z większością pakietów npm), a domyślną składnią importu (import Package from 'package'
), która działa, ale nie kiedy Babel ją analizuje dla pakietów utworzonych w TypeScript (graphql-tools, node-infx, faast itp.) Istnieje jednak obejście, które działa zarówno z, jak--experimental-modules
i wtedy, gdy Babel transponuje twój kod, więc możesz go przetestować za pomocą Jest / Ava / Mocha itp:Prawdopodobnie brzydki, ale w ten sposób możesz napisać własny kod modułów ES z
import
/export
i uruchomić go znode --experimental-modules
, bez transpilerów. Jeśli masz zależności, które nie są jeszcze gotowe na ESM, zaimportuj je jak powyżej, a będziesz mógł używać struktur testowych i innych narzędzi za pośrednictwem Babel.Poprzednia odpowiedź na pytanie - pamiętaj, nie rób tego, dopóki Node nie rozwiąże problemu z wymaganiami / importem, miejmy nadzieję, że około października 2019.
Publikowanie modułów ES6 do npm z zachowaniem wstecznej kompatybilności
Aby opublikować moduł ES do npmjs.org tak, że może on być importowane bezpośrednio, bez Babel lub innych transpilers, wystarczy wskazać
main
pola wpackage.json
do.mjs
pliku, ale pominąć rozszerzenie:To jedyna zmiana. Pomijając rozszerzenie, Node będzie najpierw szukał pliku mjs, jeśli zostanie uruchomiony z --experimental-modules. W przeciwnym razie powróci do pliku .js, więc twój istniejący proces transpilacji do obsługi starszych wersji Node będzie działał jak poprzednio - po prostu upewnij się, że wskazałeś Babel na
.mjs
plik (i).Oto źródło natywnego modułu ES z kompatybilnością wsteczną dla Node <8.5.0, które opublikowałem w NPM. Możesz go teraz używać, bez Babel ani czegokolwiek innego.
Zainstaluj moduł:
Utwórz plik testowy test.mjs :
Uruchom węzeł (v8.5.0 +) z flagą --experimental-modules:
Maszynopis
Jeśli programujesz w języku TypeScript, możesz wygenerować kod ES6 i użyć modułów ES6:
Następnie musisz zmienić nazwę
*.js
wyjścia na.mjs
, znany problem, który, miejmy nadzieję, wkrótce zostanie naprawiony, abytsc
można było.mjs
bezpośrednio wyświetlać pliki.źródło
mjs
pliki. Node.js planuje udostępnić oficjalne wsparcie w październiku 2019 r., Czyli najwcześniej, gdy poważnie wrócę do tego.@Jose ma rację. Nie ma nic złego w publikowaniu ES6 / ES2015 w NPM, ale może to powodować problemy, szczególnie jeśli osoba korzystająca z pakietu używa na przykład Webpacka, ponieważ zwykle ludzie ignorują
node_modules
folder podczas wstępnego przetwarzania w programie ze względubabel
na wydajność.Tak, wystarczy użyć
gulp
,grunt
lub po prostu node.js zbudowaćlib
folder, który jest ES5.Oto mój
build-lib.js
skrypt, który przechowuję./tools/
(niegulp
lubgrunt
tutaj):Oto ostatnia rada: musisz dodać .npmignore do swojego projektu . Jeśli
npm publish
nie znajdzie tego pliku, użyje go.gitignore
zamiast tego, co spowoduje problemy, ponieważ zwykle.gitignore
plik zostanie wykluczony./lib
i uwzględniony./src
, co jest dokładnie odwrotnością tego, czego chcesz, gdy publikujesz w NPM..npmignore
Plik ma w zasadzie taką samą składnię.gitignore
(AFAIK).źródło
.npmignore
możesz użyćfiles
pola w package.json . Pozwala dokładnie określić pliki, które chcesz opublikować, zamiast szukać losowych plików, których nie chcesz publikować..npmignore
, spróbujpackage.json
„sfiles
zamiast patrz: github.com/c-hive/guides/blob/master/js/...Zgodnie z podejściem José i Mariusa (z aktualizacją najnowszej wersji Babel w 2019 r.): Zachowaj najnowsze pliki JavaScript w katalogu src i skompiluj za pomocą
prepublish
skryptu npm i wyślij do katalogu lib..npmignore
.gitignore
Zainstaluj Babel (wersja 7.5.5 w moim przypadku)
package.json
I mam,
src/index.js
który używa funkcji strzałki:Oto repozytorium na GitHub .
Teraz możesz opublikować pakiet:
Zanim pakiet zostanie opublikowany na npm, zobaczysz, że
lib/index.js
został on wygenerowany, co jest transponowane do es5:[Aktualizacja dla pakietu zbiorczego]
Zgodnie z pytaniem @kyw, w jaki sposób można zintegrować pakiet Rollup?
Najpierw zainstaluj
rollup
irollup-plugin-babel
Po drugie, utwórz
rollup.config.js
w katalogu głównym projektuNa koniec zaktualizuj
prepublish
wpackage.json
Teraz możesz uruchomić
npm publish
, a zanim pakiet zostanie opublikowany na npm, zobaczysz, że został wygenerowany plik lib / index.js, który jest transponowany do es5:Uwaga: tak przy okazji, nie potrzebujesz już,
@babel/cli
jeśli używasz pakietu zbiorczego. Możesz go bezpiecznie odinstalować:źródło
Jeśli chcesz zobaczyć to w akcji w bardzo prostym, małym module Node o otwartym kodzie źródłowym, spójrz na nth-day (który zacząłem - także inni współpracownicy). Zajrzyj do pliku package.json i przejdź do etapu wstępnej publikacji, który doprowadzi Cię do miejsca i sposobu wykonania tej czynności. Jeśli sklonujesz ten moduł, możesz uruchomić go lokalnie i użyć jako szablonu dla siebie.
źródło
Node.js 13.2.0+ obsługuje ESM bez flagi eksperymentalnej i istnieje kilka opcji publikowania hybrydowych (ESM i CommonJS) pakietów NPM (w zależności od wymaganego poziomu kompatybilności wstecznej): https://2ality.com/2019 /10/hybrid-npm-packages.html
Zalecam skorzystanie z pełnej kompatybilności wstecznej, aby ułatwić korzystanie z pakietu. Może to wyglądać następująco:
Pakiet hybrydowy zawiera następujące pliki:
mypkg/package.json
Importowanie z CommonJS:
Importowanie z ESM:
Przeprowadziliśmy dochodzenie w sprawie obsługi ESM w 05.2019 i stwierdziliśmy, że wielu bibliotekom brakowało wsparcia (stąd zalecenie dotyczące wstecznej kompatybilności):
.mjs
plików[email protected]
.mjs
plikami:źródło
Dwa kryteria pakietu NPM to to, że można go używać tylko z plikiem
require( 'package' )
a i robi coś programistycznego.Jeśli spełniasz te dwa wymagania, możesz robić, co chcesz. Nawet jeśli moduł jest napisany w ES6, jeśli użytkownik końcowy nie musi tego wiedzieć, przetransponowałbym go na razie, aby uzyskać maksymalne wsparcie.
Jeśli jednak tak jak koa , twój moduł wymaga kompatybilności z użytkownikami używającymi funkcji ES6, to być może rozwiązanie z dwoma pakietami byłoby lepszym pomysłem.
Na wynos
require( 'your-package' )
pracy.źródło
require( 'package' )
do działania. Zmienię odpowiedź, aby było jaśniejsze. To powiedziawszy, odpowiedź Jose jest znacznie lepsza niż moja.Główny klucz
package.json
decyduje o punkcie wejścia do pakietu po jego opublikowaniu. Możesz więc umieścić wyjście Babel w dowolnym miejscu i po prostu wspomnieć o właściwej ścieżce wmain
kluczu.Oto dobrze napisany artykuł o tym, jak opublikować pakiet npm
https://codeburst.io/publish-your-own-npm-package-ff918698d450
Oto przykładowe repozytorium, którego możesz użyć w celach informacyjnych
https://github.com/flexdinesh/npm-module-boilerplate
źródło
import
umożliwiających bezpośrednio, bez konieczności używania Babel lub innych transpilerów.W zależności od anatomii twojego modułu, to rozwiązanie może nie działać, ale jeśli twój moduł jest zawarty w jednym pliku i nie ma żadnych zależności (nie korzysta z importu ), używając następującego wzorca możesz zwolnić swój kod tak, jak jest i będzie można je zaimportować z importem (moduły ES6 przeglądarki) i wymagać (moduły Node CommonJS)
Jako bonus, będzie można importować za pomocą elementu SCRIPT HTML.
main.js :
my-module.js :
package.json : `
Aby użyć swojego modułu, możesz teraz użyć zwykłej składni ...
Po zaimportowaniu do NODE ...
Po zaimportowaniu do BROWSER ...
Lub nawet jeśli jest dołączony za pomocą elementu skryptu HTML ...
źródło
Kilka dodatkowych uwag dla wszystkich, którzy używają własnych modułów bezpośrednio z github, nie przeglądają opublikowanych modułów:
( Powszechnie używany ) hak „prepublish” nic dla ciebie nie robi .
Najlepsza rzecz, jaką można zrobić (jeśli planujesz polegać na repozytoriach na githubie, a nie na publikowanych materiałach):
src
z .npmignore (innymi słowy: to pozwolić). Jeśli nie masz.npmignore
, pamiętaj:.gitignore
zamiast tego w zainstalowanej lokalizacji zostanie użyta kopia programuls node_modules/yourProject
to pokaże.babel-cli
jest to zależność w twoim module, a nie tylko devDepenceny, ponieważ faktycznie tworzysz na maszynie konsumującej, czyli na komputerze dewelopera aplikacji, który używa twojego modułuzrób budowanie w haku instalacyjnym tj .:
"install": "babel src -d lib -s"
(brak wartości dodanej w próbie „preinstalacji”, tj. może brakować babel-cli)
źródło
npm pack
wyniku, 3) sprawdzić wynik kompilacji.