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

WIP: Remove Haste from Libraries/ and convert to relative requires #14196

Closed
wants to merge 1 commit into from

Conversation

skevy
Copy link
Contributor

@skevy skevy commented May 25, 2017

Was chatting with @cpojer, and we were discussing how if we remove Haste requires from RN, we can actually rid ourselves of the awful and unstable providesModuleNodeModules option in the packager and in jest-haste-map (at least in OSS). Now that React is use in RN with a flat bundle (thanks @bvaughn!), and fbjs Haste requires were removed long ago, this seems like it might be a good move.

This would change Facebook's internal RN development workflow for anyone that works on RN core, but wouldn't change it for product engineers at Facebook, theoretically. The @providesModule pragmas are still here -- so if a FB engineer says in product code, require('View'), things should still work. But in OSS, we can turn off the providesModuleNodeModules option and just treat RN like a regular npm dependency.

Marking this as WIP -- as I haven't vetted this super well yet. Curious what others thoughts are.

@facebook-github-bot facebook-github-bot added GH Review: review-needed CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. labels May 25, 2017
@skevy
Copy link
Contributor Author

skevy commented May 25, 2017

Oh, also, here's the script I used to do this. Maybe not the prettiest thing ever, but it gets the job done.

https://gist.github.com/skevy/c323242673fb2c124269fd53b607d878

const Platform = require('Platform');
const AlertIOS = require('./AlertIOS');
const NativeModules = require('../BatchedBridge/NativeModules');
const Platform = require('../Utilities/Platform');

import type { AlertType, AlertButtonStyle } from 'AlertIOS';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just realized that I didn't modify the import type statements. Not sure if this is necessary, since flow in this repo is working in haste mode, but maybe I should change them for both consistency as well as so that that module mode isn't required for people consuming RN with Flow.

const Platform = require('Platform');
const AlertIOS = require('./AlertIOS');
const NativeModules = require('../BatchedBridge/NativeModules');
const Platform = require('../Utilities/Platform');

Choose a reason for hiding this comment

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

../Utilities/Platform Required module not found

const React = require('React');
const ColorPropType = require('../StyleSheet/ColorPropType');
const Platform = require('../Utilities/Platform');
const React = require('../react-native/React');

Choose a reason for hiding this comment

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

../react-native/React Required module not found

const View = require('View');
const StyleSheet = require('../StyleSheet/StyleSheet');
const Text = require('../Text/Text');
const TouchableNativeFeedback = require('./Touchable/TouchableNativeFeedback');

Choose a reason for hiding this comment

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

./Touchable/TouchableNativeFeedback Required module not found

const Platform = require('Platform');
const Keyboard = require('./Keyboard');
const LayoutAnimation = require('../../LayoutAnimation/LayoutAnimation');
const Platform = require('../../Utilities/Platform');

Choose a reason for hiding this comment

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

../../Utilities/Platform Required module not found

var InteractionManager = require('../../Interaction/InteractionManager');
var Interpolation = require('./Interpolation');
var NativeAnimatedHelper = require('./NativeAnimatedHelper');
var React = require('../../react-native/React');

Choose a reason for hiding this comment

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

../../react-native/React Required module not found

const DocumentSelectionState = require('../../vendor/document/selection/DocumentSelectionState');
const EventEmitter = require('../../EventEmitter/EventEmitter');
const NativeMethodsMixin = require('../../Renderer/src/renderers/native/NativeMethodsMixin');
const Platform = require('../../Utilities/Platform');

Choose a reason for hiding this comment

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

../../Utilities/Platform Required module not found

var Image = require('Image');
var NativeMethodsMixin = require('NativeMethodsMixin');
var React = require('React');
var Image = require('../../Image/Image');

Choose a reason for hiding this comment

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

../../Image/Image Required module not found

var UIManager = require('UIManager');
var ViewPropTypes = require('ViewPropTypes');
var ColorPropType = require('ColorPropType');
var ReactNativeViewAttributes = require('../View/ReactNativeViewAttributes');

Choose a reason for hiding this comment

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

no-unused-vars: 'ReactNativeViewAttributes' is assigned a value but never used.

const AppContainer = require('../ReactNative/AppContainer');
const I18nManager = require('../ReactNative/I18nManager');
const Platform = require('../Utilities/Platform');
const React = require('../react-native/React');

Choose a reason for hiding this comment

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

../react-native/React Required module not found

@@ -12,10 +12,10 @@
*/
'use strict';

const {PropTypes, checkPropTypes} = require('React');
const RCTCameraRollManager = require('NativeModules').CameraRollManager;
const {PropTypes, checkPropTypes} = require('../react-native/React');

Choose a reason for hiding this comment

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

../react-native/React Required module not found

const Platform = require('Platform');
const NativeMethodsMixin = require('../../Renderer/src/renderers/native/NativeMethodsMixin');
const NativeModules = require('../../BatchedBridge/NativeModules');
const Platform = require('../../Utilities/Platform');

Choose a reason for hiding this comment

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

../../Utilities/Platform Required module not found

const ElementProperties = require('./ElementProperties');
const NetworkOverlay = require('./NetworkOverlay');
const PerformanceOverlay = require('./PerformanceOverlay');
const React = require('../react-native/React');

Choose a reason for hiding this comment

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

../react-native/React Required module not found

const EdgeInsetsPropType = require('EdgeInsetsPropType');
const React = require('React');
const EdgeInsetsPropType = require('../../StyleSheet/EdgeInsetsPropType');
const React = require('../../react-native/React');

Choose a reason for hiding this comment

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

../../react-native/React Required module not found

const Animated = require('../../Animated/src/Animated');
const ColorPropType = require('../../StyleSheet/ColorPropType');
const EdgeInsetsPropType = require('../../StyleSheet/EdgeInsetsPropType');
const Platform = require('../../Utilities/Platform');

Choose a reason for hiding this comment

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

../../Utilities/Platform Required module not found

@@ -10,7 +10,7 @@
* @flow
*/
'use strict';
var PropTypes = require('React').PropTypes;
var PropTypes = require('../../react-native/React').PropTypes;

Choose a reason for hiding this comment

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

../../react-native/React Required module not found

@@ -11,7 +11,7 @@
*/
'use strict';

const Platform = require('Platform');
const Platform = require('../Utilities/Platform');

Choose a reason for hiding this comment

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

../Utilities/Platform Required module not found

var NativeMethodsMixin = require('../../Renderer/src/renderers/native/NativeMethodsMixin');
var ReactNativeViewAttributes = require('../View/ReactNativeViewAttributes');
var Platform = require('../../Utilities/Platform');
var React = require('../../react-native/React');

Choose a reason for hiding this comment

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

../../react-native/React Required module not found

@@ -11,8 +11,8 @@
*/
'use strict';

var React = require('React');
var StyleSheet = require('StyleSheet');
var React = require('../../react-native/React');

Choose a reason for hiding this comment

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

../../react-native/React Required module not found

const ColorPropType = require('../../StyleSheet/ColorPropType');
const NativeMethodsMixin = require('../../Renderer/src/renderers/native/NativeMethodsMixin');
const Platform = require('../../Utilities/Platform');
const React = require('../../react-native/React');

Choose a reason for hiding this comment

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

../../react-native/React Required module not found

var ReactNative = require('../../Renderer/src/renderers/native/ReactNative');
var StaticContainer = require('../StaticContainer.react');
var StyleSheet = require('../../StyleSheet/StyleSheet');
var TVEventHandler = require('../AppleTV/TVEventHandler');

Choose a reason for hiding this comment

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

../AppleTV/TVEventHandler Required module not found

const WebSocketInterceptor = require('WebSocketInterceptor');
const XHRInterceptor = require('XHRInterceptor');
const ListView = require('../Lists/ListView/ListView');
const React = require('../react-native/React');

Choose a reason for hiding this comment

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

../react-native/React Required module not found

var StyleSheet = require('StyleSheet');
var Text = require('Text');
var View = require('View');
var React = require('../react-native/React');

Choose a reason for hiding this comment

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

../react-native/React Required module not found

var Text = require('Text');
var View = require('View');
var AnimatedImplementation = require('./AnimatedImplementation');
var Image = require('../../Image/Image');

Choose a reason for hiding this comment

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

../../Image/Image Required module not found

const InteractionManager = require('InteractionManager');
const React = require('React');
const InteractionManager = require('../Interaction/InteractionManager');
const React = require('../react-native/React');

Choose a reason for hiding this comment

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

../react-native/React Required module not found

@@ -11,7 +11,7 @@
*/
'use strict';

var ReactPropTypes = require('React').PropTypes;
var ReactPropTypes = require('../react-native/React').PropTypes;

Choose a reason for hiding this comment

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

../react-native/React Required module not found

var NativeMethodsMixin = require('NativeMethodsMixin');
var React = require('React');
var NativeMethodsMixin = require('../../Renderer/src/renderers/native/NativeMethodsMixin');
var React = require('../../react-native/React');

Choose a reason for hiding this comment

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

../../react-native/React Required module not found

const EventEmitter = require('../../EventEmitter/EventEmitter');
const NativeMethodsMixin = require('../../Renderer/src/renderers/native/NativeMethodsMixin');
const Platform = require('../../Utilities/Platform');
const React = require('../../react-native/React');

Choose a reason for hiding this comment

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

../../react-native/React Required module not found

var Platform = require('Platform');
var React = require('React');
var ListViewDataSource = require('./ListViewDataSource');
var Platform = require('../../Utilities/Platform');

Choose a reason for hiding this comment

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

../../Utilities/Platform Required module not found

const Platform = require('Platform');
const React = require('React');
const ColorPropType = require('../StyleSheet/ColorPropType');
const Platform = require('../Utilities/Platform');

Choose a reason for hiding this comment

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

../Utilities/Platform Required module not found

var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var DeviceInfo = require('./DeviceInfo');
var EventEmitter = require('../EventEmitter/EventEmitter');
var Platform = require('./Platform');

Choose a reason for hiding this comment

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

./Platform Required module not found

@@ -11,14 +11,14 @@
*/
'use strict';

const React = require('React');
const React = require('../../react-native/React');

Choose a reason for hiding this comment

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

../../react-native/React Required module not found

@@ -11,7 +11,7 @@
*/
'use strict';

const Platform = require('Platform');
const Platform = require('./Platform');

Choose a reason for hiding this comment

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

./Platform Required module not found

var Platform = require('Platform');
var React = require('React');
var ColorPropType = require('../../StyleSheet/ColorPropType');
var PickerIOS = require('./PickerIOS');

Choose a reason for hiding this comment

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

./PickerIOS Required module not found

@@ -73,7 +73,7 @@ Error: ${e.message}`
};
activeWS.onmessage = ({data}) => {
// Moving to top gives errors due to NativeModules not being initialized

Choose a reason for hiding this comment

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

./HMRLoadingView Required module not found

var React = require('React');
var ColorPropType = require('../../StyleSheet/ColorPropType');
var PickerIOS = require('./PickerIOS');
var PickerAndroid = require('./PickerAndroid');

Choose a reason for hiding this comment

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

./PickerAndroid Required module not found

const PropTypes = require('prop-types');
const React = require('React');
const React = require('../../react-native/React');

Choose a reason for hiding this comment

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

../../react-native/React Required module not found

@ericvicenti
Copy link
Contributor

This approach looks great to me!

Clearly the lint bot needs to be reconfigured as well

@davidaurelio
Copy link
Contributor

Please sync up with @rozele how this is going to work with react-native-windows. They are currently overriding core modules using haste, e.g. Text.windows.js

@rozele
Copy link
Contributor

rozele commented May 26, 2017

Thanks @davidaurelio. @skevy for third-party plugin platforms like Microsoft/react-native-windows, we need the ability to override core modules. Throughout the react-native codebase, there are conditionals that allow differentiated native behaviors for iOS and Android, e.g. https://github.com/facebook/react-native/blob/master/Libraries/Components/ScrollView/ScrollView.js#L583-L593. We need to be able to also add in conditions for native behaviors of plugin platforms.

I'd be as happy as anyone to see providesModuleNodeModule go away, but we need to replace it with something equally flexible.

@skevy
Copy link
Contributor Author

skevy commented May 26, 2017

@rozele seems reasonable! I'll give it some thought. Thanks for letting me know!

@skevy
Copy link
Contributor Author

skevy commented May 31, 2017

Gonna close this for now.

The path forward is:

  • Figure out a sane way to handle new React Native platforms without relying on Haste (this is a big project that requires some careful thought -- I can open up a new issue on the metro-bundler repo when that exists and we can discuss this further)

  • Perhaps in the meantime, we can add a pre-publish step that strips haste from the JS in libraries, and publish two folders in the NPM release -- Libraries and Libraries-Haste. I'll open up a new PR that outlines my proposal here.

Thanks for the feedback everyone -- we'll do this eventually!

@skevy skevy closed this May 31, 2017
@vovkasm
Copy link
Contributor

vovkasm commented Jan 14, 2018

But now... platforms easily handled without Haste...

    import { Platform } from 'react-native'

    const Button = Platform.select({
        ios: () => require('./button-ios'),
        android: () => require('./button-android')
    })

    export default Button

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. JavaScript
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants