Hello,
I'm gonna be starting a new project soon which requires android, iOS and web apps. I'm thinking of using React Native Web to create cross platform and reusable components. However, RNW won't work with Next because of how it renders. I wonder if this feature will be supported anytime soon?
Currently, you could do webpack aliases very easily with our custom webpack config support. But you need to alias that on the Node.js side as well. We don't cover that yet. (But soon. See: https://github.com/zeit/next.js/pull/767)
Anyway, even for now you could use do it using a custom .babelrc with https://github.com/tleunen/babel-plugin-module-resolver. But correctly implementing that is tricky.
Integrating this with React Native Web (maybe by bringing the routing functionality as a React Native component?) would make React super-universal in that it could be rendered server-side, browsers, and mobile apps all from the same codebase.
Any update on this?
@scf4 Have a look at our preact example.
next.config.js to add webpack aliasmodule-alias to alias it in the server side.@scf4 here is a working boilerplate with react-native-web which I'm using for my-self.
It still have limit at server-side generated styles (created by React Native's StyleSheet)..
We could actually improve Next.js server-side rendering code to support it.. by extract element and style from react-native-web as in their document.. but I wasn't sure it worth to do it - cause not many people use Next.js this way.
Their code (from react-native-web documentation):
const { element, stylesheet } = AppRegistry.getApplication('App', { initialProps });
const initialHTML = ReactDOMServer.renderToString(element);
// construct HTML document
const document = `
<!DOCTYPE html>
<html>
<head>
${stylesheet} <!–– <= we want this one ––>
</head>
<body>
${initialHTML}
`
By the way, here is a good solution for SSR styles with react native web:
https://github.com/necolas/react-native-web/issues/462
The code in that link is out-dated, we need this instead (which I think is more elegant thanks to new updates from react-native-web):
import Document, { Head, Main, NextScript } from 'next/document'
import { AppRegistry } from 'react-native-web';
export default class MyDocument extends Document {
static async getInitialProps ({ renderPage }) {
AppRegistry.registerComponent('Main', () => Main);
const { stylesheets } = AppRegistry.getApplication('Main');
const page = renderPage();
return { ...page, styles: stylesheets };
}
render () {
return (
<html>
<Head>
<title>My page</title>
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
maybe a bit late to the party, but thought it might help someone.
Used the babelrc. route and looks like this:
{
"presets": [
"es2015",
"react",
"next/babel"
],
"plugins": [
[
"module-resolver",
{
"alias": {
"react-native": "react-native-web"
}
}
]
]
}
@cloudle Were you able to get react-native-vector-icons working with next? I can't seem to get it to compile.
I'm having the same issue with react-native-vector-icons. @amosyuen were you able to solve?
Cannot find module 'StyleSheet'
Error: Cannot find module 'StyleSheet'
at Function.Module._resolveFilename (module.js:555:15)
at Function.Module._load (module.js:482:25)
at Module.require (module.js:604:17)
at require (internal/module.js:11:18)
at Object.get StyleSheet [as StyleSheet] (/Users/joncursi/Sites/joncursi/cheddur-web/node_modules/react-native/Libraries/react-native/react-native-implementation.js:98:29)
at Object.get [as StyleSheet] (/Users/joncursi/Sites/joncursi/cheddur-web/node_modules/react-native-vector-icons/dist/lib/react-native.js:1:282)
at Object.<anonymous> (/Users/joncursi/Sites/joncursi/cheddur-web/node_modules/react-native-vector-icons/dist/lib/icon-button.js:1:2432)
at Module._compile (module.js:660:30)
at Module._compile (/Users/joncursi/Sites/joncursi/cheddur-web/node_modules/source-map-support/source-map-support.js:492:25)
at Object.Module._extensions..js (module.js:671:10)
@joncursi I wasn't able to get it to compile after a couple of days of wrestling with it. I tried various combos of compiling react-native-* with babel, and using webpack resolve alias for react-native to react-native-web, but ran into that same error message.
In the end I decided to give up on react-native-vector-icons in web and use react-icons instead. Unfortunately that means my code diverges between web and native.
Has anyone got react-native-web, next.js, and lerna working together? I opened an issue here, but also will check with this thread.
No matter what I have tried (see the other issue for what I tried), I keep getting Cannot find module 'react-native' for the lerna modules, but it is fine for the components inside the root next.js application.
I removed next.js and used webpack directly with the following configuration file:
const path = require('path');
module.exports = {
entry: path.resolve(__dirname, 'client', 'index.js'),
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
include: [
path.resolve(__dirname, 'client'),
path.resolve(__dirname, 'node_modules', 'react-native-elements'),
path.resolve(__dirname, 'node_modules', 'react-native-vector-icons')
],
use: {
loader: 'babel-loader',
options: {
babelrc: false,
cacheDirectory: true,
plugins: [
require.resolve('babel-plugin-transform-class-properties'),
require.resolve('babel-plugin-transform-object-rest-spread'),
require.resolve('babel-plugin-transform-runtime'),
require.resolve('babel-plugin-transform-decorators-legacy')
],
presets: [require.resolve('babel-preset-react')]
}
}
},
{
test: /\.(gif|jpe?g|png|svg)$/,
use: { loader: 'url-loader', options: { name: '[name].[ext]' } }
},
{
test: /\.ttf$/,
include: path.resolve(__dirname, 'node_modules', 'react-native-vector-icons'),
use: { loader: 'url-loader' }
}
]
},
resolve: {
alias: {
react: path.resolve(__dirname, 'node_modules', 'react'),
'react-dom': path.resolve(__dirname, 'node_modules', 'react-dom'),
'react-native': path.resolve(__dirname, 'node_modules', 'react-native-web'),
'react-router': path.resolve(__dirname, 'node_modules', 'react-router'),
'react-native-elements': path.resolve(__dirname, 'node_modules', 'react-native-elements'),
'react-native-vector-icons': path.resolve(__dirname, 'node_modules', 'react-native-vector-icons')
},
extensions: ['.js']
}
};
Then I went back and merged part of this configuration into my next.config.js file.
const path = require('path');
const webpack = require('webpack');
module.exports = {
webpack: config => {
config.module.rules.unshift({
test: /\.js$/,
include: [
path.resolve(__dirname, 'node_modules', 'react-native-elements'),
path.resolve(__dirname, 'node_modules', 'react-native-vector-icons')
],
use: {
loader: 'babel-loader',
options: {
babelrc: false,
cacheDirectory: true,
plugins: [
require.resolve('babel-plugin-transform-class-properties'),
require.resolve('babel-plugin-transform-object-rest-spread'),
require.resolve('babel-plugin-transform-runtime'),
require.resolve('babel-plugin-transform-decorators-legacy')
],
presets: [require.resolve('babel-preset-react')]
}
}
});
config.module.rules.unshift({
test: /\.(gif|jpe?g|png|svg)$/,
use: { loader: 'url-loader', options: { name: '[name].[ext]' } }
});
config.module.rules.unshift({
test: /\.ttf$/,
include: path.resolve(__dirname, 'node_modules', 'react-native-vector-icons'),
use: { loader: 'url-loader' }
});
config.resolve.alias = {
next: path.resolve(__dirname, 'node_modules', 'next'),
react: path.resolve(__dirname, 'node_modules', 'react'),
'react-dom': path.resolve(__dirname, 'node_modules', 'react-dom'),
'react-native': path.resolve(__dirname, 'node_modules', 'react-native-web'),
'react-native-elements': path.resolve(__dirname, 'node_modules', 'react-native-elements'),
'react-native-vector-icons': path.resolve(__dirname, 'node_modules', 'react-native-vector-icons')
};
return config;
}
};
It looks like next.js doesn't support aliases properly so I get errors like Error: Cannot find module 'react-native' in my lerna modules. Any help would be much appreciated!
@kmalakoff I also have the same issue. I thought I would get something working from your code, but it did not work. I would like to use react-native-elements. I'm running all internet for this.
https://spectrum.chat/thread/e055ef10-ea2f-4de6-8041-b4a2ca2f5e39
Error in react-native
Module not found: Error: Can't resolve '../Components/AccessibilityInfo/AccessibilityInfo' in '/Volumes/HSierraDados/Dev-2018/PWA/node_modules/react-native/Libraries/react-native'
ModuleNotFoundError: Module not found: Error: Can't resolve '../Components/AccessibilityInfo/AccessibilityInfo' in '/Volumes/HSierraDados/Dev-2018/PWA/node_modules/react-native/Libraries/react-native'
at factoryCallback (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/next/node_modules/webpack/lib/Compilation.js:276:40)
at factory (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/next/node_modules/webpack/lib/NormalModuleFactory.js:235:20)
at resolver (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/next/node_modules/webpack/lib/NormalModuleFactory.js:60:20)
at asyncLib.parallel (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/next/node_modules/webpack/lib/NormalModuleFactory.js:127:20)
at /Volumes/HSierraDados/Dev-2018/PWA/node_modules/async/dist/async.js:3874:9
at /Volumes/HSierraDados/Dev-2018/PWA/node_modules/async/dist/async.js:473:16
at iteratorCallback (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/async/dist/async.js:1048:13)
at /Volumes/HSierraDados/Dev-2018/PWA/node_modules/async/dist/async.js:958:16
at /Volumes/HSierraDados/Dev-2018/PWA/node_modules/async/dist/async.js:3871:13
at resolvers.normal.resolve (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/next/node_modules/webpack/lib/NormalModuleFactory.js:119:22)
at onError (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/enhanced-resolve/lib/Resolver.js:65:10)
at loggingCallbackWrapper (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/enhanced-resolve/lib/createInnerCallback.js:31:19)
at runAfter (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/enhanced-resolve/lib/Resolver.js:158:4)
at innerCallback (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/enhanced-resolve/lib/Resolver.js:146:3)
at loggingCallbackWrapper (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/enhanced-resolve/lib/createInnerCallback.js:31:19)
at next (/Volumes/HSierraDados/Dev-2018/PWA/node_modules/tapable/lib/Tapable.js:252:11)
@MichelDiz Thank you for chasing this up.
I ended up giving up on Next.js because of this (I probably spent over 10 hours trying), but would be happy to go back if someone can get it to work!
Any progress on this issue?
@jameskennethrobinson you may need to elaborate or open a new issue. There is already an example of using Next.js and RNW together.
@dcalhoun Apologies for the lack of specificity. I meant to tag @MichelDiz regarding his attempt to use react-native-elements in conjunction with the official example of Next.js + RNW.
I have Next 8 and RNW working, while using Yarn workspaces - configuration detailed here: https://github.com/martpie/next-transpile-modules/issues/8#issuecomment-467679124
In Next@9 the styles only seem to be rendered client side, when following the official example. Am I overlooking something, or has the setup changed?
@MrLoh the last time I encountered that, it ended up being a singleton issue in Next. That issue was resolved, but if you are encountering a similar issue, I’d recommend opening a new issue with a test case so the Next team can easily reproduce the issue and help find a fix.
It seems like it was a gost issue. Disappeared after reinstalling node_modules
@dcalhoun Now the problem reappeared, without any apparent reason. I have no idea how to reproduce it in a fresh project. Super strange. Do you have a hint how to figure out wether it could still be the same issue. Are you available for freelance work?
@MrLoh no, I am not available for freelance at this time, sorry. My recommendation would be to see if you can reproduce the issue on various major releases of Next (e.g. 9.x, 8.x, 7.x). If you can, open a new issue with a reproduced test case attached for the Next team to debug.
I will also add that if you are attempting to transpile the ES module (rather than the already transpiled CJS) exports of RNW (which are the default), then there is an active bug for that. It may/may not result in missing styles.
There seems to be an official example for react-native-web + next.js here now: https://github.com/zeit/next.js/tree/master/examples/with-react-native-web
I built a package for making this as simple as possible https://docs.expo.io/versions/latest/guides/using-nextjs/
expo init (or npx create-next-app)yarn add @expo/next-adapteryarn next-expoyarn next devHope this helps!
Hi all, i configured Next for use react-native-web.
The implementation was easy and everything works fine.
I also implemented, successful, a web storybook, using react-native-web and react-native-elements .(https://react-native-elements.github.io/react-native-elements/)
For doing that, i modified the storybook webpack adding this rules :
```rules: [
{
test: /.(gif|jpe?g|png|svg)$/,
loader: 'file-loader',
},
{
test: /.ttf$/,
loader: 'url-loader',
include: path.resolve(__dirname, '../node_modules/react-native-vector-icons/'),
},
{
test: /.(js|jsx|mjs)$/,
include: [
path.resolve(__dirname, '../src/'),
path.resolve(__dirname, '../node_modules/react-native-elements/'),
path.resolve(__dirname, '../node_modules/react-native-vector-icons/'),
path.resolve(__dirname, '../node_modules/react-native-ratings/'),
],
loader: 'babel-loader',
options: {
presets: [
[
'module:metro-react-native-babel-preset',
{ disableImportExportTransform: true }
]
],
plugins: ['react-native-web'],
cacheDirectory: true,
},
},
],
i trying to use the same approach for configure the react-native-elements, but i'm stuck on this error, and i don't understand why via Next don't works as expected.
here the error i got :
[ error ] ./node_modules/react-native/Libraries/react-native/react-native-implementation.js
Module not found: Can't resolve '../Components/AccessibilityInfo/AccessibilityInfo' in '/Users/enzo/App/React/cloudapp-web-server/node_modules/react-native/Libraries/react-native'
/Users/enzo/App/React/cloudapp-web-server/node_modules/react-native-elements/src/index.js:7
import Button from './buttons/Button';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Module._compile (internal/modules/cjs/loader.js:891:18)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
at Module.load (internal/modules/cjs/loader.js:811:32)
at Function.Module._load (internal/modules/cjs/loader.js:723:14)
at Module.require (internal/modules/cjs/loader.js:848:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object.react-native-elements (/Users/enzo/App/React/cloudapp-web-server/.next/server/static/development/pages/nativetest.js:195:18)
at __webpack_require__ (/Users/enzo/App/React/cloudapp-web-server/.next/server/static/development/pages/nativetest.js:23:31)
at Module../pages/nativetest.js (/Users/enzo/App/React/cloudapp-web-server/.next/server/static/development/pages/nativetest.js:113:79)
at __webpack_require__ (/Users/enzo/App/React/cloudapp-web-server/.next/server/static/development/pages/nativetest.js:23:31)
at Object.4 (/Users/enzo/App/React/cloudapp-web-server/.next/server/static/development/pages/nativetest.js:172:18)
at __webpack_require__ (/Users/enzo/App/React/cloudapp-web-server/.next/server/static/development/pages/nativetest.js:23:31)
at /Users/enzo/App/React/cloudapp-web-server/.next/server/static/development/pages/nativetest.js:91:18
at Object.
at Module._compile (internal/modules/cjs/loader.js:955:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
[ event ] build page: /next/dist/pages/_error
[ wait ] compiling ...
[ error ] ./node_modules/react-native/Libraries/react-native/react-native-implementation.js
Module not found: Can't resolve '../Components/AccessibilityInfo/AccessibilityInfo' in '/Users/enzo/App/React/cloudapp-web-server/node_modules/react-native/Libraries/react-native'
ModuleNotFoundError: Module not found: Error: Can't resolve '../Components/AccessibilityInfo/AccessibilityInfo' in '/Users/enzo/App/React/cloudapp-web-server/node_modules/react-native/Libraries/react-native'
at /Users/enzo/App/React/cloudapp-web-server/node_modules/webpack/lib/Compilation.js:888:10
at /Users/enzo/App/React/cloudapp-web-server/node_modules/webpack/lib/NormalModuleFactory.js:401:22
at /Users/enzo/App/React/cloudapp-web-server/node_modules/webpack/lib/NormalModuleFactory.js:130:21
at /Users/enzo/App/React/cloudapp-web-server/node_modules/webpack/lib/NormalModuleFactory.js:224:22
at /Users/enzo/App/React/cloudapp-web-server/node_modules/neo-async/async.js:2830:7
at /Users/enzo/App/React/cloudapp-web-server/node_modules/neo-async/async.js:6877:13
at /Users/enzo/App/React/cloudapp-web-server/node_modules/webpack/lib/NormalModuleFactory.js:214:25
at /Users/enzo/App/React/cloudapp-web-server/node_modules/enhanced-resolve/lib/Resolver.js:213:14
at /Users/enzo/App/React/cloudapp-web-server/node_modules/enhanced-resolve/lib/Resolver.js:285:5
at eval (eval at create (/Users/enzo/App/React/cloudapp-web-server/node_modules/tapable/lib/HookCodeFactory.js:33:10),
at /Users/enzo/App/React/cloudapp-web-server/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js:44:7
at /Users/enzo/App/React/cloudapp-web-server/node_modules/enhanced-resolve/lib/Resolver.js:285:5
at eval (eval at create (/Users/enzo/App/React/cloudapp-web-server/node_modules/tapable/lib/HookCodeFactory.js:33:10),
at /Users/enzo/App/React/cloudapp-web-server/node_modules/enhanced-resolve/lib/Resolver.js:285:5
at eval (eval at create (/Users/enzo/App/React/cloudapp-web-server/node_modules/tapable/lib/HookCodeFactory.js:33:10),
at /Users/enzo/App/React/cloudapp-web-server/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:67:43
[ event ] client pings, but there's no entry for page: /_error
```
Any help are welcome.
Most helpful comment
I built a package for making this as simple as possible https://docs.expo.io/versions/latest/guides/using-nextjs/
expo init(ornpx create-next-app)yarn add @expo/next-adapteryarn next-expoyarn next devHope this helps!