Next.js: Cannot include third party packages like react-native-web-lists

Created on 12 Oct 2018  路  13Comments  路  Source: vercel/next.js

Examples bug report

Example name

with-react-native-web

Describe the bug

How can I include react-native packages to get them to work? In the React version of react-native-web (create-react-native-app my-app --with-web-support). React includes react-native-packages. You can see this in webpack.config.js line 15 something like:

include: [
  path.resolve(appDirectory, 'src'),
  path.resolve(appDirectory, 'node_modules/react-navigation'),
  path.resolve(appDirectory, 'node_modules/react-native-tab-view'),
  path.resolve(appDirectory, 'node_modules/react-native-paper'),
  path.resolve(appDirectory, 'node_modules/react-native-vector-icons'),
  path.resolve(appDirectory, 'node_modules/react-native-safe-area-view'),
  path.resolve(appDirectory, 'node_modules/@expo/samples'),
  path.resolve(appDirectory, 'node_modules/@expo/vector-icons'),
  path.resolve(appDirectory, 'node_modules/react-native-platform-touchable'),
],

Every time I added a new library I added a row here. So for react-native-web-lists (https://github.com/react-native-web-community/react-native-web-lists):
path.resolve(appDirectory, 'node_modules/react-native-web-lists') after that it just worked.

In nextjs with-react-native-web I cannot get packages like react-native-web-lists to work (this is not the only one). I tried including this in next.config.js

config.module.rules.push({
  test: /\.js$/,
  loader: defaultLoaders.babel,
  include: [
    path.resolve(appDirectory, 'node_modules/react-native-switch'),
  ]
})

But this results in Failed to compile error. Since i'm a noob in webpack I really need some help here?

To Reproduce

  1. yarn create next-app --example with-react-native-web with-react-native-web-app
  2. yarn add react-native-web-lists @zeit/next-typescript
  3. create next.config.js
const withTypescript = require('@zeit/next-typescript')

module.exports = withTypescript({
  webpack: (config, {dev, isServer, defaultLoaders, dir}) => {
    config.resolve.alias['FlatList'] = 'react-native-web-lists/src/FlatList'
    return config
  }
})
  1. import Flatlist in pages/index.js:
import React from 'react'
import FlatList from 'FlatList'
...
  1. run yarn dev <-- will result in You may need an appropriate loader to handle this file type.
  2. Include package in next.config.js:
const path = require('path');
const appDirectory = path.resolve(__dirname, './');
....

config.module.rules.push({
  test: /\.js$/,
  loader: defaultLoaders.babel,
  include: [
    path.resolve(appDirectory, 'node_modules/react-native-web-lists'),
  ]
})
return config
  1. run yarn dev <-- will result in in Error in ./node_modules/react-native-web-lists/src/MetroListView.js Syntax Error: SyntaxError: /Users/tycho/Downloads/with-react-native-web-app/node_modules/react-native-web-lists/src/MetroListView.js: Unexpected token, expected ";" (18:5)

Expected behavior

To be able to use packages like react-native-web-lists as in React react-native-web.

good first issue example

Most helpful comment

I've struggled with this for a couple of hours too. Specifically, the fix for (7) is to use next-transpile-modules. Also, you shouldn't need to explicitly define babel loader for js files; it was causing a bunch of problems that went away when I removed it from the config and just relying on the defaults.

Here's our next.config.js:

const path = require('path')
const withImages = require('next-images')
const withTM = require('next-transpile-modules')
const withTypescript = require('@zeit/next-typescript')

module.exports = withImages(
  withTypescript(
    withTM({
      transpileModules: [
        'react-native-elements',
        'react-native-paper',
        'react-native-ratings',
        'react-native-safe-area-view',
        'react-native-status-bar-height',
        'react-native-vector-icons',
      ],
      webpack(config, options) {
        return {
          ...config,
          module: {
            ...config.module,
            rules: [
              ...config.module.rules,
              {
                test: /\.ttf$/,
                loader: 'url-loader', // or directly file-loader
                include: path.resolve(
                  __dirname,
                  'node_modules/react-native-vector-icons'
                ),
              },
            ],
          },
          resolve: {
            ...config.resolve,
            extensions: [
              '.web.ts',
              '.web.tsx',
              '.ts',
              '.tsx',
              '.web.js',
              '.web.jsx',
              '.js',
              '.jsx',
              ...config.resolve.extensions,
            ],
            alias: {
              ...config.resolve.alias,
              'mobx-react/native$': 'mobx-react',
              'react-native$': 'react-native-web',
            },
          },
        }
      },
    })
  )
)

Hope it helps!

All 13 comments

I've struggled with this for a couple of hours too. Specifically, the fix for (7) is to use next-transpile-modules. Also, you shouldn't need to explicitly define babel loader for js files; it was causing a bunch of problems that went away when I removed it from the config and just relying on the defaults.

Here's our next.config.js:

const path = require('path')
const withImages = require('next-images')
const withTM = require('next-transpile-modules')
const withTypescript = require('@zeit/next-typescript')

module.exports = withImages(
  withTypescript(
    withTM({
      transpileModules: [
        'react-native-elements',
        'react-native-paper',
        'react-native-ratings',
        'react-native-safe-area-view',
        'react-native-status-bar-height',
        'react-native-vector-icons',
      ],
      webpack(config, options) {
        return {
          ...config,
          module: {
            ...config.module,
            rules: [
              ...config.module.rules,
              {
                test: /\.ttf$/,
                loader: 'url-loader', // or directly file-loader
                include: path.resolve(
                  __dirname,
                  'node_modules/react-native-vector-icons'
                ),
              },
            ],
          },
          resolve: {
            ...config.resolve,
            extensions: [
              '.web.ts',
              '.web.tsx',
              '.ts',
              '.tsx',
              '.web.js',
              '.web.jsx',
              '.js',
              '.jsx',
              ...config.resolve.extensions,
            ],
            alias: {
              ...config.resolve.alias,
              'mobx-react/native$': 'mobx-react',
              'react-native$': 'react-native-web',
            },
          },
        }
      },
    })
  )
)

Hope it helps!

@petrbela thanks for this, super helpful. Did you have to do anything else special to get react-native-vector-icons working? I believe it's having trouble resolving the react-native module as I keep getting

TypeError: Cannot read property 'RNVectorIconsManager' of undefined

which is just importing...

Object.defineProperty(exports, '__esModule', { value: true }) var _reactNative = require('react-native') Object.keys(_reactNative).forEach(function(key) { if (key === 'default' || key === '__esModule') return Object.defineProperty(exports, key, { enumerable: true, get: function get() { return _reactNative[key] }, }) })

was just wondering if you had to do anything else to get it working in rnw + nextjs. Thanks in advance.

@followbl This looks like it's trying to pull native modules as it probably still thinks it's a React Native project, not web. Make sure you have the alias set up:

  alias: {
    ...config.resolve.alias,
    'react-native$': 'react-native-web',
  },

Also, inject the stylesheets as described in https://github.com/oblador/react-native-vector-icons#web-with-webpack

yea, you're right, it's not resolving to the proper module. wasn't able to solve it...pretty positive it's related to this. appreciate the response 馃樅

https://github.com/oblador/react-native-vector-icons/pull/991

@petrbela I followed your guide but without success , Please check my repo
https://github.com/abdullah-almesbahi/with-react-native-web-app
I've been struggling with this for a couple of days too

You will be be my hero if can help me . I got this error

Failed to compile
./node_modules/react-native-paper/lib/module/constants.js
Module not found: Can't resolve 'react-native' in '/Users/username/Code/with-react-native-web-app/node_modules/react-native-paper/lib/module'

@abdullah-almesbahi A lot of things have changed since I posted this. Next.js has now built-in support for TypeScript, and most other things shouldn't need extra compilation steps either. There's an officially maintained example of using Next.js with RNW at https://github.com/zeit/next.js/tree/master/examples/with-react-native-web which I recommend you check out first.

@petrbela I checked and tried it , I got the following errors

Error: Cannot find module 'react-native'
Require stack:
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/react-native-paper/lib/commonjs/styles/fonts.js
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/react-native-paper/lib/commonjs/styles/DefaultTheme.js
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/react-native-paper/lib/commonjs/core/theming.js
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/react-native-paper/lib/commonjs/index.js
- /Users/amesbahi/Code/with-react-native-web-app/.next/server/static/development/pages/index.js
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/next/dist/next-server/server/require.js
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/next/dist/next-server/server/load-components.js
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/next/dist/next-server/server/api-utils.js
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/next/dist/next-server/server/next-server.js
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/next/dist/server/next.js
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/next/dist/server/lib/start-server.js
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/next/dist/cli/next-dev.js
- /Users/amesbahi/Code/with-react-native-web-app/node_modules/next/dist/bin/next
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:954:17)
    at Function.Module._load (internal/modules/cjs/loader.js:847:27)
    at Module.require (internal/modules/cjs/loader.js:1016:19)
    at require (internal/modules/cjs/helpers.js:69:18)
    at Object.<anonymous> (/Users/amesbahi/Code/with-react-native-web-app/node_modules/react-native-paper/lib/commonjs/styles/fonts.js:1:279)
    at Module._compile (internal/modules/cjs/loader.js:1121:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1160:10)
    at Module.load (internal/modules/cjs/loader.js:976:32)
    at Function.Module._load (internal/modules/cjs/loader.js:884:14)
    at Module.require (internal/modules/cjs/loader.js:1016:19)
    at require (internal/modules/cjs/helpers.js:69:18)
    at Object.<anonymous> (/Users/amesbahi/Code/with-react-native-web-app/node_modules/react-native-paper/lib/commonjs/styles/DefaultTheme.js:1:282)
    at Module._compile (internal/modules/cjs/loader.js:1121:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1160:10)
    at Module.load (internal/modules/cjs/loader.js:976:32)
    at Function.Module._load (internal/modules/cjs/loader.js:884:14)

And this is my next.config.js

{
  "name": "with-react-native-web",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "latest",
    "next-images": "^1.3.1",
    "react": "^16.7.0",
    "react-art": "^16.7.0",
    "react-dom": "^16.7.0",
    "react-native-paper": "^3.6.0",
    "react-native-web": "^0.11.6"
  },
  "devDependencies": {
    "babel-plugin-react-native-web": "^0.11.7",
    "next-transpile-modules": "^3.1.0"
  }
}

I'll be really thankful if you just give me a hint or workaround

@abdullah-almesbahi Hmm I'm not sure off the top of my head what the problem/solution might be in your case. Btw are you using expo? They have their own Next.js integration https://docs.expo.io/versions/latest/guides/using-nextjs/

Hello, this my next.config.js and finally it works after struggle few hours to setup the config.

const path = require('path');
const withTM = require('next-transpile-modules')
([
  'react-native-elements',
    'react-native-paper',
  'react-native-ratings',
  'react-native-vector-icons',
  'react-native-safe-area-view',
  'react-native-status-bar-height',
  'react-native-normalize',
]);

module.exports = withTM({
  devIndicators: {
    autoPrerender: false,
  },
    webpack: (config, { defaultLoaders }) => {
        config.resolve.alias = {
            ...(config.resolve.alias || {}),
            // Transform all direct `react-native` imports to `react-native-web`
      'react-native$': 'react-native-web',
        };
        config.resolve.extensions.push('.web.ts', '.web.tsx', '.ts', '.tsx', '.web.js', '.web.jsx', '.js', '.jsx');
        config.resolve.modules = [ ...config.resolve.modules, path.resolve(__dirname, 'node_modules') ];
        config.resolve.symlinks = false;
        config.module.rules.push(
            {
                test: /\.(jpe?g|png|gif|svg)$/i,
                use: [ 'url-loader?limit=10000', 'img-loader' ]
            },
            {
                test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
                exclude: /node_modules/,
                loader: 'file-loader'
            },
            {
                test: /\.(woff|woff2)$/,
                exclude: /node_modules/,
                loader: 'url-loader?prefix=font/&limit=5000'
            },
            {
                test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
                exclude: /node_modules/,
                loader: 'url-loader?limit=10000&mimetype=application/octet-stream',
                include: path.resolve(__dirname, 'node_modules/react-native-vector-icons')
            }
        );

        return config;
    }
});

and this is my babel.config.js

module.exports = {
    presets: [ 'next/babel' ],
    plugins: [
        [ 'react-native-web', { commonjs: true } ],
        [
            '@babel/plugin-transform-runtime',
            {
                absoluteRuntime: false,
                corejs: false,
                helpers: true,
                regenerator: true,
                useESModules: true,
                version: '7.0.0-beta.0'
            }
        ],
        '@babel/plugin-proposal-object-rest-spread',
        '@babel/plugin-transform-async-to-generator',
        '@babel/plugin-proposal-class-properties'
    ]
};

hope it helps.

@kucira , i tested your config, but don't work to me, are you using also the react-native-elements ?

this is my config and the error i have : https://github.com/zeit/next.js/issues/858#issuecomment-598948150

@aethiss yes, i also using the react native elements. Maybe you can try clone this repository and run the project https://github.com/kucira/nextjs-rnweb-rnelements

Tnx a lot @kucira , i tested your repo and works.
i don't understand why mine still have this error, but i can restart step-by-step following your idea.

Appreciated a lot !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

knipferrc picture knipferrc  路  3Comments

YarivGilad picture YarivGilad  路  3Comments

jesselee34 picture jesselee34  路  3Comments

DvirSh picture DvirSh  路  3Comments

lixiaoyan picture lixiaoyan  路  3Comments