Code Monkey home page Code Monkey logo

gouqi's Introduction

🐸 枸杞 🐸

枸杞是一个跨平台的计时 App。你可以点击 ▶️ 开始计时,点击 ⏸ 停止计时,枸杞会帮助你统计计时的总时间。除去计时之外,枸杞通过网易云音乐还提供音乐播放、信息浏览等乱七八糟的功能,让你计更多的时。

枸杞在实现上使用了彻底分离的 MVC 架构,在 M 层和 C 层有 260 多个测试来保证数据和逻辑的正确,且测试覆盖率达到了 99%。更多关于枸杞的技术细节,可以查看 枸杞的由来和技术栈Roadmap without any promises

交互

   
主要功能 歌单下载
           
艺术家播放歌词

安装与调试

首先确保你已经安装了 Node.js (7.6+) 和 Xcode/Android 开发环境。

brew install yarn // Or npm install -g yarn
yarn install // 安装依赖
yarn run ios // 跑 iOS
yarn run android // 跑 Android
yarn test // 跑测试
yarn run remotedev // 打开调试器

FAQ

为什么叫「枸杞」?

因为我打飞机太多了,需要多吃点枸杞补补身子。

为什么我计时了几小时,显示单位还是秒?

这是某种神秘力量导致的 bug,我修复不了。

开门,快递/查水表/社区送温暖/清华大学录取通知书!

没有网购,家里长期停水没有水表,天气太热了不需要社区送温暖,考不上清华没有录取通知书。

我不懂这方面的开发,有没有直接可以下载安装试用的渠道?

没有,你得自己编译。如果我提供了这个渠道就会有 bad guys 发律师信给我。

楼主是气象专家吗?

不是,我对天气预报没有任何研究。

License

Do What the Fuck You Want only if you DON’T summit to App Store or any store that sells Apps.

gouqi's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gouqi's Issues

枸杞的由来和技术栈

由来

在去年 8 月份的时候,我就想做一个项目并把它开源出去,作为一名粉丝向一位长者的高寿诞辰表示祝贺。

去年前端的圈子风起云涌,各种新技术层出不穷,而我当时的工作主要负责的是 NW.js 和 Node.js ,再加上写一点 Vue。于是我就想做一个使用前端新技术的项目让自己不要落伍了。使用这些新技术不应该是浅尝辄止,而应该尽量向工业级和 best pratice 靠拢。由于我有一个失败的开源项目的维护经验(vue-strap),再加上工作也见到了很多随着一些项目越来越复杂,维护成本越来高的情况。我就下定决心以后做开源项目一定要有强制的 Linting,一定要有 Code Review,一定要有高测试覆盖率作为维护的保证。经过一段时间的考研,我选择了如下技术栈:

  • React Native。因为我想写一个 App ,但又不熟悉原生开发,Weex 和 NativeScript 生态远没有成熟,Ionic 又和写前端没太多区别,所以只能选 React Native。
  • TypeScript。当时在学习 Rust ,感受过静态+强类型语言编译成功基本就能跑的好处,对动态语言所谓「灵活」的好处也越来越嗤之以鼻,所以选择了 TypeScript。
  • Redux。跟一些 demo 写了几个 redux 例子不一样,枸杞在一开始的时候就使用了全局 store,除了少数内部自治状态和可能独立开源出去的组件之外,所有组件都没有自己的状态。
  • Redux-saga。用来处理所有的 I/O 和 effects,这样一来组件没有状态也没有逻辑,为实现 100% 测试覆盖率打下了很好的基础。

由于这些技术或者技术的使用方法都是我在日常工作中暂时用不到或者不能用的(必须考虑到团队的接受程度和开发效率),因此我写枸杞除了贺寿之外,实际上就是为了得到些经验踩一些坑,而枸杞选择技术栈和实现的的时候也是以能不能测试/好不好测试为目标。因此这实际上是一个看文章送测试,跑测试送 App 的项目。

React Native

简单来说,我认为 React Native 没有取代原生语言的能力,单靠 React Native 本身想构建一个稍大型的 App 是不现实的。

如果没有原生语言开发者,对于枸杞和系统资源有交互这样的中小型项目,React Native 原生插件社区能提供的帮助也不多。在去年的时候由于当时 React Native 没有操控 Media Center 的插件,我就一直等到了今年才能继续写下去。我现在也还记得之前 react-native-blur 这个插件没法支持 animation,当时半夜两点钟邮件收到有人发了这个 feature 的 PR,我就赶忙爬起来给 commiter 点赞拍马屁,希望 owner 赶紧 review 之后 release。可之后社区又因为 iOS 8 的兼容问题扯皮了两个月,到现在这个功能也没能真正可用。而像音乐播放这个基础功能,目前也没有任何库能够提供 cache。而这些功能如果不熟悉原生开发是完全没办法解决的。

对于 React Native 视图层的社区也并没有好到哪里去。目前带有测试并且仍然在良好维护的库屈指可数。你甚至仍然能找到一个 1k star 但是把临时变量也放在 this.state 里并且直接给 state 赋值的库。好不容易找到一个看起来靠谱的,你又发现它的文档根本没描述清楚它的所有功能(包括 React Native 本身的核心视图库)。所以为了达到你想要的功能你还得先去看看源码追根溯源一番。如果有时间的话,我建议视图库能自己写就自己写,如果实在没时间,ant-designreact-native-community 以及 wix 三个组织产出的代码都靠谱,而且多数仓库都有人在维护。

但我对 React Native 的未来还是看好的。在去年的八月份,单靠 GitHub 和开源的力量写一个枸杞这样简单的 App 都不容易。而在今天,尤其是今年 3 月的 React Conf 之后,整个社区都在蓬勃地发展:现在你可以用 create-react-native-app 省心地创建新项目,可以用 react-navigation 优雅地处理路由,可以用 react-native-interactablelottie-react-native 高效地实现复杂的动画,广受诟病的 ListView 也有了 <VirtualizedList>SectionListFlatList 三个替代品。如果你是在一年前对 React Native 浅尝辄止,那我建议不妨今天再去看看。

最遗憾的事情还是由于音乐版权的原因枸杞并不能上架,所以我也没有经验谈谈 React Native bundler 和 codepush 这两个功能。

TypeScript

我现在是 TypeScript 的脑残粉。

别误会,我还是很喜欢 ES6 和 ESLint 的。尤其是 ESLint,感觉这才是尼古拉斯·赵凯最好的发明,YUI 和 《JavaScript 高级程序设计》 都是次要的。但即便 ES6 + ESLint 的组合能够规避很多 ECMAScript 自身的缺陷,TypeScript 仍然有着不可比拟的优势。

静态类型

假设我们有这么一段代码:

const sum = (str) => str.match(/\d+/g).reduce((n, acc) => n + Number(acc), 0)

很容易看出程序期望输入一个字符串,然后返回这个字符串所有数字的和。稍有经验的开发者则能看出这个程序至少有两个错误:

  1. 传入的字符串并没有包含任何数字,match 方法会返回 null,而 null 并没有数组的方法,进而报错;
  2. 当调用 sum(str) 方法,传入的参数不是一个字符串也会报错。

对于第一种情况,在 TypeScript 中第一时间写下代码就会直接报错,因为编译器能检查到 match 返回的类型不能都使用 reduce 方法。而对于第二种情况,只要你在代码的任何第一个地方可能传入 string 以外的类型,也会报错。而完成这些检测根本不需要运行代码。

有些同学就会说,切,这有什么了不起的,老子根本不会写这种代码 in the first place 好伐?

可兄弟啊,人是一定会犯错的,而且迟早会犯错。前面的那段代码来自于一个 下载量 20万 的 NPM 包,作者在 GitHub 的 Follower 超过四位数,他没能避免写出这样的代码,你也迟早有一天也会出现这样的纰漏。而对于这种情况,工具和机器能更好解决的问题,就不应该交给人类来解决。

Language as Sever

TypeScript 还极具创新地引入了 Language as Sever 的特性(Rust 最近也把这个功能抄了过去)。什么意思呢?就是只要 tsserver 这个模块启动,就可以享受到来自于 TypeScript 本身提供的智能代码补全和代码重构功能。而这样代码补全和重构是基于类型、定义、模块的精准补全和重构,而不是不知道从哪下载到 snippets。

而这样功能并不依赖于某个特定的平台或 IDE(有人以为这个功能 VS Code 提供的),事实上不管你在任一平台 VS Code 或 Atom,还是在命令行上跑 Spacemacs 或 Vim,都可以得到这样近似于 Java 在 IntelliJ IDEA 的开发体验。可以负责任地说这个功能完全可以把写类型和定义的时间全都给挣回来。

良好的社区和开发计划

只要稍微关注一下 TypeScript 的 issue,released note 就不难发现,由 Anders Hejlsberg 领衔的 TypeScript 是一个相当靠谱的团队。(不得不说微软在工程管理方面真的不知道比某些互联网公司高到哪里去了,no offense)

TypeScript 在最近几个版本更新的 feature 都相当有诚意,例如 Generic defaults,keyof ,更好的 React / React Native 支持,更好的 literal types,同时也支持了更多 ES 新特性,例如 async/await 支持编译到 ES3/5,async iterationObject rest/spread

由于 Contextual Type 的出现,Vue 这样使用 Object literal 的 API 也能享有更好的类型推导和开发体验。听说 TypeScript 还准备实现类似于 template typing 的功能,那 Vue 和 Angular 也可能会得到 JSX 那样良好的类型推导。这样一来三大前端框架在使用 TypeScript 之后都能有效降低维护难度,不得不说实在是喜大普奔的好消息。

最后我还想讲一个很多人没有提到的优势:TypeScript 编译出来的代码(相比 babel)可读性很高,而且性能普遍比 babel 强 1,大部分语法和原生 ES6 代码性能接近,部分语法(例如 for..of rest, spread)比原生 ES6 在没有部署 Turbofan 和 Ignition 的 V8 (Node.js 8.0 / Chrome 60 以下)还快 2。另外 TypeScript 实际上可以用来做 ES6 编译器,只要你不写某些还在 stage-0/1 的语法就行。

不足

有些人会提到,ES 的原型链灵活的一逼,使用 TypeScript 限制了我的发挥。这样的说法也不对,TypeScript 是 JavaScript 的超集,你可以用 class 也可以用原型链,如果两个都熟悉混着用也没有任何关系。

我觉得最大的问题还是目前社区提供的 typings 的数量和质量都不太尽如人意。

如果引用的库没有 typings ,或者 typings 错误地映射了源码,那既得不到强类型语言的严谨,也得不到弱类型语言的灵活。写 TypeSciript 的体验就像是写残疾的 ES6。就拿 React Native 来说,FlatList 功能已经更新了两个月,typings 也还一直有问题。我本来以为对于这样一个热门的项目社区会很快有人 PR ,没想到等了那么久还是得自己动手 PR。

对于广大开发者来说,如果你发现某个库的 typings 不对或者没有,大可给 DefinitelyTyped 发 PR。自己可以看看源码学习学习,别人也能从中获益,这等利人利己的好事不妨多做。

Redux

Redux 应该是前端争议最大的一个项目之一。很多批评者认为 boilerplate 代码要写太多,概念也太多,搞来搞去也没发现能提供什么好处。我觉得 Redux 的作者 Dan Abramov 说过一句话很适合回答这类言论:

Redux 就像雨伞,当你需要的时候你就知道为什么要使用它。

而有一些项目本身交互就简单,数据流动一眼也就能望得到边。其实很可能连 React 都不需要,如果再加一个 Redux,这就有点像穿着一身蓑衣撑着一把巨伞在 CBD 的商场里逛街。——除了让人以为你在 cosplay 武林高手之外没有任何好处。

而当你真正需要 Redux 的时候,有些教程会告诉 Redux 有共享组件状态、组件间通信,统一记录/管理 action,time travel/undo/redo 等等功能。不过那些都是次要的,Redux 最重要的优点是可预测性,对于既定输入一定会产生既定输出。

可预测性有什么优点呢?最直观的优点就是易于测试,如果没有 I/O 当然最好,如果有的话需要加一层 middleware 处理写 mock 也不难;其次是数据的流动会非常清晰,这点搞一个 redux-devtool 就可以看出来;第三点是你可以先写数据结构和业务逻辑再写 UI,这听起来有点不可思议,没有 UI 和设计图怎么搞前端?

有兴趣的朋友可以看一下枸杞的 commit 记录,所有页面全都是先写数据结构和逻辑再写 UI。例如做一个播放器,点击了「下一首」这个按钮一定会发生这些事情:一定会更改播放状态;一定会请求服务器真实地址;一定会 push 一个播放记录等等... 这些事情跟把「下一首」的按钮放在哪里长什么样没有任何关系。

试想一下这个场景:你的产品经理和设计师就一个功能是放在 modal 好还是页面好,是点击触发好还是滑动触发好展开了激烈的撕逼,这个时候你已经把逻辑和测试都写好了。你可以大大方方地和他们说「你们先聊,我先走了」,等你把 PS4 都打累了,他们的撕逼也有了结果,这个时候你只需要写 dumb component,把数据和方法 connect 到 React 中就完事了。

Redux-saga

Redux 本身并没有提供处理异步的解决方案,所以需要引入一个 middleware。流行的解决方案有 redux-thunkredux-promise ,除此之外还有一些不知名的解决方案,我推荐国产的 redux-action-tools ,还可以省下一个 redux-actions 的依赖。不过这些实现都有问题:

  1. 会导致把 action 写得五花八门什么都有,破坏了 action 的语义;
  2. 不好测试,首先 I/O 必须写 mock,而对于 React Native I/O 不止是 Ajax,有些 mock 不好写,其次逻辑一旦复杂一个 action 要开好几个测试不同的 branch。

而 Redux-saga 则很好地解决了这些问题,它采用了 generator 启动了一个 long-lived transaction,然后把所有 action(不管异步还是同步)都隔离到各个 worker 上去。这意味着什么?

  • 逻辑都放在 worker 里,我们所有 action 都会是一个 Flux Standard Action ,简洁、清晰、明了;
  • 每一个 worker 是 generator ,所以我们可以像 async/await 那样写异步代码(准确来说是更像早期的 co)。但是比 async/awaitco 都更棒的是 redux-saga 为我们提供了很多专门用来处理 effect 的函数,让我们可以用声明式的语法来处理各种交互。
  • 由于 generator 其实就是迭代器的生成器,也就是说我们可以一步一步地测试 worker,校验每一个迭代,也可以测试完了这两步迭代,再倒回三步,重新测试另外的 branch。

例如我们有一个简单的登录 worker:

function* loginFlow() {
	const { username, password } = yield take(ATTEMPT_LOGIN)
  const { code, profile } = yield call(fetchLogin(username, password))
  if (code === 200) {
    yield put(updateProfile(profile))
    yield fork(Router.toHome)
  } else {
    yield put(toast('error', '登录失败'))
  }
}

我们可以这样写这样单元测试:

test('login flow', () => {
  const LOGIN_SUCCEED = { code: 200 }
  const LOGIN_FAILED = { code: 400 }
  const WALLACE = { username: 'Wallace', password: 'veryTall' }
  testSaga(loginFlow).next()
    .take(ATTEMPT_LOGIN)
    .next(WALLACE)
    .call(fetchLogin, 'Wallace', 'veryTall')
    .next(LOGIN_SUCCEED)
    .put(updateProfile(undefined))
    .next()
    .fork(Router.toHome)
    .next()
    .back(3) // 测试完成功登录之后,我们退 3 步测试登录失败的 branch
    .call(fetchLogin, 'Wallace', 'veryTall')
    .next(LOGIN_FAILED)
    .put(toast('error', '登录失败'))
    .next()
    .isDone()
})

就这样 statements 和 branch 的测试覆盖率都达到了 100%,简直不要太无脑。

最后我想谈一下 redux-saga 的作者 Yassine Elouafi:一个 40岁的中年大叔,房地产公司老板(你没看错,搞房地产的),自学编程之后为我们贡献了 redux-saga ,在这之后大叔也并没有停止奋斗。他还在多个 repo (包括 MobX ,Rxjs)的 issue 下都有鞭辟入里的发言 45,把 Redux 、Rxjs、MobX 的优劣势、适用场景说得很清楚。大叔的本可以去 Medium 发几篇文章吹吹牛逼,但他却选择了在各个 issue 下耐心帮人答疑解惑,而且不装逼不打广告不争名不夺利,实在佩服。

测试

在这篇文章里我谈过很多次测试的重要性,那测试能带来什么好处呢?

  1. 首先写测试的时候必须重新 review 源码,必要时可能还会重构源码,这就让源码变得更可靠、更健壮;
  2. 重构代码时能得到更多保障;
  3. 多人协作时能避免同事把你的代码改没用;
  4. 定位 bug 时更迅速,更自动化。再说一次,人是一定会犯错,一定会偷懒的,机器和工具能做得更好的事情就不要交给人类去做;
  5. 不写测试的公司或团队通常加班更凶。

而对于前端(或者 Node.js) 测试框架而言,现在也是百花齐放,我简单说几个:

Jest

Jest 是枸杞使用的测试框架,也是目前最热门的,它提供了很多好处:

  • Facebook 官方维护;
  • 和 React 搭配合作完美,还提供 snapshot 测试功能;
  • 几乎不用写配置文件就能支持 ES6, mock, async test等功能;
  • 跑得快;

打开 Twitter 和 Medium 也能发现到处都是安利 Jest 的声音,看起来 Jest 几乎是完美的,在我最初使用的时候也是这么个想法,直到我发现 Jest 会创建 VM 跑测试,而在 VM A 中一个数组,并不是 VM B 中 global.Array 的 instance。也就是说如下代码会返回 false : vm.runInNewContext("a instanceof Array", {a:[]}) 6。这样的情况也不能说是 bug,但会导致很多库在使用 instanceOf Array 作为判断数组方法时失效,这样就大大地增加了排查 bug 的难度。

Ava

Ava 是在 Jest 之前最受推崇的测试框架。之前枸杞用来测试网易云音乐的 API。它的优点其实和 Jest 有点像,快,不怎么用写配置文件或者加插件。但它的快是通过并发来实现的,这就导致测试流程的时候可能会把 beforeafter 写得到处都是,另外如果同时测试的文件过多,而机器本身的性能不够,也可能会影响到被测试程序本身。我觉得 Ava 还是比较适合测试一些没有什么时序或者规模较小的项目。

简单用了一下两个新晋热门测试框架之后,结论还是 mocha 最稳定 7 8。不过在测试 React 相关的项目的之后我建议还是选择 Jest。

总结

感觉就说了好多废话,最后再感慨一下。

这几年前端社区真的有了翻天覆地的变化,我现在都有点想不起来被 jQuery 支配的那些日子了。多亏了PL/编译器社区的 Anders Hejlsberg,函数式编程社区的 Evan Czaplicki,还有房地产社区😄的 Yassine Elouafi ,我们前端终于有了新玩法。而对于这么多新技术,我们应该如何应对呢?

一位长者早已告诉过我答案:

这既是我的工作,也是我个人兴趣所在。现代科学发展得这么快,我们必须加强学习以跟上形势。
——《他改变了**》,p210,罗伯特·库恩。

References:

[1] ES6 polyfill vs. feature performance tests

[2] V8, Advanced JavaScript, & the Next Performance Frontier (Google I/O '17)

[3]入坑React前没有人会告诉你的事

[4] how to throttle and then watchLatest, can we compose high-level helpers? · Issue #105 · redux-saga/redux-saga · GitHub

[5] Understanding MobX and when to use it. · Issue #199 · mobxjs/mobx · GitHub

[6] Jest globals differ from Node globals · Issue #2549 · facebook/jest · GitHub

[7] Switch to a new testing system · Issue #703 · koajs/koa · GitHub

[8] 单元测试 :Egg.js - 为企业级框架和应用而生

登录的问题

问题一:
您这的登录是和网易云音乐上的数据一样吗 我用自己的网易云音乐 登录不上去 如果方便的话 能不能告诉我个账号和密码
问题二:
我如何查看log信息

Roadmap without any promises

  • View 层的分离和测试。这个是一定会做的,这个项目就是跑测试送 App,没有测试就没意思了。虽然之前写 View 都是怎么快怎么来,但大部分 container 的子组件还是都提前写成了 functional 的样子,所以改起来应该不算麻烦。这里包括两步:
    • 用 Reselect 重写 connect ,之前写 View 层基本就是怎么快怎么来,虽然 chrome profile 和 Xcode 调试显示还没有性能问题,这个我倒是想提前优化一下;
    • 用 Recompose 分离组件,这里尽量就不用 class 来写 component 了(不过这里还有一个 React Native animation 的问题),保证每个组件都是 functional component,这样即便不用 Jest 的 snapshot 测试起来也很方便
  • 用 normalizr 重写数据结构。当时写枸杞的时候 Twitter 还没有发他们新的 mobile 版本,在 Redux devtools 看了一下他们的数据结构发现原来这么搞才更科学。
  • 接入别的音乐 API。这里依赖于前一个 todo。原理就是给每一个音乐源的 API 都写一个 normalizr,因为 saga 测试 AJAX 的 I/O 都做了提前的处理,所以 saga 的测试不用重写。
  • 支持 Android。由于我没有真机也没法做调试,另外听说现在 Android 有了很大进步,现在 2k 到 3k 阶段有什么可以推荐吗?希望对开发者友好。
  • 适配更多机器。目前应该 iPhone 5(s/SE) 和 6(s/7) 两种都没问题,但播放器写死了图片的大小,
  • 音乐的 cached。现在播放音乐使用的是 react-native-video ,在 iOS 上AVFoundation 的简单实现,每次加载音乐都要把整首歌全都下载过来才能播放。另外一个选择是 react-native-sound ,这个也写好了但效果并不比 react-native-video 好。一些支持 cache 的音乐播放实现实际上用的是 StreamKitDOUAudioStreamer ,但他们的 API 还不满足现在枸杞的需求。如果纯用 JavaScript 的话倒是有一个思路:把音乐先 fetch 成 blob,然后用 react-native-fetch-blob 转换成 stream 给 react-native-video 播放,下载完成之后缓存在本地第二次播放的时候就直接播放本地文件。不过具体到底能不能 work 还不清楚。最好还是有原生语言开发者能做这类事。

yarn run ios 直接报错

yarn run ios 后, 直接报错

error: bundling: UnableToResolveError: Unable to resolve module ./src/app from /Users/Ebates/Desktop/chamWork/ReactNative/Demo/gouqi/index.ios.js: Directory /Users/Ebates/Desktop/chamWork/ReactNative/Demo/gouqi/src/app doesn't exist

fd6defa9-ad3f-4df4-a5dc-3eac978672cb

彩蛋

最后的最后

我找到了计时器:full_moon_with_face: :full_moon_with_face:

安装失败

> [email protected] quickbuild /work/react/gouqi
> tsc --noUnusedParameters --noUnusedLocals

src/components/Slider.tsx(126,33): error TS6133: 'trackSize' is declared but never used.
src/components/Slider.tsx(127,9): error TS6133: 'mainStyles' is declared but never used.
src/components/Slider.tsx(138,9): error TS6133: 'minimumTrackStyle' is declared but never used.
src/components/Slider.tsx(145,9): error TS6133: 'touchOverflowStyle' is declared but never used.
src/components/Slider.tsx(213,30): error TS6133: 'e' is declared but never used.
src/components/Slider.tsx(222,33): error TS6133: 'e' is declared but never used.
src/components/Slider.tsx(222,44): error TS6133: 'gestureState' is declared but never used.
src/components/Slider.tsx(227,29): error TS6133: 'e' is declared but never used.
src/sagas/common.ts(77,21): error TS2346: Supplied parameters do not match any signature of call target.

npm ERR! Darwin 16.4.0
npm ERR! argv "/Users/qingtong/.nvm/versions/node/v7.0.0/bin/node" "/Users/qingtong/.nvm/versions/node/v7.0.0/bin/npm" "run" "quickbuild"
npm ERR! node v7.0.0
npm ERR! npm  v3.10.8
npm ERR! code ELIFECYCLE
npm ERR! [email protected] quickbuild: `tsc --noUnusedParameters --noUnusedLocals`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the [email protected] quickbuild script 'tsc --noUnusedParameters --noUnusedLocals'.

ios真机运行出错

大佬 已经在模拟器上成功运行项目 但尝试在真机上运行就出错了 不知所措啊
default

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.