Esta es una respuesta extremadamente larga porque esta pregunta merece una respuesta extremadamente larga y detallada ya que la forma de "mejor práctica" es más complicada que solo una respuesta de pocas líneas.
Mantuve nuestras bibliotecas internas durante más de 3.5 años en ese tiempo. Me decidí por dos maneras, creo que las bibliotecas deberían agruparse. consumidores
Método 1: Cree un archivo index.ts con todo lo que desea exportar expuesto y el paquete acumulativo de destino en este archivo como entrada. Agrupe toda su biblioteca en un solo archivo index.js e index.css; Con dependencias externas heredadas del proyecto del consumidor para evitar la duplicación del código de la biblioteca. (esencia incluida en la parte inferior de la configuración de ejemplo)
- Pros: fácil de consumir ya que los consumidores del proyecto pueden importar todo desde la ruta de la biblioteca relativa a la raíz
import { Foo, Bar } from "library"
- Contras: Esto nunca será sacudible del árbol; y antes de que la gente diga, haga esto con ESM y será sacudible. NextJS no admite ESM en esta etapa actual y tampoco lo hacen muchas configuraciones de proyecto, por eso sigue siendo una buena idea compilar esta compilación solo para CJS. Si alguien importa 1 de sus componentes, obtendrá todo el CSS y todo el JavaScript para todos sus componentes.
Método 2: Esto es para usuarios avanzados: cree un nuevo archivo para cada exportación y use rollup-plugin-multi-input con la opción "preserveModules: true" dependiendo de cómo el sistema css que esté usando también necesite asegurarse de que su css NO se fusiona en un solo archivo, pero que cada archivo css requiere una declaración (". css") se deja dentro del archivo de salida después del paquete y ese archivo css existe.
- Pros: Cuando los usuarios importen {Foo} de "library / dist / foo", solo obtendrán el código para Foo, y el CSS para Foo y nada más.
- Contras: Esta configuración implica que el consumidor que tiene que manejar node_modules requiere declaraciones (". Css") en su configuración de compilación con NextJS, esto se hace con el
next-transpile-modules
paquete npm.
- Advertencia: utilizamos nuestro propio complemento de babel que puede encontrar aquí: https://www.npmjs.com/package/babel-plugin-qubic para permitir que las personas
import { Foo,Bar } from "library"
y luego con babel lo transformen en ...
import { Foo } from "library/dist/export/foo"
import { Bar } from "library/dist/export/bar"
Tenemos múltiples configuraciones de resumen donde realmente utilizamos ambos métodos; por lo tanto, los consumidores de la biblioteca que no se preocupan por el movimiento de los árboles pueden simplemente hacer "Foo from "library"
e importar el archivo CSS único; y para los consumidores de la biblioteca que se preocupan por la sacudida de los árboles y que solo usan CSS crítico, pueden activar nuestro complemento babel.
Guía de resumen para las mejores prácticas:
ya sea que esté utilizando mecanografiado o no SIEMPRE compile con "rollup-plugin-babel": "5.0.0-alpha.1"
Asegúrese de que su .babelrc tenga este aspecto.
{
"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
}]
]
}
Y con el plugin de babel en rollup con este aspecto ...
babel({
babelHelpers: "runtime",
extensions,
include: ["src/**/*"],
exclude: "node_modules/**",
babelrc: true
}),
Y su package.json parece ATLEAST así:
"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",
}
Y, finalmente, sus elementos externos en el rollup se ven ATLEAST así.
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.
¿Por qué?
- Esto agrupará su mierda automáticamente para heredar react / react-dom y sus otras dependencias pares / externas del proyecto del consumidor, lo que significa que no se duplicarán en su paquete.
- Esto se incluirá en ES5
- Esto requerirá automáticamente ("..") en todas las funciones auxiliares de babel para objectSpread, clases, etc. DEL proyecto del consumidor que borrará otros 15-25 KB del tamaño de su paquete y significa que las funciones auxiliares para objectSpread no se duplicarán en su biblioteca salida + la salida agrupada de los proyectos consumidores.
- Las funciones asincrónicas seguirán funcionando
- los externos coincidirán con todo lo que comience con ese sufijo de dependencia de pares, es decir, babel-helpers coincidirá con los externos para babel-helpers / helpers / object-spread
Finalmente, aquí hay un resumen de un archivo de configuración de resumen de salida de archivo index.js de ejemplo único.
https://gist.github.com/ShanonJackson/deb65ebf5b2094b3eac6141b9c25a0e3
Donde el objetivo src / export / index.ts se ve así ...
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
Avíseme si tiene algún problema con babel, rollup o si tiene alguna pregunta sobre agrupación / bibliotecas.
imported
en el código, disminuyendo así el tamaño del paquete.