To jest bardzo długa odpowiedź, ponieważ to pytanie zasługuje na niezwykle długą i szczegółową odpowiedź, ponieważ metoda „najlepszych praktyk” jest bardziej skomplikowana niż tylko odpowiedź liniowa.
Iv'e utrzymywał nasze biblioteki wewnętrzne przez ponad 3,5 roku w tym czasie iv'e osiedlił się na dwa sposoby. Myślę, że biblioteki powinny być powiązane, kompromisy zależą od tego, jak duża jest twoja biblioteka i osobiście opracowujemy oba sposoby, aby zadowolić oba podzbiory konsumenci.
Metoda 1: Utwórz plik index.ts ze wszystkim, co chcesz wyeksportować, i docelowym pakietem zbiorczym dla tego pliku jako jego danych wejściowych. Spakuj całą bibliotekę w jeden plik index.js i plik index.css; Z zewnętrzną zależnością odziedziczoną po projekcie konsumenckim, aby uniknąć powielania kodu biblioteki. (Gist znajduje się na dole przykładowej konfiguracji)
- Zalety: Łatwy w użyciu, ponieważ klienci projektu mogą importować wszystko ze ścieżki względnej biblioteki głównej
import { Foo, Bar } from "library"
- Minusy: To nigdy nie będzie wstrząsać drzewem; i zanim ludzie powiedzą, zrób to z ESM, a będzie to możliwe. NextJS nie obsługuje ESM na obecnym etapie i nie ma wielu ustawień projektu, dlatego nadal dobrym pomysłem jest skompilowanie tej kompilacji tylko do CJS. Jeśli ktoś zaimportuje 1 z twoich komponentów, otrzyma wszystkie css i cały javascript dla wszystkich twoich komponentów.
Metoda 2: dla zaawansowanych użytkowników: utwórz nowy plik dla każdego eksportu i użyj wtyczki rollup-plugin-multi-input z opcją „preserveModules: true”, w zależności od tego, jakiego systemu css używasz, aby upewnić się, że Twój plik css NIE jest scalony w jeden plik, ale że każdy plik css wymaga instrukcji („. css”) pozostawia się w pliku wyjściowym po zrolowaniu i ten plik css istnieje.
- Plusy: gdy użytkownicy zaimportują {Foo} z „biblioteki / dist / foo”, dostaną tylko kod dla Foo i css dla Foo i nic więcej.
- Wady: Ta konfiguracja wymaga od konsumenta obsługi instrukcji node_modules Require (". Css") w konfiguracji kompilacji z NextJS, odbywa się to za pomocą
next-transpile-modules
pakietu npm.
- Uwaga: Używamy naszej własnej wtyczki Babel, którą można znaleźć tutaj: https://www.npmjs.com/package/babel-plugin-qubic, aby umożliwić ludziom,
import { Foo,Bar } from "library"
a następnie wraz z Babel przekształcić ją w ...
import { Foo } from "library/dist/export/foo"
import { Bar } from "library/dist/export/bar"
Mamy wiele konfiguracji zestawień, w których faktycznie używamy obu metod; więc konsumenci bibliotek, którym nie zależy na wstrząsaniu drzewem, mogą po prostu "Foo from "library"
zaimportować pojedynczy plik css; a dla użytkowników bibliotek, którzy troszczą się o drżenie drzew i używają tylko krytycznego css, mogą po prostu włączyć naszą wtyczkę Babel.
Przewodnik po najlepszych praktykach:
czy używasz maszynopisu czy nie ZAWSZE kompiluj z "rollup-plugin-babel": "5.0.0-alpha.1"
Upewnij się, że Twój .babelrc wygląda tak.
{
"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
}]
]
}
A dzięki wtyczce babel w pakiecie wygląda to tak ...
babel({
babelHelpers: "runtime",
extensions,
include: ["src/**/*"],
exclude: "node_modules/**",
babelrc: true
}),
A Twój pakiet.json wygląda ATLEAST tak:
"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",
}
I w końcu twoje zewnętrzne wyglądające tak, jakby wyglądały jak KASETA.
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.
Dlaczego?
- Spowoduje to spakowanie twojego gówna do automatycznego dziedziczenia reagowania / reagowania i innych zależności równorzędnych / zewnętrznych od projektu konsumenckiego, co oznacza, że nie będą duplikowane w twoim pakiecie.
- Spowoduje to dołączenie do ES5
- Będzie to automatycznie wymagało („..”) we wszystkich funkcjach pomocniczych babel dla ObjectSpread, klas itp. Z projektu konsumenckiego, który usunie kolejne 15-25 KB z rozmiaru pakietu i oznacza, że funkcje pomocnicze dla ObjectSpread nie będą duplikowane w bibliotece produkcja + projekty konsumenckie w pakiecie produkcja.
- Funkcje asynchroniczne będą nadal działać
- zewnętrzne będą pasować do wszystkiego, co zaczyna się od sufiksu zależności rówieśniczej, tzn. pomocnicy-babel będą pasować do zewnętrznych dla pomocników / pomocników / rozprzestrzeniania się obiektów
Na koniec znajduje się streszczenie przykładowego pojedynczego pliku konfiguracyjnego pakietu zbiorczego pliku index.js.
https://gist.github.com/ShanonJackson/deb65ebf5b2094b3eac6141b9c25a0e3
Gdzie docelowy plik src / export / index.ts wygląda tak ...
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
Daj mi znać, jeśli napotkasz jakiekolwiek problemy z babel, rollupem lub masz pytania dotyczące tworzenia pakietów / bibliotek.
imported
w kodzie, zmniejszając w ten sposób rozmiar pakietu.