V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
liaa
V2EX  ›  自言自语

@tangzx 打了鸡血的开发者,来分享一下你用sublime+node+coffeescript开发的流程吧

  •  
  •   liaa · 2013-05-30 18:29:34 +08:00 · 409 次点击
    这是一个创建于 4188 天前的主题,其中的信息可能已经有所发展或是发生改变。
    @tangzx
    First thing first: ST+node+coffeescript is "cool"
    ## 我的问题
    1. 如何管理 *.coffee 的文件:
    因为有时候他们分布在好几个文件夹中, 使用怎样的coffee命令同时管理
    2. 如何设置环境变量,同时如何设置config文件的.我是这样设置的,然后在app.js中就使用config这个变量

    ps: 虽然是个新手,可是总是对workflow这件事很在乎...求解答
    12 条回复    1970-01-01 08:00:00 +08:00
    liaa
        1
    liaa  
    OP
       2013-05-30 19:32:38 +08:00   ❤️ 1
    追加:
    3. what's your bash and sublime text theme and colorscheme.
    tangzx
        2
    tangzx  
       2013-05-30 21:38:52 +08:00 via iPhone   ❤️ 1
    @liaa 好激动一定连夜写今天不写完不睡觉
    liaa
        3
    liaa  
    OP
       2013-05-30 22:00:50 +08:00   ❤️ 1
    @tangzx 感谢~ 其实自己也是个宅,技术养成中,要成为战斗力超强的那只码农.从前端杀到后端,再杀回前端,再杀回后端...谁叫我们是JSer呢~
    tangzx
        4
    tangzx  
       2013-05-31 00:17:36 +08:00   ❤️ 1
    鸡血文来啦~~: http://posts.micy.in/2013-05-31-managing-coffee-project.html

    # 俺是咋管理CoffeeScript项目的

    First thing first: ST+node+coffeescript is "cool", 俺大部分的项目是服务端的nodejs项目,故俺这次分享的方法也许不太适用于其他类型的项目。

    ## 俺是咋管理这堆`.coffee`文件的

    首先、你需要在使用`coffee-script`模块还是发布前编译`.coffee`文件之间做一个选择,首先让俺来说下俺的观点吧,俺是推荐在nodejs项目中使用前一种方法的,即:

    1. 将`coffee-script`模块加入到你的`package.json/dependencies`中去
    2. 在入口文件(默认情况下为`./index.js`)中使用如下语句:

    ```js
    // ./index.js
    require('coffee-script'); // 引用`coffee-script`模块会加一个对应`.coffee`扩展名的require钩子
    module.exports = require('./app'); // 于是在这里就可以像引用`xxx.js`文件一样地引用`app.coffee`了
    ```

    这样做显而易见的优点是:

    * 方便,不需要本地安装coffee命令(其实是全局(`npm install -g`)安装`coffee-script`模块)
    * 源代码管理也方便

    不过之前看到过一些对此做法的反驳,故俺一一解之

    * 一个项目由许多人共同完成,有的人只想写js,有些人想写coffee

    真心不影响哦,你只要在项目的最初入口出有`require('coffee-script');`过一次,之后再`require`时便`js`和`coffee`都能引用了,在`coffee`里一样能引用`js`,写法也不变(`db = require './db' # 引用了./db.js`);你甚至可以用`coffee`来重构别人写好的`js`,或者反其道而行(所以`require`时最好不要带扩展名,这样重构之后就不用更改引用的语句了)

    * 实时编译`.coffee`会有效率问题

    正如上所述,`coffee-script`模块加了一个`require`钩子,`require`时编译`.coffee`文件,故和`require`普通`js`文件一样,该编译操作只会执行一次,并且该操作后,被`require`的模块便以函数或者对象的形式被缓存了,所以之后再调用时会和普通`js`效率是一样的。

    不过,在第一次`require`时,确实是需要花一些时间的,所以咱可以做的事儿就是尽量在代码的最外层`require`,即让程序启动时编译所有的`coffee`,免得之后再编译影响用户体验了。编译大概要多少时间呢?俺觉得还是可以接受的,俺这里有个数据给你参考一下:

    俺现在所在公司的一个小项目的服务端代码是用`IcedCoffeeScript`编写的,有**42**个`.iced`文件(`find . | grep .iced | wc -l`),这些`.iced`文件中代码总行数为**2862**行(<code>cat `find . | grep .iced` | wc -l</code>),在俺的2011未升级的硬盘快装满的老爷最低配mbp上启动要大约要3~4秒(包括连接本地mongodb和绑定http端口)

    ### 假如你的项目为前端项目或者你就是不想依赖于`coffee-script`模块

    如果你一定需要将这堆`.coffee`编译成`.js`的话,我这里推荐你使用 Makefile ,不过 Makefile 在 Windows 上就很是捉急了,如果你的项目组里有成员使用 Windows 作为开发机,你就得考虑给他安装`cygwin`,并且随时注意你写的 Makefile 中调用的工具链的cygwin兼容性了。

    虽然前端工程师们自己也有创造许多优秀的工具如`yoeman`、`Grunt`还有国内那些厂商做的一堆啥啥之类的,但是俺在这里还是推荐挺原始的Makefile([TJ也推荐咱用Makefile](https://groups.google.com/forum/#!topic/express-js/me3FL5wY7RE)),因为:

    * make 是极其简单而且成熟的产品,不会动不动改动升级,不带有任何编程语言和行业偏见(尽管它对Windows有偏见)
    * Makefile 是描述式语言而非流程式语言。
    * [不是make独有的特性] make 根据文件的mtime决定了哪些文件需要编译,便会只编译那些新更改过的文件,所以写一个好的 Makefile,便可以实现永远地增量编译。更好的是,咱可以用 `watch make`命令达到类似于“实时编译”的效果而不占用多余cpu。
    * [不是make独有的特性] make 可以分析依赖关系,管理多线程同时编译,最大化你的多核机器的效率(或者节省等待io时阻塞浪费的时间)。

    俺在这里举个栗子吧,首先做出一个假设:某个项目中的服务器端代码全部是 CoffeeScript,则`Makefile`应该包含:

    ```makefile
    COFFEEBIN = node_modules/coffee-script/bin/coffee # 用**安装的模块中包含的coffee命令**代替**全局安装的coffee命令**
    COFFEE = $(shell find . -name '*.coffee') # `find`和`ls`的区别就是: `find`列出当前目录和所有子孙目录下的文件,而不仅仅是当前目录下的文件
    COFFEEJS = $(COFFEE:.iced=.js)
    # 以上这三个变量均在 make 载入时确定其值

    all: $(COFFEEJS) # 此处定义了第一个目标(默认目标)为所有 coffee 对应的 js

    %.coffee: %.js
    $(COFFEEBIN) -c $< # `$<`是一个 [Makefile的特殊变量](http://www.gnu.org/software/make/manual/html_node/Static-Usage.html#Static-Usage)
    ```

    于是你便可以使用`make`命令将项目中的所有(更改过的)`.coffee`文件编译成`.js`文件了。故你还需要一部:别将这些编译出来的`.js`文件提交到代码仓库里面(它们只是编译结果,不应该被提交)

    ```
    ...
    # 确定你的`./.gitignore`中包含这一行:
    *.js
    ...
    ```

    ## 俺怎样使用环境变量配置nodejs程序

    Windows和xNIX中都有“环境变量”这个概念,但是Windows的环境变量不管是用法还是规则都有些特别,故这里暂只讨论`POSIX环境变量`(适用于OSX和linux)

    首先,俺推荐使用环境变量而非配置文件来配置应用程序,Heroku和CloudFoundary都采用这两种方法来配置和传递应用程序的服务接入点,并且Heroku在其发布的[12 Factors App宣言](http://www.12factor.net/config)中也说明了这样做的好处: 配置随着代码走既不方便调试也容易产生安全问题。

    例如,Heroku和CloudFoundary都采用`PORT`环境变量标示Web应用程序应该监听的端口,所以我们代码中应该这样写(Express的官方示例也是这样写的):

    ```
    server.listen (Number process.env.PORT||3000), (e)->
    throw e if e
    console.log "俺跑在了#{server.address().address}:#{server.address().port}上"
    ```

    而我们在本地调试需要启动程序时,如果想把上述程序跑在**8000**端口上,则需要执行命令

    ```
    # 一条命令
    PORT=8000 node ./index.js
    # 或者两条命令
    export PORT=8000 # 注意这里一定要加export,因为在 interactive bash 中,每敲一下回车会启动一个子shell,不export的话,子shell中的环境变量便不能导出到当前会话中
    node ./index.js
    ```

    使用`export PORT=8000`,将会把`PORT`变量设置到当前的终端会话中;直接使用`export`命令可以查看当前会话中所有环境变量的值

    ### 其实可以永远将开发环境中所用的值作为默认值

    正如以上使用`Number process.env||3000`作为端口一样,为了方便,可以使用开发环境的值作为默认值(express也是这样做的:如果不设置`NODE_ENV`环境变量,express就是用`development`配置,否则就使用`NODE_ENV`指定的配置)

    所以俺的代码中便出现了以下片段:

    ```
    # 配置数据库
    dburi = process.env.DBURI
    dburi?= "mongodb://localhost/ForensicHub-development"
    ```

    ```
    # 配置OAuth服务器
    process.env.AUTHSERVER?= 'http://192.168.18.187:8001/' # 公司内网给开发测试们用的OAuth服务器
    process.env.CLIENT_ID?= 'ForensicHubTEST' # 开发专用ID/SECRET,OAuth重定向到 http://localhost:3000/oauth_callback
    process.env.CLIENT_SECRET?= 'TESTSECRET' #
    ```

    ## 俺的ST和bash用啥color colorscheme

    其实俺对这个也没太大讲究,其实是用一段时间看得有些累了就换一个,个人喜欢比较柔和一些的颜色搭配,写下这篇分享时俺的iTerm2和SublimeText都在用[Solarized(Light)](https://github.com/altercation/solarized)这套颜色,效果大致为下图↓

    ![ ]( )

    ![ ]( )
    tangzx
        5
    tangzx  
       2013-05-31 00:18:26 +08:00
    @liaa
    太在理了
    > 要成为战斗力超强的那只码农.从前端杀到后端,再杀回前端,再杀回后端...
    liaa
        6
    liaa  
    OP
       2013-05-31 01:05:06 +08:00
    @tangzx 我刚刚上来,看了码了这么多一股股感动.不过实在等不及了,先看了再说~
    liaa
        7
    liaa  
    OP
       2013-05-31 01:41:29 +08:00   ❤️ 1






    liaa
        8
    liaa  
    OP
       2013-05-31 01:42:48 +08:00
    @tangzx 很明了了,大号感谢送上~
    lenville
        9
    lenville  
       2013-05-31 13:33:00 +08:00
    @liaa
    @tangzx

    捉到两只野生萌货,此帖甚赞
    liaa
        10
    liaa  
    OP
       2013-05-31 13:55:18 +08:00
    liaa
        11
    liaa  
    OP
       2013-05-31 13:56:07 +08:00   ❤️ 1
    lenville
        12
    lenville  
       2013-05-31 14:55:48 +08:00
    @liaa 太棒了,感谢已发

    我今天折腾下Arch, 等我回来, 如果我失败了就晚上上手机好了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2576 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 15:50 · PVG 23:50 · LAX 07:50 · JFK 10:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.