javascript - Mezclando exportaciones por defecto y con nombre con Rollup
Estoy escribiendo una biblioteca de Bluetooth para Node.js usando TypeScript y Rollup. Quiero permitir que los usuarios importen los componentes de mi biblioteca de estas maneras
import Sblendid from "@sblendid/sblendid";
import Sblendid, { Peripheral } from "@sblendid/sblendid";
const Sblendid = require("@sblendid/sblendid");
const { Peripheral } = require("@sblendid/sblendid");
La estructura de mi proyecto se ve así:
root
∟ rollup.config.ts
∟ src
∟ index.ts
∟ sblendid.ts
∟ peripheral.ts
Y el código correspondiente es este:
index.ts
export {
default,
} from "./sblendid";
export {
default as Peripheral,
} from "./peripheral";
sblendid.ts
export default class Sblendid {}
peripheral.ts
export default class Peripheral {}
Estoy agrupando todo con Rollup y toda mi configuración es esta:
import typescript from "typescript";
import commonjs from "rollup-plugin-commonjs";
import resolve from "rollup-plugin-node-resolve";
import typescriptPlugin from "rollup-plugin-typescript2";
import autoExternal from "rollup-plugin-auto-external";
import { terser } from "rollup-plugin-terser";
import pkg from "./package.json";
export default {
input: "src/index.ts",
output: [
{
file: pkg.main,
format: "cjs",
sourcemap: true
},
{
file: pkg.module,
format: "es",
sourcemap: true
}
],
plugins: [
autoExternal(),
resolve({ preferBuiltins: true }),
commonjs(),
typescriptPlugin({ typescript, objectHashIgnoreUnknownHack: true }),
terser()
]
};
Puedes encontrar el código completo aquí
https://github.com/LukasBombach/sblendid/tree/master/packages/sblendid
Ahora, esta configuración no funciona. Rollup me dice
rollup -c rollup.config.ts src/index.ts → dist/index.cjs.js, dist/index.es.js... (!) Mixing named and default exports Consumers of your bundle will have to use bundle['default'] to access the default export, which may not be what you want. Use `output.exports: 'named'` to disable this warning
lo cual es cierto. Esto
const Sblendid = require("@sblendid/sblendid");
simplemente no funciona. Lo que tengo que hacer es esto:
const Sblendid = require("@sblendid/sblendid").default;
Puedo arreglar este comportamiento no mezclando exportaciones nombradas y por defecto, ok, pero entonces pierdo la capacidad de hacer esto:
import Sblendid, { Peripheral } from "@sblendid/sblendid";
Así que me pregunto. ¿Hay alguna forma, tal vez usando múltiples paquetes, en que pueda lograr que los usuarios puedan hacer ambas cosas:
// This
import Sblendid from "@sblendid/sblendid";
import Sblendid, { Peripheral } from "@sblendid/sblendid";
// And this
const Sblendid = require("@sblendid/sblendid");
const { Peripheral } = require("@sblendid/sblendid");
Respuesta #1
Si solo apuntas al entorno de Node.js, puedes exportar así (index.ts)
import Sblendid from "./sblendid";
import Peripheral from "./peripheral";
Sblendid.Peripheral = Peripheral;
export default Sblendid;
Respuesta #2
Commonjs no tiene el concepto de exportación por defecto. Cuando puedas, haz:
const Splendid = require("@sblendid/sblendid");
const { Peripheral } = require("@sblendid/sblendid");
Significa eso
assert.equal(Splendid.Peripheral, Peripheral);
Ese Peripheral es una propiedad de Splendid.
Esto se logra básicamente mediante
Splendid.Peripheral = /* something */;
module.exports = Splendid;
Cuando el código cjs se transpila desde código esm (lo que hace rollup), la única opción es introducir una propiedad default en el objeto exports.
Si no te sientes cómodo agregando propiedades solo por el hecho de exportarlas, agrega un fragmento como este a tus documentos.
const { default: Splendid, Peripheral } = require('...');
