Fix types and exports of the package#197
Conversation
🦋 Changeset detectedLatest commit: 4b6fabe The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
robmosca
left a comment
There was a problem hiding this comment.
Tested on our code base and it seems to work well. 👍🏽
internettrans
left a comment
There was a problem hiding this comment.
This is a risky change. Changing the exports field is almost always a major breaking change, due to how different versions of Node, bundlers, etc handle the exports field. What version of typescript started supporting the exports field rather than types in package.json?
NOTE:
Due to rollup not inserting a compatibility layer when transpiling, in rare instances, consumers might have to access the main export with ".default". This is caused by a mix of named, and default exports.
The above sounds like it might be a breaking change.
| @@ -0,0 +1,5 @@ | |||
| --- | |||
| "single-spa-react": patch | |||
There was a problem hiding this comment.
Whenever the exports field changes in the package.json, it might need to be a major change because of how different bundlers and NodeJS versions handle it.
| "single-spa-react": patch | |
| "single-spa-react": major |
There was a problem hiding this comment.
This fix should handle all resolution strategies (all typescript strategies), along with all popular bundlers. Still, if someone is using an obscure tool, it might behave differently, so we could treat it as a breaking change. Problem is not only with the typescript version, but a combination of typescript "moduleResolution", and bundlers. Currently, create-single-spa uses the "node" (which is actually node10) resolution strategy. What do you think?
I have inserted a compatibility layer that fixes the issue with certain bundlers requiring access to default export with ".default". Now, all of the resolution strategies are correctly handled:
There was a problem hiding this comment.
Being totally honest, I would prefer calling it a major version just in case there's a weird edge case where it changes how things work. I don't know all the edge cases, but have had lots of github issues after changing my exports fields before.
I prefer single-spa-react users face no risk when doing patch upgrades.
There was a problem hiding this comment.
Changed it to Major.
| @@ -0,0 +1,10 @@ | |||
| import fs from "fs"; | |||
|
|
|||
| function copyFile(sourcePath, destinationPath) { | |||
There was a problem hiding this comment.
nitpick: calling fs.copyFileSync directly is simpler than extracting out a reusable copyFile function. Please remove.
There was a problem hiding this comment.
Removed the script, as it is no longer needed.
| "version": "5.1.4", | ||
| "description": "Single-spa lifecycles helper for React apps", | ||
| "main": "lib/umd/single-spa-react.js", | ||
| "main": "lib/cjs/single-spa-react.cjs", |
There was a problem hiding this comment.
Changing the main field from UMD to CJS is a breaking change. Please update the changeset to be a major
There was a problem hiding this comment.
Let's change this back - we can discuss the reasons for changing to CJS in Slack and possibly in another PR
There was a problem hiding this comment.
Reverted to UMD.
| } | ||
|
|
||
| /** | ||
| * If module is running in a CommonJS environment, a compatibility layer for node16 resolution strategy is inserted. |
There was a problem hiding this comment.
Please don't add extra changes in subsequent commits
| Parcel as SingleSpaParcel, | ||
| } from "single-spa"; | ||
|
|
||
| interface ParcelCompProps<ExtraProps = {}> { |
There was a problem hiding this comment.
Could this be moved to a shared declarations file, and then imported into both the .d.ts and .d.cts files?
import { ParcelCompProps } from './shared.d.ts';There was a problem hiding this comment.
If you agree, we can leave this as-is for now, since these files will not be needed when we migrate to typescript.
| @@ -0,0 +1,4 @@ | |||
| { | |||
| "main": "../lib/cjs/parcel.cjs", | |||
There was a problem hiding this comment.
The module format for this main field should match the format for the single-spa-react package.json (UMD)
| * During transpilation, Rollup correctly inserts the "exports.default", and "exports.__esModule" properties, but they are not respected by some bundlers. | ||
| * For more information see https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/CJSOnlyExportsDefault.md | ||
| */ | ||
| if (typeof module !== "undefined" && module.exports) { |
There was a problem hiding this comment.
Let's remove this, as discussed in the call

Fixes #170.
This fix employs several strategies to achieve compatibility with all resolution strategies (node10, node16 - cjs, node16 - esm, bundler).
Here is the analysis by https://arethetypeswrong.github.io/.
NOTE:
Due to rollup not inserting a compatibility layer when transpiling, in rare instances, consumers might have to access the main export with ".default". This is caused by a mix of named, and default exports.