blog
blog copied to clipboard
看来不应该全局安装 Node.js 模块
最近我在项目里用到了 David,它能分析你的项目的第三方依赖是否都是最新版,正好最近 Babel 发布了 6.0 版,David 就帮我监测到了,真的非常方便。
我是一个很喜欢追求“最新版”的人,APP、代码、操作系统等都希望用上最新的,因为我认为,最新的总是最好的,会提供新功能、修复 bug 等。这次 Babel 从 5.0 升级到 6.0,最大的改动就是将以往集成的一堆插件全部分开成了一个个小的模块了,使用者需要自行制定要用到哪些插件。
那么问题来了:我已经全局安装了 babel v5.x,如果我升级了 babel ,那么其他依赖 babel 的项目我也要重新配置一遍;但我(和其他大多数人,应该也包括你)认为,别说是项目了,现在连代码都提倡“模块化”——每个代码文件都应该是独立的整体,可是我现在连项目之间都相互“依赖”了;想想看,若你参与两个项目的开发,一个需要全局安装 Babel 5.x,另一个是新项目,用的是 Babel 6.x,那你怎么办,开两个虚拟机吗?
这让我反思出一个道理——我们不应该使用 npm install -g。
这样的话,每个项目都可以有不同版本的 Karma、Babel、gulp、Grunt等;在给项目写说明文件的时候,也不需要额外提示一句“需要先全局安装 balabalabalabala”——因为所有需要的文件都在 package.json 里,所以简单的告诉用户 npm install 就行了。
但是,我担心如果这些模块不全局安装的话会无法使用。可是是我多虑了,npm 早已为我们考虑到了这一点。以 npm i babel-cli --save-dev 为例,我发现项目的 node_modules 文件夹下有一个 .bin/babel.cmd 文件,然后我在 package.json 里定义了一个 script:
{
"scripts":{
"version": "babel -V"
}
}
运行 num run version,我发现输出的版本号是 6.1.1 (babel-core 6.0.20),而不是我全局安装的 5.x 版的 Babel。
另外,npm run 可以带参数,例如如果我需要运行 bower install jquery --save,我可以这么做:
{
"scripts":{
"bower":"bower"
},
"devDependencies":{
"bower":"^1.6.0"
}
}
然后 npm run bower install jquery -- --save,注意中间使用了 -- 来分隔命令与参数!
这样一来,前面提到的 David 就能监听这些原本没有列在 package.json 里的模块的版本是否有更新,项目与项目之间也能真正做到相互独立了!
对于使用 WebStorm 的开发者,则可以将 Bower 执行脚本的位置指向项目下的 node_modules/.bin/bower.cmd(Mac 用户则需要将脚本位置直接指向 node_modules/bower/bin/bower,其它可执行模块也是一样的)。顺便说一句,我已经升级到 WebStorm 11 了 ;)
看,将全局模块安装到项目本地一点难度也没有,还能解除项目(或者说开发环境)之间的依赖、独立升级,何乐而不为呢?