javascript - Blanda standard- och namngivna exporteringar med Rollup


Jag skriver ett Bluetooth-bibliotek för Node.js med TypeScript och Rollup. Jag vill att användare ska kunna importera komponenterna i mitt bibliotek på dessa sätt

import Sblendid from "@sblendid/sblendid";
import Sblendid, { Peripheral } from "@sblendid/sblendid";

const Sblendid = require("@sblendid/sblendid");
const { Peripheral } = require("@sblendid/sblendid");

Min projektstruktur ser ut så här:

root
 ∟ rollup.config.ts
 ∟ src
    ∟ index.ts
    ∟ sblendid.ts
    ∟ peripheral.ts

Och den motsvarande koden är denna:

index.ts

export {
  default,
} from "./sblendid";

export {
  default as Peripheral,
} from "./peripheral";

sblendid.ts

export default class Sblendid {}

peripheral.ts

export default class Peripheral {}

Jag paketerar allt med Rollup och hela min konfiguration är denna:

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()
  ]
};

Du kan hitta hela koden här

https://github.com/LukasBombach/sblendid/tree/master/packages/sblendid

Nu fungerar inte detta upplägg. Rollup säger till mig

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

vilket är sant. Detta

const Sblendid = require("@sblendid/sblendid");

fungerar helt enkelt inte. Det jag måste göra är detta:

const Sblendid = require("@sblendid/sblendid").default;

Jag kan åtgärda detta beteende genom att inte blanda namngivna och standardexporter, okej, men då förlorar jag möjligheten att göra detta:

import Sblendid, { Peripheral } from "@sblendid/sblendid";

Så jag undrar. Finns det något sätt, kanske genom att använda flera paket, som gör att användare kan göra båda:

// This
import Sblendid from "@sblendid/sblendid";
import Sblendid, { Peripheral } from "@sblendid/sblendid";

// And this
const Sblendid = require("@sblendid/sblendid");
const { Peripheral } = require("@sblendid/sblendid");

Svar #1

Om du bara riktar dig mot Node.js-miljön kan du exportera så här (index.ts)

import Sblendid from "./sblendid";
import Peripheral from "./peripheral";

Sblendid.Peripheral = Peripheral;
export default Sblendid;

Svar #2

Commonjs har inte konceptet med standard-export. När du kan gör:

const Splendid = require("@sblendid/sblendid");
const { Peripheral } = require("@sblendid/sblendid");

Det betyder det

assert.equal(Splendid.Peripheral, Peripheral);

Den Peripheral är en egenskap hos Splendid.

Detta uppnås i princip genom

Splendid.Peripheral = /* something */;
module.exports = Splendid;

När cjs-kod transpileras från esm-kod (vad rollup gör) är det enda alternativet att införa en default-egenskap på exports-objektet.

Om du inte känner dig bekväm med att lägga till egenskaper bara för att exportera, lägg till ett stycke som detta i din dokumentation.

const { default: Splendid, Peripheral } = require('...');

Relaterade artiklar