React-native-web: Bulding a UI module for both react-native and react-native-web

Created on 14 May 2018  ·  4Comments  ·  Source: necolas/react-native-web

Hello 😄 I'm trying to build a UI module that I can import and use both on RN and RNW.

I've tried to bundle my-ui-module with rollup using this rollup.config.js

import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import pkg from './package.json';

export default [
  {
    input: 'src/main.js',
    external: ['react', 'prop-types', 'react-native', 'react-dom'],
    output: {
      file: pkg.main,
      format: 'cjs'
    },
    plugins: [
      babel({
        exclude: ['node_modules/**']
      }),
      resolve(),
    ]
  }
];

and .babelrc

{
  "presets": [
    "react",
    [
      "env",
      {
        "modules": false
      }
    ]
  ],
  "plugins": ["transform-object-rest-spread"]
}

Then in my node app I'm using this .babelrc

{
  "presets": [
    "env",
    "react"
  ],
  "plugins": [
    "react-native-web",
    "transform-class-properties"
  ]
}

and I wanna do server-side render with this index.js

require("babel-register");
require("babel-polyfill");
require('./server');

and server.js

import React from 'react';
import ReactDOMServer from 'react-dom/server'
import { AppRegistry } from 'react-native-web'
import express from 'express';
import fs from 'fs';

// const bundledJs = fs.readFileSync('./build/static/js/main.js');

import NewsFeedApp from './src/App';

const app = express();

AppRegistry.registerComponent('NewsFeedApp', () => NewsFeedApp);
// prerender the app
const { element, getStyleElement } = AppRegistry.getApplication('NewsFeedApp', {});
// first the element
const html = ReactDOMServer.renderToString(element);
// then the styles
const css = ReactDOMServer.renderToStaticMarkup(getStyleElement());

app.get('/', (req, res) => {
  res.send(`
    ${css}
    <div id="root">${html}</div>
  `);
});

app.listen(3001, () => {
  console.log('Server started');
});

And I get this error Error: Cannot find module 'react-native' because I suspect the babel-plugin-react-native-web is not doing any transformation on an imported module.

What's the correct way to create a ui module to be shared?

Most helpful comment

I understand this might not be strictly related to react-native-web itself but the fact that it's hard to build a UI module to share between mobile and web makes it difficult to convince people to give it a try in my company for example.

I know from your tweets that it took you 18+ months to convince Twitter to use RNW, I wish this could be easier and quicker for me 😄

Any chance someone can add a clear documentation on how to achieve this?
Or at least leave this issue open and flag it as improve docs or something like that?

I honestly think this can be a very common use case.

Thank you! 👨‍🚀

All 4 comments

Looks like your server needs to alias react native to react native web package, or build your server side code using something like webpack or rollup

I understand this might not be strictly related to react-native-web itself but the fact that it's hard to build a UI module to share between mobile and web makes it difficult to convince people to give it a try in my company for example.

I know from your tweets that it took you 18+ months to convince Twitter to use RNW, I wish this could be easier and quicker for me 😄

Any chance someone can add a clear documentation on how to achieve this?
Or at least leave this issue open and flag it as improve docs or something like that?

I honestly think this can be a very common use case.

Thank you! 👨‍🚀

@mtt87 do you find a solution? I also working on an universal ui library. My current approach is to use react-native-web as default import and alias react-native. In this direction there are way less complications in view of SSR. @necolas to you would recommend this approach?

I haven't worked specifically on this anymore but I might give it another try over the weekend.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

holmesal picture holmesal  ·  3Comments

ndbroadbent picture ndbroadbent  ·  3Comments

MovingGifts picture MovingGifts  ·  3Comments

EvanBacon picture EvanBacon  ·  3Comments

roryabraham picture roryabraham  ·  3Comments