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

Fix regression in dynamic resolution for out-of-tree platforms #20662

Closed
wants to merge 15 commits into from

Conversation

matthargett
Copy link
Contributor

A recent Facebook commit broke dynamic resolution for out-of-tree platforms:
d5e9e55#diff-9b25f85c1d5984674020a6d0c7a66be9

The request for a fix resulted in another commit which hard-coded platforms:
c4bcca6#diff-9b25f85c1d5984674020a6d0c7a66be9

This PR restores the original functionality. I will update this PR with more tests before requesting merge.

Thanks to my colleague @rdy for pairing with me.

Test Plan:

[x] Ran yarn test
[ ] Add new e2e CLI tests to verify out-of-tree platforms

Release Notes:

[ GENERAL ] [ BUGFIX ] [local-cli ] Restore dynamic resolution for out-of-tree platforms.

…latform plugins. Unrelated style auto-fixes to get lint and prettier to pass. Next step is to add more tests that illustrate further regressions for this functionality.
@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 14, 2018
@pull-bot
Copy link

pull-bot commented Aug 14, 2018

Warnings
⚠️

📋 Release Notes - This PR may have incorrectly formatted Release Notes.

Generated by 🚫 dangerJS

@react-native-bot react-native-bot added Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. Core Team Missing Changelog This PR appears to be missing a changelog, or they are incorrectly formatted. labels Aug 14, 2018
@kelset
Copy link
Contributor

kelset commented Aug 14, 2018

It looks like you had some prettier/linter changing files around - would you mind reversing those to leave only the "actual" changes needed (which I guess are the ones on jest/hasteImpl.js and local-cli/core/index.js and)?


Also, it looks like some tests are failing.

@kelset
Copy link
Contributor

kelset commented Aug 17, 2018

LGTM now, but yeah we should get someone from FB to approve this.

@@ -37,7 +37,7 @@ const NAME_REDUCERS /*: Array<[RegExp, string]> */ = [
// strip .js/.js.flow suffix
[/^(.*)\.js(\.flow)?$/, '$1'],
// strip .android/.ios/.native/.web suffix
[/^(.*)\.(android|ios|native|web|windows|dom)$/, '$1'],
[/^[^\.]+(\.es\d)?$/, '$1'],
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like this could use a comment, not sure how it works

Copy link
Contributor

@rozele rozele Aug 17, 2018

Choose a reason for hiding this comment

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

I ran a test on the regex, and I can't get it to match Foo.native.js. This is the code that I had commented in Slack about. Unfortunately, hasteImpl is dynamically required by jest-haste-map, so it's not trivial to inject "plugin" platform extensions.

However, we can move to a model where plugin platforms must create their own metro.config.js and hasteImpl.js file with the platform extensions in the regex for getHasteName, but that would mean it would be more challenging to add plugin platforms to projects that already have their own metro.config.js. We could probably use babel to modify existing metro.config.js files and add hasteImplModulePath if it's not already there, and just throw a warning if it's already there pointing to instructions on how to add the necessary platform behavior to their hasteImpl.js.

Copy link
Contributor

@hramos hramos Aug 17, 2018

Choose a reason for hiding this comment

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

It looks like this regex aims to strip out .es6 suffixes, but it needs one more capture group. As it stands right now, it would take index.es6 and return .es6, which is unlike the other reducers that strip out .js or .flow.js.

It looks like you want to use ^([^\.]+)(\.es\d)?$ here, which would return index in the above example.

This doesn't match the comment from the line above it, however.

Copy link
Contributor

@hramos hramos left a comment

Choose a reason for hiding this comment

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

Thanks for sending the fix. I'd also appreciate a comment on the platform regex, before merging this.

Copy link
Contributor

@hramos hramos left a comment

Choose a reason for hiding this comment

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

Pending clarification on regex's intent.

@@ -37,7 +37,7 @@ const NAME_REDUCERS /*: Array<[RegExp, string]> */ = [
// strip .js/.js.flow suffix
[/^(.*)\.js(\.flow)?$/, '$1'],
// strip .android/.ios/.native/.web suffix
[/^(.*)\.(android|ios|native|web|windows|dom)$/, '$1'],
[/^[^\.]+(\.es\d)?$/, '$1'],
Copy link
Contributor

@hramos hramos Aug 17, 2018

Choose a reason for hiding this comment

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

It looks like this regex aims to strip out .es6 suffixes, but it needs one more capture group. As it stands right now, it would take index.es6 and return .es6, which is unlike the other reducers that strip out .js or .flow.js.

It looks like you want to use ^([^\.]+)(\.es\d)?$ here, which would return index in the above example.

This doesn't match the comment from the line above it, however.

@rozele
Copy link
Contributor

rozele commented Aug 17, 2018

I'm not convinced about the regex change. My concern is that this forces the repo to stick to a strict convention that module.X.js is only used for X = platform, when no such strict requirement existed before, as the set of platform moniker was enumerated. I agree that something needs to be done to address this for extracting haste names for other platforms, but I'm not positive this is the best solution.

@matthargett
Copy link
Contributor Author

Yea, as I'm iterating and seeing the issues unfold, it turned out that assuming the convention would hold in a consistent way was a poor choice on my part. I'm open to suggestions that can be implemented in time for cherry-picking into the next 0.57 RC.

…prevents us from adding a file to the repo for out-of-tree platforms that allows us to resolve Haste modules at the top-level of the repo. This change ensures that if a user has a file, those settings are not overwritten by React Native.
@kelset kelset removed ‼️Large PR Missing Changelog This PR appears to be missing a changelog, or they are incorrectly formatted. labels Aug 23, 2018
@matthargett
Copy link
Contributor Author

@empyrical @rozele @CaptainNic @madhavarshney @Maxris @vincentriemer If you could check if this approach of overriding via metro.config.js works for your projects, it would be appreciated. The plan is for this to be cherry-picked into 0.57. Thanks!

},

getProvidesModuleNodeModules(): Array<string> {
return ['react-native', 'react-native-windows', 'react-native-dom'];
return ['react-native', ...plugins.platforms];
Copy link
Contributor

Choose a reason for hiding this comment

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

plugins.platforms is an array of strings like this:

[ 'react-native-foo/local-cli/platform.js' ]

Which it gets from an entry in react-native-foo's package.json like this:

  "rnpm": {
    "platform": "./local-cli/platform.js"
  }

But getProvidesModuleNodeModules() just wants entries like react-native-foo, so unless I did something wrong this doesn't seem to work.

BTW, I just discovered this repo:

https://github.com/react-native-community/discussions-and-proposals/issues

Perhaps a discussion on how renderer plugins could be implemented could be started there too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed. Yes, that would be a good place to propose a new API, or discuss on the contributor's slack.

@empyrical
Copy link
Contributor

empyrical commented Aug 24, 2018

I made a version partially inspired by how you did it, and also inspired by the "jest": { "haste": ... } entries in RN's `package.json.

empyrical@d7a0c6b
(edit: diff commit url)

You add this entry to your react-native-foo renderer's package.json:

{
  "rnpm": {
    "haste": {
      "providesModuleNodeModules": [
        "react-native-foo"
      ],
      "platforms": [
        "foo"
      ]
    }
}

And both jest/hasteImpl.js and local-cli/core/index.js will look for react native plugins that have this haste entry.

One thing I find appealing about this way is it leaves open the possibility to declare multiple providesModuleNodeModules and platforms for the packager to look in, if you want. And could be extended to have more Metro configuration options later on too. If you're okay with me doing this, perhaps I could submit this commit as a pull request for consideration too? (I want to clean some things up first and test it a bit more, though)

@empyrical
Copy link
Contributor

Made a proposal here: react-native-community/discussions-and-proposals#21

@matthargett
Copy link
Contributor Author

Closing in favor of #20825

facebook-github-bot pushed a commit that referenced this pull request Aug 30, 2018
Summary:
This pull request adds the ability for a platform developer to provide a `"haste"` key under the `"rnpm"` key in their `package.json` which allows the packager to pick up that platform's javascript files. The intent is to remove the need to have custom platforms hardcoded in. This is inspired by the `"jest": { "haste": {} }` key used by jest.

For example, React Native Dom would have an entry like:

```json
{
  "rnpm": {
    "haste": {
      "providesModuleNodeModules": [
        "react-native-dom"
      ],
      "platforms": [
        "dom"
      ]
    }
  }
}
```

Support for more keys (path blacklists perhaps?) could be added in the future.

This succeeds #20662, as per a discussion I had with matthargett.

I've got an open discussion over here as well: react-native-community/discussions-and-proposals#21
Pull Request resolved: #20825

Differential Revision: D9596429

Pulled By: hramos

fbshipit-source-id: a02f0da0bea8870bdc45d55e23da8ccbc36249f2
kelset pushed a commit that referenced this pull request Aug 31, 2018
Summary:
This pull request adds the ability for a platform developer to provide a `"haste"` key under the `"rnpm"` key in their `package.json` which allows the packager to pick up that platform's javascript files. The intent is to remove the need to have custom platforms hardcoded in. This is inspired by the `"jest": { "haste": {} }` key used by jest.

For example, React Native Dom would have an entry like:

```json
{
  "rnpm": {
    "haste": {
      "providesModuleNodeModules": [
        "react-native-dom"
      ],
      "platforms": [
        "dom"
      ]
    }
  }
}
```

Support for more keys (path blacklists perhaps?) could be added in the future.

This succeeds #20662, as per a discussion I had with matthargett.

I've got an open discussion over here as well: react-native-community/discussions-and-proposals#21
Pull Request resolved: #20825

Differential Revision: D9596429

Pulled By: hramos

fbshipit-source-id: a02f0da0bea8870bdc45d55e23da8ccbc36249f2
gengjiawen pushed a commit to gengjiawen/react-native that referenced this pull request Sep 14, 2018
Summary:
This pull request adds the ability for a platform developer to provide a `"haste"` key under the `"rnpm"` key in their `package.json` which allows the packager to pick up that platform's javascript files. The intent is to remove the need to have custom platforms hardcoded in. This is inspired by the `"jest": { "haste": {} }` key used by jest.

For example, React Native Dom would have an entry like:

```json
{
  "rnpm": {
    "haste": {
      "providesModuleNodeModules": [
        "react-native-dom"
      ],
      "platforms": [
        "dom"
      ]
    }
  }
}
```

Support for more keys (path blacklists perhaps?) could be added in the future.

This succeeds facebook#20662, as per a discussion I had with matthargett.

I've got an open discussion over here as well: react-native-community/discussions-and-proposals#21
Pull Request resolved: facebook#20825

Differential Revision: D9596429

Pulled By: hramos

fbshipit-source-id: a02f0da0bea8870bdc45d55e23da8ccbc36249f2
aleclarson pushed a commit to aleclarson/react-native that referenced this pull request Sep 16, 2018
Summary:
This pull request adds the ability for a platform developer to provide a `"haste"` key under the `"rnpm"` key in their `package.json` which allows the packager to pick up that platform's javascript files. The intent is to remove the need to have custom platforms hardcoded in. This is inspired by the `"jest": { "haste": {} }` key used by jest.

For example, React Native Dom would have an entry like:

```json
{
  "rnpm": {
    "haste": {
      "providesModuleNodeModules": [
        "react-native-dom"
      ],
      "platforms": [
        "dom"
      ]
    }
  }
}
```

Support for more keys (path blacklists perhaps?) could be added in the future.

This succeeds facebook#20662, as per a discussion I had with matthargett.

I've got an open discussion over here as well: react-native-community/discussions-and-proposals#21
Pull Request resolved: facebook#20825

Differential Revision: D9596429

Pulled By: hramos

fbshipit-source-id: a02f0da0bea8870bdc45d55e23da8ccbc36249f2
t-nanava pushed a commit to microsoft/react-native-macos that referenced this pull request Jun 17, 2019
Summary:
This pull request adds the ability for a platform developer to provide a `"haste"` key under the `"rnpm"` key in their `package.json` which allows the packager to pick up that platform's javascript files. The intent is to remove the need to have custom platforms hardcoded in. This is inspired by the `"jest": { "haste": {} }` key used by jest.

For example, React Native Dom would have an entry like:

```json
{
  "rnpm": {
    "haste": {
      "providesModuleNodeModules": [
        "react-native-dom"
      ],
      "platforms": [
        "dom"
      ]
    }
  }
}
```

Support for more keys (path blacklists perhaps?) could be added in the future.

This succeeds facebook#20662, as per a discussion I had with matthargett.

I've got an open discussion over here as well: react-native-community/discussions-and-proposals#21
Pull Request resolved: facebook#20825

Differential Revision: D9596429

Pulled By: hramos

fbshipit-source-id: a02f0da0bea8870bdc45d55e23da8ccbc36249f2
t-nanava pushed a commit to microsoft/react-native-macos that referenced this pull request Jun 17, 2019
Summary:
This pull request adds the ability for a platform developer to provide a `"haste"` key under the `"rnpm"` key in their `package.json` which allows the packager to pick up that platform's javascript files. The intent is to remove the need to have custom platforms hardcoded in. This is inspired by the `"jest": { "haste": {} }` key used by jest.

For example, React Native Dom would have an entry like:

```json
{
  "rnpm": {
    "haste": {
      "providesModuleNodeModules": [
        "react-native-dom"
      ],
      "platforms": [
        "dom"
      ]
    }
  }
}
```

Support for more keys (path blacklists perhaps?) could be added in the future.

This succeeds facebook#20662, as per a discussion I had with matthargett.

I've got an open discussion over here as well: react-native-community/discussions-and-proposals#21
Pull Request resolved: facebook#20825

Differential Revision: D9596429

Pulled By: hramos

fbshipit-source-id: a02f0da0bea8870bdc45d55e23da8ccbc36249f2
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. Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants