• [調查] 包管理方案 at 2014年03月02日

    大概一年前了解到 Component, 但是最终没有在我们的前端项目里面使用,基于以下几点:

    1. build 的过程的可控性不高,custom 的成本略高。( copy, concat, build templates
    2. 没有完善的 watch 机制,TJ 的 watch 实用性太低。
    3. 一次 build 的速度没法保障,在 rebuild 过程中没有 cache.
    4. 所有的包都必须被 Wrap, 这其实并不实用.. ( 想想那些之前不支持 CMD 以及 AMD 的,还有大量的 jquery 插件。
    5. Component 不鼓励使用 Coffee, SCSS 之类的产品做 component, 也没有对应的支持。而我们的项目全部使用 Coffee 与 SCSS 编写。

    基于我们项目的需求,自己开发了 Linner, 这个项目的灵感其实是从 brunch 来的。基于我们使用的是 SCSS, 以及速度和定制性方面的考虑,选择了自己开发。

    从现在的使用效果上来说,团队成员还是比较满意的,即使有很一些新的需求,也能很快的加上。

    模块可以有选择性的被包装为 CMD, 这样我就不用在每一个模块里面都声明一下 require "jquery", 只需要指定需要被包装的路径就可以了。在被包装过的模块里,大家的命名空间不会相互污染。

    我们现在的项目代码量属于比较多的,其中的模块数量非常多。所以第一次 watch 的时间往往需要 5 秒左右,但是一旦 watch 完毕,接下来的修改只需要在 300ms 左右就能响应完毕并且完成 LiveReload. 这种响应是别的产品做不到的。

    最近也新加了一个 bundle(包管理) 机制,直接从远端拉取源码,不用考虑什么注册机制,是不是 CMD, AMD 包装,简单实用。

    我们的自己的项目也是在用 bundle 机制组织。

  • 谁有 MAC 接投影仪的线可以带一下。

  • #14 楼 @dylanninin 有兴趣在小公司干活的话可以联系我。

  • #38 楼 @ytwman h3c 旁边,西溪已经坐不下了。

  • #33 楼 @fsword 你能赶过来吗?这边离余杭挺远的。

  • #24 楼 @ruohanc 顶楼已经是新地址了...

  • #22 楼 @huacnlee 是的,以前的地方坐不下了...

  • 欢迎大家来指导交流...

  • #14 楼 @_samqiu 😄 😄 😄 多谢,期待你的新项目!...

  • #5 楼 @bhuztez LINQ 的写法类似 List Comprehension, Stream 就真是 stream, 链式调用... Java 的列表转换和 ORM 至少是有救了。

  • #6 楼 @blackanger 社区里还是有很多靠 Java 生活的工程师的,况且不是还在招聘 JavaScript 工程师嘛...

  • #3 楼 @bhuztez Java 8 还是有很大改进的,虽然我现在在写 Ruby 和 JavaScript...

    Java 8 Stream :

    int sum = widgets.stream()
                      .filter(b -> b.getColor() == RED)
                      .mapToInt(b -> b.getWeight())
                      .sum();
    
  • REM 不支持 IE 8.

    http://caniuse.com/#search=rem

    不考虑兼容性的话,REM 确实是非常好的开发实践。

  • #28 楼 @aptx4869 最后这个问题也是 Linner 解决过的问题,CSS 中载入其他资源可以用 Linner 的 copy 命令指定他 copy 后的相对位置。这个问题本身是不存在的。

    而 js 异步载入其他 js 的问题,实际上 Linner 默认使用了 CMD 规范,所有文件都可以 require 获得,这个地址在 linner watch 的时候已经确定了,所以也没问题。

    teaspoon 本身也没什么特别的,可以集成 mocha, 而且有两种模式,一种是浏览器内,一种是 phantomjs 后台运行,浏览器端的没什么特别的,这个大家都可以做。服务端的话可以后台集成,这个我已经有一个 issue 在了。后面会做。

  • #24 楼 @aptx4869 javascript 的测试用 mocha 可以在浏览器上测试。你的 testsuite 使用什么写的?

    selenium? 还是 jasmin ? mocha?

  • #22 楼 @aptx4869

    多么痛的领悟!...

    这就是为什么要有 Linner 这样的工具的原因。

  • #13 楼 @kaka

    不知道部署会不会痛苦!之前用 requirejs 部署的时候出了各种问题... 后来就放弃了!

    用 Linner 部署不痛苦。

    开发阶段与生产阶段的区别只是:

    Linner watchLinner build 的区别。

  • #12 楼 @alvin2ye

    刚开始用的时候各种痛苦,各种反对意见,各种吐槽。

    说明你用错工具了。

    Linner 只需要四行就写完你的好几十行了。

    modules:
      wrapper: "cmd"
      ignored: "vendor/**/*"
      definition: "/pokeball.js"
    

    效果是一样的。

  • bower 所存在的问题

    1. 首先,bower 的覆盖面不够大。( 市面上还有大量的 javascript libraries 是不支持的。

    2. 其次,没多少人写 main property. ( main 的自动引入由 sprockets 提供

    3. 再次,ignore property 更没多少人写。

    这里举两个最简单的例子:

    而且,当没有 main property 支持的时候,用完之后会发现,整个 public 目录杂乱无章。各种 图片,README.md 都进来了。解决方案是:你只能 Fork 一份自己的来发到 bower 上,这是最痛苦的一点。

    人民大救星

    为什么不让 Javascript 跟 CSS 的引入回归本源呢?

    让我为大家推荐下面这个工具:Linner

    Linner Linner 是一个功能完整的 Assets 打包工具,其功能集是 Sprockets 的超集。

    • 支持 Sass, Coffee 作为基础语言。
    • 支持 连接,拷贝,预编译,CSS Sprite 作为基础功能集。
    • 支持 Javascript Common Module Definition 规范,指定代码会被 CMD 所包装。
    • 支持 LiveReload.
    • 支持 OS X Lion and Mountaion Lion 的原生通知
    • 支持 压缩代码
    • 等等。

    最重要的,支持 Linner install 来安装 Linner 所需的各种 library bundles.

    Linner 使用 config.yml 或者 Linnerfile 文件作为自己的配置文件,一份生产环境中使用的 Linnerfile 是这样的:

    paths:
      app: "src"
      public: "public"
    groups:
      scripts:
        paths:
          - "src/scripts"
        concat:
          "/pokeball.js": "{src,vendor}/**/*.{js,coffee}"
        order:
          - vendor/jquery.js
          - vendor/handlebars.js
          - vendor/lodash.js
          - vendor/moment.js
          - vendor/moment/zh-ch.js
          - vendor/pikaday.js
          - vendor/jquery/jquery.ui.widget.js
          - vendor/jquery/jquery.iframe-transport.js
          - vendor/jquery/jquery.fileupload.js
      styles:
        paths:
          - "src/styles"
        concat:
          "/pokeball.css": "{src,vendor}/**/[a-z]*.{css,scss}"
        order:
          - vendor/normalize.css
          - ...
          - src/styles/pokeball.scss
      templates:
        paths:
          - "src/scripts"
        precompile:
          "../vendor/templates.js": "{src,vendor}/**/*.hbs"
    modules:
      wrapper: "cmd"
      ignored: "vendor/**/*"
      definition: "/pokeball.js"
    notification: true
    bundles:
      jquery.js:
        version: 1.10.2
        url: http://code.jquery.com/jquery-1.10.2.js
      jquery/jquery.ui.widget.js:
        version: 1.10.3
        url: https://raw.github.com/blueimp/jQuery-File-Upload/9.3.0/js/vendor/jquery.ui.widget.js
      jquery/jquery.iframe-transport.js:
        version: 1.8.1
        url: https://raw.github.com/blueimp/jQuery-File-Upload/9.3.0/js/jquery.iframe-transport.js
      jquery/jquery.fileupload.js:
        version: 9.3.0
        url: https://raw.github.com/blueimp/jQuery-File-Upload/9.3.0/js/jquery.fileupload.js
      jquery/jquery.pagination.js:
        version: 2.2.1
        url: https://raw.github.com/gbirke/jquery_pagination/3a614db5fa1e02a5f568b2ac798224efb963a843/src/jquery.pagination.js
      jquery/jquery.serialize-object.js:
        version: 2.0.3
        url: https://raw.github.com/hongymagic/jQuery.serializeObject/v2.0.3/jquery.serializeObject.js
      jquery/jquery.validator.js:
        version: 1.2.0
        url: https://raw.github.com/TerminusHQ/validator.js/1.2.0/validator.js
      lodash.js:
        version: 2.2.1
        url: https://raw.github.com/lodash/lodash/2.2.1/dist/lodash.underscore.js
      spin.js:
        version: 1.3.2
        url: https://raw.github.com/fgnass/spin.js/1.3.2/spin.js
      moment.js:
        version: 2.4.0
        url: https://raw.github.com/moment/moment/2.4.0/moment.js
      moment/zh-ch.js:
        version: 2.4.0
        url: https://raw.github.com/moment/moment/2.4.0/lang/zh-cn.js
      handlebars.js:
        version: 1.0.0
        url: https://raw.github.com/wycats/handlebars.js/1.0.0/dist/handlebars.runtime.js
      pikaday.js:
        version: 1.1.0
        url: https://raw.github.com/dbushell/Pikaday/1.1.0/pikaday.js
      normalize.css:
        version: 1.1.3
        url: https://raw.github.com/necolas/normalize.css/v1.1.3/normalize.css
    

    而我们今天着重着墨的就是 bundles 这部分。结合 scripts 下面的 order 配置部分,我们就轻松解决了 Sprockets 关于引入顺序的问题...

    让我们先来解决 Bower 所不能解决的那两个问题。

    • 引入 Modernizr
    modernizr.js:
        version: 2.7.1
        url: https://raw.github.com/h5bp/html5-boilerplate/v4.3.0/js/vendor/modernizr-2.7.1.min.js
    

    modernizr 就会被安装在 vendor 目录中,呈现出:

    vendor
    └ modernizr.js
    

    而 modernizr.js 同时会被缓存在 ~/.linner/bundles 内部。

    • 引入 moment.js 的同时引入 moment.zh-cn.js 作为 i18n 文件。
    moment.js:
      version: 2.4.0
      url: https://raw.github.com/moment/moment/2.4.0/moment.js
    moment/zh-ch.js:
      version: 2.4.0
      url: https://raw.github.com/moment/moment/2.4.0/lang/zh-cn.js
    

    moment 就会被安装在 vendor 目录中,呈现出:

    vendor
    └ moment.js
    └ moment
       └ zh-ch.js
    

    Linner bundles 给你最大的限度来操控自己的 vendor 目录,全面使用 Linner bundles 之后你的 vendor 目录完全可以被加入 .gitignore. 同时你可以获得最大限度的目录操控,适合有洁癖的你。

  • Bootstrap 2 or 3 at 2013年11月28日

    #4 楼 @Peter semantic-ui 加载慢是有原因的。

    因为 semantic, 所以导致 CSS 的 selector 堆积太多,在智能手机上的性能自然就差。

    一种叫做 BEM 的方法,可以解决性能问题,但是命名会非常丑。类似这样:.text-cols--2__active

    semantic-ui 的定义比较容易导致 CSS 冲突,在定义的过程中要比较小心,不过是可以避免的。但如果当你自己需要扩展 semantic-ui 的时候,你就必须非常了解其内部实现。

  • 在几天前用 1password 把自己常用的站点密码全部更新了一遍。

  • 投给 Rust.

    Scala 跟 Java 更适合服务端编程,而且 Java 我已经学过了,作为 JVM 上的二奶语言。脱离不了我大 Java 生态圈,是很悲剧的一件事。Clojure 也是如此。

    关于 Go. 如果用 Go 去做 Web, 我觉得就没必要学习了。因为不会带给我新的东西。系统级编程 Go 又不行.. 现在的问题就是 Go 只能成为更快的静态类型 Ruby Python.. 而且语法灵活程度上大败.. 自己可以权衡一下。

    Elixir 需要深厚的 Erlang 背景,学习 Erlang 当然是一件好事,因为可以带给你全新的思维方式。败笔就是也是一个二奶语言。

    相对而言,更喜欢 Rust.

  • #4 楼 @luikore 这是一个 this 是谁的问题..

    最近 coffee 写多了...

    initailize()
    initailize this, arguments
    

    所以就 eval 了。

    这是病,得电...

  • 因为 patch binding 对象会很方便:

     irb
    2.0.0p247 :001 > x = 1
     => 1
    2.0.0p247 :002 > eval("x", binding)
     => 1
    

    这个就满足大部分 pry 的需求了... 主要也是获取 binding 内的各种值。连 eval 都赠送了..

  • Mac QQ 3.0 的东西,已关闭。

  • #4 楼 @fsword 说明我语文学的好啊,回复很有吸引力,不然你也不会回复我...

  • 啊,这次在悉尼了,上次过去的时候恰好也在开 RubyConf AU, 但是在墨尔本。没有门票,加上消费实在是太高,所以还是没有去墨尔本玩。

    不过这次应该也没机会就是了...

  • #79 楼 @gene_wu 下个月不一定在,在的话已经会再来参加的。

    #68 楼 @iBachue 据我多次 Ruby Tuesday 的参会经验,搞点原理/实现性知识大家参与是比较踊跃的。对于平时工作中没时间研究的人来说帮助也比较大。

  • #22 楼 @yedingding 嗯,那就再找时间喽,看大家还有没有听的需求。