DEV Community

Cover image for How to create React Native App for Android, iOS and Web without Expo

How to create React Native App for Android, iOS and Web without Expo

Shivam Sharma on June 12, 2021

Note: This article is updated on 08-Aug-2021, to solve this StackOverflow issue, In this update, Creation of .babelrc is removed, babel.config.js ...
Collapse
 
19007361 profile image
CJ Meyer • Edited

I have a weird issue

When I use exactly this file of yours: github.com/ShivamS136/react-native...

It runs fine with npx react-native run-android

But when I enter even one single letter differently, inside Text, styles, variable names, anything, it shows many errors "Error: Text strings must be rendered within a component.", and also some errors "Invariant Violation: View config getter callback for component div must be a function (received undefined). Make sure to start component names with a capital letter."

Collapse
 
shivams136 profile image
Shivam Sharma

div component is not available in React Native, It's part of react-dom... So can't be used here.
For the Text issue, can you please share a screenshot or code block or regeneratable example.
I hope you are running for android, not web as in web it'll not run as mentioned in the step 10.

Collapse
 
19007361 profile image
CJ Meyer

Thank you for your reply. It is exactly the same code as you have in App.js, I am running for Android yes

Collapse
 
dgtman profile image
David Taylor

I just get a blank page, no rendered HTML, no JS assets loaded by the browser. The CLI reports that everything worked though:

i 「wds」: Project is running at localhost:8080/
i 「wds」: webpack output is served from /
i 「wds」: Content not from webpack is served from E:\Storage\Projects\react-native\AwesomeProject
i 「wdm」: asset bundle.web.js 1.72 MiB emitted 1 related asset
runtime modules 26.7 KiB 13 modules
modules by path ./node_modules/ 1.56 MiB 105 modules
./index.web.js 526 bytes [built] [code generated]
./src/components/App.jsx 4.99 KiB [built] [code generated]
./app.json 66 bytes [built] [code generated]
webpack 5.40.0 compiled successfully in 2378 ms
i 「wdm」: Compiled successfully.

I've been over the steps 3 times, everything in the instructions I did as far as I can tell.

Collapse
 
keiteldog profile image
Keitel Jovin

Then the configuration worked for you, now you need to go on the Browser console and see what's the javascript error. It could be syntax error, could be your own code importing "type" code (you should tell webpack to convert node module that uses them), it could be metro bundler not running, etc.
But you have to debug it in Browser console now.

Collapse
 
dgtman profile image
David Taylor

I forgot to say, nothing in the browser console. Not even a request to load the generated JS bundle. The index.html page is not loading.

However, if I change the URL to put a filename that does NOT exist in the app, I do get a "not found" error. So it's talking to the server, just not rendering anything.

Thread Thread
 
keiteldog profile image
Keitel Jovin

Oh ok, I see what you mean. Did you set the bable presets and plugins in config?

What does your web/webpack.config.js look like?

Thread Thread
 
keiteldog profile image
Keitel Jovin

Keep in mind that webpack serve is serving in memory in development. You won't even see the bundle file generated.

Thread Thread
 
shivams136 profile image
Shivam Sharma • Edited

@dgtman , Can you please check that you have included budle.web.js there or the entry point index.web.js is correct in webpack config and this file exists. Or you can share a github repo like the one I mentioned to generate the error at my end.

Collapse
 
keiteldog profile image
Keitel Jovin

Thanks for helping me out on this, I've learned a lot here. I always want to have more control on my codes.
I want to stay away of Expo because it's too big and lack of some features that I wanted to test each time on Local. I tried react-scripts, but at some points, I couldn't know what was happening. Didn't try expo eject though, but I heard it's still not reducing enough the size. This full babel and webpack config was what I wanted.

TIP for readers, read carefully the Babel Compilation part in Webpack Config to know when to add a module to be compiled. For example, this compiled the package react-native-paper (Material Design):

path.resolve(appDirectory, 'node_modules/react-native-paper'),

Collapse
 
shivams136 profile image
Shivam Sharma

Your most welcome, I am happy that my learning could helped someone.

Collapse
 
railway17 profile image
Rail Way • Edited

Hi, I've noticed strange issue while working on windows.
I have successfully run out by using this article, but can't start in windows.
It shows error that I attached at stackoverflow.com/questions/705180...
Please help me why it shows error.
Thank you
Han

Collapse
 
shivams136 profile image
Shivam Sharma

Hi @railway17

Actually, I worked on React Native for a very short amount of time, I was also stuck too many times in setting this up that's why created that article along with learning, I don't have any knowledge apart from that, So I'll not able to help here.

I would suggest you to post a help discussion on react-native-web package, the community there is very helpful, I also got help from there when I was stuck.

Collapse
 
ironsteel profile image
ironsteel

آهن پرمصرف‌ترین فلز دنیا است و اصلی‌ترین دلیل هم قیمت مناسب و استحکام بسیار بالای آن است. به‌طوری که تقریباً تمام سازه‌‌های دنیا با استفاده از آهن آلات و انواع مقاطع فولادی ساخته شده از مشتقات آهن ساخته شده‌اند. میزان مقاومت و کیفیت آهن به درجۀ خلوص آن بستگی دارد. در ترکیبات سنگ آهن ناخالصی‌‌هایی وجود دارد که باید از آن جدا شود. مهم است آهن و فولاد که محصول نهایی چقدر خالص باشد و چگونه و توسط کدام فرایند به درصد خلوص لازم برسد.در واقع زمانی که ناخالصی‌‌ها از سنگ آهن جدا‌‌‌ می‌شوند و افزودنی‌هایی به آن اضافه‌‌‌ می‌شود، آلیاژهای مختلفی از این ماده به‌وجود می‌آید. آلیاژها ‌ترکیبی از فلز با ماده‌ای دیگر هستند که ممکن است آن فلز آهنی یا غیرآهنی باشد.

Collapse
 
reinraus profile image
ReinRaus

Step 9

"web": "webpack serve -d source-map --mode development --config \"./web/webpack.config.js\" --inline --color --hot"
Enter fullscreen mode Exit fullscreen mode

--inline is deprecated

stackoverflow.com/questions/705284...

Collapse
 
mdmudassir47 profile image
Mohammed Mudassir

Getting this error
ERROR in ./index.web.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Plugin/Preset files are not allowed to export objects, only functions. In /Users/Projects/demo-app/node_modules/babel-preset-es2015/lib/index.js

Collapse
 
shivams136 profile image
Shivam Sharma

Note: This article is updated on 08-Aug-2021, to solve this StackOverflow issue, In this update, Creation of .babelrc is removed, babel.config.js & webpack.config.js are updated. The changes are equivalent to this commit.

Collapse
 
ashutoshmukherjee35 profile image
AshutoshMukherjee35

Getting the following error while following your documentation:-

ERROR in ./App.js 8:4
Module parse failed: Unexpected token (8:4)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See webpack.js.org/concepts#loaders
| const App = () => {
| return (

<>

|
|
@ ./index.web.js 1:261-277

webpack 5.75.0 compiled with 1 error in 1193 ms

Here's how my web/webpack.config.js file looks:-

const path = require('path');
const webpack = require('webpack');

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)|(jsx)$/,
  test: /\.js$|jsx/,
  // Add every directory that needs to be compiled by Babel during the build.
  include: [
    path.resolve(appDirectory, 'index.web.js'),
    path.resolve(appDirectory, 'src'),
    path.resolve(appDirectory, 'node_modules/react-native-uncompiled'),
  ],
  use: {
    loader: 'babel-loader',
    options: {
      cacheDirectory: true,
      // The 'metro-react-native-babel-preset' preset is recommended to match React Native's packager
      presets: ['module:metro-react-native-babel-preset'],
      // Re-write paths to import only the modules needed by the app
      plugins: [
        'react-native-web',
        [
          'module-resolver',
          {
            alias: {
              '^react-native$': 'react-native-web',
            },
          },
        ],
      ],
    },
  },
};

// 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]',
      esModule: false,
    },
  },
};

module.exports = {
  entry: [
    // load any web API polyfills
    // path.resolve(appDirectory, 'polyfills-web.js'),
    // your web-specific entry file
    path.resolve(appDirectory, 'index.web.js'),
  ],

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

  // ...the rest of your config

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

  resolve: {
    // This will only alias the exact import "react-native"
    alias: {
      'react-native$': 'react-native-web',
    },
    // 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', '.jsx'],
  },
};
Enter fullscreen mode Exit fullscreen mode

Package.json

{
"name": "AwesomeProject",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint .",
"web": "webpack serve -d source-map --mode development --config \"./web/webpack.config.js\" --color --hot",
"build:web": "webpack --mode production --config \"./web/webpack.config.js\" --hot"
},
"dependencies": {
"react": "18.1.0",
"react-dom": "^18.2.0",
"react-native": "0.70.6",
"react-native-web": "^0.18.10"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@babel/runtime": "^7.12.5",
"@react-native-community/eslint-config": "^2.0.0",
"ajv": "^7.2.4",
"babel-jest": "^26.6.3",
"babel-loader": "^9.1.0",
"babel-plugin-module-resolver": "^4.1.0",
"babel-plugin-react-native-web": "^0.18.10",
"eslint": "^7.32.0",
"jest": "^26.6.3",
"metro-react-native-babel-preset": "0.72.3",
"react-test-renderer": "18.1.0",
"url-loader": "^4.1.1",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.0",
"webpack-dev-server": "^4.11.1",
"webpack-merge": "^5.8.0"
},
"jest": {
"preset": "react-native-web"
}
}

babel.config.js

module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};

My folder Structure:-

Image description

index.web.js

`import React from 'react';
import {AppRegistry} from 'react-native';
// import App from './src/components/App';
import App from './App'
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

AppRegistry.runApplication(appName, {
rootTag: document.getElementById('react-native-web-app'),
});`

.flowconfig:-
`
[ignore]
; We fork some components by platform
./[.]android.js

; Ignore "BUCK" generated dirs
/.buckd/

; Ignore polyfills
node_modules/react-native/Libraries/polyfills/.*

; Flow doesn't support platforms
.*/Libraries/Utilities/LoadingView.js

.*/node_modules/resolve/test/resolver/malformed_package_json/package.json$

[untyped]
./node_modules/@react-native-community/cli/./.*

[include]

[libs]
node_modules/react-native/interface.js
node_modules/react-native/flow/

[options]
emoji=true

exact_by_default=true

format.bracket_spacing=false

module.file_ext=.js
module.file_ext=.json
module.file_ext=.ios.js

munge_underscores=true

module.name_mapper='^react-native/(.*)$' -> '/node_modules/react-native/\1'
module.name_mapper='^@?[./a-zA-Z0-9$_-]+.(bmp|gif|jpg|jpeg|png|psd|svg|webp|m4v|mov|mp4|mpeg|mpg|webm|aac|aiff|caf|m4a|mp3|wav|html|pdf)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub'

suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState

Alias the package name

module.name_mapper='^react-native$' -> 'react-native-web'

Point flow to the 'module' field by default

module.system.node.main_field=module
module.system.node.main_field=main

[lints]
sketchy-null-number=warn
sketchy-null-mixed=warn
sketchy-number=warn
untyped-type-import=warn
nonstrict-import=warn
deprecated-type=warn
unsafe-getters-setters=warn
unnecessary-invariant=warn

[strict]
deprecated-type
nonstrict-import
sketchy-null
unclear-type
unsafe-getters-setters
untyped-import
untyped-type-import

[version]
^0.182.0
`

Please help me to resolve this error.

Collapse
 
criszz77 profile image
criszz77

This is a very hard and messy way to get it started. You can use react-scripts which have react-native-web support. I created a react-native-web template which also has web configurations for important libraries like react-navigation and react-native-vector-icons using CRACO to override react-scripts web pack config without ejecting.

github.com/plaut-ro/luna

Collapse
 
akshayagashe06 profile image
PetrolHead • Edited

What are the modifications I need to do if I were using Typescript template?
I tried to follow the same and just change App.jsx to App.tsx. There were some errors after doing so, which I resolved.

Error
ERROR in ./index.web.js 1:261-292
Module not found: Error: Can't resolve './src/components/App'

Collapse
 
nts0312 profile image
nts0312 • Edited

[webpack-cli] Error: Unknown option '--inline' , this error i am getting, also if i remove --inline from scripts then , blank html page is shown.

Collapse
 
elanjsuriyan profile image
elanjsuriyan

please answer this question immediately, It's very urgent...
how to resolve this error
[webpack-cli] Error: Unknown option '--inline'
[webpack-cli] Run 'webpack --help' to see available commands and options

Collapse
 
yalcinyagizkorkmaz profile image
Yalçın Yağız KORKMAZ

how to resolve this error [webpack-cli] Error: Unknown option '--inline'
[webpack-cli] Run 'webpack --help' to see available commands and options
how did u solve this problem?

Collapse
 
akshayagashe06 profile image
PetrolHead

'--inline' is deprecated and is treated as true by default.
However, I see the blank screen too. With a message 'Cannot GET /' on it.

Collapse
 
gj_choo_642e75a0e4a2aa83f profile image
GJ Choo

create a "public" folder in the root level, shift your index.html into the "public" folder. Re-run the web app again.

Thread Thread
 
akshayagashe06 profile image
PetrolHead

Thank you.This was helpful to run the application successfully.

Collapse
 
elanjsuriyan profile image
elanjsuriyan

how to resolve this error [webpack-cli] Error: Unknown option '--inline'
[webpack-cli] Run 'webpack --help' to see available commands and options

Collapse
 
ccheever profile image
Charlie Cheever

Hi - Just curious, why did you not want to use Expo here?

Collapse
 
shivams136 profile image
Shivam Sharma

For me, the main reason was the overhead Expo brings... A simple Hello World app is about 25 MB. You can find the full list here.

Collapse
 
shelzxy profile image
Shelton tembo

I think it's because expo is trash and doesn't work.....

Collapse
 
tobyakselrad profile image
TobyAkselrad • Edited

Hi, I followed the post step by step but I'm getting error 404. HTML shows "Cannot GET /" and console shows: "Failed to load resource: the server responded with a status of 404 (Not Found)".
Thanks

Collapse
 
lovishtater profile image
Lovish Tater

I am getting same error, how did you solved it ?

Collapse
 
cuong1999 profile image
Nguyễn Cường

me too :((( you know cause, don't you?

Collapse
 
iplushcode profile image
IrinaKomar

Reply by J.J. Chu, written on February 16. 22, helped me:

"create a "public" folder in the root level, shift your index.html into the "public" folder. Re-run the web app again."

Collapse
 
coding_legend profile image
pras14587

Very good

Collapse
 
shivams136 profile image
Shivam Sharma

Thanks

Collapse
 
elielsimoncelo profile image
Eliel Simoncelo

Save the project ...

Collapse
 
buwanekasumanasekara profile image
Buwaneka Tharanga Sumanasekara

Thanks buddy. saved my time :)

Collapse
 
fridaycandours profile image
Friday candour

Am very happy to see this, please give me a repo to clone and be up