Saya akan menerbitkan modul untuk NPM, ketika saya berpikir untuk menulis ulang di ES6, untuk kedua-bukti masa depan itu, dan belajar ES6. Saya telah menggunakan Babel untuk mengubah ke ES5, dan menjalankan tes. Tetapi saya tidak yakin bagaimana untuk melanjutkan:
- Apakah saya mentranspile, dan menerbitkan folder yang dihasilkan / keluar ke NPM?
- Apakah saya menyertakan folder hasil di repo Github saya?
- Atau apakah saya memelihara 2 repo, satu dengan kode ES6 + skrip gulp untuk Github, dan satu dengan hasil + tes yang di-transile untuk NPM?
Singkatnya: langkah apa yang harus saya ambil untuk menerbitkan modul yang ditulis dalam ES6 ke NPM, sementara masih memungkinkan orang untuk menelusuri / garpu kode asli?
javascript
node.js
npm
ecmascript-6
babeljs
Bepergian Tek Guy
sumber
sumber
Jawaban:
Pola yang telah saya lihat sejauh ini adalah untuk menyimpan file es6 dalam
src
direktori dan membangun barang-barang Anda di npm's prublish kelib
direktori.Anda akan memerlukan file .npmignore, mirip dengan Gitignore tetapi mengabaikan
src
bukannyalib
.sumber
./node_modules/babel-cli/bin/babel.js -s inline -d lib -w src
. Ini harus memastikan bahwa pemasangan tidak gagal ketika menggunakan ke lingkungan baru..npmignore
Anda bisa menggunakanfiles
bidang di package.json . Ini memungkinkan Anda menentukan dengan tepat file yang ingin Anda terbitkan, alih-alih mencari file acak yang tidak ingin Anda terbitkan.Saya suka jawaban José. Saya perhatikan beberapa modul sudah mengikuti pola itu. Inilah cara Anda dapat dengan mudah mengimplementasikannya dengan Babel6. Saya menginstal
babel-cli
secara lokal sehingga build tidak rusak jika saya pernah mengubah versi global babel saya..npmignore
.gitignore
Instal Babel
package.json
sumber
scripts
akannode_modules/.bin
ditambahkan ke mereka$PATH
dan sejakbabel-cli
menginstal biner kenode_modules/.bin/babel
tidak perlu merujuk perintah dengan jalan.prepublish
ini bermasalah karena dapat berjalan pada waktu pemasangan ( github.com/npm/npm/issues/3059 ), lebih sukaversion
kait skrip yang lebih idiomatis ( docs.npmjs.com/cli/version )prepublish
masih ada di sana. Saat ini saya pikir secara manual menyusunsrc
direktori dannpm publish
adalah cara untuk pergi.prepublishOnly
kait skrip (lihat docs.npmjs.com/misc/scripts#prepublish-and-prepare ). Perhatikan bahwa dalam versi 5 dari npm ini harus berfungsi seperti yang diharapkan, tetapi untuk sekarang (dengan asumsi Anda menggunakan npm v4 +) ini harus berfungsi.prepublish
berjalan sebelumnyapublish
(obv.), Yang mendorong hal-hal ke npm (atau di mana pun Anda mengkonfigurasi). Jadi ini untuk membangun apa yang ada dalam paket NPM, bahkan jika itu tidak masuk.TL; DR - Jangan, sampai ~ Oktober 2019. Tim Modul Node.js telah bertanya :
Pembaruan 2019 Mei
Sejak 2015 ketika pertanyaan ini diajukan, dukungan JavaScript untuk modul telah matang secara signifikan, dan semoga akan stabil secara resmi pada Oktober 2019. Semua jawaban lain sekarang sudah usang atau terlalu rumit. Inilah situasi saat ini dan praktik terbaik.
Dukungan ES6
99% dari ES6 (alias 2015) telah didukung oleh Node sejak versi 6 . Versi Node saat ini adalah 12. Semua peramban hijau mendukung sebagian besar fitur ES6. ECMAScript sekarang di versi 2019 , dan skema versi sekarang lebih suka menggunakan tahun.
Modul ES (alias modul ECMAScript) di browser
Semua evergreen browser telah mendukung
import
-ing modul ES6 sejak 2017. impor dinamis yang didukung oleh Chrome (+ garpu seperti Opera dan Samsung internet) dan Safari. Dukungan Firefox dijadwalkan untuk versi berikutnya, 67.Anda tidak lagi memerlukan Webpack / rollup / Parcel dll untuk memuat modul. Mereka mungkin masih berguna untuk tujuan lain, tetapi tidak diharuskan memuat kode Anda. Anda dapat langsung mengimpor URL yang menunjuk ke kode modul ES.
Modul ES di Node
Modul ES (
.mjs
file denganimport
/export
) telah didukung sejak Node v8.5.0 dengan memanggilnode
dengan--experimental-modules
flag. Node v12, dirilis pada April 2019, menulis ulang dukungan modul eksperimental. Perubahan yang paling terlihat adalah bahwa ekstensi file harus ditentukan secara default saat mengimpor:Perhatikan
.mjs
ekstensi wajib di seluruh. Jalankan sebagai:Rilis Node 12 juga ketika Tim Modul meminta pengembang untuk tidak mempublikasikan paket modul ES yang dimaksudkan untuk digunakan oleh Node.js sampai solusi ditemukan untuk menggunakan paket melalui keduanya
require('pkg')
danimport 'pkg'
. Anda masih dapat menerbitkan modul ES asli yang ditujukan untuk browser.Dukungan ekosistem modul ES asli
Pada Mei 2019, dukungan ekosistem untuk Modul ES belum sempurna. Misalnya, kerangka kerja pengujian seperti Jest dan Ava tidak mendukung
--experimental-modules
. Anda perlu menggunakan transpiler, dan kemudian harus memutuskan antara menggunakanimport { symbol }
sintaks import ( ) yang bernama (yang belum bekerja dengan sebagian besar paket npm), dan sintaks impor default (import Package from 'package'
), yang berfungsi, tetapi tidak ketika Babel mem-parsingnya untuk paket - paket yang ditulis dalam TypeScript (graphql-tools, node-influx, faast dll.) Namun ada solusi yang berfungsi baik dengan--experimental-modules
dan jika Babel mengubah kode Anda sehingga Anda dapat mengujinya dengan Jest / Ava / Mocha dll:Bisa dibilang jelek, tetapi dengan cara ini Anda bisa menulis kode modul ES Anda sendiri dengan
import
/export
dan menjalankannyanode --experimental-modules
, tanpa transpiler. Jika Anda memiliki dependensi yang belum siap ESM, impor mereka seperti di atas, dan Anda akan dapat menggunakan kerangka kerja pengujian dan perkakas lain melalui Babel.Jawaban sebelumnya untuk pertanyaan - ingat, jangan lakukan ini sampai Node menyelesaikan masalah persyaratan / impor, semoga sekitar Oktober 2019.
Menerbitkan modul ES6 ke npm, dengan kompatibilitas ke belakang
Untuk menerbitkan modul ES untuk npmjs.org sehingga dapat diimpor langsung, tanpa Babel atau transpilers lainnya, hanya titik
main
lapangan di Andapackage.json
ke.mjs
file, namun menghilangkan ekstensi:Itu satu-satunya perubahan. Dengan menghilangkan ekstensi, Node akan mencari file mjs terlebih dahulu jika dijalankan dengan --experimental-modules. Jika tidak, ia akan kembali ke file .js, sehingga proses transpilasi Anda yang ada untuk mendukung versi Node yang lebih lama akan berfungsi seperti sebelumnya - pastikan untuk mengarahkan Babel ke
.mjs
file tersebut.Inilah sumber untuk modul ES asli dengan kompatibilitas ke belakang untuk Node <8.5.0 yang saya terbitkan ke NPM. Anda dapat menggunakannya sekarang, tanpa Babel atau apa pun.
Pasang modul:
Buat file tes test.mjs :
Jalankan node (v8.5.0 +) dengan flag --experimental-modules:
TypeScript
Jika Anda mengembangkan dalam TypeScript, Anda dapat menghasilkan kode ES6 dan menggunakan modul ES6:
Kemudian, Anda perlu mengubah nama
*.js
keluaran menjadi.mjs
, masalah yang diketahui yang diharapkan akan segera diperbaiki sehinggatsc
dapat menampilkan.mjs
file secara langsung.sumber
mjs
file. Node.js berencana untuk menggelar dukungan resmi pada Oktober 2019 yang merupakan awal saya akan serius meninjau kembali ini.@ Jose benar. Tidak ada yang salah dengan menerbitkan ES6 / ES2015 ke NPM tetapi itu dapat menyebabkan masalah, khususnya jika orang yang menggunakan paket Anda menggunakan Webpack, misalnya, karena biasanya orang mengabaikan
node_modules
folder saat preprocessing denganbabel
alasan kinerja.Jadi, cukup gunakan
gulp
,grunt
atau cukup Node.js untuk membuatlib
folder yang ES5.Inilah
build-lib.js
skrip saya , yang saya simpan./tools/
(tidakgulp
atau digrunt
sini):Berikut saran terakhir: Anda perlu menambahkan .npmignore ke proyek Anda . Jika
npm publish
tidak menemukan file ini, itu akan digunakan.gitignore
sebagai gantinya, yang akan menyebabkan Anda bermasalah karena biasanya.gitignore
file Anda akan dikecualikan./lib
dan disertakan./src
, yang merupakan kebalikan dari apa yang Anda inginkan saat Anda menerbitkan ke NPM. The.npmignore
berkas pada dasarnya memiliki sintaks yang sama.gitignore
(AFAIK).sumber
.npmignore
Anda bisa menggunakanfiles
bidang di package.json . Ini memungkinkan Anda menentukan dengan tepat file yang ingin Anda terbitkan, alih-alih mencari file acak yang tidak ingin Anda terbitkan..npmignore
, cobapackage.json
'sfiles
sebaliknya, lihat: github.com/c-hive/guides/blob/master/js/...Mengikuti pendekatan José dan Marius, (dengan pembaruan versi terbaru Babel pada tahun 2019): Simpan file JavaScript terbaru dalam direktori src, dan bangun dengan
prepublish
skrip npm dan hasilkan ke direktori lib..npmignore
.gitignore
Instal Babel (versi 7.5.5 dalam kasus saya)
package.json
Dan saya punya
src/index.js
yang menggunakan fungsi panah:Inilah repo di GitHub .
Sekarang Anda dapat mempublikasikan paket:
Sebelum paket dipublikasikan ke npm, Anda akan melihat bahwa
lib/index.js
telah dihasilkan, yang dialihkan ke es5:[Pembaruan untuk Rollup bundler]
Sebagaimana ditanyakan oleh @kyw, bagaimana Anda mengintegrasikan bundler Rollup?
Pertama, instal
rollup
danrollup-plugin-babel
Kedua, buat
rollup.config.js
di direktori root proyekTerakhir, memperbarui
prepublish
dipackage.json
Sekarang Anda dapat menjalankan
npm publish
, dan sebelum paket diterbitkan ke npm, Anda akan melihat bahwa lib / index.js telah dihasilkan, yang ditranslasikan ke es5:Catatan: ngomong-ngomong, Anda tidak perlu lagi
@babel/cli
jika menggunakan bundler Rollup. Anda dapat dengan aman menghapusnya:sumber
Jika Anda ingin melihat ini beraksi dalam modul Node open source kecil yang sangat sederhana maka lihatlah hari ke-n (yang saya mulai - juga kontributor lainnya). Lihat di file package.json dan pada langkah prapublikasi yang akan mengarahkan Anda ke mana dan bagaimana melakukannya. Jika Anda mengkloning modul itu, Anda dapat menjalankannya secara lokal dan menggunakannya sebagai templat untuk Anda.
sumber
Node.js 13.2.0+ mendukung ESM tanpa flag eksperimental dan ada beberapa opsi untuk menerbitkan paket NPM hybrid (ESM dan CommonJS) (tergantung pada tingkat kompatibilitas yang dibutuhkan): https://2ality.com/2019 /10/hybrid-npm-packages.html
Saya sarankan pergi cara kompatibilitas penuh untuk membuat penggunaan paket Anda lebih mudah. Ini bisa terlihat sebagai berikut:
Paket hybrid memiliki file-file berikut:
mypkg/package.json
Mengimpor dari CommonJS:
Mengimpor dari ESM:
Kami melakukan penyelidikan terhadap dukungan ESM pada 05.2019 dan menemukan bahwa banyak perpustakaan kekurangan dukungan (maka rekomendasi untuk kompatibilitas mundur):
.mjs
file[email protected]
.mjs
file:sumber
Dua kriteria paket NPM adalah bahwa ia dapat digunakan dengan tidak lebih dari sebuah
require( 'package' )
dan melakukan sesuatu perangkat lunak.Jika Anda memenuhi kedua persyaratan itu, Anda dapat melakukan apa pun yang Anda inginkan. Sekalipun modul ditulis dalam ES6, jika pengguna akhir tidak perlu mengetahuinya, saya akan memindahkannya untuk saat ini untuk mendapatkan dukungan maksimal.
Namun, jika seperti koa , modul Anda memerlukan kompatibilitas dengan pengguna yang menggunakan fitur ES6, maka mungkin solusi dua paket akan menjadi ide yang lebih baik.
Bawa pulang
require( 'your-package' )
bekerja.sumber
require( 'package' )
bekerja. Saya akan mengedit jawaban saya untuk membuatnya lebih jelas. Yang mengatakan, jawaban Jose jauh lebih baik daripada jawaban saya.Kunci utama dalam
package.json
menentukan titik masuk ke paket setelah diterbitkan. Jadi, Anda dapat menempatkan output Babel di mana pun Anda inginkan dan hanya perlu menyebutkan jalur yang benarmain
.Inilah artikel yang ditulis dengan baik tentang cara mempublikasikan paket npm
https://codeburst.io/publish-your-own-npm-package-ff918698d450
Berikut ini contoh repo yang dapat Anda gunakan untuk referensi
https://github.com/flexdinesh/npm-module-boilerplate
sumber
import
dapat secara langsung tanpa memerlukan Babel atau transponder lainnya.Bergantung pada anatomi modul Anda, solusi ini mungkin tidak berfungsi, tetapi jika modul Anda terkandung di dalam satu file, dan tidak memiliki dependensi (tidak menggunakan impor ), menggunakan pola berikut Anda dapat melepaskan kode Anda seperti itu , dan akan dapat diimpor dengan impor (Browser ES6 Modul) dan memerlukan (Modul Node CommonJS)
Sebagai bonus, akan layak untuk diimpor menggunakan Elemen HTML SCRIPT.
main.js :
my-module.js :
package.json : `
Untuk menggunakan modul Anda, sekarang Anda dapat menggunakan sintaks ...
Saat diimpor dalam NODE ...
Saat diimpor dalam BROWSER ...
Atau bahkan ketika disertakan menggunakan Elemen Script HTML ...
sumber
Beberapa catatan tambahan untuk siapa saja, menggunakan modul sendiri langsung dari github, tidak melalui modul yang diterbitkan :
The ( banyak digunakan ) "prepublish" hook tidak melakukan apa-apa untuk Anda.
Hal terbaik yang dapat dilakukan (jika berencana mengandalkan repositori github, bukan hal-hal yang dipublikasikan):
src
dari .npmignore (dengan kata lain: izinkan saja). Jika Anda tidak memiliki.npmignore
, ingat: Salinan.gitignore
akan digunakan sebagai gantinya di lokasi yang diinstal, seperti yangls node_modules/yourProject
akan menunjukkan kepada Anda.babel-cli
adalah ketergantungan pada modul Anda, bukan hanya devDepenceny karena Anda memang membangun mesin konsumsi alias di komputer pengembang aplikasi, yang menggunakan modul Andalakukan build build, di install hook yaitu:
"install": "babel src -d lib -s"
(tidak ada nilai tambah dalam mencoba apa pun "pra-instal", yaitu babel-cli mungkin hilang)
sumber
npm pack
output, 3) check in build output.