Skip to content
This repository has been archived by the owner on Mar 9, 2021. It is now read-only.

Does anyone manage to compile the app for web ? #278

Open
DevDaoud opened this issue Jun 10, 2019 · 4 comments
Open

Does anyone manage to compile the app for web ? #278

DevDaoud opened this issue Jun 10, 2019 · 4 comments
Labels

Comments

@DevDaoud
Copy link

Hi everyone did anyone manage to compile andross with react-native-web ? i tried to follow this guide but i'm sure i'm missing something
here is the guide i'm trying to follow
I would be really interested to know if someone tried it, or what are the resources i could use to make it work.

@HZSamir
Copy link

HZSamir commented Jul 1, 2019

Just spent the last two days getting it to work and nothing so far.
Hoping someone will notice this issue.

@DevDaoud
Copy link
Author

DevDaoud commented Jul 3, 2019

@Unforgiven-wanda did it work ? i totally gave up on that and went with pure react app and maybe in the future a react native app

@HZSamir
Copy link

HZSamir commented Jul 4, 2019

@daoudjahdou Unfortunately no. I kept hopping from problem to problem when fixing one would generate three others.
It didn't help that I was on RN 0.59 with AndroidX here and most native dependencies being broken. I might try it again now that 0.60 is out and if I succeed I'll let you know.

@HZSamir
Copy link

HZSamir commented Jul 21, 2019

@daoudjahdou
So, I did manage to convert my app to React-native-web, but before I get into specifics let me tell you it's completely broken beyond repair (both visuals and 90% of the libs I use) I guess you really need to start a project from scratch to use RNW, because converting an existing one is just not doable.

Here, a screenshot of how it looks on device
screenshot-2019-07-21_11 40 51 61

And here you can see this horror in browser
DeepinScreenshot_select-area_20190721112819

Okay, so first you need to create a file at web/webpack.config.js. Here is mine:

// webpack.config.js
const webpack = require("webpack");

const path = require("path");

const HTMLWebpackPlugin = require("html-webpack-plugin");

const HtmlWebpackRootPlugin = require("html-webpack-root-plugin");

const HardSourceWebpackPlugin = require("hard-source-webpack-plugin");

console.log("dirname : " + __dirname);
const appDirectory = path.resolve(__dirname, "../");

module.exports = {
  devServer: {
    contentBase: path.join(__dirname, "../public"),
    // enable HMR
    hot: false, // not now
    // embed the webpack-dev-server runtime into the bundle
    inline: true,
    compress: false, // should be faster
    // serve index.html in place of 404 responses to allow HTML5 history
    historyApiFallback: true,
    port: 8080,
    host: "0.0.0.0"
  },
  devtool: "eval", // see https://webpack.js.org/configuration/devtool/
  entry: [
    "webpack-dev-server/client?http://localhost:8080",
    // "webpack/hot/only-dev-server",
    // "react-hot-loader/patch",
    path.join(__dirname, "../index.web.js")
  ],
  module: {
    rules: [
      {
        test: /.(ts|tsx|js|jsx)$/,
        include: [
          path.resolve(appDirectory, "index.web.js"),
          path.resolve(appDirectory, "App"),
          path.resolve(
            appDirectory,
            "node_modules/@react-native-community/async-storage"
          ),
          path.resolve(appDirectory, "node_modules/react-native-dev-menu"),
          path.resolve(
            appDirectory,
            "node_modules/react-native-spring-scrollview"
          ),
          path.resolve(
            appDirectory,
            "node_modules/react-native-modal-translucent"
          ),
          path.resolve(appDirectory, "node_modules/react-native-reanimated"),
          path.resolve(appDirectory, "node_modules/react-native-screens"),
          path.resolve(
            appDirectory,
            "node_modules/@react-native-community/netinfo"
          ),
          path.resolve(
            appDirectory,
            "node_modules/react-native-devmenu-trigger"
          ),
          path.resolve(
            appDirectory,
            "node_modules/react-native-bottom-action-sheet"
          ),
          path.resolve(
            appDirectory,
            "node_modules/react-native-linear-gradient"
          ),
          path.resolve(appDirectory, "node_modules/react-native-sqlite-2"),
          path.resolve(appDirectory, "node_modules/react-native-vector-icons"),
          path.resolve(
            appDirectory,
            "node_modules/react-native-gesture-handler"
          ),
          path.resolve(appDirectory, "node_modules/react-native-action-button"),
          path.resolve(appDirectory, "node_modules/react-navigation-tabs"),
          path.resolve(appDirectory, "node_modules/react-navigation-drawer"),
          path.resolve(
            appDirectory,
            "node_modules/react-native-keyboard-aware-scroll-view"
          ),
          path.resolve(
            appDirectory,
            "node_modules/react-native-material-bottom-navigation"
          ),
          path.resolve(appDirectory, "node_modules/react-native-picker-select"),
          path.resolve(appDirectory, "node_modules/@react-navigation"),
          path.resolve(appDirectory, "node_modules/react-native-tags"),
          path.resolve(appDirectory, "node_modules/react-native-timeline-feed"),
          path.resolve(
            appDirectory,
            "node_modules/react-navigation-redux-helpers"
          ),
          path.resolve(appDirectory, "node_modules/react-native-slider-custom"),
          path.resolve(appDirectory, "node_modules/pouchdb-authentication"),
          path.resolve(
            appDirectory,
            "node_modules/pouchdb-adapter-asyncstorage"
          )
        ],
        loader: "babel-loader?+cacheDirectory"
      },
      {
        test: /\.(gif|jpe?g|png|svg)$/,
        loader: "url-loader",
        query: { name: "[name].[hash:16].[ext]" }
      }
    ]
  },
  output: {
    path: path.resolve(__dirname, "../public"),
    filename: "bundle.web.js"
  },
  plugins: [
    new HardSourceWebpackPlugin({
      // Either an absolute path or relative to webpack's options.context.
      cacheDirectory: "node_modules/.cache/hard-source/[confighash]",
      // Either a string of object hash function given a webpack config.
      configHash: function(webpackConfig) {
        // node-object-hash on npm can be used to build this.
        return require("node-object-hash")({ sort: false }).hash(webpackConfig);
      },
      // Either false, a string, an object, or a project hashing function.
      environmentHash: {
        root: process.cwd(),
        directories: [],
        files: ["package-lock.json", "yarn.lock"]
      }
    }),
    // new webpack.HotModuleReplacementPlugin(),
    new HTMLWebpackPlugin(),
    new HtmlWebpackRootPlugin(),
    new webpack.NamedModulesPlugin(),
    new webpack.DefinePlugin({
      "process.env": {
        NODE_ENV: JSON.stringify("development")
      },
      __DEV__: JSON.stringify("development")
    })
  ],
  resolve: {
    extensions: [".web.js", ".js", ".android.js", ".json", ".jsx"],
    modules: [path.join(__dirname, "..", "node_modules")],
    alias: {
      "react-native": "react-native-web",
      // "@react-native-community/async-storage": "react-native-web",
      "@react-native-community/async-storage": "@callstack/async-storage",
      "react-native-linear-gradient": "react-native-web-linear-gradient"
    }
  }
};

Metro.config.js

/**
 * Metro configuration for React Native
 * https://github.com/facebook/react-native
 *
 * @format
 */
const path = require("path");
// const blacklist = require('metro').createBlacklist;
const blacklist = require("metro-config/src/defaults/blacklist");

module.exports = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: false
      }
    })
  },
  /**
   * Add "global" dependencies for our RN project here so that our local components can resolve their
   * dependencies correctly
   */
  resolver: {
    extraNodeModules: {
      "react-native-mediafirst": path.resolve(
        __dirname,
        "node_modules/react-native-mediafirst"
      ),
      "react-native-mediafirst-lib": path.resolve(
        __dirname,
        "node_modules/react-native-mediafirst-lib"
      )
    },
    blacklistRE: blacklist([
      /node_modules\/.*\/node_modules\/react-native\/.*/,
      /nodejs-assets\/.*/,
      /android\/.*/,
      /ios\/.*/
    ])
  },
  /**
   * Add our workspace roots so that react native can find the source code for the included packages
   * in the monorepo
   */
  projectRoot: path.resolve(__dirname),
  watchFolders: [
    path.resolve(__dirname, "node_modules/react-native-mediafirst"),
    path.resolve(__dirname, "node_modules/react-native-mediafirst-lib")
  ]
};

I'll explain in a minute. First you need to install [email protected] (this specific version), html-webpack-plugin, html-webpack-root-plugin and hard-source-webpack-plugin (and also path-to-regexp@latest this one seemed to cause a weird bug unless installed)
Also make sure your version of react-dom is similar to your version of React (in this case 16.8.6)
The alias you see in the file is because I needed to use the web version of these packages.

Basically what happens is you need to compile any module that appears in red when you first run ./node_modules/.bin/webpack-dev-server -d --config ./web/webpack.config.js --inline --hot --colors --clearCache because that means the package needs to be compiled. It was somewhat confusing because some of these libs were pure JS.

So if for example you get an error like: at "react-native-some-lib" you may need an appropriate loader, just add it with path.resolve(appDirectory, "node_modules/pouchdb-authentication"),

Now create an index.web.js file at the root of your project

import "./polyfill";
import { AppRegistry } from "react-native";
import App from "./App/Containers/App";

// Change the app name appropriately
AppRegistry.registerComponent("igniteAndross", () => App);
AppRegistry.runApplication("igniteAndross", {
  rootTag: document.getElementById("root")
});

You need to make sure you don't register your app in your root component. Create a root component and only then import it in index.web.js then register it.

Also you need to get rid of any background={TouchableNativeFeedback.Ripple or TouchableNativeFeedback.SelectableBackground as they will break your app.

This should be it. If you have any questions feel free.

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

No branches or pull requests

3 participants