How to Setup React Native Web with Storybook
Cody Pearce
Posted on February 25, 2020
This was originally published on codinhood.com
TLDR
Create a file named webpack.config.js
within the .storybook
folder with an alias for React Native Web.
module.exports = {
...
resolve: {
alias: {
"react-native$": "react-native-web"
}
}
};
Intro
Storybook is an excellent component development environment for React and other frameworks. However, if you're using React Native Web or would like to create some RNW components with Storybook you'll need to add some more configuration. If you already have a React or React Native Web app setup then you might want to skip to the Render React Native Web with Storybook
section of this article because the first section will start from scratch.
Basic React Setup
First, initialize a package.json
.
npm init
Then, install React, Babel, Webpack, and the usual loaders for running a typical React app.
npm install react react-dom babel-loader @babel/core @babel/preset-env @babel/preset-react html-loader html-webpack-plugin webpack webpack-dev-server webpack-cli
Create Webpack config
Create webpack.config.js
at the root of the project with the following basic react configuration.
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules\/(?!()\/).*/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
},
},
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
},
],
},
],
},
plugins: [
new HtmlWebPackPlugin({
template: "./public/index.html",
filename: "./index.html",
}),
],
devServer: {
historyApiFallback: true,
contentBase: "./",
hot: true,
},
};
Public Folder and HTML
Create a public
folder at the project root. Inside that folder, create a index.html
with the following HTML:
<!DOCTYPE html>
<html>
<head>
<title>React Native Web Storybook</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
App Entry and Component
Create a folder src
at the project root. Inside that folder, create index.js
with the following React setup code:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(<App />, document.getElementById("app"));
Next, create App.js
inside the src
folder with the following "Hello World" code
import React from "react";
export default class App extends React.Component {
render() {
return <div>Hello world</div>;
}
}
Running Hello World
Add the following two scripts to the scripts
object in package.json
for running and building the app with Webpack.
"scripts": {
"build": "webpack --mode production",
"start": "webpack-dev-server --config ./webpack.config.js --mode development",
},
Finally, run npm start
in your terminal and hello world should be shown at http://localhost:8080/.
Setup Storybook with React
First, install Storybook.
npm i @storybook/react
Create a script, storybook
, for starting the storybook dev server.
"scripts": {
"build": "webpack --mode production",
"start": "webpack-dev-server --config ./webpack.config.js --mode development",
"storybook": "start-storybook"
},
Create a folder, .storybook
, at the project root. Create another project file, main.js
within that folder and add the following:
module.exports = {
stories: ["../src/**/*.stories.[tj]s"],
};
Create index.stories.js
within src
to test that Storybook is configured correctly.
import React from "react";
export default { title: "Hello World" };
export const withText = () => <div>Hello World</div>;
Finally, run npm run storybook
, and the storybook server should start running on the port indicated in your terminal. In my case, the server is running on http://localhost:57823/.
Setup React Native Web
First, install React Native Web.
npm i react-native-web
Go to webpack.config.js
at the project root and add an alias for react-native
to react-native-web
so Webpack will pull components from react-native-web
instead of React Native. Add the following below plugins
and above devServer
:
...
resolve: {
alias: {
"react-native$": "react-native-web",
},
},
...
This is the only config necessary to use React Native Web components given our current simple setup. Let's test this configuration by adding a React Native component to src/App.js
.
import React from "react";
import { Text } from "react-native";
export default class App extends React.Component {
render() {
return <Text>Hello world</Text>;
}
}
Run the app server again with npm start
and you should see "Hello World" just as before, except this time the syntax matches React Native. The main app is now set up to render React Native components.
Render React Native Web with Storybook
Assuming you have React, React Native Web, and Storybook set up properly, the only step left is to add an alias for the Storybook Webpack server to look for react-native
imports within react-native-web
.
Create a file named webpack.config.js
within the .storybook
folder that resolves an alias for React Native Web as shown below.
module.exports = {
...
resolve: {
alias: {
"react-native$": "react-native-web"
}
}
};
Now, open src/index.stories.js
and create a component with React Native.
import { Text } from "react-native";
...
export const reactNative = () => <Text>React Native Web is Awesome!</Text>;
Run Storybook again with npm run storybook
.
We can use any of the API's found on React Native Web's README. For example,
import { ActivityIndicator } from "react-native";
...
export const reactNativeActivity = () => <ActivityIndicator />;
Conclusion
Getting React Native Web working with Storybook can be extremely simple, but it can also be more complicated depending on the third-party libraries your app is utilizing.
Posted on February 25, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.