20、生产部署与 React Native 开发指南

生产部署与 React Native 开发指南

在软件开发中,将项目部署到生产环境以及开发移动应用是两个重要的环节。下面将详细介绍生产部署的流程以及 React Native 开发的相关内容。

生产部署流程
  1. 配置 Jenkins 任务
    • 在文本区域脚本中添加 npm install && npm run start-production
    • 点击“Apply”,然后点击“Save”按钮。
  2. 测试 Jenkins 任务
    • 若之前遵循了特定步骤,需使用命令 npm run stop 停止 PM2 服务器,并删除之前克隆的生产目录,避免 Jenkins 任务出现问题。
    • 修改一个简单文件,如修改 Home 组件,添加额外文本(Jenkins):
import React from 'react';
import styles from './Home.scss';
const Home = props => (
  <h1 className={styles.Home}>Hello {props.name || 'World'} (Jenkins)</h1>
);
export default Home;
- 文件路径为 `src/client/home/index.jsx`。
- 提交并推送到 master 分支。
- 打开 Jenkins,选择任务,点击“Build Now”。
- 点击最新构建(首次构建为 #1)。在构建中可查看启动构建的用户和正在构建的版本(master 的最后一次提交)。若想查看控制台输出,可点击左侧菜单中的相应选项。
  1. 查看控制台输出
    • 每次运行新构建时,Jenkins 会执行以下操作:
      • 获取仓库的最新更改: git config remote.origin.url https://github.com/csantany/production.git
      • 获取 master 的最后一次提交: git rev-parse refs/remotes/origin/master^{commit}
      • 执行在构建后任务中指定的命令: npm install && npm run start-production
    • 若一切正常,输出末尾应显示 Finished: SUCCESS
  2. 访问生产站点
    • 等待 30 秒或 1 分钟后,访问生产站点(如 http://142.93.28.244/ ),即可看到新更改。文件存储在 /var/lib/jenkins/workspace/<your_jenkins_job_name> 目录下。
React Native 开发

React Native 是一个使用 JavaScript 和 React 构建移动应用的框架,它可以将 React 代码转换为 Android 的 Java 代码或 iOS 的 Objective - C 代码,从而构建原生应用。

React Native 的优势
  • 一次编码,可获得两个原生应用(Android 和 iOS)。
  • 无需具备 Java、Objective - C 或 Swift 的经验。
  • 开发速度更快。
  • 采用 MIT 开源许可证。
系统要求
操作系统 要求
Windows Android Studio、Android SDK(>= 7.0 Nougat)、Android AVD
Mac XCode(>= 9)、Simulator
创建第一个 React Native 应用
  1. 安装依赖
    • 安装 react-native-cli 包: npm install -g react-native-cli
  2. 创建应用
    • 使用命令 react-native init MyFirstReactNativeApp 创建应用。
  3. 安装 Watchman
    • Watchman 是 React Native 所需的文件监视服务。可前往 https://facebook.github.io/watchman/docs/install.html 下载适合操作系统(Windows、Mac 或 Linux)的最新版本。
    • 对于 Mac,可使用 Homebrew 安装。若未安装 Homebrew,可使用命令 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 进行安装。
    • 安装 Watchman 的命令如下:
brew update
brew install watchman
  1. 启动项目
    • 使用命令 react-native start 启动 React Native 项目。
    • 若出现 Watchman 错误,可先使用 brew unlink watchman 卸载,再使用 brew update && brew upgrade brew install watchman 重新安装。
  2. 运行应用
    • 打开新终端(Cmd + T),根据所需设备运行相应命令:
      • 运行 iOS 应用: react-native run-ios
      • 运行 Android 应用: react-native run-android
  3. 修改代码
    • 修改 App.js 文件:
export default class App extends Component<Props> {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          This is my first React Native App!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit App.js
        </Text>
        <Text style={styles.instructions}>{instructions}</Text>
      </View>
    );
  }
}
- 若要在模拟器中查看新更改,需按 Cmd + R 重新加载应用。
- 可按 Cmd + D 打开开发菜单,选择“Enable Live Reload”选项实现自动重新加载。
- 点击“Debug JS Remotely”可自动打开 Chrome 标签,查看使用 `console.log` 添加的日志。
  1. 创建新组件
    • 创建 components 目录,并在其中创建 Home.js 文件:
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
class Home extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.home}>Home Component</Text>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  home: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  }
});
export default Home;
- 在 `App.js` 中导入并渲染 Home 组件:
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Home from './components/Home';
class App extends Component {
  render() {
    return (
      <Home />
    );
  }
}
export default App;
创建 React Native 待办事项列表
  1. 项目准备
    • 创建新的 React 应用 MySecondReactNativeApp ,创建 src 文件夹并将 App.js 文件移入其中,修改 App.js 文件以包含待办事项列表:
import React, { Component } from 'react';
import Todo from './components/Todo';
export default class App extends Component {
  render() {
    return (
      <Todo />
    );
  }
}
  1. 创建 Todo 组件
import React, { Component } from 'react';
import {
  Text,
  View,
  TextInput,
  TouchableOpacity,
  ScrollView
} from 'react-native';
import styles from './TodoStyles';
class Todo extends Component {
  state = {
    task: '',
    list: []
  };
  onPressAddTask = () => {
    if (this.state.task) {
      const newTask = this.state.task;
      const lastTask = this.state.list[0] || { id: 0 };
      const newId = Number(lastTask.id + 1);
      this.setState({
        list: [{ id: newId, task: newTask }, ...this.state.list],
        task: ''
      });
    }
  }
  onPressDeleteTask = id => {
    this.setState({
      list: this.state.list.filter(task => task.id !== id)
    });
  }
  render() {
    const { list } = this.state;
    let zebraIndex = 1;
    return (
      <View style={styles.container}>
        <ScrollView
          contentContainerStyle={{
            flexGrow: 1,
          }}
        >
          <View style={styles.list}>
            <View style={styles.header}>
              <Text style={styles.headerText}>Todo List</Text>
            </View>
            <View style={styles.add}>
              <TextInput
                style={styles.inputText}
                placeholder="Add a new task"
                onChangeText={(value) => this.setState({ task: value })}
                value={this.state.task}
              />
              <TouchableOpacity
                style={styles.button}
                onPress={this.onPressAddTask}
              >
                <Text style={styles.submitText}>+ Add Task</Text>
              </TouchableOpacity>
            </View>
            {list.length === 0 && (
              <View style={styles.noTasks}>
                <Text style={styles.noTasksText}>
                  There are no tasks yet, create a new one!
                </Text>
              </View>
            )}
            {list.map((item, i) => {
              zebraIndex = zebraIndex === 2 ? 1 : 2;
              return (
                <View key={`task${i}`} style={styles[`task${zebraIndex}`]}>
                  <Text>{item.task}</Text>
                  <TouchableOpacity onPress={() => {
                    this.onPressDeleteTask(item.id)
                  }}>
                    <Text style={styles.delete}>
                      X
                    </Text>
                  </TouchableOpacity>
                </View>
              );
            })}
          </View>
        </ScrollView>
      </View>
    );
  }
}
export default Todo;
  1. 创建样式文件
import { StyleSheet } from 'react-native';
export default StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5FCFF',
    height: 50
  },
  list: {
    flex: 1
  },
  header: {
    backgroundColor: '#333',
    alignItems: 'center',
    justifyContent: 'center',
    height: 60
  },
  headerText: {
    color: 'white'
  },
  inputText: {
    color: '#666',
    height: 40,
    borderColor: 'gray',
    borderWidth: 1
  },
  button: {
    paddingTop: 10,
    paddingBottom: 10,
    backgroundColor: '#1480D6'
  },
  submitText: {
    color: '#fff',
    textAlign: 'center',
    paddingLeft: 10,
    paddingRight: 10
  },
  task1: {
    flexDirection: 'row',
    height: 50,
    backgroundColor: '#ccc',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingLeft: 5
  },
  task2: {
    flexDirection: 'row',
    height: 50,
    backgroundColor: '#eee',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingLeft: 5
  },
  delete: {
    margin: 10,
    fontSize: 15
  },
  noTasks: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center'
  },
  noTasksText: {
    color: '#888'
  }
});
  1. 防止误删除任务
    • 若要防止用户误删任务,可导入 Alert 组件并修改 onPressDeleteTask 方法:
import {
  Text,
  View,
  TextInput,
  TouchableOpacity,
  ScrollView,
  Alert
} from 'react-native';
onPressDeleteTask = id => {
  Alert.alert('Delete', 'Do you really want to delete this task?', [
    {
      text: 'Yes, delete it.',
      onPress: () => {
        this.setState({
          list: this.state.list.filter(task => task.id !== id)
        });
      }
    }, {
      text: 'No, keep it.'
    }
  ]);
}
实现 React Navigation V2
  1. 安装依赖
    • 安装 react-navigation 依赖: npm install react-navigation
  2. 实现导航功能
    • App.js 中引入相关组件和依赖:
import React, { Component } from 'react';
import { StyleSheet, View, ScrollView, Image } from 'react-native';
import { createDrawerNavigator, DrawerItems } from 'react-navigation';
import Home from './sections/Home';
import Configuration from './sections/Configuration';
- 创建自定义抽屉组件 `CustomDrawerComponent`:
const CustomDrawerComponent = props => (
  <View style={styles.area}>
    <View style={styles.drawer}>
      <Image
        source={require('./assets/codejobs.jpeg')}
        style={styles.logo}>
      </Image>
    </View>
    <ScrollView>
      <DrawerItems {...props} />
    </ScrollView>
  </View>
);
- 创建 `AppDrawerNavigator`:
const AppDrawerNavigator = createDrawerNavigator({
  Home,
  Configuration
},
{
  contentComponent: CustomDrawerComponent
});
- 创建 `App` 类并渲染 `AppDrawerNavigator` 组件:
class App extends Component {
  render() {
    return (
      <AppDrawerNavigator />
    );
  }
}
const styles = StyleSheet.create({
  area: {
    flex: 1
  },
  drawer: {
    height: 150,
    backgroundColor: 'white',
    alignItems: 'center',
    justifyContent: 'center'
  },
  logo: {
    height: 120,
    width: 120,
    borderRadius: 60
  }
});
export default App;
  1. 创建章节组件
    • Home 组件
import React, { Component } from 'react';
import { View, Text, Image, TouchableOpacity } from 'react-native';
import styles from './SectionStyles';
class Home extends Component {
  static navigationOptions = {
    drawerIcon: () => (
      <Image
        style={styles.iconsItem}
        source={require('../assets/home.png')}
      />
    )
  }
  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity
          onPress={() => this.props.navigation.openDrawer()}
          style={styles.iconMenu}
        >
          <Image
            style={styles.menu}
            source={require('../assets/menu.png')}
          />
        </TouchableOpacity>
        <Text style={styles.titleText}>I'm the home section</Text>
      </View>
    );
  }
}
export default Home;
- **Configuration 组件**:
import React, { Component } from 'react';
import { View, Text, Image, TouchableOpacity } from 'react-native';
import styles from './SectionStyles';
class Configuration extends Component {
  static navigationOptions = {
    drawerIcon: () => (
      <Image
        style={styles.iconsItem}
        source={require('../assets/config.png')}
      />
    )
  };
  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity
          onPress={() => this.props.navigation.openDrawer()}
          style={styles.iconMenu}
        >
          <Image
            style={styles.menu}
            source={require('../assets/menu.png')}
          />
        </TouchableOpacity>
        <Text style={styles.titleText}>I'm the configuration section</Text>
      </View>
    );
  }
}
export default Configuration;
  1. 创建样式文件
import { StyleSheet } from 'react-native';
export default StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  iconMenu: {
    position: 'absolute',
    left: 0,
    top: 5
  },
  titleText: {
    fontSize: 26,
    fontWeight: 'bold',
  },
  menu: {
    width: 80,
    height: 80,
  },
  iconsItem: {
    width: 25,
    height: 25
  }
});

以上就是生产部署和 React Native 开发的详细流程和代码示例,希望能帮助你顺利完成项目的部署和开发。

生产部署与 React Native 开发指南(续)

生产部署与 React Native 开发的关键要点回顾

在前面的内容中,我们详细介绍了生产部署的流程以及 React Native 开发的多个方面。生产部署主要围绕 Jenkins 任务的配置和测试展开,通过一系列操作确保项目能顺利部署到生产环境。而 React Native 开发则涵盖了创建第一个应用、创建待办事项列表以及实现 React Navigation V2 等内容。下面我们来深入分析这些过程中的关键要点和技术细节。

生产部署关键要点
  • Jenkins 配置 :在文本区域脚本中添加 npm install && npm run start-production 是确保项目依赖安装和生产环境启动的关键步骤。点击“Apply”和“Save”保存配置后,后续的构建操作将以此为基础执行。
  • 代码修改与提交 :修改代码并提交到 master 分支是触发 Jenkins 构建的前提。例如修改 Home 组件添加额外文本,这不仅可以验证 Jenkins 是否正常工作,还能让我们看到代码更改在生产环境中的更新效果。
  • 控制台输出分析 :Jenkins 构建过程中的控制台输出包含了重要信息。通过查看输出,我们可以了解到仓库的更新情况(如 git config remote.origin.url git rev-parse 命令的执行结果)以及命令执行的状态。若输出末尾显示 Finished: SUCCESS ,则表示构建成功。
React Native 开发关键要点
  • 环境搭建 :安装 react-native-cli 和 Watchman 是创建 React Native 项目的基础。不同操作系统对于开发环境有不同的要求,如 Windows 需要 Android Studio 等,Mac 需要 XCode 等。
  • 组件开发 :在 React Native 中,组件的开发与 React 有一些区别。例如,使用 <View> 替代 <div> ,使用 <Text> 替代 <p> ,并且样式采用对象形式。创建新组件时,需要注意样式的使用和组件之间的引用关系。
  • 事件处理 :在待办事项列表的开发中,我们学习了如何处理事件。如 TextInput 组件使用 onChangeText 来更新状态, TouchableOpacity 组件使用 onPress 来处理点击事件。这些事件处理机制是实现交互功能的关键。
技术点分析
生产部署中的版本控制与自动化构建

在生产部署过程中,版本控制和自动化构建是非常重要的技术点。Jenkins 通过 git 命令获取仓库的最新更改和最后一次提交,确保每次构建使用的都是最新的代码。这种自动化的版本控制和构建流程可以提高开发效率,减少人为错误。

graph LR
    A[代码提交到 master 分支] --> B[Jenkins 触发构建]
    B --> C[获取仓库最新更改]
    C --> D[获取 master 最后一次提交]
    D --> E[执行构建后命令]
    E --> F{构建是否成功}
    F -- 是 --> G[生产环境更新]
    F -- 否 --> H[查看控制台输出调试]
React Native 中的样式与布局

React Native 的样式和布局与传统的 Web 开发有所不同。它使用 StyleSheet 对象来创建样式,并且样式规则的应用有一些限制。例如,某些样式属性不能直接应用于 <View> 组件,需要应用于 <Text> 组件。

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    home: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    }
});

在布局方面, flex 布局是常用的方式。通过设置 flex 属性,可以实现灵活的布局效果。例如,在待办事项列表中,使用 flexDirection justifyContent 等属性来排列任务项。

总结与展望

通过本文的介绍,我们详细了解了生产部署和 React Native 开发的相关知识和操作步骤。生产部署的自动化流程可以确保项目的稳定发布,而 React Native 开发则为我们提供了一种高效的移动应用开发方式。

在未来的开发中,我们可以进一步优化生产部署流程,例如增加更多的自动化测试环节,提高代码质量和稳定性。在 React Native 开发方面,我们可以探索更多的组件和功能,如集成第三方库、实现数据存储等,以丰富应用的功能。

希望本文能为开发者提供有价值的参考,帮助大家在生产部署和 React Native 开发中取得更好的成果。

本课题设计了一种利用Matlab平台开发的植物叶片健康状态识别方案,重点融合了色彩纹理双重特征以实现对叶片病害的自动化判别。该系统构建了直观的图形操作界面,便于用户提交叶片影像并快速获得分析结论。Matlab作为具备高效数值计算数据处理能力的工具,在图像分析模式分类领域应用广泛,本项目正是借助其功能解决农业病害监测的实际问题。 在色彩特征分析方面,叶片影像的颜色分布常其生理状态密切相关。通常,健康的叶片呈现绿色,而出现黄化、褐变等异常色彩往往指示病害或虫害的发生。Matlab提供了一系列图像处理函数,例如可通过色彩空间转换直方图统计来量化颜色属性。通过计算各颜色通道的统计参数(如均值、标准差及主成分等),能够提取具有判别力的色彩特征,从而为不同病害类别的区分提供依据。 纹理特征则用于描述叶片表面的微观结构形态变化,如病斑、皱缩或裂纹等。Matlab中的灰度共生矩阵计算函数可用于提取对比度、均匀性、相关性等纹理指标。此外,局部二值模式Gabor滤波等方法也能从多尺度刻画纹理细节,进一步增强病害识别的鲁棒性。 系统的人机交互界面基于Matlab的图形用户界面开发环境实现。用户可通过该界面上传待检图像,系统将自动执行图像预处理、特征抽取分类判断。采用的分类模型包括支持向量机、决策树等机器学习方法,通过对已标注样本的训练,模型能够依据新图像的特征向量预测其所属的病害类别。 此类课题设计有助于深化对Matlab编程、图像处理技术模式识别原理的理解。通过完整实现从特征提取到分类决策的流程,学生能够将理论知识实际应用相结合,提升解决复杂工程问题的能力。总体而言,该叶片病害检测系统涵盖了图像分析、特征融合、分类算法及界面开发等多个技术环节,为学习掌握基于Matlab的智能检测技术提供了综合性实践案例。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值