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

The field "addWorkout" cannot be queried on the type "Mutation"

My journey with GraphQL has just begun, and after resolving a reference error in my previous question, I have encountered a new challenge. It appears that adding a workout is not working as expected, as the schema does not recognize it as a mutation field. ...

Struggling to make Vue.js transition effects function properly?

I'm having trouble getting a vue.js (version 1) transition to work. I copied the code from their official website, but it's not running the javascript console.logs! Vue.transition('fade', { css: false, enter: function ( ...

Can you guide me in utilizing this API endpoint efficiently to enable search functionality using React Query?

const { isLoading, isError, data, error, refetch } = useQuery( "college", async () => { const { result } = await axios( "http://colleges.hipolabs.com/search?name=middle" ); console.log(&quo ...

Manipulating elements with JavaScript to remove them, while ensuring that the empty space is automatically filled

Recently, I decided to enhance my understanding of JavaScript by experimenting with it on various websites. My goal was to use JavaScript to remove the right bar from a webpage and have the remaining body text automatically fill in the space left behind. ...

When publishing an Angular library using npm, you can exclude a specific folder while still including all of its files and sub-folders in the

After building my angular library app, I find the artifacts stored in the directory dist/. This means that when the library is imported into another application, it is done like this: import { XXX } from 'libname/dist' However, I wish to have th ...

Sending information from one page to another and then sending it once more

I am currently utilizing the following code to submit a form's data to : <script type="text/javascript"> $(document).ready(function(){ $("#textnextofkin").validate({ debug: false, rules: { ...

The initial click event for the input element in Jquery is not functioning correctly

I found a jQuery date selector online and the script looked something like this... <script type="text/javascript> $(document).ready(function () { $("#date3").click(function() { $("#date3").scroller({ preset: 'datetime' }); wheels = []; whe ...

Nunjucks not loading the script when moving from one page to another

Currently, I am in the process of developing a website utilizing nunjucks and express. This website serves as a blog platform with content sourced from prismic. My goal is to load a script file for an active campaign form whenever a user navigates from a b ...

How can the backgroundImage css in react admin <Login /> be replaced using Material-UI?

I have been refering to the following resources: Learn about customizing login page background in React-Admin: Explore themes customization in Material-UI: https://material-ui.com/customization/components/ Instead of using a preset background, I want to ...

Using Typescript for-loop to extract information from a JSON array

I'm currently developing a project in Angular 8 that involves utilizing an API with a JSON Array. Here is a snippet of the data: "success":true, "data":{ "summary":{ "total":606, "confirmedCasesIndian":563, "con ...

Troubleshooting Puppeteer installation error with npm on Ubuntu

Having trouble globally installing Puppeteer on Ubuntu 20.04: $ sudo npm install puppeteer -g An error message appeared: npm error code 1 npm error path /usr/local/lib/node_modules/puppeteer npm error command failed npm error command sh -c node install.mj ...

Is there a similar alternative to ignoring in webpack or browserify?

My code works perfectly in the browser after ignoring two packages with browserify: browserify files.js -i fs-extra -i request --standalone files > files.browserify.js. However, when I try to use webpack instead, the code throws errors about missing mod ...

What is the process for capturing a window screenshot using Node.js?

I am currently conducting research to discover a way to capture a screenshot of a window using Node.js. I have been attempting to achieve this with node-ffi, but I am facing some difficulties at the moment: var ffi = require('ffi'); var user32 ...

Tips for improving the scrolling function in Java with Selenium for optimal performance

I'm currently working on a project using Java in MAVEN. My task involves retrieving a URL, scrolling down the page, and extracting all the links to other items on that website. So far, I have been able to achieve this dynamically using Selenium, but ...

Decoding JavaScript elements embedded in an HTML website

My current HTML site includes the following code: <script type="text/javascript"> jwplayer('player_container').setup( { 'width': '640', ...

Using Firebase Admin or the regular Firebase with Next.js

Currently, I am working on a project using Next.js and integrating Firebase. I have been successfully fetching data in my components using the Firebase package designed for frontend use. However, I recently attempted to utilize Firebase within getServerS ...

`Can you bind ngModel values to make select options searchable?`

Is there a way to connect ngModel values with select-searchable options in Ionic so that default values from localStorage are displayed? <ion-col col-6> <select-searchable okText="Select" cancelText="Cancel" cla ...

setting up React package with npm installation

Currently, I am transitioning to react from pure front end development involving HTML, CSS, and a bit of jquery. As such, I have no prior experience with package installation. My intention was to install axios using npm. I initiated the process by running ...

Struggling to retrieve data from AJAX POST request [Revised Post]

I am encountering an issue with posting a form using the AJAX POST method in jQuery. I am using the serialize method to retrieve the form data, but it seems to fail. The problem might be related to the JavaScript files of the Steps Wizard plugin that I am ...

Dynamic Rendering of Object Arrays in Table Columns using JavaScript

In the process of developing an appointment slot selection grid, I have successfully grouped all appointments by dates. However, I am facing challenges in displaying this array of Objects as a clickable grid with columns. The current output can be viewed h ...