Questa è una risposta estremamente lunga perché questa domanda merita una risposta estremamente lunga e dettagliata in quanto il modo "best practice" è più complicato di una risposta di poche righe.
Ho mantenuto le nostre librerie in-house per oltre 3,5 anni in quel momento, ho optato per due modi in cui penso che le biblioteche dovrebbero essere raggruppate, i compromessi dipendono da quanto è grande la tua biblioteca e personalmente compiliamo entrambi i modi per soddisfare entrambi i sottogruppi di consumatori.
Metodo 1: Creare un file index.ts con tutto ciò che si desidera venga esportato esposto e destinazione rollup in questo file come input. Raggruppa l'intera libreria in un singolo file index.js e file index.css; Con la dipendenza esterna ereditata dal progetto del consumatore per evitare la duplicazione del codice della libreria. (sintesi inclusa nella parte inferiore della configurazione di esempio)
- Pro: facile da consumare poiché i consumatori del progetto possono importare tutto dal percorso della libreria relativa radice
import { Foo, Bar } from "library"
- Contro: questo non sarà mai agitabile; e prima che la gente dica di farlo con ESM e sarà alberabile. NextJS non supporta ESM in questa fase attuale e nemmeno molte configurazioni del progetto, ecco perché è comunque una buona idea compilare questa build solo per CJS. Se qualcuno importa 1 dei tuoi componenti otterrà tutti i CSS e tutti i JavaScript per tutti i tuoi componenti.
Metodo 2: Questo è per utenti esperti: crea un nuovo file per ogni esportazione e usa rollup-plugin-multi-input con l'opzione "preservModules: true" a seconda di quale sistema css stai usando devi anche assicurarti che il tuo css NON viene unito in un singolo file ma ogni file css richiede che l'istruzione (". css") venga lasciata nel file di output dopo il rollup e che il file css esista.
- Pro: Quando gli utenti importano {Foo} da "library / dist / foo" otterranno solo il codice per Foo, i CSS per Foo e nient'altro.
- Contro: Questa configurazione prevede che il consumatore debba gestire le istruzioni (". Css") di node_modules nella configurazione di build con NextJS, questo viene fatto con il
next-transpile-modules
pacchetto npm.
- Avvertenza: utilizziamo il nostro plug-in babel che puoi trovare qui: https://www.npmjs.com/package/babel-plugin-qubic per consentire alle persone di
import { Foo,Bar } from "library"
trasformarlo in ...
import { Foo } from "library/dist/export/foo"
import { Bar } from "library/dist/export/bar"
Abbiamo diverse configurazioni di rollup in cui utilizziamo effettivamente entrambi i metodi; così per i consumatori di biblioteche che non si preoccupano di scuotere l'albero possono semplicemente fare "Foo from "library"
e importare il singolo file CSS; e per i consumatori di biblioteche che si preoccupano di scuotere gli alberi e di usare solo i CSS critici possono semplicemente attivare il nostro plug-in babel.
Guida al rollup per le migliori pratiche:
indipendentemente dal fatto che tu stia usando dattiloscritto o meno SEMPRE build con "rollup-plugin-babel": "5.0.0-alpha.1"
Assicurati che il tuo .babelrc assomigli a questo.
{
"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
}]
]
}
E con il plugin babel in rollup che assomiglia a questo ...
babel({
babelHelpers: "runtime",
extensions,
include: ["src/**/*"],
exclude: "node_modules/**",
babelrc: true
}),
E il tuo package.json sembra ATLEAST in questo modo:
"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",
}
E infine i tuoi esterni nel rollup sembrano ATLEAST così.
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.
Perché?
- Questo raggrupperà la tua merda per ereditare automaticamente la reazione / reazione-dom e le altre dipendenze peer / esterne dal progetto del consumatore, il che significa che non saranno duplicati nel tuo bundle.
- Questo verrà raggruppato in ES5
- Ciò richiederà automaticamente ("..") in tutte le funzioni di babel helper per objectSpread, classi ecc. DAL progetto del consumatore che eliminerà altri 15-25 KB dalle dimensioni del pacchetto e significherà che le funzioni di helper per objectSpread non verranno duplicate nella libreria output + output dei progetti di consumo in bundle.
- Le funzioni asincrone continueranno a funzionare
- gli esterni corrisponderanno a tutto ciò che inizia con quel suffisso di dipendenza tra pari, cioè gli babel-helper corrisponderanno a quelli esterni per babel-helper / helper / object-spread
Infine ecco un esempio per un esempio di file di configurazione di rollup di output del file index.js singolo.
https://gist.github.com/ShanonJackson/deb65ebf5b2094b3eac6141b9c25a0e3
Dove il target src / export / index.ts si presenta così ...
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
Fammi sapere se riscontri problemi con babel, rollup o hai domande sul raggruppamento / sulle librerie.
imported
nel codice, riducendo così la dimensione del bundle.