Building a Cross-Platform App with React Native Web and TypeScript
React Native Web allows you to use the same codebase for mobile and web applications, leveraging the power of React Native’s components. Using TypeScript alongside React Native Web enhances type safety and provides a better developer experience. In this article, we'll walk through each step needed to set up React Native CLI for both web and mobile using TypeScript.
1. Prerequisites
Before starting, ensure you have:
2. Setting Up the Project
Create a new React Native project with TypeScript:
npx react-native init MyCrossPlatformApp --template react-native-template-typescript
cd MyCrossPlatformApp
This creates a React Native project with TypeScript support out of the box.
3. Installing React Native Web
To enable web support in your React Native project, install react-native-web and react-dom:
npm install react-native-web react-dom
Update your package.json to include a script for starting the web server:
"scripts": { "web": "react-native-web start" }
You should now be able to run the project on a web browser, but we need to configure a few more things to ensure it works seamlessly.
4. Configuring the Webpack
React Native Web requires Webpack to bundle the app for the browser. Install Webpack and the necessary plugins:
npm install --save-dev webpack webpack-cli webpack-dev-server babel-loader @babel/core @babel/preset-env
Then, create a webpack.config.js file in the root directory of your project:
webpack.config.js:
const path = require('path');
module.exports = {
entry: path.resolve(__dirname, 'index.web.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
resolve: {
alias: {
'react-native$': 'react-native-web',
},
extensions: ['.web.js', '.js', '.ts', '.tsx'],
},
module: {
rules: [
{
test: /\.(js|ts|tsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['module:metro-react-native-babel-preset', '@babel/preset-env'],
},
},
},
],
},
devServer: {
contentBase: path.resolve(__dirname, 'dist'),
compress: true,
port: 8080,
},
};
This configuration tells Webpack to look for files with .web.js, .js, .ts, and .tsx extensions. The alias for react-native points to react-native-web, ensuring it recognizes web-specific code.
5. Setting Up Babel Configuration
React Native uses Babel to transpile JavaScript and TypeScript. To ensure compatibility with the web, update your babel.config.js:
module.exports = {
presets: ['module:metro-react-native-babel-preset', '@babel/preset-env'],
plugins: ['react-native-reanimated/plugin'], // Optional for animations
};
6. Creating Entry Files for Web and Mobile
React Native uses index.js as the entry point. To support web, create an additional entry file named index.web.js:
index.web.js:
领英推荐
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
import { registerRootComponent } from 'expo';
// Register for web
AppRegistry.registerComponent(appName, () => App);
AppRegistry.runApplication(appName, {
initialProps: {},
rootTag: document.getElementById('app-root'),
});
Add a public/index.html file with a root div for Webpack to inject the app:
public/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React Native Web</title>
</head>
<body>
<div id="app-root"></div>
<script src="bundle.js"></script>
</body>
</html>
7. Adding Platform-Specific Components
React Native Web allows you to create platform-specific code. For instance, if you want to render a different component for web, mobile, and desktop, you can use platform-specific files.
Create two files in the components folder: Button.web.tsx and Button.tsx:
Button.web.tsx:
import React from 'react';
import { Button, View, Text } from 'react-native';
const WebButton: React.FC = () => (
<View>
<Button title="Click me - Web" onPress={() => alert('Web Button clicked!')} />
</View>
);
export default WebButton;
Button.tsx (for mobile):
import React from 'react';
import { Button, View, Text } from 'react-native';
const MobileButton: React.FC = () => (
<View>
<Button title="Click me - Mobile" onPress={() => alert('Mobile Button clicked!')} />
</View>
);
export default MobileButton;
React Native will automatically pick up the platform-specific files when running the app on different platforms.
8. Using TypeScript Types and Interfaces
TypeScript helps manage data types effectively across platforms. Here’s an example of using TypeScript types in the app:
App.tsx:
import React from 'react';
import { SafeAreaView, StyleSheet, Text } from 'react-native';
import PlatformButton from './components/Button';
interface Props {
platform: string;
}
const App: React.FC<Props> = ({ platform }) => (
<SafeAreaView style={styles.container}>
<Text style={styles.title}>Hello from {platform}</Text>
<PlatformButton />
</SafeAreaView>
);
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
title: {
fontSize: 24,
},
});
export default App;
This component displays platform-specific text and uses TypeScript to enforce type-checking.
9. Running the Application
Once everything is set up, you can run the app on mobile and web platforms:
To Run on Mobile (Android/iOS):
npx react-native run-android # For Android
npx react-native run-ios # For iOS (on macOS)
To Run on Web:
First, build the project for the web using Webpack:
npx webpack serve
Now, open https://localhost:8080 in your browser to see the web version of your React Native app.
10. Summary
By following these steps, you’ve set up a React Native project with TypeScript and React Native Web support. Here’s what we covered:
React Native Web and TypeScript provide a powerful combination for building cross-platform applications, offering type safety, efficient code management, and the flexibility to target both mobile and web users. This setup allows you to leverage one codebase to create a unified experience across platforms.
#ReactNative #TypeScript #ReactNativeWeb #CrossPlatform #MobileAppDevelopment #FrontendDevelopment #JavaScript #CodeReuse #WebDevelopment #MobileDevelopment
Tech Leader | Expert in JavaScript (ECMAScript) & Modern Frameworks | Over a Decade Building Scalable, Future-Proof Solutions for Global Audiences.
3 周This wont work, at all. npx @react-native-community/cli@latest init MyProject —version latest