npm 将默认导出和命名导出与汇总混合

kdfy810k  于 2023-10-19  发布在  其他
关注(0)|答案(3)|浏览(129)

我正在使用TypeScript和Rollup编写Bluetooth library for Node.js。我想让用户能够通过以下方式导入我的库组件

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

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

我的项目结构看起来像这样:

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

相应的代码是这样的:

index.ts

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

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

sblendid.ts

export default class Sblendid {}

peripheral.ts

export default class Peripheral {}

我把所有的东西都和Rollup捆绑在一起,我的整个配置是这样的:

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

你可以在这里找到完整的代码
https://github.com/LukasBombach/sblendid/tree/master/packages/sblendid
现在,这个设置不起作用。汇总显示

$ 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

这是真的这

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

根本不起作用我要做的是:

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

我可以通过 * 不 * 混合命名广告默认导出来修复此行为,好吧,但这样我就失去了这样做的能力:

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

所以我在想。有没有 * 任何 * 方法,也许使用多个捆绑包,我可以让用户能够做到这两点:

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

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

vptzau2j1#

如果你只针对nodejs环境,你可以像这样导出(index.ts)

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

Sblendid.Peripheral = Peripheral;
export default Sblendid;
yhxst69z

yhxst69z2#

Commonjs没有 default 导出的概念。当你能够做到:

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

这确实意味着

assert.equal(Splendid.Peripheral, Peripheral);

Peripheral * 是Splendid的一个属性。
这基本上是通过

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

当cjs代码从esm代码转译时(rollup所做的),唯一的选择是在exports对象上引入default属性。
如果你不习惯仅仅为了导出而添加属性,可以在你的文档中添加一个这样的剪切。

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

toe950273#

我们可以通过修补汇总来实现这一点。
https://github.com/avisek/rollup-patch-seamless-default-export

// Default export
const lib = require('your-library')
lib('Hello') // <-- instead of using `.default` property

// Named exports
const { namedExport1, namedExport2 } = lib

// One liner syntex. This is also supported.
const { default: defaultExport, namedExport1, namedExport2 } = require('your-library')

相关问题