developit / microbundle

📦 Zero-configuration bundler for tiny modules.
https://npm.im/microbundle
MIT License
8.03k stars 362 forks source link

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

Open hood opened 2 years ago

hood commented 2 years ago

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?

rschristian commented 2 years ago

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

hood commented 2 years ago

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?

rschristian commented 2 years ago

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?

hood commented 2 years ago

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.

rschristian commented 2 years ago

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.

hood commented 2 years ago

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?

rschristian commented 2 years ago

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).

hood commented 2 years ago

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 commented 2 years ago

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

rschristian commented 2 years ago

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.