无法编译 React Native 应用程序

时间:2021-01-26 04:51:18

标签: reactjs react-native expo abp

我正在构建要部署的 ABP.IO 反应前端(除了 Environment.js 之外没有任何修改),但是它失败了。我已经尝试根据其他一些帖子 such as 安装软件包。

我正在运行 expo build:web --no-pwa 并得到以下信息:

Failed to compile.

C:/Users/INeedHelpPlz/Desktop/myProject/react-native/node_modules/@codler/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js 13:12
Module parse failed: Unexpected token (13:12)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| } from 'react-native'
| import { isIphoneX } from 'react-native-iphone-x-helper'
> import type { KeyboardAwareInterface } from './KeyboardAwareInterface'
| 
| const _KAM_DEFAULT_TAB_BAR_HEIGHT: number = isIphoneX() ? 83 : 49
Error: C:/Users/INeedHelpPlz/Desktop/myProject/react-native/node_modules/@codler/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js 13:12
Module parse failed: Unexpected token (13:12)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| } from 'react-native'
| import { isIphoneX } from 'react-native-iphone-x-helper'
> import type { KeyboardAwareInterface } from './KeyboardAwareInterface'
| 
| const _KAM_DEFAULT_TAB_BAR_HEIGHT: number = isIphoneX() ? 83 : 49
    at C:\@expo\xdl@59.0.14\src\Webpack.ts:280:23
    at finalCallback (C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\webpack\lib\Compiler.js:257:39)
    at C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\webpack\lib\Compiler.js:273:13
    at AsyncSeriesHook.eval [as callAsync] (eval at create (C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:33:1)
    at AsyncSeriesHook.lazyCompileHook (C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\tapable\lib\Hook.js:154:20)
    at onCompiled (C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\webpack\lib\Compiler.js:271:21)
    at C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\webpack\lib\Compiler.js:681:15
    at AsyncSeriesHook.eval [as callAsync] (eval at create (C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:6:1)
    at AsyncSeriesHook.lazyCompileHook (C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\tapable\lib\Hook.js:154:20)
    at C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\webpack\lib\Compiler.js:678:31
    at AsyncSeriesHook.eval [as callAsync] (eval at create (C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:9:1)
    at AsyncSeriesHook.lazyCompileHook (C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\tapable\lib\Hook.js:154:20)
    at C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\webpack\lib\Compilation.js:1423:35
    at AsyncSeriesHook.eval [as callAsync] (eval at create (C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:9:1)
    at AsyncSeriesHook.lazyCompileHook (C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\tapable\lib\Hook.js:154:20)
    at C:\Users\INeedHelpPlz\AppData\Roaming\npm\node_modules\expo-cli\node_modules\webpack\lib\Compilation.js:1414:32

编辑,为 KeyboardAwareHOC.js 添加代码

/* @flow */

import React from 'react'
import {
  Keyboard,
  Platform,
  UIManager,
  TextInput,
  findNodeHandle,
  Animated
} from 'react-native'
import { isIphoneX } from 'react-native-iphone-x-helper'
import type { KeyboardAwareInterface } from './KeyboardAwareInterface'

const _KAM_DEFAULT_TAB_BAR_HEIGHT: number = isIphoneX() ? 83 : 49
const _KAM_KEYBOARD_OPENING_TIME: number = 250
const _KAM_EXTRA_HEIGHT: number = 75

const supportedKeyboardEvents = [
  'keyboardWillShow',
  'keyboardDidShow',
  'keyboardWillHide',
  'keyboardDidHide',
  'keyboardWillChangeFrame',
  'keyboardDidChangeFrame'
]
const keyboardEventToCallbackName = (eventName: string) =>
  'on' + eventName[0].toUpperCase() + eventName.substring(1)
const keyboardAwareHOCTypeEvents = supportedKeyboardEvents.reduce(
  (acc: Object, eventName: string) => ({
    ...acc,
    [keyboardEventToCallbackName(eventName)]: Function
  }),
  {}
)

export type KeyboardAwareHOCProps = {
  viewIsInsideTabBar?: boolean,
  resetScrollToCoords?: {
    x: number,
    y: number
  },
  enableResetScrollToCoords?: boolean,
  enableAutomaticScroll?: boolean,
  extraHeight?: number,
  extraScrollHeight?: number,
  keyboardOpeningTime?: number,
  onScroll?: Function,
  update?: Function,
  contentContainerStyle?: any,
  enableOnAndroid?: boolean,
  innerRef?: Function,
  ...keyboardAwareHOCTypeEvents
}
export type KeyboardAwareHOCState = {
  keyboardSpace: number
}

export type ElementLayout = {
  x: number,
  y: number,
  width: number,
  height: number
}

export type ContentOffset = {
  x: number,
  y: number
}

export type ScrollPosition = {
  x: number,
  y: number,
  animated: boolean
}

export type ScrollIntoViewOptions = ?{
  getScrollPosition?: (
    parentLayout: ElementLayout,
    childLayout: ElementLayout,
    contentOffset: ContentOffset
  ) => ScrollPosition
}

export type KeyboardAwareHOCOptions = ?{
  enableOnAndroid: boolean,
  contentContainerStyle: ?Object,
  enableAutomaticScroll: boolean,
  extraHeight: number,
  extraScrollHeight: number,
  enableResetScrollToCoords: boolean,
  keyboardOpeningTime: number,
  viewIsInsideTabBar: boolean,
  refPropName: string,
  extractNativeRef: Function
}

function getDisplayName(WrappedComponent: React$Component) {
  return (
    (WrappedComponent &&
      (WrappedComponent.displayName || WrappedComponent.name)) ||
    'Component'
  )
}

const ScrollIntoViewDefaultOptions: KeyboardAwareHOCOptions = {
  enableOnAndroid: false,
  contentContainerStyle: undefined,
  enableAutomaticScroll: true,
  extraHeight: _KAM_EXTRA_HEIGHT,
  extraScrollHeight: 0,
  enableResetScrollToCoords: true,
  keyboardOpeningTime: _KAM_KEYBOARD_OPENING_TIME,
  viewIsInsideTabBar: false,

  // The ref prop name that will be passed to the wrapped component to obtain a ref
  // If your ScrollView is already wrapped, maybe the wrapper permit to get a ref
  // For example, with glamorous-native ScrollView, you should use "innerRef"
  refPropName: 'ref',
  // Sometimes the ref you get is a ref to a wrapped view (ex: Animated.ScrollView)
  // We need access to the imperative API of a real native ScrollView so we need extraction logic
  extractNativeRef: (ref: Object) => {
    // getNode() permit to support Animated.ScrollView automatically
    // see https://github.com/facebook/react-native/issues/19650
    // see https://stackoverflow.com/questions/42051368/scrollto-is-undefined-on-animated-scrollview/48786374
    if (ref.getNode) {
      return ref.getNode()
    } else {
      return ref
    }
  }
}

function KeyboardAwareHOC(
  ScrollableComponent: React$Component,
  userOptions: KeyboardAwareHOCOptions = {}
) {
  const hocOptions: KeyboardAwareHOCOptions = {
    ...ScrollIntoViewDefaultOptions,
    ...userOptions
  }

  return class
    extends React.Component<KeyboardAwareHOCProps, KeyboardAwareHOCState>
    implements KeyboardAwareInterface {
    _rnkasv_keyboardView: any
    keyboardWillShowEvent: ?Function
    keyboardWillHideEvent: ?Function
    position: ContentOffset
    defaultResetScrollToCoords: ?{ x: number, y: number }
    mountedComponent: boolean
    handleOnScroll: Function
    state: KeyboardAwareHOCState
    static displayName = `KeyboardAware${getDisplayName(ScrollableComponent)}`

    // HOC options are used to init default props, so that these options can be overriden with component props
    static defaultProps = {
      enableAutomaticScroll: hocOptions.enableAutomaticScroll,
      extraHeight: hocOptions.extraHeight,
      extraScrollHeight: hocOptions.extraScrollHeight,
      enableResetScrollToCoords: hocOptions.enableResetScrollToCoords,
      keyboardOpeningTime: hocOptions.keyboardOpeningTime,
      viewIsInsideTabBar: hocOptions.viewIsInsideTabBar,
      enableOnAndroid: hocOptions.enableOnAndroid
    }

    constructor(props: KeyboardAwareHOCProps) {
      super(props)
      this.keyboardWillShowEvent = undefined
      this.keyboardWillHideEvent = undefined
      this.callbacks = {}
      this.position = { x: 0, y: 0 }
      this.defaultResetScrollToCoords = null
      const keyboardSpace: number = props.viewIsInsideTabBar
        ? _KAM_DEFAULT_TAB_BAR_HEIGHT
        : 0
      this.state = { keyboardSpace }
    }

    componentDidMount() {
      this.mountedComponent = true
      // Keyboard events
      if (Platform.OS === 'ios') {
        this.keyboardWillShowEvent = Keyboard.addListener(
          'keyboardWillShow',
          this._updateKeyboardSpace
        )
        this.keyboardWillHideEvent = Keyboard.addListener(
          'keyboardWillHide',
          this._resetKeyboardSpace
        )
      } else if (Platform.OS === 'android' && this.props.enableOnAndroid) {
        this.keyboardWillShowEvent = Keyboard.addListener(
          'keyboardDidShow',
          this._updateKeyboardSpace
        )
        this.keyboardWillHideEvent = Keyboard.addListener(
          'keyboardDidHide',
          this._resetKeyboardSpace
        )
      }

      supportedKeyboardEvents.forEach((eventName: string) => {
        const callbackName = keyboardEventToCallbackName(eventName)
        if (this.props[callbackName]) {
          this.callbacks[eventName] = Keyboard.addListener(
            eventName,
            this.props[callbackName]
          )
        }
      })
    }

    componentDidUpdate(prevProps: KeyboardAwareHOCProps) {
      if (this.props.viewIsInsideTabBar !== prevProps.viewIsInsideTabBar) {
        const keyboardSpace: number = this.props.viewIsInsideTabBar
          ? _KAM_DEFAULT_TAB_BAR_HEIGHT
          : 0
        if (this.state.keyboardSpace !== keyboardSpace) {
          this.setState({ keyboardSpace })
        }
      }
    }

    componentWillUnmount() {
      this.mountedComponent = false
      this.keyboardWillShowEvent && this.keyboardWillShowEvent.remove()
      this.keyboardWillHideEvent && this.keyboardWillHideEvent.remove()
      Object.values(this.callbacks).forEach((callback: Object) =>
        callback.remove()
      )
    }

    getScrollResponder = () => {
      return (
        this._rnkasv_keyboardView &&
        this._rnkasv_keyboardView.getScrollResponder &&
        this._rnkasv_keyboardView.getScrollResponder()
      )
    }

    scrollToPosition = (x: number, y: number, animated: boolean = true) => {
      const responder = this.getScrollResponder()
      responder && responder.scrollResponderScrollTo({ x, y, animated })
    }

    scrollToEnd = (animated?: boolean = true) => {
      const responder = this.getScrollResponder()
      responder && responder.scrollResponderScrollToEnd({ animated })
    }

    scrollForExtraHeightOnAndroid = (extraHeight: number) => {
      this.scrollToPosition(0, this.position.y + extraHeight, true)
    }

    /**
     * @param keyboardOpeningTime: takes a different keyboardOpeningTime in consideration.
     * @param extraHeight: takes an extra height in consideration.
     */
    scrollToFocusedInput = (
      reactNode: any,
      extraHeight?: number,
      keyboardOpeningTime?: number
    ) => {
      if (extraHeight === undefined) {
        extraHeight = this.props.extraHeight || 0
      }
      if (keyboardOpeningTime === undefined) {
        keyboardOpeningTime = this.props.keyboardOpeningTime || 0
      }
      setTimeout(() => {
        if (!this.mountedComponent) {
          return
        }
        const responder = this.getScrollResponder()
        responder &&
          responder.scrollResponderScrollNativeHandleToKeyboard(
            reactNode,
            extraHeight,
            true
          )
      }, keyboardOpeningTime)
    }

    scrollIntoView = async (
      element: React.Element<*>,
      options: ScrollIntoViewOptions = {}
    ) => {
      if (!this._rnkasv_keyboardView || !element) {
        return
      }

      const [parentLayout, childLayout] = await Promise.all([
        this._measureElement(this._rnkasv_keyboardView),
        this._measureElement(element)
      ])

      const getScrollPosition =
        options.getScrollPosition || this._defaultGetScrollPosition
      const { x, y, animated } = getScrollPosition(
        parentLayout,
        childLayout,
        this.position
      )
      this.scrollToPosition(x, y, animated)
    }

    _defaultGetScrollPosition = (
      parentLayout: ElementLayout,
      childLayout: ElementLayout,
      contentOffset: ContentOffset
    ): ScrollPosition => {
      return {
        x: 0,
        y: Math.max(0, childLayout.y - parentLayout.y + contentOffset.y),
        animated: true
      }
    }

    _measureElement = (element: React.Element<*>): Promise<ElementLayout> => {
      const node = findNodeHandle(element)
      return new Promise((resolve: ElementLayout => void) => {
        UIManager.measureInWindow(
          node,
          (x: number, y: number, width: number, height: number) => {
            resolve({ x, y, width, height })
          }
        )
      })
    }

    // Keyboard actions
    _updateKeyboardSpace = (frames: Object) => {
      // Automatically scroll to focused TextInput
      if (this.props.enableAutomaticScroll) {
        let keyboardSpace: number =
          frames.endCoordinates.height + this.props.extraScrollHeight
        if (this.props.viewIsInsideTabBar) {
          keyboardSpace -= _KAM_DEFAULT_TAB_BAR_HEIGHT
        }
        this.setState({ keyboardSpace })
        const currentlyFocusedField = TextInput.State.currentlyFocusedField()
        const responder = this.getScrollResponder()
        if (!currentlyFocusedField || !responder) {
          return
        }
        UIManager.viewIsDescendantOf(
          currentlyFocusedField,
          responder.getInnerViewNode(),
          (isAncestor: boolean) => {
            if (isAncestor) {
              // Check if the TextInput will be hidden by the keyboard
              UIManager.measureInWindow(
                currentlyFocusedField,
                (x: number, y: number, width: number, height: number) => {
                  const textInputBottomPosition = y + height
                  const keyboardPosition = frames.endCoordinates.screenY
                  const totalExtraHeight =
                    this.props.extraScrollHeight + this.props.extraHeight
                  if (Platform.OS === 'ios') {
                    if (
                      textInputBottomPosition >
                      keyboardPosition - totalExtraHeight
                    ) {
                      this._scrollToFocusedInputWithNodeHandle(
                        currentlyFocusedField
                      )
                    }
                  } else {
                    // On android, the system would scroll the text input just
                    // above the keyboard so we just neet to scroll the extra
                    // height part
                    if (textInputBottomPosition > keyboardPosition) {
                      // Since the system already scrolled the whole view up
                      // we should reduce that amount
                      keyboardSpace =
                        keyboardSpace -
                        (textInputBottomPosition - keyboardPosition)
                      this.setState({ keyboardSpace })
                      this.scrollForExtraHeightOnAndroid(totalExtraHeight)
                    } else if (
                      textInputBottomPosition >
                      keyboardPosition - totalExtraHeight
                    ) {
                      this.scrollForExtraHeightOnAndroid(
                        totalExtraHeight -
                          (keyboardPosition - textInputBottomPosition)
                      )
                    }
                  }
                }
              )
            }
          }
        )
      }
      if (!this.props.resetScrollToCoords) {
        if (!this.defaultResetScrollToCoords) {
          this.defaultResetScrollToCoords = this.position
        }
      }
    }

    _resetKeyboardSpace = () => {
      const keyboardSpace: number = this.props.viewIsInsideTabBar
        ? _KAM_DEFAULT_TAB_BAR_HEIGHT
        : 0
      this.setState({ keyboardSpace })
      // Reset scroll position after keyboard dismissal
      if (this.props.enableResetScrollToCoords === false) {
        this.defaultResetScrollToCoords = null
        return
      } else if (this.props.resetScrollToCoords) {
        this.scrollToPosition(
          this.props.resetScrollToCoords.x,
          this.props.resetScrollToCoords.y,
          true
        )
      } else {
        if (this.defaultResetScrollToCoords) {
          this.scrollToPosition(
            this.defaultResetScrollToCoords.x,
            this.defaultResetScrollToCoords.y,
            true
          )
          this.defaultResetScrollToCoords = null
        } else {
          this.scrollToPosition(0, 0, true)
        }
      }
    }

    _scrollToFocusedInputWithNodeHandle = (
      nodeID: number,
      extraHeight?: number,
      keyboardOpeningTime?: number
    ) => {
      if (extraHeight === undefined) {
        extraHeight = this.props.extraHeight
      }
      const reactNode = findNodeHandle(nodeID)
      this.scrollToFocusedInput(
        reactNode,
        extraHeight + this.props.extraScrollHeight,
        keyboardOpeningTime !== undefined
          ? keyboardOpeningTime
          : this.props.keyboardOpeningTime || 0
      )
    }

    _handleOnScroll = (
      e: SyntheticEvent<*> & { nativeEvent: { contentOffset: number } }
    ) => {
      this.position = e.nativeEvent.contentOffset
    }

    _handleRef = (ref: React.Component<*>) => {
      this._rnkasv_keyboardView = ref ? hocOptions.extractNativeRef(ref) : ref
      if (this.props.innerRef) {
        this.props.innerRef(this._rnkasv_keyboardView)
      }
    }

    update = () => {
      const currentlyFocusedField = TextInput.State.currentlyFocusedField()
      const responder = this.getScrollResponder()

      if (!currentlyFocusedField || !responder) {
        return
      }

      this._scrollToFocusedInputWithNodeHandle(currentlyFocusedField)
    }

    render() {
      const { enableOnAndroid, contentContainerStyle, onScroll } = this.props
      let newContentContainerStyle
      if (Platform.OS === 'android' && enableOnAndroid) {
        newContentContainerStyle = [].concat(contentContainerStyle).concat({
          paddingBottom:
            ((contentContainerStyle || {}).paddingBottom || 0) +
            this.state.keyboardSpace
        })
      }
      const refProps = { [hocOptions.refPropName]: this._handleRef }
      return (
        <ScrollableComponent
          {...refProps}
          keyboardDismissMode='interactive'
          contentInset={{ bottom: this.state.keyboardSpace }}
          automaticallyAdjustContentInsets={false}
          showsVerticalScrollIndicator={true}
          scrollEventThrottle={1}
          {...this.props}
          contentContainerStyle={
            newContentContainerStyle || contentContainerStyle
          }
          keyboardSpace={this.state.keyboardSpace}
          getScrollResponder={this.getScrollResponder}
          scrollToPosition={this.scrollToPosition}
          scrollToEnd={this.scrollToEnd}
          scrollForExtraHeightOnAndroid={this.scrollForExtraHeightOnAndroid}
          scrollToFocusedInput={this.scrollToFocusedInput}
          scrollIntoView={this.scrollIntoView}
          resetKeyboardSpace={this._resetKeyboardSpace}
          handleOnScroll={this._handleOnScroll}
          update={this.update}
          onScroll={Animated.forkEvent(onScroll, this._handleOnScroll)}
        />
      )
    }
  }
}

// Allow to pass options, without breaking change, and curried for composition
// listenToKeyboardEvents(ScrollView);
// listenToKeyboardEvents(options)(Comp);
const listenToKeyboardEvents = (configOrComp: any) => {
  if (typeof configOrComp === 'object' && !configOrComp.displayName) {
    return (Comp: Function) => KeyboardAwareHOC(Comp, configOrComp)
  } else {
    return KeyboardAwareHOC(configOrComp)
  }
}

export default listenToKeyboardEvents

0 个答案:

没有答案