Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove 'import' from default Package Exports conditions #36584

Closed
wants to merge 1 commit into from
Closed

Remove 'import' from default Package Exports conditions #36584

wants to merge 1 commit into from

Conversation

huntie
Copy link
Member

@huntie huntie commented Mar 22, 2023

Summary:
The Exports RFC had assumed that supporting the "import" condition was a syntax-only difference, given we are not in a Node.js environment — and so was worthwhile to support for maximal ecosystem compatibility.

image

This assumption is similar to --moduleResolution bundler in TypeScript 5.0:

bundlers and runtimes that include a range of Node-like resolution features and ESM syntax, but do not enforce the strict resolution rules that accompany ES modules in Node or in the browser
-- microsoft/TypeScript#51669 (comment)

However, @robhogan has rightly pointed out that we should not do this!

  • ESM (once transpiled) is not simply a stricter subset of in-scope features supported by CJS. For example, it supports top-level async, which would be breaking at runtime.
  • We recently made the same change for our Jest environment:

As such, we are erring on the side of correctness and supporting only ['require', 'react-native'] in our defaults. At runtime, all code run by React Native is anticipated to be CommonJS. "exports" will instead allow React Native to correctly select the CommonJS versions of modules from all npm packages.

  • Metro will require future extended behaviour in order to dynamically set 'import' based on how the module is imported/require()d. For now this is not in scope.

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now ['require', 'react-native']

Metro changelog: [Experimental] Package Exports unstable_conditionNames now defaults to ['require']

Differential Revision: D44303559

@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Facebook Partner: Facebook Partner fb-exported labels Mar 22, 2023
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D44303559

@analysis-bot
Copy link

analysis-bot commented Mar 22, 2023

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 8,520,044 +0
android hermes armeabi-v7a 7,835,942 +0
android hermes x86 8,999,858 +0
android hermes x86_64 8,855,178 +0
android jsc arm64-v8a 9,141,421 +0
android jsc armeabi-v7a 8,333,361 +0
android jsc x86 9,195,916 +0
android jsc x86_64 9,454,039 +0

Base commit: 0443c2a
Branch: main

huntie added a commit to huntie/metro that referenced this pull request Mar 23, 2023
Summary:
X-link: facebook/react-native#36584

The [Exports RFC](https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md) had assumed that supporting the `"import"` condition was a syntax-only difference, given we are not in a Node.js environment — and so was worthwhile to support for maximal ecosystem compatibility.

{F915841105}

This assumption is similar to [`--moduleResolution bundler` in TypeScript 5.0](microsoft/TypeScript#51669):

> bundlers and runtimes that include a range of Node-like resolution features and ESM syntax, but do not enforce the strict resolution rules that accompany ES modules in Node or in the browser
> -- microsoft/TypeScript#51669 (comment)

However, robhogan has rightly pointed out that **we should not do this!**

- ESM (once transpiled) is **not** simply a stricter subset of in-scope features supported by CJS. For example, it supports top-level async, which would be breaking at runtime.
- We recently made the same change for our Jest environment:
    - facebook/react-native@681d7f8

As such, we are erring on the side of correctness and supporting only `['require', 'react-native']` in our defaults. At runtime, all code run by React Native is anticipated to be CommonJS. `"exports"` will instead allow React Native to correctly select the CommonJS versions of modules from all npm packages.

Changelog:
[Change][General] Default condition set for experimental Package Exports is now `['require', 'react-native']`

Metro changelog: [Experimental] Package Exports `unstable_conditionNames` now defaults to `['require']`

Differential Revision: D44303559

fbshipit-source-id: 703561b16d0afc7723b763cdfd61236b46202f50
huntie added a commit to huntie/metro that referenced this pull request Mar 23, 2023
Summary:
Pull Request resolved: facebook#955

X-link: facebook/react-native#36584

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now `['require', 'react-native']`

The [Exports RFC](https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md) had assumed that supporting the `"import"` condition was a syntax-only difference, given we are not in a Node.js environment — and so was worthwhile to support for maximal ecosystem compatibility.

{F915841105}

This assumption is similar to [`--moduleResolution bundler` in TypeScript 5.0](microsoft/TypeScript#51669):

> bundlers and runtimes that include a range of Node-like resolution features and ESM syntax, but do not enforce the strict resolution rules that accompany ES modules in Node or in the browser
> -- microsoft/TypeScript#51669 (comment)

However, robhogan has rightly pointed out that **we should not do this!**

- ESM (once transpiled) is **not** simply a stricter subset of in-scope features supported by CJS. For example, it supports top-level async, which would be breaking at runtime.
- We recently made the same change for our Jest environment:
    - facebook/react-native@681d7f8

As such, we are erring on the side of correctness and supporting only `['require', 'react-native']` in our defaults. At runtime, all code run by React Native is anticipated to be CommonJS. `"exports"` will instead allow React Native to correctly select the CommonJS versions of modules from all npm packages.

Metro changelog: [Experimental] Package Exports `unstable_conditionNames` now defaults to `['require']`

Differential Revision: D44303559

fbshipit-source-id: fd32e5664679fa6d8fe8c6dca8c3d4b43d867589
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D44303559

Summary:
X-link: facebook/metro#955

Pull Request resolved: #36584

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now `['require', 'react-native']`

The [Exports RFC](https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md) had assumed that supporting the `"import"` condition was a syntax-only difference, given we are not in a Node.js environment — and so was worthwhile to support for maximal ecosystem compatibility.

{F915841105}

This assumption is similar to [`--moduleResolution bundler` in TypeScript 5.0](microsoft/TypeScript#51669):

> bundlers and runtimes that include a range of Node-like resolution features and ESM syntax, but do not enforce the strict resolution rules that accompany ES modules in Node or in the browser
> -- microsoft/TypeScript#51669 (comment)

However, robhogan has rightly pointed out that **we should not do this!**

- ESM (once transpiled) is **not** simply a stricter subset of in-scope features supported by CJS. For example, it supports top-level async, which would be breaking at runtime.
- We recently made the same change for our Jest environment:
    - 681d7f8

As such, we are erring on the side of correctness and supporting only `['require', 'react-native']` in our defaults. At runtime, all code run by React Native is anticipated to be CommonJS. `"exports"` will instead allow React Native to correctly select the CommonJS versions of modules from all npm packages.

Metro changelog: [Experimental] Package Exports `unstable_conditionNames` now defaults to `['require']`

Reviewed By: robhogan

Differential Revision: D44303559

fbshipit-source-id: 1198de4e629e23f1c7a36e5d1d23d2013203d3db
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D44303559

huntie added a commit to huntie/metro that referenced this pull request Mar 23, 2023
Summary:
Pull Request resolved: facebook#955

X-link: facebook/react-native#36584

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now `['require', 'react-native']`

The [Exports RFC](https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md) had assumed that supporting the `"import"` condition was a syntax-only difference, given we are not in a Node.js environment — and so was worthwhile to support for maximal ecosystem compatibility.

{F915841105}

This assumption is similar to [`--moduleResolution bundler` in TypeScript 5.0](microsoft/TypeScript#51669):

> bundlers and runtimes that include a range of Node-like resolution features and ESM syntax, but do not enforce the strict resolution rules that accompany ES modules in Node or in the browser
> -- microsoft/TypeScript#51669 (comment)

However, robhogan has rightly pointed out that **we should not do this!**

- ESM (once transpiled) is **not** simply a stricter subset of in-scope features supported by CJS. For example, it supports top-level async, which would be breaking at runtime.
- We recently made the same change for our Jest environment:
    - facebook/react-native@681d7f8

As such, we are erring on the side of correctness and supporting only `['require', 'react-native']` in our defaults. At runtime, all code run by React Native is anticipated to be CommonJS. `"exports"` will instead allow React Native to correctly select the CommonJS versions of modules from all npm packages.

Metro changelog: [Experimental] Package Exports `unstable_conditionNames` now defaults to `['require']`

Reviewed By: robhogan

Differential Revision: D44303559

fbshipit-source-id: 0d7395ad0a44019ef4b2cad0b43d78dcecc5ecd0
facebook-github-bot pushed a commit to facebook/metro that referenced this pull request Mar 23, 2023
Summary:
Pull Request resolved: #955

X-link: facebook/react-native#36584

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now `['require', 'react-native']`

The [Exports RFC](https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md) had assumed that supporting the `"import"` condition was a syntax-only difference, given we are not in a Node.js environment — and so was worthwhile to support for maximal ecosystem compatibility.

{F915841105}

This assumption is similar to [`--moduleResolution bundler` in TypeScript 5.0](microsoft/TypeScript#51669):

> bundlers and runtimes that include a range of Node-like resolution features and ESM syntax, but do not enforce the strict resolution rules that accompany ES modules in Node or in the browser
> -- microsoft/TypeScript#51669 (comment)

However, robhogan has rightly pointed out that **we should not do this!**

- ESM (once transpiled) is **not** simply a stricter subset of in-scope features supported by CJS. For example, it supports top-level async, which would be breaking at runtime.
- We recently made the same change for our Jest environment:
    - facebook/react-native@681d7f8

As such, we are erring on the side of correctness and supporting only `['require', 'react-native']` in our defaults. At runtime, all code run by React Native is anticipated to be CommonJS. `"exports"` will instead allow React Native to correctly select the CommonJS versions of modules from all npm packages.

Metro changelog: [Experimental] Package Exports `unstable_conditionNames` now defaults to `['require']`

Reviewed By: robhogan

Differential Revision: D44303559

fbshipit-source-id: 0077e547e7775e53d1e4e9c3a9d01347f4fb7d4a
@facebook-github-bot facebook-github-bot added the Merged This PR has been merged. label Mar 23, 2023
@facebook-github-bot
Copy link
Contributor

This pull request has been merged in 308838c.

cipolleschi pushed a commit that referenced this pull request Mar 31, 2023
Summary:
X-link: facebook/metro#955

Pull Request resolved: #36584

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now `['require', 'react-native']`

The [Exports RFC](https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md) had assumed that supporting the `"import"` condition was a syntax-only difference, given we are not in a Node.js environment — and so was worthwhile to support for maximal ecosystem compatibility.

{F915841105}

This assumption is similar to [`--moduleResolution bundler` in TypeScript 5.0](microsoft/TypeScript#51669):

> bundlers and runtimes that include a range of Node-like resolution features and ESM syntax, but do not enforce the strict resolution rules that accompany ES modules in Node or in the browser
> -- microsoft/TypeScript#51669 (comment)

However, robhogan has rightly pointed out that **we should not do this!**

- ESM (once transpiled) is **not** simply a stricter subset of in-scope features supported by CJS. For example, it supports top-level async, which would be breaking at runtime.
- We recently made the same change for our Jest environment:
    - 681d7f8

As such, we are erring on the side of correctness and supporting only `['require', 'react-native']` in our defaults. At runtime, all code run by React Native is anticipated to be CommonJS. `"exports"` will instead allow React Native to correctly select the CommonJS versions of modules from all npm packages.

Metro changelog: [Experimental] Package Exports `unstable_conditionNames` now defaults to `['require']`

Reviewed By: robhogan

Differential Revision: D44303559

fbshipit-source-id: 0077e547e7775e53d1e4e9c3a9d01347f4fb7d4a
@huntie
Copy link
Member Author

huntie commented Apr 7, 2023

Counterexample for this is packages which (somewhat incorrectly) specify "import" but not a "default" condition match 🫤: https://github.com/ipfs/js-ipfs-unixfs/blob/master/packages/ipfs-unixfs-importer/package.json. These cases won't work better out-of-the-box.

@robhogan
Copy link
Contributor

robhogan commented Apr 7, 2023

That’s sort of unfortunate - but that’s an example of a package which only distributes ESM (see index.js), so there is simply no way to require it - Node JS won’t let you either. There could legally be top level await in there, etc - it’s proper ESM (and the fact that it’s set up that way might be an indication that the authors don’t want to be constrained by CJS).

Node would let you await import() it from CommonJS, so to complete* the work here we ought to allow that from Metro - in that case, the conditions would include import but not require, and we’d be able to resolve it.

[*] - To complete the resolver work, that is - unfortunately there’s a whole can of worms here as to how Metro should deal with ESM. We can (do) YOLO transform it to CJS and turn all its imports into requires, which isn’t semantically sound and will break on ESM->ESM dependencies like this one. Not transforming it isn’t an option because Hermes doesn’t support ESM. There might be a pragmatic “as close to correct as possible” path we can walk here but I’m not sure exactly where that is. Such is the state of ESM in JS today. One to chew over/discuss on Tuesday!

huntie added a commit to huntie/react-native that referenced this pull request Apr 13, 2023
Summary:
Reverts facebook#36584.

Since we've come across example packages (typically targeting Node.js) which only distribute ESM, we believe it's more helpful to return to asserting the `"import"` condition by default, for maximum compatibility. The above issue and comments outline the pros/cons.

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now ['require', 'import', 'react-native']

Metro changelog: [Experimental] Package Exports unstable_conditionNames now defaults to ['require', 'import']

Differential Revision: D44962143

fbshipit-source-id: 45ebf746b39acf57d939d8add9db32ec899b1a2e
huntie added a commit to huntie/react-native that referenced this pull request Apr 14, 2023
Summary:
Pull Request resolved: facebook#36902

Reverts facebook#36584.

Since we've come across example packages (typically targeting Node.js) which only distribute ESM, we believe it's more helpful to return to asserting the `"import"` condition by default, for maximum compatibility. The above issue and comments outline the pros/cons.

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now ['require', 'import', 'react-native']

Metro changelog: [Experimental] Package Exports unstable_conditionNames now defaults to ['require', 'import']

Reviewed By: robhogan

Differential Revision: D44962143

fbshipit-source-id: d2004df313c858c70bc41c5e096ae2ab9f627bc1
huntie added a commit to huntie/react-native that referenced this pull request Apr 14, 2023
Summary:
Pull Request resolved: facebook#36902

Reverts facebook#36584.

Since we've come across example packages (typically targeting Node.js) which only distribute ESM, we believe it's more helpful to return to asserting the `"import"` condition by default, for maximum compatibility. The above issue and comments outline the pros/cons.

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now ['require', 'import', 'react-native']

Metro changelog: [Experimental] Package Exports unstable_conditionNames now defaults to ['require', 'import']

Reviewed By: robhogan

Differential Revision: D44962143

fbshipit-source-id: f110182f37c07bc3fa5a3e6f936148e44b30a536
facebook-github-bot pushed a commit that referenced this pull request Apr 14, 2023
Summary:
Pull Request resolved: #36902

Reverts #36584.

Since we've come across example packages (typically targeting Node.js) which only distribute ESM, we believe it's more helpful to return to asserting the `"import"` condition by default, for maximum compatibility. The above issue and comments outline the pros/cons.

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now ['require', 'import', 'react-native']

Metro changelog: [Experimental] Package Exports unstable_conditionNames now defaults to ['require', 'import']

Reviewed By: robhogan

Differential Revision: D44962143

fbshipit-source-id: 004172388916c902469b49cfc920ebe13c62c430
facebook-github-bot pushed a commit to facebook/metro that referenced this pull request Apr 14, 2023
Summary:
X-link: facebook/react-native#36902

Reverts facebook/react-native#36584.

Since we've come across example packages (typically targeting Node.js) which only distribute ESM, we believe it's more helpful to return to asserting the `"import"` condition by default, for maximum compatibility. The above issue and comments outline the pros/cons.

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now ['require', 'import', 'react-native']

Metro changelog: [Experimental] Package Exports unstable_conditionNames now defaults to ['require', 'import']

Reviewed By: robhogan

Differential Revision: D44962143

fbshipit-source-id: 004172388916c902469b49cfc920ebe13c62c430
jeongshin pushed a commit to jeongshin/react-native that referenced this pull request May 7, 2023
Summary:
X-link: facebook/metro#955

Pull Request resolved: facebook#36584

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now `['require', 'react-native']`

The [Exports RFC](https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md) had assumed that supporting the `"import"` condition was a syntax-only difference, given we are not in a Node.js environment — and so was worthwhile to support for maximal ecosystem compatibility.

{F915841105}

This assumption is similar to [`--moduleResolution bundler` in TypeScript 5.0](microsoft/TypeScript#51669):

> bundlers and runtimes that include a range of Node-like resolution features and ESM syntax, but do not enforce the strict resolution rules that accompany ES modules in Node or in the browser
> -- microsoft/TypeScript#51669 (comment)

However, robhogan has rightly pointed out that **we should not do this!**

- ESM (once transpiled) is **not** simply a stricter subset of in-scope features supported by CJS. For example, it supports top-level async, which would be breaking at runtime.
- We recently made the same change for our Jest environment:
    - facebook@681d7f8

As such, we are erring on the side of correctness and supporting only `['require', 'react-native']` in our defaults. At runtime, all code run by React Native is anticipated to be CommonJS. `"exports"` will instead allow React Native to correctly select the CommonJS versions of modules from all npm packages.

Metro changelog: [Experimental] Package Exports `unstable_conditionNames` now defaults to `['require']`

Reviewed By: robhogan

Differential Revision: D44303559

fbshipit-source-id: 0077e547e7775e53d1e4e9c3a9d01347f4fb7d4a
jeongshin pushed a commit to jeongshin/react-native that referenced this pull request May 7, 2023
Summary:
Pull Request resolved: facebook#36902

Reverts facebook#36584.

Since we've come across example packages (typically targeting Node.js) which only distribute ESM, we believe it's more helpful to return to asserting the `"import"` condition by default, for maximum compatibility. The above issue and comments outline the pros/cons.

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now ['require', 'import', 'react-native']

Metro changelog: [Experimental] Package Exports unstable_conditionNames now defaults to ['require', 'import']

Reviewed By: robhogan

Differential Revision: D44962143

fbshipit-source-id: 004172388916c902469b49cfc920ebe13c62c430
OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this pull request May 22, 2023
Summary:
X-link: facebook/metro#955

Pull Request resolved: facebook#36584

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now `['require', 'react-native']`

The [Exports RFC](https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md) had assumed that supporting the `"import"` condition was a syntax-only difference, given we are not in a Node.js environment — and so was worthwhile to support for maximal ecosystem compatibility.

{F915841105}

This assumption is similar to [`--moduleResolution bundler` in TypeScript 5.0](microsoft/TypeScript#51669):

> bundlers and runtimes that include a range of Node-like resolution features and ESM syntax, but do not enforce the strict resolution rules that accompany ES modules in Node or in the browser
> -- microsoft/TypeScript#51669 (comment)

However, robhogan has rightly pointed out that **we should not do this!**

- ESM (once transpiled) is **not** simply a stricter subset of in-scope features supported by CJS. For example, it supports top-level async, which would be breaking at runtime.
- We recently made the same change for our Jest environment:
    - facebook@681d7f8

As such, we are erring on the side of correctness and supporting only `['require', 'react-native']` in our defaults. At runtime, all code run by React Native is anticipated to be CommonJS. `"exports"` will instead allow React Native to correctly select the CommonJS versions of modules from all npm packages.

Metro changelog: [Experimental] Package Exports `unstable_conditionNames` now defaults to `['require']`

Reviewed By: robhogan

Differential Revision: D44303559

fbshipit-source-id: 0077e547e7775e53d1e4e9c3a9d01347f4fb7d4a
OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this pull request May 22, 2023
Summary:
Pull Request resolved: facebook#36902

Reverts facebook#36584.

Since we've come across example packages (typically targeting Node.js) which only distribute ESM, we believe it's more helpful to return to asserting the `"import"` condition by default, for maximum compatibility. The above issue and comments outline the pros/cons.

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now ['require', 'import', 'react-native']

Metro changelog: [Experimental] Package Exports unstable_conditionNames now defaults to ['require', 'import']

Reviewed By: robhogan

Differential Revision: D44962143

fbshipit-source-id: 004172388916c902469b49cfc920ebe13c62c430
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. p: Facebook Partner: Facebook Partner
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants