Це надзвичайно довга відповідь, оскільки це запитання заслуговує на надзвичайно довгу та детальну відповідь, оскільки спосіб "найкращої практики" є складнішим, ніж лише декілька рядкових відповідей.
Iv'e підтримував наші домашні бібліотеки протягом 3,5+ років. На той час я вирішувався двома способами, я думаю, що бібліотеки повинні бути об'єднані, компроміси залежать від того, наскільки велика ваша бібліотека, і особисто ми складаємо обидва способи, щоб задовольнити обидва підмножини споживачі.
Спосіб 1: Створіть файл index.ts із усім, що ви хочете експортувати, і цільовим складом цього файлу в якості вхідного даних. Об’єднайте всю вашу бібліотеку в один файл index.js та файл index.css; Якщо зовнішня залежність успадковується від споживчого проекту, щоб уникнути дублювання бібліотечного коду. (суть міститься внизу прикладу конфігурації)
- Плюси: споживачі проектів легко використовувати, оскільки вони можуть імпортувати все з кореневої відносної бібліотеки
import { Foo, Bar } from "library"
- Мінуси: це ніколи не буде хитне дерево; і перед тим, як люди скажуть, зробіть це з ESM, і це буде зруйноване по деревах. NextJS не підтримує ESM на нинішньому етапі, а також не створює багато налаштувань проектів, тому все-таки хороша ідея зібрати цю збірку просто на CJS. Якщо хтось імпортує 1 ваш компонент, він отримає всі css та всі javascript для всіх ваших компонентів.
Спосіб 2: Це для досвідчених користувачів. Створіть новий файл для кожного експорту та використовуйте збірний плагін-мультивхід з опцією "saveModules: true", залежно від того, яку систему css ви використовуєте, також переконайтесь, що ваш css НЕ об'єднаний в один файл, але кожен файл css вимагає (". css") оператора залишається всередині вихідного файлу після скручування, і цей файл css існує.
- Плюси: Коли користувачі імпортують {Foo} з "library / dist / foo", вони отримають лише код для Foo, а css для Foo та більше нічого.
- Мінуси: ця налаштування передбачає, що споживач повинен обробляти node_modules вимагає (". Css") операторів у своїй конфігурації збірки з NextJS, це робиться з
next-transpile-modules
пакетом npm.
- Caveat: Ми використовуємо наш власний плагін Babel, який ви можете знайти тут: https://www.npmjs.com/package/babel-plugin-qubic, щоб дозволити людям,
import { Foo,Bar } from "library"
а потім за допомогою вавило перетворити його на ...
import { Foo } from "library/dist/export/foo"
import { Bar } from "library/dist/export/bar"
У нас є кілька конфігурацій збору, де ми використовуємо обидва способи; тож для користувачів бібліотеки, які не піклуються про струшування дерев, можна просто зробити "Foo from "library"
та імпортувати єдиний файл css; а для користувачів бібліотеки, які піклуються про струшування дерев і лише використовують критичний css, вони можуть просто увімкнути наш плагін babel.
Посібник зі збору кращих практик:
ви використовуєте машинопис або не ЗАВЖДИ будуєте за допомогою "rollup-plugin-babel": "5.0.0-alpha.1"
Переконайтесь, що ваш .babelrc виглядає так.
{
"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
}]
]
}
І так, що плагін Babel у сукупності виглядає так ...
babel({
babelHelpers: "runtime",
extensions,
include: ["src/**/*"],
exclude: "node_modules/**",
babelrc: true
}),
А ваш package.json виглядає НАСТУПНО так:
"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",
}
І, нарешті, ваші зовнішні представники в сукупності виглядають НАСТУПНО так.
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.
Чому?
- Це призведе до автоматичного успадкування реакції реагування / реагування дому та інших ваших однолітків / зовнішніх залежностей від споживчого проекту, тобто вони не будуть дублюватися у вашому пакеті.
- Це додасть до ES5
- Це автоматично зажадає ("..") у всіх функціях помічників для вафелі для objectSpread, класів тощо від споживчого проекту, який видалить ще 15-25 КБ від вашого розміру пакета і означатиме, що допоміжні функції для objectSpread не будуть дублюватися у вашій бібліотеці вихід + споживані проекти, що комплектуються.
- Функції асинхронізації все ще працюватимуть
- зовнішні відповідатимуть будь-чому, що починається з цього суфікса одноліткової залежності, тобто babel-helpers відповідатиме зовнішньому для babel-helpers / helpers / object-spread
Нарешті, ось суть для прикладу одного конфігураційного файлу виводу одного файлу index.js.
https://gist.github.com/ShanonJackson/deb65ebf5b2094b3eac6141b9c25a0e3
Де цільовий src / export / index.ts виглядає так ...
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
Повідомте мене, якщо у вас виникли проблеми з babel, накопиченням або у вас є які-небудь питання щодо комплектування / бібліотек.
imported
в коді, зменшуючи розмір пакета.