Skip to content

(marked) Add export map and esm entrypoint#57236

Merged
weswigham merged 1 commit intomasterfrom
marked-export-map
Nov 18, 2021
Merged

(marked) Add export map and esm entrypoint#57236
weswigham merged 1 commit intomasterfrom
marked-export-map

Conversation

@weswigham
Copy link
Contributor

This adds an export map that mirror's marked's own and a compatible esm entrypoint which ensures typescript can correctly allow both esm and cjs imports of the package under module: nodenext.

@typescript-bot
Copy link
Contributor

typescript-bot commented Nov 17, 2021

@weswigham Thank you for submitting this PR!

This is a live comment which I will keep updated.

1 package in this PR

Code Reviews

Because this PR edits the configuration file, it can be merged once it's reviewed by a DT maintainer.

You can test the changes of this PR in the Playground.

Status

  • ✅ No merge conflicts
  • ✅ Continuous integration tests have passed
  • 🕐 A DT maintainer needs to approve changes which affect module config files

Once every item on this list is checked, I'll ask you for permission to merge and publish the changes.


Diagnostic Information: What the bot saw about this PR
{
  "type": "info",
  "now": "-",
  "pr_number": 57236,
  "author": "weswigham",
  "headCommitOid": "5f2eadf20d68a1acc3a2d39ea499862a8d5f3c46",
  "lastPushDate": "2021-11-17T21:41:35.000Z",
  "lastActivityDate": "2021-11-17T22:00:03.000Z",
  "hasMergeConflict": false,
  "isFirstContribution": false,
  "tooManyFiles": false,
  "popularityLevel": "Popular",
  "pkgInfo": [
    {
      "name": "marked",
      "kind": "edit",
      "files": [
        {
          "path": "types/marked/OTHER_FILES.txt",
          "kind": "package-meta",
          "suspect": "not [the expected form](https://github.com/DefinitelyTyped/DefinitelyTyped#user-content-other_filestxt)"
        },
        {
          "path": "types/marked/index.d.mts",
          "kind": "package-meta",
          "suspect": "edited"
        },
        {
          "path": "types/marked/package.json",
          "kind": "package-meta",
          "suspect": "not [the expected form](https://github.com/DefinitelyTyped/DefinitelyTyped#user-content-packagejson) (check: `exports`)"
        }
      ],
      "owners": [
        "worr",
        "BendingBender",
        "CrossR",
        "mwickett",
        "htkzhtm",
        "ezracelli",
        "scandinave",
        "sarunint",
        "UziTech",
        "Toliak"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Popular"
    }
  ],
  "reviews": [
    {
      "type": "approved",
      "reviewer": "UziTech",
      "date": "2021-11-17T22:00:03.000Z",
      "isMaintainer": false
    }
  ],
  "mainBotCommentID": 972087140,
  "ciResult": "pass"
}

@typescript-bot typescript-bot added Popular package This PR affects a popular package (as counted by NPM download counts). Check Config Changes a module config files labels Nov 17, 2021
@typescript-bot
Copy link
Contributor

🔔 @worr @BendingBender @CrossR @mwickett @htkzhtm @ezracelli @scandinave @sarunint @UziTech @Toliak — please review this PR in the next few days. Be sure to explicitly select Approve or Request Changes in the GitHub UI so I know what's going on.

@@ -0,0 +1 @@
export * from "./index.js"; No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is index.js referring to here? should it be index.d.ts?

Copy link
Contributor Author

@weswigham weswigham Nov 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah - esm imports have to have extensions and TS expects them to be the "output" extensions - so the js file extension (TS then maps that back to the declaration file internally).

@typescript-bot typescript-bot added the Owner Approved A listed owner of this package signed off on the pull request. label Nov 17, 2021
@weswigham weswigham merged commit 7d18234 into master Nov 18, 2021
@43081j
Copy link
Contributor

43081j commented May 16, 2022

just noticed this when updating one of our repos. @weswigham would you mind explaining what the new mts file's purpose is?

the existing index.d.ts already has named exports, which are accurate under CJS and ESM (since there's no node-specific nonsense like export assignments).

out of curiosity more than anything, what does it solve that was presumably broken before? i.e. couldn't you have just pointed both the cjs and esm type exports to the same file since they really are the same as far as the type system is concerned.

@weswigham
Copy link
Contributor Author

weswigham commented May 16, 2022

It allows TS to detect the correct format data for the import, and thus prevent getting a phantom default import member when importing in esm.

@43081j
Copy link
Contributor

43081j commented May 16, 2022

since there is no export assignment (CJS) or default export, the existing types were correct for both CJS and ESM consumption, as far as i can see.

tsc would have loaded types from @types/marked which would've been index.d.ts - type definitions which are correct regardless of your module system.

where would we get a default export? maybe im just missing some special behaviour tsc has, but it looks like we should only need two type entry points if the types differ between CJS and ESM (which they don't here).

@weswigham
Copy link
Contributor Author

where would we get a default export?

An esm file importing a cjs file module has the whole cjs module available as a default - this is node's behavior. An import of an esm file, meanwhile, does not.

@43081j
Copy link
Contributor

43081j commented May 16, 2022

but here we're only concerned with the type system. so does typescript apply some special behaviour where it fabricates a default export?

before this PR, importing this in ESM and CJS worked as expected. so the situation where it wouldn't work was what?

sorry for the many questions, just trying to get my head around why this change was needed in case it pops up elsewhere and to be sure it isn't redundant.

@weswigham
Copy link
Contributor Author

It's not so much TS "giving a module a default" as TS building the module's externally visible exports in a way closer to node itself?

For context, when an esm file in node imports a cjs file, node syntactically finds export names in the cjs file, hoists those names to be visible as named imports, and then makes the module itself available as the default import (so, for example, export assigned modules are available). If the cjs module actually has an export named default, which is often the case, such a member becomes available as the default member of the default import. Eg, if you wrote import * as NS from "mod", you'd have to write NS.default.default to get the actual cjs module's 'default'.

@43081j
Copy link
Contributor

43081j commented May 17, 2022

yup i understand all of that now

in the package exports, you could've technically pointed both at the same d.ts though, right? since there's no difference, both export exactly the same types as far as tsc is concerned. and in that case, why did we need the exports map at all?

i guess the bit im missing is: how does this change help with what you explained. typescript will see the exact same exports before and after this change, so is it doing something special just because its a d.mts file?

@weswigham
Copy link
Contributor Author

weswigham commented May 17, 2022

No, you can't point both at the same file because the format is determined by the file, not the export map condition, and a file only has one format. A import condition is free to point at a cjs file if you'd like.

so is it doing something special just because its a d.mts file?

Yes.

@43081j
Copy link
Contributor

43081j commented May 17, 2022

ok i kinda see now.

i had a play around and i see, if you import from a cjs file (resolving to cjs/cts/d.cts), you have a default export always available. in all other cases, there isn't one unless we literally exported a default (esm).

so i guess the default must be commonjs since we haven't given it a cts extension.

@jakebailey jakebailey deleted the marked-export-map branch March 27, 2023 16:34
@reosablo reosablo mentioned this pull request Apr 16, 2023
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Check Config Changes a module config files Owner Approved A listed owner of this package signed off on the pull request. Popular package This PR affects a popular package (as counted by NPM download counts).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants