js nodejs npm之间的关系+npm安装备忘

一、js nodejs npm 的关系

前端Javascript与Nodejs的异同
nodeJs和JavaScript的异同
nodejs和npm关系

前端的JavaScript其实是由ECMAScript、DOM、BOM组合而成。

JavaScript:

  • ECMAScript(语言基础,如:语法、数据类型结构以及一些内置对象)
  • DOM(一些操作页面元素的方法)
  • BOM(一些操作浏览器的方法)
    上面是JavaScript的组成部分,那么Nodejs呢?

Nodejs:

  • ECMAScript(语言基础,如:语法、数据类型结构以及一些内置对象)
  • os(操作系统)
  • file(文件系统)
  • net(网络系统)
  • database(数据库)

分析:很容易看出,前端和后端的js相同点就是,他们的语言基础都是ECMAScript,只是他们所扩展的东西不同,前端需要操作页面元素,于是扩展了DOM,也需要操作浏览器,于是就扩展了BOM。而服务端的js则也是基于ECMAScript扩展出了服务端所需要的一些API,稍微了解后台的童鞋肯定知道,后台语音有操作系统的能力,于是扩展os,需要有操作文件的能力,于是扩展出file文件系统、需要操作网络,于是扩展出net网络系统,需要操作数据,于是要扩展出database的能力。

引用大神的总结:
其实npm是nodejs的包管理器(package manager)。我们在node.js上开发时,会用到很多别人已经写好的javascript代码,如果每当我们需要别人的代码时,都根据名字搜索一下,下载源码,解压,再使用,会非常麻烦。于是就出现了包管理器npm。大家把自己写好的源码上传到npm官网上,如果要用某个或某些个,直接通过npm安装就可以了,不用管那个源码在哪里。并且如果我们要使用模块A,而模块A又依赖模块B,模块B又依赖模块C和D,此时npm会根据依赖关系,把所有依赖的包都下载下来并且管理起来。试想如果这些工作全靠我们自己去完成会多么麻烦!

二、npm安装

参考
玩转npm
gulp详细入门教程

1.先正确的安装nodejs
打开nodejs官网,点击硕大的绿色Download按钮,它会根据系统信息选择对应版本(.msi文件)。然后像安装QQ一样安装它就可以了(安装路径随意)。
注意,如果两台机器安装的node版本如果不一致,会造成脚本生成的文件不一致,然后Svn对比起来很麻烦。多成员合作时,每个人生成的文件都不一样,提交起来冲突不断,更烦。
使用node -v可以看到当前的node.js版本。比如我的是v6.11.2,然后去http://nodejs.org/dist/,找到node-v6.11.2-x64.msi这个文件下载即可。关于多版本,可以参考【nodejs那些事儿】Nodejs && npm超灵活安装 -- Windows篇
也可以都更新到最新版本,参考windows 下更新 npm 和 node

2.npm init
说到npm就不得不说package.json,每一个npm包都必须有一个package.json文件,年轻时候的我还傻乎乎的从其他地方拷贝package.json过来然后修改,为了自动化还写了个自动生成的脚本。后来才发现原来npm自带此功能,官方原厂功能更好更强大,只需要执行npm init即可,以交互方式完成package.json的创建。
关于package.json可参考 对package.json的理解和学习

3.npm install
作为npm最重要的功能和最常用的功能,不用过多说明,这里只介绍三个非常有用的选项–global,–save,–save-dev。想必读者肯定知道–global可以简写成-g,其实另外两个选项也有简写形式,–save可以简写成-S,–save-dev可以简写成-D,注意大写。

以下参考《Node.js开发指南 ByVoid》Page42
全局和本地,参考【原】nodejs全局安装和本地安装的区别
为什么要使用全局模式呢?多数时候并不是因为许多程序都有可能用到它,为了减少多重副本而使用全局模式,而是因为本地模式不会注册 PATH 环境变量。举例说明,我们安装supervisor 是为了在命令行中运行它,譬如直接运行 supervisor script.js,这时就需要在 PATH环境变量中注册 supervisor。npm 本地模式仅仅是把包安装到 node_modules 子目录下,其中的 bin 目录没有包含在 PATH 环境变量中,不能直接在命令行中调用。而当我们使用全局模式安装时,npm 会将包安装到系统目录,譬如 /usr/local/lib/node_modules/,同时 package.json 文件中 bin 字段包含的文件会被链接到 /usr/local/bin/。/usr/local/bin/ 是在 PATH 环境变量中默认定义的,因此就可以直接在命令行中运行 supervisor script.js 命令了。

每一次的更新可能带来不一样的功能,在多人合作、发布模块到npmjs社区、上传到github给其他人使用时,保留模块的版本信息可用于下载指定的版本号显得特别重要。本地安装可以让每个项目拥有独立的包,不受全局包的影响,方便项目的移动、复制、打包等,保证不同版本包之间的相互依赖,这些优点是全局安装难以做到的。另外,据node团队介绍,本地安装包对于项目的加载会更快。有优点也少不了缺点,如每次新项目都要本地安装所依赖的包,安装包时间相对较长,一来是包太大导致下载慢;二是浪费了硬盘空间,不过现在电脑硬盘动不动就几个T,你还会在意节省这点空间吗?

总而言之,当我们要把某个包作为工程运行时的一部分时,通过本地模式获取,如果要在命令行下使用,则使用全局模式安装。

–save的作用是在packaje.json的dependencies字段增加或者修改一个安装包和版本号名值对,–save-dev则是修改devDependencies
参考纠结应该是把包放在devDependencies还是dependencies?

dependencies就是你程序跑起来需要的模块,没有这个模块你程序就会报错。
devDependencies见命知意了,开发程序的时候需要的模块了。
举个例子,你用angularjs框架开发一个程序,开发阶段需要用到gulp来构建你的开发和本地运行环境。所以angularjs一定要放到dependencies里,因为以后程序到生产环境也要用。gulp则是你用来压缩代码,打包等需要的工具,程序实际运行的时候并不需要,所以放到dev里就ok了。
再深入一些,你写程序要用ES6标准,浏览器并不完全支持,所以你要用到babel来转换代码。程序里有消息提示,你想用toaster。同样一个开发用,一个运行用。所以babel放dev,toaster放dependencies。

4.选装cnpm
说明:因为npm安装插件是从国外服务器下载,受网络影响大,可能出现异常,如果npm的服务器在中国就好了,所以我们乐于分享的淘宝团队干了这事。来自官网:“这是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。”;官方网址:http://npm.taobao.org
安装:命令提示符执行npm install cnpm -g --registry=https://registry.npm.taobao.org; 注意:安装完后最好查看其版本号cnpm -v或关闭命令提示符重新打开,安装完直接使用有可能会出现错误;
注:cnpm跟npm用法完全一致,只是在执行命令时将npm改为cnpm(以下操作将以cnpm代替npm)。

5.如何知道是不是安装了某个包
参考查看使用 npm 安装插件的版本号,如何知道是否安装了某个插件:

在node_modules同级路径下运行npm list

6.npm查看全局安装过的包
在使用node的时候,用npm安装了很多软件,过一段时间没有使用就会忘记,怎么查看自己全局安装过的包,用命令
npm list -g --depth 0

image.png

7.npm-check
参考
npm模块管理进阶 — npm-check + cnpm 构建包更新环境
在中国,安装 & 升级 npm 依赖的正确方法
npm 是node下的包管理工具,给我们提供了强大的包管理功能,简化了项目的代码部署过程。但是,npm也不是尽善尽美,批量更新时便很捉急。npm-check便应运而生。npm-check是一个npm包更新工具。它还可以检查项目的npm依赖包是否有更新,缺失,错误以及未使用等情况。其几大主要优势如下:

  • 提供图形化界面,还有emoji,点个赞(不用对着黑白界面简直良心啊!我也想用emoji写啊!:-))
  • 批量更新依赖包,还兼职检测包使用情况
  • 项目下更新支持自动检测包的 "dependencies" 和"devDependencies"并更新"package.json"信息 !

npm install -g npm-check安装完成后,使用npm-check -g

image.png

-u, --update       显示一个交互式UI,用于选择要更新的模块,并自动更新"package.json"内包版本号信息
-g, --global       检查全局下的包
-s, --skip-unused  忽略对未使用包的更新检查
-p, --production   忽略对"devDependencies"下的包的检查
-d, --dev-only     忽略对"dependencies"下的包的检查
-i, --ignore       忽略对指定包的检查.
-E, --save-exact   将确切的包版本存至"package.json"(注意,此命令将存储'x.y.z'而不是'^x.y.z')
8.Node.js中package.json中库的版本号详解(^和~区别)
"dependencies": {
    "bluebird": "^3.3.4",
    "body-parser": "~1.15.2"
  }

当我们使用最新的Node运行‘npm instal --save xxx',的时候,他会优先考虑使用插入符号(^)而不是波浪符号(~)了。

这对于你来说意味这什么呢?首先我们需要理解这两者(~和^)的区别。

波浪符号(~):他会更新到当前minor version(也就是中间的那位数字)中最新的版本。放到我们的例子中就是:body-parser:~1.15.2,这个库会去匹配更新到1.15.x的最新版本,如果出了一个新的版本为1.16.0,则不会自动升级。波浪符号是曾经npm安装时候的默认符号,现在已经变为了插入符号。
插入符号(^):这个符号就显得非常的灵活了,他将会把当前库的版本更新到当前major version(也就是第一位数字)中最新的版本。放到我们的例子中就是:bluebird:^3.3.4,这个库会去匹配3.x.x中最新的版本,但是他不会自动更新到4.0.0。
总结一下:

~1.15.2 :=  >=1.15.2 <1.16.0     

^3.3.4 := >=3.3.4 <4.0.0

最后解释下之前提到的minor verision和major version:

1.15.2对应就是MAJOR,MINOR.PATCH:1是marjor version;15是minor version;2是patch version。

MAJOR:这个版本号变化了表示有了一个不可以和上个版本兼容的大更改。

MINOR:这个版本号变化了表示有了增加了新的功能,并且可以向后兼容。

PATCH:这个版本号变化了表示修复了bug,并且可以向后兼容。

因为major version变化表示可能会影响之前版本的兼容性,所以无论是波浪符号还是插入符号都不会自动去修改major version,因为这可能导致程序crush,可能需要手动修改代码。

推荐阅读更多精彩内容

  • Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 众所周知,在Netscape设计出JavaScri...
    w_zhuan阅读 2,996评论 2 40
  • Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 众所周知,在Netscape设计出JavaScri...
    Myselfyan阅读 3,465评论 2 57
  • ## 前端开发的工具 ### 编辑器: 1. 轻量级的,依靠插件:sublime;atom(github);vs ...
    浪流儿阅读 2,170评论 0 2
  • 1233
    219d40f98c3a阅读 78评论 0 0
  • 与你相遇好幸运。 世界很大,大到分离就再也不会遇见彼此,世界很小,小到你记得的还是初中时候的那个我。 我同学的老公...
    w尺素寸心阅读 82评论 0 0