快乐Node程序员的10个习惯
JavaScript出现近二十年了,但由于其有些问题不能解决,使得像Python和Ruby这一类的语言很吸引人,这些问题包括命令行接口、交互式开发环境、包的管理和没有一个有组织开源社区等。幸亏Node.js和npm,使得JavaScript的现状有了明显改善。网络程序员正使用强大的新工具,这使他们可以做他们想到的任何事情。\
\
下面是一个让你的快乐和让你程序很好工作的小技巧清单。
\
1、用npm init开始你的程序
npm包括一个用init命令创建一个package.json文件的过程。尽管你也许很熟悉package.json极其属性,但是npm init仍然是一个很方便的方法让你的新的节点应用程序(node app)或模块开始走上正轨。它为你智能地进行默认设置,就像从其父目录推断模块名称,从~/.npmrc中读取作者信息,或者是使用你的git设置来确定repository。
::: {#highlighter_109104 .syntaxhighlighter .bash}
+------------------------------------+------------------------------------+
| ::: {.line .number1 .index0 .alt2} | :::::: container |
| 1 | ::: {.line .number1 .index0 .alt2} |
| ::: | mkdir
{.bash |
| | .functions} my-node-app
{.bash |
| ::: {.line .number2 .index1 .alt1} | .plain} |
| 2 | ::: |
| ::: | |
| | ::: {.line .number2 .index1 .alt1} |
| ::: {.line .number3 .index2 .alt2} | cd
{.bash |
| 3 | .functions} my-node-app
{.bash |
| ::: | .plain} |
| | ::: |
| | |
| | ::: {.line .number3 .index2 .alt2} |
| | npm init
{.bash .plain} |
| | ::: |
| | :::::: |
+------------------------------------+------------------------------------+
:::
\
2、声明所有的依赖关系
每次你在本地安装一个模块,使用--save或者是--save-dev是一个很好的习惯。这些标记把给定的模块增加到你的package.json的dependencies或devDependencies的列表中,并且它会使用一个合理的默认的semver range{rel="nofollow" target="_blank"}。
::: {#highlighter_725871 .syntaxhighlighter .bash}
+------------------------------------+-------------------------------------+
| ::: {.line .number1 .index0 .alt2} | :::: container |
| 1 | ::: {.line .number1 .index0 .alt2} |
| ::: | npm
{.bash .plain}install
{.bash |
| | .functions} domready --save
{.bash |
| | .plain} |
| | ::: |
| | :::: |
+------------------------------------+-------------------------------------+
:::
注意现在npm使用的caret-style semver ranges{rel="nofollow" target="_blank"} :
::: {#highlighter_971995 .syntaxhighlighter .js}
+------------------------------------+------------------------------------+
| ::: {.line .number1 .index0 .alt2} | :::::: container |
| 1 | ::: {.line .number1 .index0 .alt2} |
| ::: | "dependencies"
{.js |
| | .string}: {
{.js .plain} |
| ::: {.line .number2 .index1 .alt1} | ::: |
| 2 | |
| ::: | ::: {.line .number2 .index1 .alt1} |
| |
{.js .spaces}"domready"
{.js |
| ::: {.line .number3 .index2 .alt2} | .string}:
{.js |
| 3 | .plain}"^1.0.4"
{.js .string} |
| ::: | ::: |
| | |
| | ::: {.line .number3 .index2 .alt2} |
| | }
{.js .plain} |
| | ::: |
| | :::::: |
+------------------------------------+------------------------------------+
:::
\
3、指定一个启动脚本
在package.json中为scripts.start设置一个值以便允许你在命令行中用npm start来打开你的app。这是一个很好的要去遵守的惯例,这样这可以让任何的节点开发人员来拷贝你的app并没有任何问题地运行。
Bonus:如果你在你的package.json中定义了scripts.start,那么你就不需要Procfile了。正如web process{rel="nofollow" target="_blank"}使用npm start时Procfile将自动地被创建出来。
这有一个打开script的例子
::: {#highlighter_43883 .syntaxhighlighter .js}
+------------------------------------+------------------------------------+
| ::: {.line .number1 .index0 .alt2} | :::::: container |
| 1 | ::: {.line .number1 .index0 .alt2} |
| ::: | "scripts"
{.js .string}: {
{.js |
| | .plain} |
| ::: {.line .number2 .index1 .alt1} | ::: |
| 2 | |
| ::: | ::: {.line .number2 .index1 .alt1} |
| |
{.js .spaces}"start"
{.js |
| ::: {.line .number3 .index2 .alt2} | .string}:
{.js |
| 3 | .plain}"node index.js"
{.js |
| ::: | .string} |
| | ::: |
| | |
| | ::: {.line .number3 .index2 .alt2} |
| | }
{.js .plain} |
| | ::: |
| | :::::: |
+------------------------------------+------------------------------------+
:::
\
4、指定一个测试脚本
就像你团队中任何人都应该能运行你的程序一样,他们也应该都能测试它。在package.json 中的scripts.test字段是用来指定一个脚本来运行测试的。如果你正在使用如mocha一类的东西来进行测试,请确保在package.json中包含它,并且要指明这是你本地项目的字节文件而不是已经发布的mocha。
::: {#highlighter_262260 .syntaxhighlighter .js}
+------------------------------------+------------------------------------+
| ::: {.line .number1 .index0 .alt2} | :::::: container |
| 1 | ::: {.line .number1 .index0 .alt2} |
| ::: | "scripts"
{.js .string}: {
{.js |
| | .plain} |
| ::: {.line .number2 .index1 .alt1} | ::: |
| 2 | |
| ::: | ::: {.line .number2 .index1 .alt1} |
| |
{.js .spaces}"test"
{.js |
| ::: {.line .number3 .index2 .alt2} | .string}:
{.js |
| 3 | .plain}"mocha"
{.js .string} |
| ::: | ::: |
| | |
| | ::: {.line .number3 .index2 .alt2} |
| | }
{.js .plain} |
| | ::: |
| | :::::: |
+------------------------------------+------------------------------------+
:::
\
5、避免代码的依赖关系
许多节点app使用依赖于C的npm模式,像bson、ws、和hiredis,他们必须为HeroKu的64位Linux系统架构重新编译。这个编辑编译过程很费时。为了使这个过程尽可能快,下载过和编译后HeroKu在节点建立缓存以便在后续使用中被重复使用。这个缓存意味着占用更少的网络流量进行更少的编译。忽略node_modules也是npm模块作者推荐的做法。
::: {#highlighter_489566 .syntaxhighlighter .bash}
+------------------------------------+------------------------------------------------+
| ::: {.line .number1 .index0 .alt2} | :::: container |
| 1 | ::: {.line .number1 .index0 .alt2} |
| ::: | echo
{.bash |
| | .functions} node_modules >> .gitignore
{.bash |
| | .plain} |
| | ::: |
| | :::: |
+------------------------------------+------------------------------------------------+
:::
\
6、使用环境变量配置npm
来自npm配置文档{rel="nofollow" target="_blank"}:
任何以npm_config_开始的环境变量将被解释成一个配置参数。例如,把npm_config_foo=bar放在你的环境变量中将把foo放到bar的配置参数中。任何没有被初始化的环境变量将被设置成true。配置值不区分大小写,因此NPM_CONFIG_FOO=bar也能同样的工作。
正如最近被改变的一样,在所有的HeroKu框架中app环境变量设置都是有效地{rel="nofollow" target="_blank"}。这种改变使得HeroKu的节点使用者可以控制他们的npm的配置,并且不需要改变他们的程序代码。第七个习惯是一个极好的实例。
\
7、带着你自己的npm注册表
最近几年公开的npm注册增长的很快,但这伴随着一些不稳定因素。结果很多的节点使用者正寻找可替换的办法,为了同时提高开发周期开发稳定性,或者是为了建立自己的私人节点模块。Nodejits{rel="nofollow" target="_blank"}u{rel="nofollow" target="_blank"}和Gemfury{rel="nofollow" target="_blank"}提供付过费的私人注册表,并且有一些免费的替代品,例如Mozilla's read-only S3/CloudFront mirror{rel="nofollow" target="_blank"}和Maciej Ma?ecki's European mirror.{rel="nofollow" target="_blank"}配置你的Heroku节点应用程序来使用一个自定义注册中心是很容易的:
::: {#highlighter_189380 .syntaxhighlighter .bash}
+------------------------------------+-----------------------------------------------+
| ::: {.line .number1 .index0 .alt2} | :::: container |
| 1 | ::: {.line .number1 .index0 .alt2} |
| ::: | heroku config:
{.bash .plain}set
{.bash |
| | .functions} npm_config_registry=http:
{.bash |
| | .plain}//registry
{.bash |
| | .plain}.npmjs
{.bash .plain} |
| | ::: |
| | :::: |
+------------------------------------+-----------------------------------------------+
:::
8、跟踪过时的依赖关系
如果你已经从事编程很久了,你可能是dedependency hell{rel="nofollow" target="_blank"}。幸运的是Node.js和npm都会对改变进行说明,通过Semantic Versioning Specification{rel="nofollow" target="_blank"}。在这种情况下,版本号和他们改变了的实现方式能传达出从一个版本到另一个版本底层是如何实现的。
npm有一个鲜为人知的命令outdated。使用npmupdate,这是一个很好的工具来检测你的app的依赖关系是否已经过时并且需要升级。
::: {#highlighter_270834 .syntaxhighlighter .bash}
+--------------------------------------+--------------------------------------------------------------------------+
| ::: {.line .number1 .index0 .alt2} | :::::::::::::: container |
| 1 | ::: {.line .number1 .index0 .alt2} |
| ::: | cd
{.bash .functions} my-node-app
{.bash .plain} |
| | ::: |
| ::: {.line .number2 .index1 .alt1} | |
| 2 | ::: {.line .number2 .index1 .alt1} |
| ::: | npm outdated
{.bash .plain} |
| | ::: |
| ::: {.line .number3 .index2 .alt2} | |
| 3 | ::: {.line .number3 .index2 .alt2} |
| ::: | Package Current Wanted Latest Location
{.bash .plain} |
| | ::: |
| ::: {.line .number4 .index3 .alt1} | |
| 4 | ::: {.line .number4 .index3 .alt1} |
| ::: | ------- ------- ------ ------ --------
{.bash .plain} |
| | ::: |
| ::: {.line .number5 .index4 .alt2} | |
| 5 | ::: {.line .number5 .index4 .alt2} |
| ::: | express 3.4.8 3.4.8 4.0.0-rc2 express
{.bash .plain} |
| | ::: |
| ::: {.line .number6 .index5 .alt1} | |
| 6 | ::: {.line .number6 .index5 .alt1} |
| ::: | jade 1.1.5 1.1.5 1.3.0 jade
{.bash .plain} |
| | ::: |
| ::: {.line .number7 .index6 .alt2} | |
| 7 | ::: {.line .number7 .index6 .alt2} |
| ::: | cors 2.1.1 2.1.1 2.2.0 cors
{.bash .plain} |
| | ::: |
| ::: {.line .number8 .index7 .alt1} | |
| 8 | ::: {.line .number8 .index7 .alt1} |
| ::: | jade 0.26.3 0.26.3 1.3.0 mocha > jade
{.bash |
| | .plain} |
| ::: {.line .number9 .index8 .alt2} | ::: |
| 9 | |
| ::: | ::: {.line .number9 .index8 .alt2} |
| | diff
{.bash |
| ::: {.line .number10 .index9 .alt1} | .functions} 1.0.7 1.0.7 1.0.8 mocha >
{.bash |
| 10 | .plain}diff
{.bash .functions} |
| ::: | ::: |
| | |
| ::: {.line .number11 .index10 .alt2} | ::: {.line .number10 .index9 .alt1} |
| 11 | glob 3.2.3 3.2.3 3.2.9 mocha > glob
{.bash |
| ::: | .plain} |
| | ::: |
| | |
| | ::: {.line .number11 .index10 .alt2} |
| | commander 2.0.0 2.0.0 2.1.0 mocha > commander
{.bash |
| | .plain} |
| | ::: |
| | :::::::::::::: |
+--------------------------------------+--------------------------------------------------------------------------+
:::
如果你工作在开源的节点app或模式上,检查david-dm{rel="nofollow" target="_blank"}、NodeICO{rel="nofollow" target="_blank"}、和shields.io{rel="nofollow" target="_blank"}这三大服务,它提供图形包,你能使用它们显示你的工程的README或者是website。
\
9、使用npm脚本运行自定义构建步骤
随着npm的发展,出现了自动开发构建过程。Grunt{rel="nofollow" target="_blank"}是迄今为止世界上最流行的构建工具,但是新工具如gulp.js{rel="nofollow" target="_blank"}和plain old npm scripts{rel="nofollow" target="_blank"}也同样吸引具有吸引力。
当你部署一个节点qpp到HeroKu上,执行npm install --production命令来确保你的app的npm 依赖包被下载和安装。这个命令有时也可以做其他的事情。它运行你在package.json文件中定义的npm script hooks{rel="nofollow" target="_blank"},例如preinstall和postintall。下面是一个例子:
::: {#highlighter_280989 .syntaxhighlighter .js}
+-------------------------------------+-------------------------------------+
| ::: {.line .number1 .index0 .alt2} | ::::::::::::: container |
| 1 | ::: {.line .number1 .index0 .alt2} |
| ::: | {
{.js .plain} |
| | ::: |
| ::: {.line .number2 .index1 .alt1} | |
| 2 | ::: {.line .number2 .index1 .alt1} |
| ::: |
{.js .spaces}"name"
{.js |
| | .string}:
{.js |
| ::: {.line .number3 .index2 .alt2} | .plain}"my-node-app"
{.js |
| 3 | .string},
{.js .plain} |
| ::: | ::: |
| | |
| ::: {.line .number4 .index3 .alt1} | ::: {.line .number3 .index2 .alt2} |
| 4 |
{.js .spaces}"version"
{.js |
| ::: | .string}:
{.js |
| | .plain}"1.2.3"
{.js |
| ::: {.line .number5 .index4 .alt2} | .string},
{.js .plain} |
| 5 | ::: |
| ::: | |
| | ::: {.line .number4 .index3 .alt1} |
| ::: {.line .number6 .index5 .alt1} |
{.js .spaces}"scripts"
{.js |
| 6 | .string}: {
{.js .plain} |
| ::: | ::: |
| | |
| ::: {.line .number7 .index6 .alt2} | ::: {.line .number5 .index4 .alt2} |
| 7 |
{.js |
| ::: | .spaces}"preinstall"
{.js |
| | .string}:
{.js |
| ::: {.line .number8 .index7 .alt1} | .plain}"echo here it comes!"
{.js |
| 8 | .string},
{.js .plain} |
| ::: | ::: |
| | |
| ::: {.line .number9 .index8 .alt2} | ::: {.line .number6 .index5 .alt1} |
| 9 |
{.js |
| ::: | .spaces}"postinstall"
{.js |
| | .string}:
{.js |
| ::: {.line .number10 .index9 .alt1} | .plain}"echo there it goes!"
{.js |
| 10 | .string},
{.js .plain} |
| ::: | ::: |
| | |
| | ::: {.line .number7 .index6 .alt2} |
| |
{.js .spaces}"start"
{.js |
| | .string}:
{.js |
| | .plain}"node index.js"
{.js |
| | .string},
{.js .plain} |
| | ::: |
| | |
| | ::: {.line .number8 .index7 .alt1} |
| |
{.js .spaces}"test"
{.js |
| | .string}:
{.js |
| | .plain}"tap test/*.js"
{.js |
| | .string} |
| | ::: |
| | |
| | ::: {.line .number9 .index8 .alt2} |
| |
{.js .spaces}}
{.js .plain} |
| | ::: |
| | |
| | ::: {.line .number10 .index9 .alt1} |
| | }
{.js .plain} |
| | ::: |
| | ::::::::::::: |
+-------------------------------------+-------------------------------------+
:::
这些脚本可以内联bash命令,或者是参考command-line executables{rel="nofollow" target="_blank"}。你也可以参考其他的npm 脚本:
::: {#highlighter_270724 .syntaxhighlighter .js}
+------------------------------------+-------------------------------------------------+
| ::: {.line .number1 .index0 .alt2} | ::::::::::: container |
| 1 | ::: {.line .number1 .index0 .alt2} |
| ::: | {
{.js .plain} |
| | ::: |
| ::: {.line .number2 .index1 .alt1} | |
| 2 | ::: {.line .number2 .index1 .alt1} |
| ::: |
{.js .spaces}"scripts"
{.js |
| | .string}: {
{.js .plain} |
| ::: {.line .number3 .index2 .alt2} | ::: |
| 3 | |
| ::: | ::: {.line .number3 .index2 .alt2} |
| |
{.js .spaces}"postinstall"
{.js |
| ::: {.line .number4 .index3 .alt1} | .string}:
{.js |
| 4 | .plain}"npm run build && npm run rejoice"
{.js |
| ::: | .string},
{.js .plain} |
| | ::: |
| ::: {.line .number5 .index4 .alt2} | |
| 5 | ::: {.line .number4 .index3 .alt1} |
| ::: |
{.js .spaces}"build"
{.js |
| | .string}:
{.js .plain}"grunt"
{.js |
| ::: {.line .number6 .index5 .alt1} | .string},
{.js .plain} |
| 6 | ::: |
| ::: | |
| | ::: {.line .number5 .index4 .alt2} |
| ::: {.line .number7 .index6 .alt2} |
{.js .spaces}"rejoice"
{.js |
| 7 | .string}:
{.js .plain}"echo yay!"
{.js |
| ::: | .string},
{.js .plain} |
| | ::: |
| ::: {.line .number8 .index7 .alt1} | |
| 8 | ::: {.line .number6 .index5 .alt1} |
| ::: |
{.js .spaces}"start"
{.js |
| | .string}:
{.js .plain}"node index.js"
{.js |
| | .string} |
| | ::: |
| | |
| | ::: {.line .number7 .index6 .alt2} |
| |
{.js .spaces}}
{.js .plain} |
| | ::: |
| | |
| | ::: {.line .number8 .index7 .alt1} |
| | }
{.js .plain} |
| | ::: |
| | ::::::::::: |
+------------------------------------+-------------------------------------------------+
:::
\
10、尝试新的东西
Harmony是ES6工作集名字,下一个ECMAScript语言的版本就是人们熟知的JavaScript。Harmony给JavaScript带来了大量的令人兴奋的功能,其中有许多在新一点的版本中已经可以使用了。
Harmony实现了许多新功能像block scoping{rel="nofollow" target="_blank"}、generators{rel="nofollow" target="_blank"}、proxies{rel="nofollow" target="_blank"}和weak maps{rel="nofollow" target="_blank"}等。
为了在你的节点app中实现新功能,尤其是一个新版本像0.11.x,在你的启动脚本中加入--harmony吧:
::: {#highlighter_675564 .syntaxhighlighter .js}
+------------------------------------+----------------------------------------+
| ::: {.line .number1 .index0 .alt2} | ::::::::::: container |
| 1 | ::: {.line .number1 .index0 .alt2} |
| ::: | {
{.js .plain} |
| | ::: |
| ::: {.line .number2 .index1 .alt1} | |
| 2 | ::: {.line .number2 .index1 .alt1} |
| ::: |
{.js .spaces}"scripts"
{.js |
| | .string}: {
{.js .plain} |
| ::: {.line .number3 .index2 .alt2} | ::: |
| 3 | |
| ::: | ::: {.line .number3 .index2 .alt2} |
| |
{.js .spaces}"start"
{.js |
| ::: {.line .number4 .index3 .alt1} | .string}:
{.js |
| 4 | .plain}"node --harmony index.js"
{.js |
| ::: | .string} |
| | ::: |
| ::: {.line .number5 .index4 .alt2} | |
| 5 | ::: {.line .number4 .index3 .alt1} |
| ::: |
{.js .spaces}},
{.js .plain} |
| | ::: |
| ::: {.line .number6 .index5 .alt1} | |
| 6 | ::: {.line .number5 .index4 .alt2} |
| ::: |
{.js .spaces}"engines"
{.js |
| | .string}: {
{.js .plain} |
| ::: {.line .number7 .index6 .alt2} | ::: |
| 7 | |
| ::: | ::: {.line .number6 .index5 .alt1} |
| |
{.js .spaces}"node"
{.js |
| ::: {.line .number8 .index7 .alt1} | .string}:
{.js .plain}"0.11.x"
{.js |
| 8 | .string} |
| ::: | ::: |
| | |
| | ::: {.line .number7 .index6 .alt2} |
| |
{.js .spaces}}
{.js .plain} |
| | ::: |
| | |
| | ::: {.line .number8 .index7 .alt1} |
| | }
{.js .plain} |
| | ::: |
| | ::::::::::: |
+------------------------------------+----------------------------------------+
:::
11、Browserify
客户端的JavaScript有一个"面条式代码"的遗留问题,但语言本身不是这样的。缺乏正当的依赖管理使得我们陷入jQuery-plugin copy-pasta这种状态长达数年。多亏了npm,我们正在进入前端复兴:npm注册的疯狂,在浏览器中模式设计的盛行是惊人的。
Browserify是一个了不起的工具,使得节点设计模式能在浏览器中工作。如果你是一个前端开发人员,browserify{rel="nofollow"
target="_blank"}可以改变你的生活。也许不是今天,也许不是明天,但就在不远的将来了。开始使用browserify{rel="nofollow"
target="_blank"}吧,查看文章{rel="nofollow"
target="_blank"}。
\
你的习惯是什么呢?
无论你是否已经在node上编程一段时间了或者是仅仅刚刚开始,都希望你找到有用的方法。如果你有什么好的note习惯要分享,用#node_habits{rel="nofollow" target="_blank"}作为标签写文章吧。happy hacking!
译者:renyuzhuo
转自:http://ourjs.com/detail/53272b83cc7e181509000003
原文:https://blog.heroku.com/archives/2014/3/11/node-habits?utm_source=nodeweekly&utm_medium=email#6-use-environment-variables-to-configure-npm&utm_source=ourjs.com