Combining default and named exports in Rollup configuration

Currently, I am in the process of developing a Bluetooth library for Node.js which will be utilizing TypeScript and Rollup. My goal is to allow users to import components from my library in various ways.

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

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

The structure of my project is organized as follows:

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

The corresponding code for each file is demonstrated like this:

index.ts

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

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

sblendid.ts

export default class Sblendid {}

peripheral.ts

export default class Peripheral {}

To bundle everything together with Rollup, here is my configuration:

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

You can view the complete code here:

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

However, there seems to be an issue with the current setup. Rollup is indicating that:

$ 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

This means that simply using:

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

is not functioning as expected. To address this, I must adjust it to:

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

Although this resolves the issue, it limits the capability of doing both:

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

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

Answer №1

To export in a nodejs environment specifically, you can use the following method in your index.ts file:

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

Sblendid.Peripheral = Peripheral;
export default Sblendid;

Answer №2

In the Commonjs module system, there is no direct support for default exports. This means that when you import modules, you need to explicitly specify which parts of the module you want to use:

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

This leads to:

assert.equal(Splendid.Peripheral, Peripheral);

Showing that Peripheral is a property of the Splendid object.

To simulate default export behavior in Commonjs, you can manually assign properties and then export the module like so:

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

During transpilation from ES module code to Commonjs (which tools like Rollup do), a `default` property is added to the `exports` object as a workaround.

If you prefer not to add properties just to facilitate exporting, you can use a destructuring assignment with a `default` alias:

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

Answer №3

To achieve this, we can apply a patch to rollup.

Check out the rollup patch for seamless default export here

// Use of default export
const myLibrary = require('your-library')
myLibrary('Hello') // <-- avoiding usage of `.default` property

// Using named exports
const { namedExport1, namedExport2 } = myLibrary

// One-liner syntax also works:
const { default: defaultExport, namedExport1, namedExport2 } = require('your-library')

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

List component in Angular not refreshing after sorting the array in the service

Currently, I am delving into the realm of Angular (version 5+) to enhance my skills by working on a small project. The project involves setting up basic routing functionalities to showcase the ContactList component upon selecting a navigation tab. Addition ...

A convenient npm tool for combining HTML files into a single document

I have a specific need to combine several HTML files into a single file. This involves eliminating the HTML tags and HEAD tag from each file, then merging them into one file with only one set of HTML and HEAD tags. I am wondering if there are any existing ...

Deactivate the backface culling feature when loading an imported .obj file in three.js

I'm struggling with disabling wireframe rendering on the rear side of my vehicle. Any ideas on how to deactivate backface culling in wireframe mode for three.js? Check out this link for a helpful image ...

Ensuring Filesize Verification Prior to Upload on Internet Explorer Using Javascript

Can JavaScript be used to verify a file's size before it is uploaded to the server at the client side? This application is developed using EXTJS and Java and is limited to Internet Explorer 7 on Windows XP machines. ActiveX cannot be used. The workf ...

Error encountered: Exceeded maximum update depth in Material UI Data Grid

Encountering an error or warning when inputting rows in the table that is causing the screen to freeze. Warning: Maximum update depth exceeded. This issue can arise when a component triggers setState within useEffect, but useEffect doesn't have a de ...

Can you show me a way to display a dynamically created array component on an Angular2 template html?

One way I've been able to generate dynamic component instances is by choosing from pre-existing components. For instance, @Component({ selector: 'dynamic-component', template: `<div #container><ng-content></ng-conten ...

Setting attributes on an AngularJS Directive element in real time

My goal is to create a directive in AngularJS with a template that can contain other AngularJS directives. All of my directives require an "id" attribute, so I must set the "id" on the directive within the template. However, no matter how I attempt this, A ...

Retrieve the database value for the chosen name and then add that name to a different table

I am working on a dropdown feature that fetches categories from a database and displays the selected category price in a textfield. For example, when 'web development' is selected, the price ($12) will display in the textfield. Below is the cod ...

What is the best way to eliminate all frames from the current windows using jQuery?

When transitioning to another page from my center frame, I need to ensure that the top and bottom frames are not visible in the new page. This will prevent my spinner or footer from showing up on the page I'm navigating to. Is it possible to achieve ...

Tips for obtaining results from a File Reader

I am currently facing an issue with an onchange event in my HTML. The event is intended to retrieve an image from the user, convert it to a data URL, and then send it over socket.io to store in the database. However, I am struggling to figure out how to ac ...

Developing maintenance logic in Angular to control subsequent API requests

In our Angular 9 application, we have various components, some of which have parent-child relationships while others are independent. We begin by making an initial API call that returns a true or false flag value. Depending on this value, we decide whether ...

Navigate to items within a content block with a set height

I have a <div> that has a fixed height and overflow-y: scroll. Inside this div, there is mostly a <p> tag containing a long text with some highlighting (spans with background-color and a numbered id attribute). Just to note, this is an HTML5 a ...

An elusive melody that plays only when I execute the play command

I am currently working on creating a music Discord bot using the yt-search library, however, I am encountering an issue where it returns undefined when trying to play a song and joins the voice channel without actually playing anything. My approach is to u ...

What is the best way to create shaded areas upon clicking them?

How can I implement shading on areas when they are clicked? Contractor Form (Package One) <area id="39" name ="39" alt="" title="39" href="#" shape="poly" coords="12,204,12,120,138,117,144,72,248,72,252,124,526,125,632,81,668,157,698,149,722,2 ...

Steps for deploying Angular 2 using grunt

I'm currently in the process of developing an Angular2 application and my goal is to utilize Grunt for deployment. However, upon running the deployed index.html file, I've encountered issues with my code not functioning as intended. The specific ...

The Chrome developer tools are unable to locate the HttpRequest

While working in Python, I am utilizing the requests library to make a POST request to a specific URL. However, upon clicking the button, it seems that nothing is happening as per Chrome Developer Tools. No XHR requests are being made and no data is being ...

What is the process for installing the most recent minor release of a package on npm?

For instance: I currently have version 2.0.0 of the package named package-name installed. The latest minor version with the same major version is 2.1.2 The latest major version (which would be installed if I ran npm install package-name@latest) is 4.3.0 ...

Return to the previous URL after executing window.open in the callback

I need help redirecting the callback URL back to the parent window that initially called window.open. Right now, the callback URL opens inside the child window created by the parent. Here's the scenario: The Parent Window opens a child window for aut ...

What could be causing TypeScript to throw errors when attempting to utilize refs in React?

Currently, I am utilizing the ref to implement animations on scroll. const foo = () => { if (!ref.current) return; const rect = ref.current.getBoundingClientRect(); setAnimClass( rect.top >= 0 && rect.bottom <= window.i ...

What is the correct way to insert a new key-value pair into an object within the state of functional components?

Is there a way to dynamically add key-value pairs to the initial state of an empty object in functional components, similar to computed property names in class components? I currently have an initial state of {}. const [choice, setChoice] = useState({}) ...