microbundle icon indicating copy to clipboard operation
microbundle copied to clipboard

[Question] How to specify different formats for multiple exports?

Open hood opened this issue 3 years ago • 10 comments

I'm trying to setup microbundle to provide separate exports for several modules my package is exporting, like this:

{
  "name": "x",
  "type": "module",
  "version": "10.0",
  "author": "y",
  "license": "MIT",
  "devDependencies": {
    "microbundle": "^0.15.0",
    "np": "^7.6.1",
    "typescript": "^4.6.4"
  },
  "dependencies": {},
  "scripts": {
    "prepare": "microbundle ./src/one.ts ./src/two.ts"
  },
  "exports": {
    "one": "./dist/one.modern.js",
    "two": "./dist/two.modern.js"
  },
  "files": [
    "dist"
  ],
  "types": "dist/index.d.ts"
}

However, I don't know how to specify different export formats for each one of my exports.

The documentations provides either this example, which shows how to proceed when doing "single" exports:

"exports": {
  "require": "./dist/foo.cjs",
  "default": "./dist/foo.modern.js"
},

or this example, which shows an example of multiple exports, but in a single format:

"exports": {
  ".": "./dist/foo.modern.mjs",
  "./lite": "./dist/lite.modern.mjs",
  "./full": "./dist/full.modern.mjs"
},

How could I specify multiple formats like in the 1st example, while still specifying multiple named exports like in the 2nd example?

hood avatar Jun 21 '22 16:06 hood

You combine them:

"exports": {
  "./one": {
    "require": "./dist/one.cjs",
    "default": "./dist/one.modern.js"
  },
  "./two": {
    "require": "./dist/two.cjs",
    "default": "./dist/two.modern.js"
  }
},

See https://nodejs.org/api/packages.html#exports

rschristian avatar Jun 21 '22 16:06 rschristian

Thanks a lot. Now I'm getting Cannot find module 'x/one' or its correspondent type declarations errors whenever trying to import stuff like:

import One from 'x/one';
import Two from 'x/two';

Is there something I should additionally specify in my package.json?

hood avatar Jun 21 '22 17:06 hood

Hmm, are you sure the path is correct/types distributed?

In TS 4.7 I believe you're required to add types to subpath exports like this, though (AFAIK) that's still in beta:

"exports": {
  "./one": {
    "types": "./dist/one.d.ts",
    "require": "./dist/one.cjs",
    "default": "./dist/one.modern.js"
  },
  "./two": {
    "types": "./dist/two.d.ts",
    "require": "./dist/two.cjs",
    "default": "./dist/two.modern.js"
  }
},

Edit: Microbundle might be compiling both types files to the same output destination. Does dist/index.d.ts look right for x/two?

rschristian avatar Jun 21 '22 17:06 rschristian

I can confirm my dist folder contains both one.d.ts and two.d.ts. After adding the types fields in my exports stuff nothing changed though. Same errors as before.

hood avatar Jun 21 '22 17:06 hood

It does contain a one.d.ts and two.d.ts? Are you using TS 4.7?

You have "types": "dist/index.d.ts" listed in your package.json. Does this file exist? Before TS 4.7, that's the field in use.

rschristian avatar Jun 21 '22 17:06 rschristian

It does contain a one.d.ts and two.d.ts? Are you using TS 4.7?

Yes and yes (on 4.7.4 as we're speaking).

You have "types": "dist/index.d.ts"listed in yourpackage.json`. Does this file exist? Before TS 4.7, that's the field in use.

I actually removed that field after adding types fields in my exports as you suggested. Should I add it back?

hood avatar Jun 21 '22 17:06 hood

Hm, interesting. Can reproduce, but don't know what the correct method is in TS these days. It sounds like this should work? https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/#package-json-exports-imports-and-self-referencing

"types" sounds like it's legacy and not preferred. In my previous comment I was thinking it maybe took precedence and you still had it lying around (neither of which are the case).

rschristian avatar Jun 21 '22 18:06 rschristian

I've set up a reproduction here: https://github.com/hood/microbundle-issue-973 . This is almost identical to the project I'm having issues configuring.

EDIT: To make testing more straightforward, I've also setup a test project here https://github.com/hood/microbundle-issue-973-annex , which imports the previously mentioned reproduction repository, in order to show you how things look in the current situation.

EDIT #2: I've also updated my exports to look like the following

  "exports": {
    "./a": {
      "import": {
        "types": "./dist/a.d.ts",
        "default": "./dist/a.modern.js"
      },
      "require": {
        "types": "./dist/a.d.ts",
        "default": "./dist/a.cjs"
      }
    },
    "./b": {
      "import": {
        "types": "./dist/b.d.ts",
        "default": "./dist/b.modern.js"
      },
      "require": {
        "types": "./dist/b.d.ts",
        "default": "./dist/b.cjs"
      }
    }
  },

but still to no avail. :cry:

hood avatar Jun 21 '22 19:06 hood

Any news on this? It's pretty blocking for a project I'm currently working on...

hood avatar Jun 23 '22 09:06 hood

Well, there's no news because this isn't a Microbundle issue. I personally have no idea how TS wants users to distribute types these days, your best bet is probably to post on Stack or a TS forum. I imagine this might be somewhat editor-specific too.

rschristian avatar Jun 23 '22 09:06 rschristian