Búsqueda de sitios web

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('...');

Artículos relacionados