• #22 楼 @Saito 相比服务端,客户端确实更在乎大小,所以尽量不要载入重复的包。不过如果像 Webpack 那样推崇从源码编译打包的,每个模块(文件)都是依赖,成百上千,这时候其实只要通过一些手段(比如 dedupe)去重后,最终容量在一个可接受范围,也不会太 care 有没有重复。也许还是会有一点重复,但人工成本省了很多,还有其他诸多优势,也是一种权衡。

  • 没看懂你的 SQL,但显然复杂了(可能有错)。

    反过来思考下,时间段不重合 情况就两种:

    # a: |-------|
    # b:              |-------|
    # a.end_at < b.start_at
    
    # a:              |-------|
    # b: |-------|
    # a.start_at > b.end_at
    

    综合一下,取个反就是你想要的结果了。这个可以简化 SQL,1 楼的写法简化参数,应该够了。

  • 关于 JWT,它是 明文 的,把中间一段抠出来用 base64 解码就可以获得原始数据。它的签名算法只是为了防止数据被中间人篡改,而不是加密数据。显然这是不能用于验证码这种敏感数据的。

  • 这个问题本质上是:服务端要在若干个 HTTP 请求的工作流中,记住用户相关的验证码数据(验证码) ,方便做后续处理(校验)。这必须把数据临时存放在某个地方。

    我能想到的一个解决方法是用 redis 存储验证码,key 设置为用户 id 相关的,value 设置成验证码,再设置一个过期时间(比如 5 分钟)。这样流程就变成:

    • 客户端进入某页面,服务端渲染页面的时候生成验证码,并存入 redis。
    • 客户端输入正确的验证码,提交数据(我很好奇客户如何知道正确的验证码是什么?)
    • 服务端从请求中获得验证码,跟 redis 中的验证码对比,通过则创建数据,然后把 redis 的数据删掉。

    更进一步,如果服务端需要记住的验证码是 用户 + 设备 唯一的,则可以考虑服务端为每个创建操作生成一个 uuid,这样服务端记录的 key 是 用户 id + 随机 uuid ,其他部分思路相同就不多说了。

  • @Saito 问题是 tree shaking 需要静态分析模块依赖来支撑,目前只有 ES module 能做到这点。而 Node.js 因为入 CommonJS 的坑已久,迟迟不能支持。这个问题不是短期能够解决的,而且要把大部分 package 重新用 ES module 的方式写也不现实。前端因为有预处理器,受这个的影响反而很小。

    其实我就只希望 yarn 能锁定版本,是不是像 Bundler 一样 flat dependency 不是那么重要。拿“两个包依赖的 underscore 版本不一样导致无法顺利安装”的例子来说,反过来想应该是“我想用的只是 A 和 B 但并不在乎它们有什么依赖,为什么它们的依赖要对我产生影响?” 。这也是另一种 dependency hell。如果能用一点多余的空间解除一些依赖的限制,也是值得的。如果这样想的话,会发现 small-focused-module 就比 big-focused-module 更有利(占的空间更少)。

  • 找个时间试试。现在觉得 lock 还是很必要的。以前我还写了个回复说依靠 SemVer 自我约束就行了,但自从搞了 React 之后我再也不相信 SemVer 了。现实中很有一部分 npm 包遵循的是这种规则:

    • 0.x.y 版本,x 就是 breaking change,y 才是 bugfix。到了 1.0 在遵循 SemVer 不迟。
    • x.y.z 版本,基本还是遵循 SemVer 的

    不过,我还是觉得 npm 推崇的 nest dependency 是有价值的,它可以让间接依赖变得更加灵活,从而可以让直接依赖少点限制。

  • 这些规则都是可以配置的。我记得如果没有配置任何规则, 默认 ESLint 不会干任何事情 。所以说,出现的 error 基本都是自己加了相应的规则。程序员得明白自己在干什么。

    然后,不想因为 error 把 build 过程挂掉的话,配置成 warning 等级就行了。比如 console.log 相关的我就配置成 warning。

    @lgn21st Atom 有对应的插件,我想其他编辑器也不差这个。我倒觉得不需要集成进去。不是所有人都喜欢预装一堆东西的编辑器。就像 Firefox 默认没有装一个插件一样。如果从工程角度考虑,集成进 build 流程更好,这样 CI 等流程都可以用,集成进编辑器只是方便开发者这一个环节。

  • 这本身就是要自己组合的。取决于你基于什么目的用什么技术,没用过 Node,仅供几个方向参考:

    1. 传统网站,部分页面有复杂的交互:主用 Rails,Angular 集成进部分页面(找找 Sprockets 的集成方案)做前端增强,用户验证还是用 session/cookies。
    2. 前后端分离的模式:Rails 做 API,Angular 做整个前端,集成方式可以用 Sprockets 也可以用 Webpack,部署方式取决于集成方式。用户验证一般用 token,也可以用 session/cookies。

    Node.js 一般跟 Rails 是二选一的,所以我想也不存在什么框架集成两者(没有应用场景)。拿 Node.js 当构建工具的不算。我能想到的需要 Node.js 做服务器端的工作的就是 SSR,这个需要 Node.js 做中间层。不过 Angular 又不支持 SSR。

  • @lilijreey 这不是坑,语言设计不同而已。获得了方法调用不带括号的便利,也得在其他方面做点牺牲。你要的是这个:

    puts_method = method(:puts)  # => #<Method: Object(Kernel)#puts>
    puts_method.('hello')  # => 等同于 puts 'hello'
    
  • 到底如何做 HTTP API? at 2016年08月31日

    能遵照 RESTful 就尽量遵照,但不要偏执于一切都 RESTful。API 设计主要是保持 resource 的细粒度。方便前端组合重用。那种一个 API 请求满足一个页面需求的看起来对前端简单,其实是最坑的方案,很容易变成同一个 resource 根据不同页面要写多个 API 的情况。所以一开始就不要这么做。

    另外很多人忽略的一点是 relationship,这点是 RESTful 并没有仔细考虑的问题,很多是做成返回 xxx_id 或者直接嵌套的结构。在 relationship 比较复杂的情况下也很容易坑。如果业务场景确实复杂,可以考虑 JSON API 规范,至少可以借鉴一部分,比如它的状态码设定,可以省很多琐碎的决策。API 开发的很多部分都是体力活。

    最后说一个例子,我最近的项目是用的 JSON API 的 response 结构(只用了 response,其他保持 RESTful),一是需要有一个标准化和扁平化的 response 方便配合 Redux。这样一套 deserialize 的代码就可以处理多种 resource 的数据转换逻辑,不用针对每个 API 或 resource 写特殊的转换逻辑(尤其是有 relationship 的情况)。二是可以用 compound document 加载额外的数据,类似 ActiveRecord 的 include/preload,增加 API 的灵活性。

  • ` 包含的命令不会输出到 stdout,为什么要拘泥于 FileUtils 来给自己找麻烦呢?不要执着于 一切都用 Ruby 来写

  • 干掉你代码中的坏味道 at 2016年08月24日

    最近加了 reek,只用了它做检查,因为检查整个项目问题太多。我们写了一个 rake task 来检查 feature branch 内改动的代码,准备写功能的时候顺手改一下。

    # lib/tasks/reek.rake
    namespace :reek do
      desc "Check code smells for changed files (based on staging)"
      task :changed, [:branch] do |t, args| # 加一个 branch 参数
        branch = args[:branch] || 'staging'
    
        # 获取改变的文件名,剔除掉被删的文件
        re = `git diff --name-only #{branch}`
        files = re.split("\n").delete_if { |name| !File.exist?(name) }
    
        if files.blank?
          puts "\nNo files changed\n"
          return
        end
    
        # 打印一下文件列表
        puts "\nReek changed files:"
        files.each do |file|
          puts "  #{file}"
        end
        puts
    
        # 调用 reek
        system "bundle exec reek #{files.join(' ')}"
      end
    end
    

    详细信息可以看 这里

  • Ionic 可以在浏览器上直接运行

  • stream_for 只是一个方便的写法,方便根据 model 生成 channel name,底层调用的还是 stream_from 。我大部分时候都用的 stream_from ,因为构造的 channel name 都不大规则……

  • @holin AR 也有 preload,可以强制分开查询语句。不过 Ecto 的 preload 确实更强大,默认并发加载数据,因为可以传入完整的 query 所以能很方便地指定 order。这点 AR 里只能通过一些变通方法(加额外的 relationship 来配合 preload)来解决。

  • The Rails Doctrine - 中文翻译 at 2016年08月02日

    但框架要是只是厚重的教科书就不可能了,新的应用好比一张白纸。蛋蛋 是要理解从那开始,如何起步,就需要花费巨大的努力。

    揪个小错误。开始还没会过来,想着 DHH 文风果然狂野……

  • 你写 js 还敢不加分号? at 2016年07月12日

    解决方法上面的都已经说了,规则也挺简单。少数时候分号还是必须的。所以这种风格国外叫 semicolon less 而不是 semicolon free。

    我觉得 [a, b, c].doSomething 这种行首写中括号的方式在实际编程中是不可避免,相比写大量冗余的分号,偶尔容忍一点奇怪的语法也是可以接受的。

    最后,不管用什么风格,加个 ESLint 检查下总没错。最怕的就是“我想打就打不想打就不打反正也不会报错”流……

  • 看过一个 Draft.js,不是开箱即用的那种,但可以用于自己制作文本编辑器。也是 Facebook 出的。

  • 在不需要 down vote 的情况下,心形感觉更好

  • 有意思的思路。刚好前几天看 RailsConf 2016 的 How Sprocket Works 也讲了自定义 processor,对照一下感觉不错。

  • @nightire 赞一个,原来你们的产品做得这么漂亮!

  • Ruby SH 薄荷聚会有感 at 2016年05月23日

    @skhizein 其实还有一个原因,其他领域一般都已经有很成熟的选择,比如 Python 在科学计算方面。就算用 Ruby 实现一套也没有本质的提升,所以大多数该领域的人会选择学一门新语言而不是拿着 Ruby 造轮子。

  • @whitecrow 原来 SegmentFault 上那条评论是你写的啊 :)

    @lvsheng 对!这点是我写完之后才突然想到的,就没更新进去了。这些所谓的构造函数本身也都是 function,这样解释就很圆满了。

  • @nightire 啊对,我记错了。名字太相似了。这是不是跟 Rx.js 很像?

  • 补充几点。Ember 默认对 Array, String, Function 的 prototype 做了部分扩展来添加一些方法,你说的 pushObject 就是这类。常见的还有 Function 的 onpropertyobserves 。这个特性也可以关掉,具体见 这里

    至于为什么?因为 Ember 的双向绑定机制是 KVO (Key Value Observer) 。它通过给对象加 observer 来通知页面更新(和做双向绑定链)。但 JavaScript 原生的对象没有这种功能。所以常用对象都要用 Ember 提供的类封装一下,这也是为什么必须使用 get/set 来更新属性的原因。如果 ES 的 Object.observable 没有被废弃的话,Ember 会是最大的受益者。不过现在公认看好的解决方案是 virtual dom,所以……

  • @1272729223 我没什么建议。因为我觉得前端就应该懂这些东西,也要求一定的跨界能力。因为涉及的面比较广,所以开发者要做很多选择。全栈框架比较省事就是因为它帮你做了很多选择(而且都是比较优质的)。

    其实广义一点说,web 开发者本身不也是要懂很多东西么?就算传统的后端工程师不是也要懂数据库设计,面向对象,数据结构和算法,分层模型,缓存,服务器优化,HTML/CSS/JavaScript 等等嘛。

  • JavaScript ASI 机制详解 at 2016年05月05日

    @1272729223 对,而且正常情况下也就 ([ 两个。

  • @lyfi2003 那我说说原因:

    Angular 我在用,说它不是一个好框架,是因为它自己造了一些概念(虽然不难理解)提升学习成本,而且在某些细节上有些诡异的 bug(尤其是双向绑定方面)。它能够流行是因为它的自由度(尤其是 directive),这对做 UI 库是很有利的。这也可以解释为什么后来 React 突然火起来了,也是为什么 Ember 一直没有什么好的 UI 库的原因。这并不是说不流行的就不好,只是普遍来说,轻量灵活的框架和库有更好的泛用性。尤其那时的前端可以说是“春秋战国”时期,都没有想明白,就各种自己组装。

    不过前端现在的情况是基本有些统一的方向了,这还得感谢 React 和 Redux。在有一个比较清晰统一的道路的情况下,框架会越来越注重软件设计方面,传统后端的一些设计思路会越来越多的加入(也许会变个形状和说法)。集合优秀 idea 的全栈框架会崛起,减轻黏合成本。Angular 2 整体设计还比较清晰,而且也不是非用 TypeScript 不可。Ember 的优势在慢慢体现(虽然我觉得他们的进度还是有点慢)。

    Meteor 我本来也不看好,知道我折腾了一小段时间的 React 和 server side rendering,我才了解了一点它的想法:它想做新一代的全栈框架,统一前后端开发,让 website 也能更轻松地实现一些交互特性。轻量的可以用自带的模板引擎,重量点可以可以自己搭配 Angular 或 React 做 SPA。我不好说这是不是一个好主意。也许它得等到前端发展得更成熟的时候才有发亮的机会。不管怎么样,我觉得做这件事的一群人是很有远见和勇气的。用一句话简单的否定了未免太武断。

  • 我的某些看法恰恰相反:

    1. Angular 1 不是一个好的框架,Angular 2 有望成为一个好的框架。
    2. 没了解过 Meteor,不过如果它那么没用,不至于 Vue 的作者跑到 Meteor core team 去。
  • @tangmonk @coolzilj 大部分这种问题都可以通过搜索引擎加合适的关键字解决。随手搜到的:https://lincolnloop.com/blog/speeding-npm-installs/

    总之,你得相信自己不是第一个碰到问题的人。