Ini adalah jawaban yang sangat panjang karena pertanyaan ini layak mendapatkan jawaban yang sangat panjang dan terperinci karena cara "praktik terbaik" lebih rumit daripada hanya beberapa tanggapan baris.
Iv'e mempertahankan perpustakaan di rumah kami selama 3,5+ tahun pada waktu itu. Saya setuju dengan dua cara. Saya pikir perpustakaan harus dibundel tergantung dari seberapa besar perpustakaan Anda dan secara pribadi kami menyusun kedua cara untuk menyenangkan kedua himpunan bagian dari konsumen.
Metode 1: Buat file index.ts dengan semua yang Anda inginkan diekspor dan rollup target pada file ini sebagai inputnya. Gabungkan seluruh perpustakaan Anda menjadi satu file index.js dan file index.css; Dengan ketergantungan eksternal yang diwarisi dari proyek konsumen untuk menghindari duplikasi kode perpustakaan. (intisari di bagian bawah contoh konfigurasi)
- Kelebihan: Mudah dikonsumsi karena konsumen proyek dapat mengimpor semuanya dari jalur pustaka relatif root
import { Foo, Bar } from "library"
- Cons: Ini tidak akan pernah menjadi goyah pohon; dan sebelum orang mengatakan melakukan ini dengan ESM dan itu akan berbahaya. NextJS tidak mendukung ESM pada tahap saat ini dan juga tidak banyak pengaturan proyek itu sebabnya masih merupakan ide bagus untuk mengkompilasi build ini menjadi hanya CJS. Jika seseorang mengimpor 1 komponen Anda, mereka akan mendapatkan semua css dan semua javascript untuk semua komponen Anda.
Metode 2: Ini untuk pengguna tingkat lanjut: Buat file baru untuk setiap ekspor dan gunakan rollup-plugin-multi-input dengan opsi "preserveModules: true" tergantung pada bagaimana sistem css apa yang Anda gunakan, Anda juga perlu memastikan bahwa css Anda TIDAK digabung menjadi satu file tetapi setiap file css membutuhkan pernyataan (". css") yang tersisa di dalam file output setelah rollup dan file css itu ada.
- Pro: Ketika pengguna mengimpor {Foo} dari "library / dist / foo" mereka hanya akan mendapatkan kode untuk Foo, dan css untuk Foo dan tidak lebih.
- Cons: Setup ini melibatkan konsumen yang harus menangani pernyataan node_modules memerlukan (". Css") dalam konfigurasi build mereka dengan NextJS ini dilakukan dengan
next-transpile-modules
paket npm.
- Peringatan: Kami menggunakan plugin babel kami sendiri yang dapat Anda temukan di sini: https://www.npmjs.com/package/babel-plugin-qubic untuk memungkinkan orang lain
import { Foo,Bar } from "library"
dan kemudian dengan babel mengubahnya menjadi ...
import { Foo } from "library/dist/export/foo"
import { Bar } from "library/dist/export/bar"
Kami memiliki beberapa konfigurasi rollup di mana kami benar-benar menggunakan kedua metode; jadi bagi konsumen perpustakaan yang tidak peduli dengan guncangan pohon, cukup lakukan "Foo from "library"
dan impor file css tunggal; dan untuk konsumen perpustakaan yang peduli terhadap goncangan pohon dan hanya menggunakan css kritis, mereka bisa menyalakan plugin babel kami.
Panduan rollup untuk praktik terbaik:
apakah Anda menggunakan naskah atau SELALU membangun dengan "rollup-plugin-babel": "5.0.0-alpha.1"
Pastikan .babelrc Anda terlihat seperti ini.
{
"presets": [
["@babel/preset-env", {
"targets": {"chrome": "58", "ie": "11"},
"useBuiltIns": false
}],
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
["@babel/plugin-transform-runtime", {
"absoluteRuntime": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"useESModules": false,
"version": "^7.8.3"
}],
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-classes",
["@babel/plugin-proposal-optional-chaining", {
"loose": true
}]
]
}
Dan dengan plugin babel dalam tampilan seperti ini ...
babel({
babelHelpers: "runtime",
extensions,
include: ["src/**/*"],
exclude: "node_modules/**",
babelrc: true
}),
Dan package.json Anda terlihat ATLEAST seperti ini:
"dependencies": {
"@babel/runtime": "^7.8.3",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"regenerator-runtime": "^0.13.3"
},
"peerDependencies": {
"react": "^16.12.0",
"react-dom": "^16.12.0",
}
Dan akhirnya eksternal Anda dalam rollup tampak ATLEAST seperti ini.
const makeExternalPredicate = externalArr => {
if (externalArr.length === 0) return () => false;
return id => new RegExp(`^(${externalArr.join('|')})($|/)`).test(id);
};
//... rest of rollup config above external.
external: makeExternalPredicate(Object.keys(pkg.peerDependencies || {}).concat(Object.keys(pkg.dependencies || {}))),
// rest of rollup config below external.
Mengapa?
- Ini akan membundel omong kosong Anda untuk secara otomatis mewarisi reaksi / reaksi dom dan dependensi rekan / eksternal Anda lainnya dari proyek konsumen yang berarti mereka tidak akan diduplikasi dalam bundel Anda.
- Ini akan dibundel ke ES5
- Ini akan secara otomatis membutuhkan ("..") di semua fungsi pembantu babel untuk objectSpread, kelas dll DARI proyek konsumen yang akan menghapus 15-25KB lain dari ukuran bundel Anda dan berarti bahwa fungsi pembantu untuk objekSebar tidak akan digandakan di perpustakaan Anda output + proyek yang dikonsumsi keluaran yang dibundel.
- Fungsi Async masih akan berfungsi
- eksternal akan cocok dengan apa pun yang dimulai dengan sufiks peer-dependency yaitu babel-helper akan cocok dengan eksternal untuk babel-helper / helper / penyebaran objek
Akhirnya di sini adalah inti untuk contoh file konfigurasi rollup file index.js tunggal.
https://gist.github.com/ShanonJackson/deb65ebf5b2094b3eac6141b9c25a0e3
Di mana target src / ekspor / index.ts terlihat seperti ini ...
export { Button } from "../components/Button/Button";
export * from "../components/Button/Button.styles";
export { Checkbox } from "../components/Checkbox/Checkbox";
export * from "../components/Checkbox/Checkbox.styles";
export { DatePicker } from "../components/DateTimePicker/DatePicker/DatePicker";
export { TimePicker } from "../components/DateTimePicker/TimePicker/TimePicker";
export { DayPicker } from "../components/DayPicker/DayPicker";
// etc etc etc
Beritahu saya jika Anda mengalami masalah dengan babel, rollup, atau memiliki pertanyaan tentang bundling / pustaka.
imported
dalam kode sehingga mengurangi ukuran bundel.