Giter Site home page Giter Site logo

react-native-note's People

Contributors

lixingdecai avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

react-native-note's Issues

react native duplicate commit in android 防重复提交

在android上实现页面跳转的防重复提交。

在android 的单页面应用中,跳转到另一个页面后,当前页面的脚本就停止运行。所以无法使用回调来触发触控区域的可点击性,只能使用简单粗暴的定时器来解决。用状态state 来设置 TouchableOpacity的 disabled属性。disabled如果如果设为true,则禁止此组件的一切交互。只用去控制这个state可以实现防重复提交。

在android下,性能会相对比较差,点击跳转会相对比较慢。一开始我设置的延迟时间是1000ms,甚至后面的1500ms,在机子比较卡顿的时候,还是相对比较容易触发onPress() 事件。

对于这种重复提交的使用比较频繁,复用高,将 TouchableHighlight 和 TouchableOpacity 进行封装使用;具体封装代码如下:

/**
 * MTouchableOpacity 
 * @desc TouchableOpacity 封装了防重复提交事件  默认禁止重复提交
 * @param disableDoubleClick 为true时 开启防重复提交
 * @param disableDuration 防重复提交事件,默认2000ms
 * @author [email protected]
 */
import React, {Component, PropTypes} from 'react';
import {
  StyleSheet,
  View,
  Text,
  Image,
  TouchableOpacity
} from 'react-native';


export default class MTouchableOpacity extends Component {
  constructor(props) {
    super(props);
    this.state = {
      disableDoubleClick: false
    };
  }

  static defaultProps = {
    disableDoubleClick: true, // 默认禁止重复提交
    disableDuration: 1000,
  };

  static propTypes = {
    disableDoubleClick : PropTypes.bool,
    disableDuration: PropTypes.number
  };

  /**
   * 禁止重复提交
   * 
   * @memberof Index
   */
  async _disableDoubleClick() {
    await this.setState({
      disableDoubleClick: true
    })
    // this.state.disableDoubleClick = true;
    this.timer = setTimeout(async () => {
      // this.state.disableDoubleClick = false;
      await this.setState({
        disableDoubleClick: false
      })
    }, this.props.disableDuration);
  }

  componentWillUnMount() {
    this.timer && clearTimeout(this.timer)
  }

  async _onPress() {
    const {onPress} = this.props;
    console.log('点击1 : ' + this.state.disableDoubleClick);
    onPress && onPress();
    this.props.disableDoubleClick && await this._disableDoubleClick(); // 如果不禁用重复提交
  }

  render() {
    const {onPress, disabled, ...attributes} = this.props;
    const isDisable = disabled === undefined ? this.state.disableDoubleClick : disabled;
    return (
     <TouchableOpacity
        onPress={this._onPress.bind(this)}
        disabled={isDisable}
        {...attributes}
      >
        {this.props.children}
     </TouchableOpacity>
    )
  }
}

const styles = StyleSheet.create({
});

android页面跳转使用异步会不调用

#场景,我在点击一个item时,希望做数据上报,但我担心阻塞主进程,所以在执行数据上报的时候,我对其进行了异步操作。

// 一个点击事件
_goChapter() {
   this._gaShowCollect(); // 一个setTimeout  100ms 异步执行的操作
   Service .runAction('/novel/chapter', params).then(res => {console.log(res);});  // 单页面跳转
 }

但是在android下,页面跳转后,这个页面的进程就停止了,setTimeout,将方法的线程排在了事件队列的最后,但是只有等上个页面回退,回到当前页面的上下文,才会继续执行。

react native 打包删除console相关模块

方法一

简单两步,打包的时候删除bundle中console相关代码

  1. 注册 babel 插件

npm i babel-plugin-transform-remove-console --save

  1. 编辑.babelrc 内容,加入以下代码
{
  "env": {
    "production": {
      "plugins": ["transform-remove-console"]
    }
  }
}

两步 让你在生产环境中的bundle文件不存在 console相关代码,减少了一定的代码量,和隐藏相关备注信息。

========
此方法,并不能去除所有console
originData.replace(/console[.]log[(].+[)]/g, '')

方法二

正则表达式 匹配删除console

originData.replace(/console[.]log[(].+[)]/g, '')

但是也只适合在没有压缩的代码里使用。在压缩的代码中使用,里面有各种字符,没办法匹配结束

https://stapp.space/how-to-remove-javascript-console-log-pros-2/

方法三

重写console 方法
if(!DEV) {
console = {};
console.log = () => {};
console.error = () => {};
}

其他重写

setState并不是立即生效

这是新手的一个必趟误区。
认为setState()结束后会渲染页面。但是并不是这样。

看例子

componentDidMount(){
  this.setState({
    val: this.state.count + 1
  });
  //第一次输出
  console.log(this.state.count);

  this.setState({
    val: this.state.count + 1
  });
  //第二次输出
  console.log(this.state.count);

  setTimeout(()=>{
    this.setState({val: this.state.count + 1});
    //第三次输出
    console.log(this.state.count);
    this.setState({
        val: this.state.val + 1
    });
    //第四次输出
    console.log(this.state.count);
  }, 0);  
}

输出结果 0 0 2 3

四次打印,分为两组,这两组的调用栈都是不同的

看看setState的调用流程
this.setState() == 传入state/ 还有回调 ==> enqueueSetState() / enqueueCallback ==> 是否处于批量更新模式 ==> updateComponent == > 更新pending state or props
image

空不等于false

在RN中,我会根据某字段来显示和隐藏某个部分。而在很多异步返回的字段,有可能为空。在js中,我们默认一个空的对象 === false;

正常的写法是:
{
    isShowTheView && <View><Text>有数据</Text></View>
}

可是当异步返回的数据,也就是this.setState({isShowTheView: ''})的时候会报RawText "" must be wrapped in an explicit component的红屏错误

image

解决方法很简单,将 isShowTheView 改为 !!isShowTheView, 相反再相反强行转为true 或者 false

{
    !!isShowTheView && <View><Text>有数据</Text></View>
}

react native version manager

RN开发中的版本管理

在使用RN做单页面开发集成Native app中,会出现很多版本:你APP的版本,RN的版本,你的RN-业务工程的版本三个版本交错,所以在版本管理上会是个很蛋疼的问题,下面草图是我gitlab RN项目的版本管理。先做个记录吧。

本来也是准备用tag来做版本的标记,但是RN的版本更新和APP的版本更新又不太一样,因为具备热更新,有时候一个bug就直接发版本。而且,RN的版本的维度又会更多,不仅自身的,还有APP和RN的版本维度。所以将APP版本作为分支,进行对应开发,develop分支作为打包分支,合并触发CI自动打包。

image

react native 使用Eslint

  1. npm install --save-dev eslint
  2. eslint --init
    image
    上图是我的style,怕麻烦可以直接选择Airbnb的配置
    image

react native 升级 0.43 --> 0.48

版本升级的带来的成本还是挺大的,特别是iOS 和 android上。纯前端大部分是根据你页面数量,来手动修改,春劳力成本输出,大部分的版本兼容性问题,都会在手机 或者流浪器的console中进行提示,根据提示还是很好进行定位。

这次版本升级,前前后后耗费将近一周的时间把。

对于版本升级,现在0.40以后大部分都是修补漏洞,对于没有太大需求,是没必要进行无谓升级,当然,如果你刚开始使用 RN , 还是推荐实现当前最新版本。版本升级,当你觉得有必要的时候再进行,不影响工程项目的前提先,没必要修复,那些升级修复的功能,你可能没用到,也可能永远不会用到。

安装 react-native-git-upgrade

$ npm install -g react-native-git-upgrade

react-native-git-upgrade提供了豪华的一条龙自动合并更新流程,主要包含两个服务:

+  首先它会利用Git工具计算新旧版本文件间的差异并生成补丁
+  然后在用户的项目文件上应用补丁

运行更新命令

$ react-native-git-upgrade

这样会直接把react native升级到最新版本

或者是:

$ react-native-git-upgrade X.Y.Z

这样把react native升级到指定的X.Y.Z版本

运行结果

image

手动修改

修改 package.json

package.json 文件又不会修改你的依赖版本,你还得手动更改,不然你重新下载依赖又照样报错了

修改 React.prototype

npm install --save prop-types

React.PropTypes

// After (15.5)
import React from 'react';
import PropTypes from 'prop-types';

class Component extends React.Component {
  render() {
    return <div>{this.props.text}</div>;
  }
}

Component.propTypes = {
  text: PropTypes.string.isRequired,
};

修改 React.creatClass

React.createClass

// After (15.5)
var createReactClass = require('create-react-class');

var Component = createReactClass({
  mixins: [MixinA],
  render() {
    return <Child />;
  }
});

NetInfo

网络监听的事件名称修改: change -- > connectionChange

NetInfo
      .isConnected
      .addEventListener('connectionChange', this._handleConnectionInfoChange.bind(this));

TextInput selectionColor

报错 Error while updating property 'selectionColor' of a view managed by: AndroidTextInput
image

一开始以为是 react-native-elements 版本问题,升级到最新后,还是不行
看了这个issue后,直接将selectionColor去掉了。有其他办法的,可以帮忙贴出来

Flatlist 大面积空白解决

在使用FlatList后,快速滑动,页面会出现大面积空白。原因是屏幕外的界面,还没来得及渲染,所以会产生空白的界面。

image

在RN的官方也说,为了更好的性能,牺牲了用户体验,会出现大面积的空白。正在优化中 -->
image

本来已经放弃升级了,但是今天看了官方demo,和源码,发现了其实还是有可以解决,可以牺牲性能,提高用户体验。

源码
image
使用
image
disableVirtualization : 虚拟化显著的提高了内存和性能,但是在屏幕外的实例都被卸载了。
这个属性只存在源码和demo中,在官方demo里是没有对这个参数进行描述。

热更新的代价

背景

目前的前端算比较是大热。react、vue、ng三辆马车在前端领域的推动。基于三辆马车的热更新的前端框架RN、Weex、NS应运而生。本来一开始在选型是选的weex,但是后面坐了两个页面就换RN了,因为社区和文档的不成熟等在开发的效率和代价上很大影响。所以本文热更新出现的相关问题,都是基于RN进行描述。

公司属于国内的二线互联网公司,主要产品就是移动APP,我们在RN上的使用,是以嵌入式的方式,集成到已有的 Native APP 中。在RN中的使用定位是,替代一些PV较高的H5,和一些新的业务的功能模块。展现的形式有,独立完整的页面 和 页面中的某个卡片,最终都会以RNView的形式展示,这个就很大了提高了RN展示的自由度。

热更新带来的好处

提高用户体验
不管是快速解决线上bug,还是解决
版本审核这个在iOS上的特有的环节,

热更新带来的问题

版本管理

竟然可以热更新了,那就可以自由的发布发版本。这里版本涉及到APP版本、RN 生产的bundle版本、RN版本;
APP版本:APP对RN的支持,是根据你的需求所需要的功能,一步步的接入,所以APP版本也是要考虑
RN bundle版本:这个是业务相关的RN的代码了,其实我们根据生产的zip包下发;
RN 版本:RN的官方版本,目前使用的是0.43版本,RN不向上兼容,所以升级的代价还是挺大的。

APP 版本 和 RN版本的对应配置

所谓的热更新,就是可以实时更新相对应的功能,那怎么更新呢,这需要一个下发机制。APP有个版本,RN有个版本,当这两个版本匹配的时候,会下发你所需要的更新;

RN不同版本的代码管理

并不能完全热更新

这个问题在RN技术刚引入的时候,表现的非常明显。比如你要引入一个监听页面重新回到屏幕的方法,就得客户端支持,这个就受限于App版本,只能等下个版本APP支持了这个功能以后,才能做相对应实现的热更新。毕竟没有办法一口吃成胖子,一方面客户端没有办法一下子全都实现,另一方面你在没遇到相关需求问题的时候,没有办法预料到需要哪些功能实现。
所以在初期,会给产品经理和其他同事一感觉,这也并不是如吹捧的可以不跟版本的热更新。

个人开发成本变多

对于RN相关开发人来说,工作量不是变少,而是变多了。对于之前Native开发,iOS程序员开发iOS,android程序员开发android,而RN,虽然是一套代码开发两端代码(理想),可是总还是会有区别的;
一个是适配造成差异性。
一种是业务上的差别,举个栗子,付费功能在iOS上是需要很严格的审核的,而android不用,所以在android会先上付费功能,而iOS得审核通过才能上,夸张的是有的公司十几次版本的申请都没过。
在开发的过程中,还要测试,边开发边测试。这也是相当大的工作量。

所以单纯拿业务页面的工作量来对比RN和Native,是大于1小于2;

测试开发成本变多

对于iOS 和 android 两种系统,同一套代码,不能保证两个实现都一样,只要验证一种系统的手机就行了。就RN而言,他对iOS的支持度好于android。
还有一个问题是,测试人员可能对RN不大了解,而你又是个前端的开发人员,可能他们会潜意识把RN当做H5,然后就会觉得测试比H5麻烦多的多。她们心里的预设就会觉得RN测试成本好大好大。

沟通成本变多

作为嵌入Native App 的 RN,RN需要沟通的对象就有iOS业务、iOS架构、android业务、android架构、产品、测试、H5、服务端、统计等。俨然就是个产品,跟所有部门都得打交道,在沟通和对接的环节就变得多了。而且在初期大家对RN的都不太熟,增加了很大的沟通成本。

整个公司的接受度

在引入RN到现在,每个环境都如履薄冰,如果没有一个强有力的人员主导这件事情,可能在任何一个环节就夭折掉或者限制了RN的在公司里面的发展。因为RN增加的工作量,让大家会开始慢慢抵触,

时效性时间差

Native 的更新默认都是根据版本,都在新版本中生效。这个对于热更新来说,没什么问题。
但是H5 和 RN之间就存在问题了;H5的页面是发布在互联网上的一个地址,只要不设置缓存,所以可以理解为是即时生效的,而RN的功能,是根据后台配置的,他生效时机依托于他的触发时机。而触发热更新的时机,或者说热更新生效的时机,一般都是在APP重新启动的时候。
所以问题来了,在H5生效和RN生效之间会有个时间差,这个时间差的长短,依托于用户重启app的时间。所以很可能H5 和RN 同时上了新版本,但H5生效了,RN还未生效的情况。
这是个很容易出现严重问题,但容易被忽略,或者考虑不到的问题

react native工程化:规范化

RN 工程规范化: eslint + prettier + vscode

编码规范:每个人的编码风格和习惯不同,例如有些人习惯句尾写封号,但是如果这些代码风格不进行一个
统一的规范,在多人的项目的代码管理中,就会造成很多不必要的代价。目前市场主流的编码规范Airbnb的编码风格,我们也是基于这套 -->
Airbnb React/JSX 编码规范

规范化的好处

  • 提高阅读性: 统一编码风格,编码和注释都像是来自同一个人。干净 整洁 看起来就很爽。
  • 减少出错率:不符合代码规则的代码,很多就是错误的。一定层度可以规避很多风险
  • 提高开发效率:代码风格不统一,在团队代码合并等很容易引起冲突
  • 提高个人能力:有很多你默认习惯的方法,其实是错误的。代码检测修复,也是一个非常好的自检和学习的过程。
  • 方便代码工程管理:诸多好处很显然可以让你在对工程 和 代码的管理上少了很多麻烦

规范性的好处很多,但是他的优先级并不是最高,它是在你项目发展到一定层度,项目相对稳定可以引进的。它是可以让你项目开发管理上变得更好的东西,但并不是必须配。

编辑器选择微软的VS code
vscode 使用 代码统一风格工具.editorconfig

使用vscode + eslint + prettier 修改后的效果图:
image

左侧41个文件是eslint fix 自动修复的文件数;中间是前后两个文件的代码差异比对,红色区域是eslint 自动修复的语法规则。右侧带有下滑线是不符合设定的eslint语法规则,需要手动修改的代码

使用Eslint 代码格式检测工具

  1. VSCode 安装 eslint 插件
    image

  2. npm install --save-dev eslint

  3. npm install --save-dev babel-eslint eslint-plugin-react-native eslint-plugin-jsx-a11y eslint-plugin-import
    (或者将下面的package.json拷到你的项目直接安装)
    babel-eslint 是 eslint 的解析器
    eslint-plugin-jsx-a11y 是 jsx 的插件
    eslint-plugin-react-native 是 react native 插件
    eslint-plugin-import 是支持es6 import/export 的插件
    eslint-config-airbnb 基于airbnb的eslint代码规则

附一份package.json的依赖配置作参考

 "dependencies": {
    "antd-mobile": "^2.0.0-beta.2",
    "babel-plugin-import": "^1.5.0",
    "create-react-class": "^15.6.2",
    "prop-types": "^15.6.0",
    "react": "16.0.0-alpha.12",
    "react-native": "^0.48.3",
    "react-native-animatable": "^1.1.1",
    "react-native-blur": "^3.1.2",
    "react-native-elements": "^0.11.2",
    "react-native-picker": "^4.0.18",
    "react-native-picker-android": "^1.0.3",
    "react-native-storage": "^0.2.1",
    "react-native-vector-icons": "^4.0.1",
    "react-navigation": "^1.0.0-beta.11"
  },
  "devDependencies": {
    "babel-eslint": "^8.0.1",
    "babel-jest": "19.0.0",
    "babel-preset-react": "^6.24.1",
    "babel-preset-react-native": "1.9.1",
    "eslint": "^4.9.0",
    "eslint-config-airbnb": "^16.1.0",
    "eslint-plugin-import": "^2.8.0",
    "eslint-plugin-jsx-a11y": "^6.0.2",
    "eslint-plugin-react": "^7.4.0",
    "eslint-plugin-react-native": "^3.1.0",
    "jest": "19.0.2",
    "q": "^1.5.0",
    "react-native-webpack-server": "^0.9.3",
    "react-test-renderer": "~15.4.0",
    "shelljs": "^0.7.7"
  },
  1. eslint --init
    image
    上图是我的style,怕麻烦可以直接选择Airbnb的配置
    image

当然相对于Airbnb,我们RN工程的一些差异性,我们还是做了小的改动,下面是我的.eslintrc 中eslint的一些规则:

module.exports = {
    "extends": ["airbnb"],
    "parser": "babel-eslint",
    "plugins": [
        "react",
        "react-native",
        "jsx-a11y",
        "import"
    ],
    rules: {
        // 0 = off, 1 = warn, 2 = error
        // FB配置参考:
        // https://github.com/facebook/react-native/blob/8baaad9b0fbda2b02bb1834452aa63cac7910dc5/.eslintrc
        "arrow-parens": ["error", "as-needed"],
        "global-require": 0,
        "no-use-before-define": 0,       // disallow use of variables before they are defined
        "max-len": 0,                    // specify the maximum length of a line in your program (off by default)
        "no-console": 0,                 // disallow use of console (off by default in the node environment)
        "no-undef": 2,                   // disallow use of undeclared variables unless mentioned in a /*global */ block
        "no-unused-expressions": ["error", { "allowShortCircuit": true, "allowTernary": true }], // allow short circuit allow  ternary
        // "no-empty": [2, { methods: true }],
        "no-unused-vars": 0,
        "no-underscore-dangle": 0,
        "no-param-reassign": ["error", { "props": false }],
        "radix": 0,
        "block-scoped-var": 0,           // treat var statements as if they were block scoped (off by default)
        "complexity": 0,                 // specify the maximum cyclomatic complexity allowed in a program (off by default)
        "consistent-return": 0,          // require return statements to either always or never specify values
        "class-methods-use-this": 0,
        // allow async-await
        'generator-star-spacing': 0,
        'curly': 0,
        "object-curly-spacing": 0,
        "one-var": 0,
        "no-return-assign": 1,           // disallow use of assignment in return statement
    
        "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
        "react/self-closing-comp": 1,
        "react/jsx-closing-bracket-location": 0,
        "react/prop-types": 0, // 避免redux等注入属性的情况
        "react/forbid-prop-types": 0
      },
    
      // 这里设置可能用到的全局变量
      "globals": {
        "window": true,
        "__DEV__": true,
        "__APP__": true,
        "__ANDROID__": true,
        "__IOS__": true
      }
};
  1. 执行eslint --ext .js ./src --fix
    但是执行完eslint --ext .js ./src --fix,几个简单页面的demo 报了上百个错误,就这些报错,估计语法错误,估计得改好久时间。
    而平常使用的格式化或者代码美化工具,没办法按照eslint的规则进行美化。我使用的react-beautify插件,就不行。在你改好代码,比如表达式最后一句,结尾使用逗号,格式化会将其删除
    image

使用Prettier 代码格式化工具

https://www.npmjs.com/package/prettierrc

  1. 安装prettier

1.1. npm install prettier --save-d / yarn add prettier --dev

1.2. 安装插件

prettier 在每个对应的IDE都有对应的插件,我使用的是VS code。就以vs code举例。搜索prettier插件的第一条就是,如下图所示
image

  1. 配置规则
    vscode 配置规则地址
    2.1. 直接在 package.json 里面配置
{
  "name": "projectname",
  "version": "1.0.0",
  "description": "test",
  "dependencies": {
    "prettier": "latest"
  },
  "prettier": {
    "singleQuote": true, // 规则 
     ……
  }
}

2.2. 配置文件.prettier
配置内容如下

{
    "useTabs": false,      // Indent lines with tabs instead of spaces. 
    "printWidth": 80,      // Specify the length of line that the printer will wrap on. 
    "tabWidth": 2,         // Specify the number of spaces per indentation-level. 
    "singleQuote": false,  // Use single quotes instead of double quotes. 
    /**
     * Print trailing commas wherever possible.
     * Valid options:
     *   - "none" - no trailing commas
     *   - "es5" - trailing commas where valid in ES5 (objects, arrays, etc)
     *   - "all" - trailing commas wherever possible (function arguments)
     */
    "trailingComma": "none",
    /**
     * Do not print spaces between brackets.
     * If true, puts the > of a multi-line jsx element at the end of the last line instead of being
     * alone on the next line
     */
    "jsxBracketSameLine": false,
    /**
     * Specify which parse to use.
     * Valid options:
     *   - "flow"
     *   - "babylon"
     */
    "parser": "babylon",
    /**
     * Do not print semicolons, except at the beginning of lines which may need them.
     * Valid options:
     * - true - add a semicolon at the end of every line
     * - false - only add semicolons at the beginning of lines that may introduce ASI failures
     */
    "noSemi": true,
    /**
     * Add additional logging from prettierrc (not prettier itself).
     * Defaults to false
     * Valid options:
     * - true - enable additional logging
     * - false - disable additional logging
     */
    "rcVerbose": true
}

坑: 使用此配置文件的时候,请将里面的注释删除,不然可能不生效

prettier 和 Eslint 冲突

其实prettier 的格式化不完全和 eslint的规则相符,还是会有冲突的地方。从上面的配置文件可以看出,prettier 可配置的选项还是比较简单的。在有些地方prettier 还是会把一些正确的格式成eslint不允许的。这种时候只能去修改eslint的配置文件.eslintrc

  1. arrow-parens 箭头函数的参数是否需要括号包裹

出现:
image

prettier格式化后:
image

解决:
在.eslintrc中添加 "arrow-parens": ["error", "as-needed"]

gitlab + jenkins 代码提交自动触发构建

第一种方法gitlab webhook + jenkins 的token

流程

1、gitlab 安装gitlab-runner
2、jenkins 安装插件 Gitlab Hook Plugin + Build Authorization Token Root Plugin
3、配置代码源,和构建分支
image

4、配置jenkins 的触发器
image

5、将上面的URL,配置到你的gitlab的intergrations里面;

如果403 就要加用户名和密码,不然可以省略

404:得将上面的URL变成下面的URL,我的工程是根目录,直接把上面的project的省略掉

URL = http://用户名:密码@CI地址:端口号/你工程的路径/buildByToken/build?job=工程名&token=序列号
image

6、保存,然后就是点击测试
image
如果现实蓝色201,则恭喜你,基本成功了。
image

第二种方法 gitlab webhook + jenkins allow branch

第一种方法存在一个很大的问题,就是,任何一个分支有push event 都会触发 jenkins的触发器。这是一个很大的问题,我们的目的是只要触发指定的分支,才触发jenken的触发器。所以就有了下面这种解决办法。

但要注意的点,gitlab 配置好地址和token 后 点击push test 是无效的。你只能在分支上进行真实的push event 进行测试。

流程

image
image
两图中红框的地方都要注意,token是图二生成放到图一里的。allow branch 里面填入你想要触发的分支就好

数据缓存的两种策略

数据缓存的优点,也是以下两种策略的共同有点是,页面能更快的渲染出现,减少网络请求的耗时,特别是当网络比较差的时候,页面能有数据出现,而不是在loading中或者白屏中。
第一种 和 第二种 相比较各有优缺点;
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.