首页
吐槽
友链
关于
Search
1
WHMCS官方最新版下载+开心教程
640 阅读
2
【React Native】如何拨打电话?
620 阅读
3
为TypeScript项目添加Eslint和Prettier
466 阅读
4
React Native原理和架构
311 阅读
5
本站免费提供微软office A1P、A1账号
237 阅读
前端开发
后端开发
源码分享
技术分享
生活娱乐
影视评价
闲言碎语
登录
Search
标签搜索
ios
前端
JavaScript
阿里
Teambition
typecho
小火箭
shadowsocks
React
React Native
SQL
eslint
prettier
typescript
GraphQL
WHMCS
WHMCS开心版
Zsh
on-my-zsh
代理
夜雨
累计撰写
31
篇文章
累计收到
45
条评论
首页
栏目
前端开发
后端开发
源码分享
技术分享
生活娱乐
影视评价
闲言碎语
页面
吐槽
友链
关于
搜索到
31
篇与
surile
的结果
2022-02-22
oh-my-zsh的git快捷命令
{card-describe title="快捷命令"}g - gitgst - git statusgl - git pullgup - git pull --rebasegp - git pushgd - git diffgdc - git diff --cachedgdv - git diff -w "$@" | viewgc - git commit -vgc! - git commit -v --amendgca - git commit -v -agca! - git commit -v -a --amendgcmsg - git commit -mgco - git checkoutgcm - git checkout mastergr - git remotegrv - git remote -vgrmv - git remote renamegrrm - git remote removegsetr - git remote set-urlgrup - git remote updategrbi - git rebase -igrbc - git rebase --continuegrba - git rebase --abortgb - git branchgba - git branch -agcount - git shortlog -sngcl - git config --listgcp - git cherry-pickglg - git log --stat --max-count=10glgg - git log --graph --max-count=10glgga - git log --graph --decorate --allglo - git log --oneline --decorate --colorglog - git log --oneline --decorate --color --graphgss - git status -sga - git addgm - git mergegrh - git reset HEADgrhh - git reset HEAD --hardgclean - git reset --hard && git clean -dfxgwc - git whatchanged -p --abbrev-commit --pretty=mediumgsts - git stash show --textgsta - git stashgstp - git stash popgstd - git stash dropggpull - git pull origin $(current_branch)ggpur - git pull --rebase origin $(current_branch)ggpush - git push origin $(current_branch)ggpnp - git pull origin $(current_branch) && git push origin $(current_branch)glp - _git_log_prettily{/card-describe}
2022年02月22日
78 阅读
0 评论
0 点赞
2021-11-13
React Native原理和架构
React Native原理和架构发展历程原生开发(Native APP)Native APP 基于智能手机本地操作系统如iOS、Android、WP并使用原生程式编写运行的第三方应用程序,一般开发的语言为Java、C++等。,有很强的交互是一个完整的App,可拓展性强。需要用户下载安装使用。优点:打造完美的用户体验,用户留存率高性能稳定,操作速度快,上手流畅访问本地资源(通讯录,相册),可以调用移动硬件设备(摄像头、麦克风等)缺点:开发成本高(每种移动操作系统都需要独立的开发项目,不同平台有不同的开发语言和界面适配)维护成本高(下载是用户控制的,例如一款App已更新至5.0版本,但仍有用户在使用3.0,2.0版本,需要更多的开发人员维护之前的版本)更新缓慢,应用商店发布审核周期长,安卓平台大概要1~3天,而iOS平台需要的时间更长混合开发(Hybrid APP)Hybrid APP 就是原生开发和web的混合开发。在原生APP中内置浏览器,合适的功能页面采用网页的形式呈现。比如京东的某些营销页面,今日头条的某些新闻页面、微信的腾讯新闻的内容页面等。优点:学习成本低天然跨平台无审核热更新可扩展缺点:性能很差##### 跨平台开发框架本质上,跨平台开发是为了增加代码复用,减少开发者对多个平台差异适配的工作量,降低开发成本,提高业务专注的同时,提供比web更好的体验。想要解决用户体验的问题,基本还是需要回到 native 来进行开发,但是这种行为必然会与平台绑定。其中一件事情就是自动将某个平台的代码转换到另外的平台上去。前移动端跨平台开发中,备受关注的方案大致归纳为以下几种情况:1)React Native、Weex均使用JavaScript作为编程语言,目前JavaScript在跨平台开发中,占据半壁江山,大有“一统天下”的趋势;2)Flutter是Google跨平台移动UI框架,Dart作为谷歌的亲儿子,毫无疑问Dart成为flutter的编程语言。作为巨头新生儿,在flutter官网也可以看出,flutter同样“心怀天下”(可支持Web端、Android端、iOS端等)。React Native的原理与特性介绍理念架构“Learn once, write anywhere” , React Native 使用 React 的设计模式,但UI渲染、动画效果、网络请求等均由原生端实现。开发者编写的JavaScript代码,通过 React Native 的中间层转化为原生控件和操作,比ionic等跨平台应用,大大提高了的用户体验。总结:React Native是通过js来调用Native端组件在 React Native 里面,真正有三个重要的线程在执行,他们分别是 Shadow thread、UI thread 和 JS thread。JS thread。是读取和编译所有 JavaScript 代码、处理应用程序大部分业务逻辑的地方。Metro(打包工具)将React源码打包成一个单一JS文件(就是图中JSBundle)。然后传给JS引擎执行(现在ios和android统一用的是JSC)。JS thread 负责 JS 和原生代码的交互,因为 JS 是单线程模型,所以需要一个单独的线程来驱动,并且 JS 和 Native 交互(Bridge)是异步的。UI Thread(Main Thread/Native thread)。这个线程主要负责两部分:原生渲染(Native UI):负责页面的交互,以及当显示、更改UI时,完成控件绘制逻辑。调用原生功能(Native Modules):比如蓝牙等。当我们使用应用程序时,所有本地模块都会启动。这意味着即使不需要使用蓝牙模块,React Native 也将始终激活它。Shadow Thread。 是 React Native 计算布局的地方。这个线程会创建Shadow Tree来模拟React结构树。Shadow Tree可以类似虚拟dom。它使用 Facebook 自己的名为 Yoga 的布局引擎来计算 flexbox 布局,然后将结果发送到 Native UI(RN使用Flexbox布局,但是原生是不支持,所以Yoga就是用来将Flexbox布局转换为原生平台的布局方式)。JavaScriptCore JavaScriptCore 是 JavaScript 引擎,通常会被叫做虚拟机,专门设计来解释和执行 JavaScript 代码。在 React Native 里面,JavaScriptCore 负责 bundle 产出的 JS 代码的解析和执行。JS EngineReact Native 需要一个 JS 的运行环境,因为 React Native 会把应用的 JS 代码编译成一个 JS 文件(x x.bundle),React Native 框架的目标就是解释运行这个 JS 脚本文件。如果是 Native 拓展的 API,则直接通过 bridge 调用 Native 方法,最基础的比如绘制 UI 界面,映射 Virtual DOM 到真实的 UI 组件中。脱离 React Native,纯原生端是如何与 JS 交互的?来看下 iOS 里面是如何实现的。在 Native 创建一个 JS 上下文:// 创建一个ctx的JS上下文 JSContent *ctx = [[JSContent alloc] init]; // 创建一个变量name [ctx evaluateScript:@"var name = 'Hellen'"]; // 创建一个方法 [ctx evaluateScript:@"var hello = function(name) { return 'hello ' + name }"];Native 调用 JavaScript 方法:// 通过ctx上下文对象,获取到hello方法 JSValue *helloFUnction = ctx[@"hello"]; // 运行js方法 JSValue *greetings = [helloFunction callWithArguments:@[@"bytedancers"]; // hello bytedancers所以,JavaScript 代码只要将变量暴露在 JS 上下文全局,Native 就能获取到,并运行 JS 的代码。JavaScript 调用 Native,首先需要在 Native 端,将一个变量暴露在 JS 上下文全局,在 JavaScript 全局变量里面就能获取到并执行这个方法:ctx[@"createdByNative"] = ^(NSString *name) { // do something return someResult }React Native 同样借助 JS Engine 的能力,基于 JavaScriptCore 来执行 JS,但是是通过 Bridge 来进行交互的,JS 不会直接引用 Native 层的对象实例,Native 也不会直接引用 JS 层的对象实例(在 React Native 里所有 Native 和 JS 互调都是通过 Bridge 层的几个最基础的方法衔接的)。Hermes EngineHermes 是 Facebook 在 2019 年发布的新一代 JS Engine,Hermes 是一款小巧轻便的 JavaScript 引擎,专门针对在 Android 上运行 React Native 进行了优化:应用启动时间减少、减少内存使用量并缩小应用程序大小,此外因为它采用 JavaScript 标准实现,所以很容易在 React Native 应用中集成。Hermes vs JavaScriptCore vs V8经过官方的数据验证,Faceback 团队提出的关键性指标相较于原先的 JavaScriptCore 方案都有了显著提高。首先,是产物文件的大小方面,RN 所依赖的必要 so 库,Hermes 比 JavaScriptCore 减少了约 16%,V8 则要远大于 Hermes 和 JavaScriptCore。热更新React Native 的产物 bundle 文件,本质上是 JS 的逻辑代码加上 React Native 的 Runtime 的集合,所以在应用一启动的时候就会去获取 bundle 文件,之后解析 bundle 文件,最后再由 JS Engine 去执行具体的业务代码逻辑。这就可以允许开发者在云端去更新 bundle 文件,然后应用启动的时候获取最新的 bundle 文件,这一整个流程下来就实现了热更新。增量更新(拆包)对于 React Native 的代码打包之后只会生成一个 Bundle 文件,这里面包含了基础业务逻辑、React Native 的基础库类,所以我们可以把一个包拆分成:一个基础包+ n 个业务包,其中基础包是不变的,这就是 runtime,业务包就是具体的业务,后面如果有更新,也只需要再打出一个业务包就行。目前行业的解决方案有 facebook 官方提供的 metro bundle:facebook.github.io/metro/React Native新架构FB团队逐渐意识到Bridge存在的一些问题,同时也受到Flutter的压力,在2018年提出了新架构:移除了Bridge,取而代之的是一个名为 Javascript Interface (JSI) 的新组件。新的架构主要由 JSI、Fabric、TurboModules、CodeGen、LeanCode组成。JSIJSI(Javascript Interface)是整个架构的核心和基石,所有的一切都是建立在它上面。用于取代原先的 bridge,提高通信效率,JSI 已经跟随 RN 0.59 (JSIExecuter.cpp) 发布。JSI 本身不是 React Native 的一部分——它是一个统一的、轻量的、通用适用于任何(理论上) JavaScript 虚拟机的接口层。让各种平台可以方便地使用不同的 JavaScript 解析引擎(JavaScript virtual machine 包含 JavaScript Engine)。当把 JSI 加入到新架构中后,它使得一些真正重要的改进成为可能。第一个改进很直观 —— 有了JSI,JS引擎不再局限于JSC。换句话说,JSC 引擎现在可以与其他具有更好性能的 JavaScript 引擎交换,比如微软的 ChakraCore 和谷歌的 V8等,进一步提高JS解析执行的速度。通过JSI,JS对象可以直接持有C++宿主对象(Host Objects)引用,并调用它们的方法。宿主对象:由宿主环境提供的对象,对应Native Object。如JavaScript中,浏览器宿主环境中的window对象以及其下边所有的子对象(如bom、dom等等),node宿主环境中的globla及其子对象。这意味着:自此三个线程通信再也不需要通过Bridge,JavaScript 和 Native 之间真正地相互知晓,并且不再需要通过 JSON 序列化传递消息,这会消除 Bridge 的阻塞问题。不像原来那样用一层 bridge 来排队等待原生层返回的消息,让同步通信成为现实。具体的用法可以看 官方例子。JS -> JSI -> C++ -> ObjectC/JavaFabricFabric是整个架构中的新UI层,包括了新架构图中的renderer和shadow thread。下图是旧的通信模型。三个线程通过Bridge异步通信,数据需要拷贝多份。有了JSI以后,JS可以直接掉调用其他线程,实现同步通信机制。另外数据可以直接引用,不需要拷贝,于是就变成了下面新的通信模式.除了同步能力,直接引用,另外一个好处是Fabric现在支持渲染优先级比如React的Concurrent和Suspense模式下面两张图是从启动到渲染阶段,加入Fabric前后的变化。改造为Fabric之后TurboModulesTurboModules主要和原生应用能力相关,对应新架构图上的Native Modules,这部分的优化是:通过JSI,可以让JS直接调用Native模块,实现一些同步操作。比如调用摄像头能力。Native模块懒加载。之前RN框架启动的时候会加载所有Native模块,导致启动慢,时间久。现在有了TurboModules后,可以实现按需加载,减少启动时间,提高性能。CodeGen通过CodeGen,自动将Flow或者Ts等有静态类型的JS代码翻译成Fabric和TurboModules使用的原生代码。Lean Core这部分主要是包的瘦身,以前所有的包都放在RN核心工程里面。现在RN核心只保留必要的包,其他都移到react-native-community 或者拆出单独的组件,比如Webview和AsyncStore。开发进度2018 年 6 月,Facebook 曾在 宣布了大规模 重构 RN 的计划和路线图;期间,JSI、LeanCore、Fabric、TurboModules一项一项陆续开发完成;2021 年 7 月 14 日,React Native 核心团队的 Joshua Gross 在 Twitter 说,RN 的新架构已经在 Facebook 内部落地了,并且 99%的代码已经开源。性能评价引自React Native 迎来重大架构升级,性能将大幅提升重构目的是为了让 RN 更轻量化、更适应混合开发,接近甚至达到原生的体验。具体包括以下几个方面:改变线程模型。UI 更新不再同时需要在三个不同的线程上触发执行,而是可以在任意线程上同步调用 JavaScript 进行优先更新,同时将低优先级工作推出主线程,以便保持对 UI 的响应。引入异步渲染能力,允许多个渲染并简化异步数据处理。简化 JSBridge,让它更快更轻量。这次升级过后,RN 在性能上能够追平 Flutter。首先,JavaScript 和 Dart 语言上都支持了 AOT 预编译,打个平手。其次,JavaScript 和 Dart 和底层交互都是通过 C++ 进行的,也是打个平手。最后,RN 原生组件绘制有平台的优化加成, 相对于 Flutter 自绘引擎绘制,可能还会好上一些。除了显着提升线程之间的通信性能外,这种新架构还让我们可以直接控制 Native Modules。也就是说,可以仅在需要时使用原生模块,而不是在启动应用程序时将它们全部激活。这为应用程序启动时间提供了显着的性能改进。这种新机制有可能在许多不同的用例中使我们受益。例如,现在我们掌握了 C++ 的强大功能,很容易看出 React Native 是如何用于大型系统目标的。
2021年11月13日
311 阅读
0 评论
1 点赞
2021-06-26
现在的我
厌倦等待,害怕失去,讨厌主动。渐渐的,生活的圈子越来越窄,孤独的感觉越来越强,一个人的时候越来越多。有时候明明很想念一个人,但心想如果对方也想我,他一定会主动联系的;有时候明明很孤独,可是翻遍通讯录,也不想找一个人说话;有时候明明很无聊,也不愿主动约别人。渐渐,生活只剩下自己。年轻的时候有资本不主动、不将就、不迎合、不讨好,可年纪大了,孤独的舞台只剩下自己,自导自演,孤芳自赏。曾经以为这是高傲,后来想想是自卑,害怕高估自己在别人心里的位置,怕别人没那么喜欢,害怕受伤,怕出丑,怕被拒绝,所以宁愿失去也不主动。可是这样下去,幸福是不会来敲门的,你躲在角落,看着不断有人从你身边经过又离开。如果不争取的话,这辈子都遇不到喜欢的人了。你要学会的是,不要自我怀疑,自我否定,要相信自己值得被爱,被善待。付出真心没有错,对一个人好更没有错,哪怕他不爱你你还爱着他也没有错。我们今天害怕的无非就是失去,但那又如何呢?爱情不就是我敢喜欢又敢离开吗?可明明知道这些道理,却也终究是很难迈开那一步,做人真的很苦啊。
2021年06月26日
83 阅读
2 评论
3 点赞
2021-06-25
GraphQL 入门: 简介
GrqphQL是Facebook开发的一个应用层查询语言,后端定义基于图的模式,客户端可以按需查询需要的数据。上图所示,查询流程分为几个步骤,涉及多个组件,包括客户端应用程序(Web,手机,桌面APP),一个GraphQL服务器用于解析查询,以及多个不同的数据来源。客户端数据要求发生变化时,不需要修改后端。因此,你不必因为客户端数据需求的变更而改变你的后端。这解决了管理REST API中最大的问题。为什么解决了RESE API的大问题,看如下阐述:注解:只要你的义务模型没有发生变化,数据模型就不会发生变化,那么我们就不需要修改后端API。前端只需要按需要的字段进行查询即可。如果业务发生了变化,那么我们只需要修改GrqphQL的模型定义。并且实现对应的服务端数据查询逻辑即可。但是传统REST查询是固定,客户端不能指定,GraphQL可以让客户端指定要获取那么手写字段的数据,给客户端带来了极大的灵活性。GraphQL同样能够让客户端高效的获取数据,例如,看下面这个请求:{ latesPost { _id title content author { name } comments { content author { name } } } }这个请求获取了一遍博客文章和对应评论与作者信息的数据,下面是请求的返回结果:{ "data": { "latestPost": { "_id": "03390abb5570ce03ae524397d215713b", "title": "New Feature: Tracking Error Status with Kadira", "content": "Here is a common feedback we received from our users ...", "author": { "name": "Pahan Sarathchandra" }, "comments": [ { "content": "This is a very good blog post", "author": { "name": "Arunoda Susiripala" } }, { "content": "Keep up the good work", "author": { "name": "Kasun Indi" } } ] } } }如果你使用的是REST的话,你需要调用多个REST API的请求才能获取这些信息。
2021年06月25日
63 阅读
0 评论
1 点赞
2021-06-25
为TypeScript项目添加Eslint和Prettier
众所周知,代码质量检查和代码风格的统一对于一个项目来说非常的重要,也有助于避免一些低级的错误。相信很多人都已经在JavaScript项目中使用ESLint和Prettier了,但我猜大多数人不太清楚如何在TypeScript项目中进行配置,本文就来介绍具体的配置步骤。为TypeScript设置ESLint让ESLint支持TypeScriptESLint本身不是为了TypeScript设计的,但是它能通过配置parser来支持不同的语言,进而实现对TypeScript代码的检查和修复。yarn add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --deveslint: ESLint库本身@typescript-eslint/parser: TypeScript团队提供的ESLint parser,用于实现支持TypeScript代码的lint@typescript-eslint/eslint-plugin: ESLint插件,包含一系列TypeScript相关的ESLint规则然后,添加在项目根目录添加.eslintrc.js,一个基本的例子如下:module.exports = { parser: '@typescript-eslint/parser', // 指定parser plugins: ["@typescript-eslint"], // 启用插件 extends: [ 'plugin:@typescript-eslint/recommended', // 使用推荐的规则,来自@typescript-eslint/eslint-plugin ], parserOptions: { ecmaVersion: 2020, // 让parser按更新的语法来解析 sourceType: 'module', // 让parser按ESM解析 }, rules: { // 此处书写需要覆盖的配置 // 例如,"@typescript-eslint/explicit-function-return-type": "off", }, };其中有些细节值得一提:extends部分的plugin:@typescript-eslint/recommended是可选的,但对于绝大多数项目推荐使用,如果有不合适的可以单独调整。另外,在配置plugin:@typescript-eslint/recommended-requiring-type-checking中还包含了一系列依赖类型信息的规则,这些规则能帮助你更好的规范代码,但可能会带来一些性能上的损耗,相关信息详见 此处 。parserOptions支持的配置可以分别在ESLint文档和@typescript-eslint/parser的README中查阅,在配置ESLint支持React和需要类型信息的规则时会用到。配置PrettierPrettier和ESLint是两个独立的工具,Prettier专注于代码格式化,而ESLint专注于代码质量检查(顺便提供了一些修复)。Prettier的格式化和eslint --fix都会涉及代码风格的调整,有时二者会发生冲突。目前社区中处理这个问题的工具有以下几种:prettier-eslint:这是一个JS模块,其处理方式是将代码先由Prettier处理一次,再将输出进行eslint --fix得到最终结果。已不推荐使用。eslint-plugin-prettier:这是一个ESLint插件,该插件实现了一系列额外的ESLint规则。这些规则使用Prettier来检查代码格式,如果格式与Prettier期望的不同,会抛出对应的ESLint错误。同时这些错误在eslint --fix时会交由Prettier进行修复。eslint-config-prettier:这是一个ESLint配置,该配置将可能与Prettier冲突的规则关闭,从而使得你能将Prettier于其他的ESLint配置(如eslint-config-airbnb)一起使用。目前推荐的实践是将eslint-plugin-prettier和eslint-config-prettier结合使用,下面就介绍如何进行配置。首先需要安装相关依赖:yarn add prettier eslint-config-prettier eslint-plugin-prettier --dev然后在根目录添加Prettier的配置文件:module.exports = { semi: true, trailingComma: 'all', singleQuote: true, printWidth: 120, tabWidth: 4, // 格式与eslint的overrides一致 "overrides": [ { "files": "*.json", "options": { tabWidth: 2 } }, { "files": ["*.html", "legacy/**/*.js"], "options": { printWidth: 240 } } ] };最后更新ESLint的配置即可:module.exports = { parser: '@typescript-eslint/parser', // 指定parser plugins: ["@typescript-eslint"], // 启用插件 extends: [ 'plugin:react/recommended', // 使用react的推荐规则 'plugin:@typescript-eslint/recommended', // 使用推荐的规则,来自@typescript-eslint/eslint-plugin 'plugin:prettier/recommended', // 使用eslint-plugin-prettier推荐的配置,注意需要在最后一个 ], parserOptions: { ecmaVersion: 2020, // 让parser按更新的语法来解析 sourceType: 'module', // 让parser按ESM解析 ecmaFeatures: { jsx: true, // 支持解析JSX }, }, rules: { // 此处书写需要覆盖的配置 // 例如,"@typescript-eslint/explicit-function-return-type": "off", }, settings: { react: { version: 'detect', // 让eslint-plugin-react自动检测react版本 }, }, };extends字段中添加的plugin:prettier/recommended是eslint-plugin-prettier提供的推荐配置,其中引用了eslint-config-prettier并设置相应的规则,这个配置相当于:{ "extends": ["prettier"], "plugins": ["prettier"], "rules": { "prettier/prettier": "error", "arrow-body-style": "off", "prefer-arrow-callback": "off" } }有时候会在网上的文章中看到,extends字段中除了prettier外还有prettier/react之类的配置,但从eslint-config-prettier的8.0.0版本开始只需要一个prettier就能引入全部配置了
2021年06月25日
466 阅读
0 评论
0 点赞
1
2
3
...
7