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

[babel-plugin] ViewLayoutEvent type not exported as per react-native #822

Closed
dmeehan1968 opened this issue Feb 15, 2018 · 9 comments
Closed

Comments

@dmeehan1968
Copy link

dmeehan1968 commented Feb 15, 2018

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

NB: Using Flow for type checking.

ViewLayoutEvent not accessible as a named export from RNW in the same was as from RN.

ViewLayoutEvent is required for correct parameter typing of the onLayout handler passed to View components.

What is the expected behavior?

The following line works in RN, but not in RNW

import { View, Text, ViewLayoutEvent } from 'react-native'

This produces the following error:

Module not found: Error: Can't resolve 'react-native-web/dist/exports/ViewLayoutEvent' in '...'

A workaround is to use a import on all of RN, then reference the type.

import RN, { View, Text } from 'react-native'

//...
  handleLayout = (e: RN.ViewLayoutEvent) => {
    //...
  }
//...

Environment (include versions). Did this work in previous versions?

Untested in previous versions.

  • OS: MacOs 10.13.3
  • Device: Macbook Pro
  • Browser: Safari
  • React Native for Web (version): 0.3.2
  • React (version): 16.0.0
  • flow-bin: 0.65.0
webpack.config.js
// https://github.com/necolas/react-native-web/blob/master/website/guides/getting-started.md

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin')

const appDirectory = path.resolve(__dirname, '../');

// This is needed for webpack to compile JavaScript.
// Many OSS React Native packages are not compiled to ES5 before being
// published. If you depend on uncompiled packages they may cause webpack build
// errors. To fix this webpack can be configured to compile to the necessary
// `node_module`.
const babelLoaderConfiguration = {
  test: /\.js$/,
  // Add every directory that needs to be compiled by Babel during the build.
  include: [
    path.resolve(appDirectory, 'index.js'),
    path.resolve(appDirectory, 'src'),
    // path.resolve(appDirectory, 'node_modules/react-native-uncompiled')
  ],
  use: {
    loader: 'babel-loader',
    options: {
      cacheDirectory: true,
      // Babel configuration (or use .babelrc)
      // This aliases 'react-native' to 'react-native-web' and includes only
      // the modules needed by the app.
      plugins: [
        'react-native-web',
        'transform-function-bind'],
      // The 'react-native' preset is recommended to match React Native's packager
      presets: ['react-native'],
      // Source Maps
      sourceMap: true
    }
  }
};

// This is needed for webpack to import static images in JavaScript files.
const imageLoaderConfiguration = {
  test: /\.(gif|jpe?g|png|svg)$/,
  use: {
    loader: 'url-loader',
    options: {
      name: '[name].[ext]'
    }
  }
};

module.exports = {
  // your web-specific entry file
  entry: path.resolve(appDirectory, 'index.js'),

  // configures where the build ends up
  output: {
    filename: 'bundle.web.js',
    path: path.resolve(appDirectory, 'dist')
  },

  // ...the rest of your config

  devtool: 'eval-source-map',

  devServer: {
    contentBase: path.resolve(appDirectory, 'dist')
  },

  module: {
    rules: [
      babelLoaderConfiguration,
      imageLoaderConfiguration
    ]
  },

  plugins: [
    // `process.env.NODE_ENV === 'production'` must be `true` for production
    // builds to eliminate development checks and reduce build size. You may
    // wish to include additional optimizations.
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
      __DEV__: process.env.NODE_ENV === 'production' || true
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, 'index.html'),
      filename: 'index.html'
    })
  ],

  resolve: {
    // If you're working on a multi-platform React Native app, web-specific
    // module implementations should be written in files using the extension
    // `.web.js`.
    extensions: [ '.web.js', '.js' ]
  }
}
@dmeehan1968 dmeehan1968 changed the title Missing ViewLayoutEvent type from exports ViewLayoutEvent type not exported as per react-native Feb 15, 2018
@dmeehan1968
Copy link
Author

This may also affect ViewLayout and ViewProps also exported from src/export/ViewPropTypes.js

@dmeehan1968
Copy link
Author

Having looked a little into this, the problem seems to be that the babel-plugin-react-native-web uses the import name to determine which exports file to load. Because ViewLayoutEvent is inside ViewPropTypes, it fails. This is why the error message contains react-native-web/dist/exports/.

It seems the exports are correctly stated, its the module mapping between RN and RNW that gets it wrong. I've also found that ViewEventLayout is a property of the View component in both RN & RNW, so the following works:

import { View } from 'react-native'

//...
  handleLayout = (e: View.ViewLayoutEvent) => {
    //...
  }
//...

@necolas
Copy link
Owner

necolas commented Feb 15, 2018

If it's a type shouldn't you be importing it as a type rather than a module?

@dmeehan1968
Copy link
Author

I tried the 'type' keyword but this didn't make any difference. There is a definite weakness in the Babel plugin in how it tries to locate the export module based on the import name, which is what generates the error message.

I'm happy for this issue to be closed and a new one created to document the plugin weakness.

@necolas
Copy link
Owner

necolas commented Feb 16, 2018

Please can you try disabling the babel plugin in development. Babel is meant to remove flow types so I'm thinking the import rewrites won't matter for production builds.

@necolas necolas changed the title ViewLayoutEvent type not exported as per react-native [babel-plugin] ViewLayoutEvent type not exported as per react-native Feb 16, 2018
@dmeehan1968
Copy link
Author

Sorry, but I don't understand what you mean by that. If I remove the babel-plugin-react-native-web plugin from my webpack config, its just hurls a ton of errors about missing modules. Am I supposed to replace the plugin with another way of resolving?

@necolas
Copy link
Owner

necolas commented Feb 16, 2018

Remove the plugin in development and do the react-native package name aliasing by hand in webpack. Let me know what that does

@dmeehan1968
Copy link
Author

@necolas Thanks for the clarification. I don't have time right now and have a workaround. I'll try and come back to it.

@necolas necolas reopened this Feb 19, 2018
@dmeehan1968
Copy link
Author

I've just updated to RNW 0.4, just realised I was not on latest. I'm guessing that you have another release coming up as you've made commits today etc.

Problem still exists, but it seems that its temperamental regarding which plugins its installed alongside. My webpack config has changed since I opened the issue, best thing would be to look in the repo:

https://github.com/dmeehan1968/react-native-web-sketch-boilerplate

Webpack config is in ./web, and the RNW plugin is in webpack.common.js. This is almost verbatim from the webpack config included in the RNW guide.

As it stands, the code is running as I used a workaround listed above to get at the ViewLayoutEvent type.

To trigger the problem, modify ./demo/Draggable.js, changing the third line from

import { Animated, PanResponder, View, StyleSheet } from 'react-native'

to

import { Animated, PanResponder, View, StyleSheet, ViewLayoutEvent } from 'react-native'

Then run npm run webpack and check the browser developer console.

Don't worry that its not used, the import is enough to trigger the bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants