Skip to content

ozcanzaferayan/react-native-web-webpack-integration

Repository files navigation

Steps

  1. Create project and add dependencies
# Creating project
npx react-native init ReactNativeWebIntegration
# Dependencies
yarn add react-native-web react-dom
# Dev dependencies
yarn add -D @babel/preset-env @babel/preset-react babel-loader html-webpack-plugin url-loader webpack webpack-cli webpack-dev-server
  1. Add webpack.config.js
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');

const HTMLWebpackPluginConfig = new HTMLWebpackPlugin({
  template: path.resolve(__dirname, './public/index.html'),
  filename: 'index.html',
  inject: 'body',
});

module.exports = {
  entry: path.join(__dirname, 'index.web.js'),
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, '/build'),
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules\/(?!()\/).*/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-react'],
          },
        },
      },
    ],
  },
  plugins: [HTMLWebpackPluginConfig],
  resolve: {
    alias: {
      'react-native$': 'react-native-web',
    },
  },
};
  1. Add public/index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>RN Web</title>
    <style>
      #app-root {
        display: flex;
        flex: 1 1 100%;
        height: 100vh;
      }
    </style>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
  1. Add index.web.js
import {AppRegistry} from 'react-native';
import App from './App';
if (module.hot) {
  module.hot.accept();
}
AppRegistry.registerComponent('App', () => App);
AppRegistry.runApplication('App', {
  initialProps: {},
  rootTag: document.getElementById('root'),
});
  1. Change App.js correctly
import React from 'react';
import {SafeAreaView, StatusBar, Text, View} from 'react-native';
const App = () => {
  return (
    <SafeAreaView>
      <StatusBar barStyle="dark-content" />
      <View style={{alignItems: 'center'}}>
        <Text style={{fontSize: 64}}>React Native Web App Example</Text>
      </View>
    </SafeAreaView>
  );
};
export default App;
  1. Add web script to package.json:
{
  "web": "webpack-dev-server --config ./webpack.config.js --mode development"
}

For Storybook

  1. Add storybook to project
npx sb init --type react -f
  1. Add components into src/components
  2. Inject webpack into .storybook/main.js
const custom = require('../webpack.config');

module.exports = {
  stories: ['../src/components/**/*.stories.[tj]s'],
  webpackFinal: config => {
    return {
      ...config,
      resolve: {alias: {...config.resolve.alias, ...custom.resolve.alias}},
      module: {...config.module, rules: custom.module.rules},
    };
  },
  framework: '@storybook/react',
  core: {
    builder: '@storybook/builder-webpack5',
  },
};
  1. Add alias to webpack.config
module.exports = {
  resolve: {
    alias: {
      'react-native$': 'react-native-web',
      '@storybook/react-native': '@storybook/react', //<-here
    },
  },
};
  1. Run storybook
yarn storybook