Это очень длинный ответ, потому что этот вопрос заслуживает очень длинного и подробного ответа, поскольку способ «наилучшей практики» является более сложным, чем ответ в несколько строк.
Iv'e поддерживал наши собственные библиотеки в течение 3,5 с лишним лет, и тогда я остановился на двух способах, которые, по моему мнению, должны быть связаны между собой библиотеками. Компромиссы зависят от того, насколько велика ваша библиотека, и лично мы компилируем оба способа, чтобы удовлетворить оба подмножества потребители.
Способ 1. Создайте файл index.ts со всем, что вы хотите, чтобы он был экспортирован, и целевым накоплением для этого файла в качестве входных данных. Объедините всю свою библиотеку в один файл index.js и файл index.css; С внешней зависимостью, унаследованной от потребительского проекта, чтобы избежать дублирования библиотечного кода. (Гист включен в нижней части примера конфигурации)
- Плюсы: легко использовать, так как пользователи проекта могут импортировать все из корневого пути относительно библиотеки
import { Foo, Bar } from "library"
- Минусы: это никогда не будет шататься по дереву; и, прежде чем люди скажут, сделайте это с ESM, и это будет с треском. NextJS не поддерживает ESM на данном текущем этапе и не поддерживает множество настроек проекта, поэтому все еще хорошая идея скомпилировать эту сборку только для CJS. Если кто-то импортирует 1 из ваших компонентов, он получит все css и весь javascript для всех ваших компонентов.
Метод 2: Это для опытных пользователей: создайте новый файл для каждого экспорта и используйте rollup-plugin-multi-input с опцией «preserveModules: true» в зависимости от того, какую систему css вы используете, вам также нужно убедиться, что ваш css НЕ объединен в один файл, но для каждого css-файла требуется оператор (". css"), который остается внутри выходного файла после свертывания, и этот css-файл существует.
- Плюсы: когда пользователи импортируют {Foo} из "library / dist / foo", они получают только код для Foo и css для Foo и ничего более.
- Минусы: эта настройка подразумевает, что потребитель должен обрабатывать операторы node_modules require (". Css") в своей конфигурации сборки с помощью NextJS, это делается с
next-transpile-modules
помощью пакета npm.
- Предостережение: Мы используем наш собственный плагин Babel, который вы можете найти здесь: https://www.npmjs.com/package/babel-plugin-qubic, чтобы позволить людям,
import { Foo,Bar } from "library"
а затем с Babel преобразовать его в ...
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
- Это автоматически потребует ("..") во всех вспомогательных функциях babel для objectSpread, классов и т. Д. От потребительского проекта, который уничтожит еще 15-25 КБ от размера вашего пакета и означает, что вспомогательные функции для objectSpread не будут дублироваться в вашей библиотеке. выходные данные + связанные проекты.
- Асинхронные функции все еще будут работать
- externals будет соответствовать всему, что начинается с этого суффикса зависимости от сверстников, т.е. babel-helpers будет совпадать с external для 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
в коде, таким образом уменьшая размер пакета.