摘自 https://blog.csdn.net/u011240877/article/details/76582670#什么是-npmjavascript
npm 是前端开发普遍使用的包管理工具,以前使用 Weex 时看了阮一峰前辈的文章了解了一些,此次结合官方文章总结一下,加深下理解吧!html
读完本文你将了解:前端
官方文档中对它的介绍是:vue
npm makes it easy for JavaScript developers to share and reuse code, and it makes it easy to update the code that you’re sharing.html5
即: npm 是一个包管理器,它让 JavaScript 开发者分享、复用代码更方便(有点 maven 的感受哈)。java
在程序开发中咱们经常须要依赖别人提供的框架,写 JS 也不例外。这些能够重复的框架代码被称做包(package)或者模块(module),一个包能够是一个文件夹里放着几个文件,同时有一个叫作 package.json
的文件。node
一个网站里一般有几十甚至上百个 package,分散在各处,一般会将这些包按照各自的功能进行划分(相似咱们安卓开发中的划分子模块),可是若是重复造一些轮子,不如上传到一个公共平台,让更多的人一块儿使用、参与这个特定功能的模块。webpack
而 npm 的做用就是让咱们发布、下载一些 JS 轮子更加方便。git
咱们能够去官方网站 https://www.npmjs.com/ 浏览、搜索想要的轮子,也能够直接在命令行中 search 一下意中轮。github
使用 npm 后咱们能够很是方便地查看依赖的轮子是否有更新、是否须要下载新版本。
如今咱们知道 npm 是干什么的了。当人们提及 “npm” 时,可能在说三个东西:
只要开发者发布某个模块到仓库中,其余人就能够从 npm 网站或者命令行中下载、使用它了!
npm 是依附于 node.js 的,咱们能够去它的官网 https://nodejs.org/en/download/ 下载安装 node.js。
下载好 node.js, npm 也就有了,使用 npm -v
查看安装的 npm 版本:
zhangshixin$ node -v v6.10.0
npm 更新地可比 node 勤快多了,所以你下载的 node 附带的 npm 版本可能不是最新的,你可使用以下命令下载最新 npm:
npm install npm@latest -g
其中 install 不用介绍了,就是安装,后面的 npm@latest
就是 <packageName>@<version>
的格式,咱们在下载其余模块时也是这个格式。-g
表明全局安装。
package.json
文件很是重要,所以须要单独一小节介绍。
管理本地安装 npm 包的最好方式就是建立 package.json
文件。
一个 package.json
文件能够有如下几点做用:
使用 npm init
便可在当前目录建立一个 package.json
文件:
如图所示,输入 npm init
后会弹出一堆问题,咱们能够输入对应内容,也可使用默认值。在回答一堆问题后输入 yes
就会生成图中所示内容的 package.json
文件。
若是嫌回答这一大堆问题麻烦,能够直接输入 npm init --yes
跳过回答问题步骤,直接生成默认值的 package.json
文件:
package.json
文件至少要有两部份内容:
好比:
{
"name": "shixinzhang-demo-package", "version": "1.0.0" }
其余内容:
description
:描述信息,有助于搜索main
: 入口文件,通常都是 index.js
scripts
:支持的脚本,默认是一个空的 testkeywords
:关键字,有助于在人们使用 npm search
搜索时发现你的项目author
:做者信息license
:默认是 MITbugs
:当前项目的一些错误信息,若是有的话咱们能够为 init
命令设置一些默认值,好比:
> npm set init.author.email "shixinzhang2016@gmail.com" > npm set init.author.name "shixinzhang" > npm set init.license "MIT"
注意:
若是 package.json 中没有description
信息,npm 使用项目中的 README.md 的第一行做为描述信息。这个描述信息有助于别人搜索你的项目,所以建议好好写description
信息。
咱们须要在 package.json
文件中指定项目依赖的包,这样别人在拿到这个项目时才可使用 npm install
下载。
包有两种依赖方式:
dependencies
:在生产环境中须要用到的依赖devDependencies
:在开发、测试环境中用到的依赖举个例子:
{
"name": "my-weex-demo", "version": "1.0.0", "description": "a weex project", "main": "index.js", "scripts": { "build": "weex-builder src dist", "build_plugin": "webpack --config ./tools/webpack.config.plugin.js --color", "dev": "weex-builder src dist -w", "serve": "serve -p 8080" }, "keywords": [ "weex" ], "author": "fkysly@gmail.com", "license": "MIT", "devDependencies": { "babel-core": "^6.14.0", "babel-loader": "^6.2.5", "babel-preset-es2015": "^6.18.0", "vue-loader": "^10.0.2", "eslint": "^3.5.0", "serve": "^1.4.0", "webpack": "^1.13.2", "weex-loader": "^0.3.3", "weex-builder": "^0.2.6" }, "dependencies": { "weex-html5": "^0.3.2", "weex-components": "*" } }
https://docs.npmjs.com/getting-started/semantic-versioning
dependencies
的内容,以 "weex-html5": "^0.3.2"
为例,咱们知道 key 是依赖的包名称,value 是这个包的版本。那版本前面的 ^ 或者版本直接是一个 * 是什么意思呢?
这就是 npm 的 “Semantic versioning”,简称”Semver”,中文含义即“语义化版本规则”。
在安卓开发中咱们有过这样的经验:有时候依赖的包升级后大改版,以前提供的接口不见了,这对使用者的项目可能形成极大的影响。
所以咱们在声明对某个包的依赖时须要指明是否容许 update 到新版本,什么状况下容许更新。
这就须要先了解 npm 包提供者应该注意的版本号规范。
若是一个项目打算与别人分享,应该从 1.0.0 版本开始。之后要升级版本应该遵循如下标准:
了解了提供者的版本规范后, npm 包使用者就能够针对本身的须要填写依赖包的版本规则。
做为使用者,咱们能够在 package.json
文件中写明咱们能够接受这个包的更新程度(假设当前依赖的是 1.0.4 版本):
小结一下:总共三种版本变化类型,接受依赖包哪一种类型的更新,就把版本号准确写到前一位。
使用 npm 安装 package 有两种方式:本地(当前项目路径)安装 或者 全局安装。
你选择哪一种安装方式取决于你将如何使用这个包:
require()
加载使用,那你能够安装到本地 npm install
默认就是安装到本地的grunt
CLI,就须要安装到全局了若是在你的项目里有 package.json
文件,运行 npm install
后它会查找文件中列出的依赖包,而后下载符合语义化版本规则的版本。
npm install
默认会安装 package.json
中 dependencies
和 devDependencies
里的全部模块。
若是想只安装 dependencies
中的内容,可使用 --production
字段:
npm install --production
npm 使用下面的命令下载一个包:
npm install <package_name>
后面就是要安装包的名称。这个命令会在当前目录建立一个 node_modules
目录,而后下载咱们指定的包到这个目录中。
举个例子:
zhangshixindeMacBook-Pro:publish-pkg zhangshixin$ npm install lodash zhangshixindeMacBook-Pro:publish-pkg zhangshixin$ ls index.js package-lock.json node_modules package.json zhangshixindeMacBook-Pro:publish-pkg zhangshixin$ ls node_modules/ lodash
下载后的项目文件夹:
安装指定版本:
npm install
默认安装最新版本,若是想要安装指定版本,能够在库名称后加 @版本号
:
$ npm install sax@latest $ npm install sax@0.1.1 $ npm install sax@">=0.1.0 <0.2.0"
若是当前项目有 package.json
文件,下载包时会下载这个文件中指定的版本;
若是当前项目中没有 package.json
文件,就会下载指定包的最新版本。
有时下载会报错:
npm install error saveError ENOENT: no such file or directory, open '/Users/zhangshixin/package.json'
解决办法:
- 在目录下执行npm init
建立package.json
,输入初始化信息
- 而后再执行下载命令
--save
和 --save -dev
添加依赖时咱们能够手动修改 package.json
文件,添加或者修改 dependencies
devDependencies
中的内容便可。
另外一种更酷的方式是用命令行,在使用 npm install
时增长 --save
或者 --save -dev
后缀:
npm install <package_name> --save
表示将这个包名及对应的版本添加到 package.json
的 dependencies
npm install <package_name> --save-dev
表示将这个包名及对应的版本添加到 package.json
的 devDependencies
下载后 node_modules
文件夹中有要使用的包,咱们就可使用其中的代码了。
好比在 Node.js 项目中,咱们能够用 require(XXX)
引入它。
举个例子:
建立一个 index.js 文件,写入以下代码:
在使用 require('lodash')
后引入了 lodash 库,而后调用了它的 without()
方法,这个方法能够去除第一个数组参数中与第二个参数重复的数据。
保存这个文件后,使用 node index.js
运行这个文件,成功的话就能够获得运行结果;若是以前安装失败,可能就会遇到这个错误:
module.js:340 throw err; ^ Error: Cannot find module 'lodash'
这时你须要在这个目录下从新运行 npm install lodash
安装。
有时候咱们想知道依赖的包是否有新版本,可使用 npm outdated
查看,若是发现有的包有新版本,就可使用 npm update <package-name>
更新它,或者直接 npm update
更新全部:
上图中,咱们在输入 npm update
后发现本地的 lodash
模块还不是最新的,这是为何呢?
原来,npm update 的工做过程是这样的:
package.json
中对应的语义版本规则一开始我本地的 package.json 的依赖是这样的:
"dependencies": { "lodash": "^3.1.0" }
根据前面的介绍咱们能够知道,这表示只接受小版本或者补丁版本的更新,所以在执行了一次 npm update
后它变成了这样:
"dependencies": { "lodash": "^3.10.1" }
第二位升到了最高,可是没法更新第一位,所以没法更新到最新的 4.17.4。
因此我须要把它修改为:
"dependencies": { "lodash": "*" }
这表示任何版本的更新都接受,而后再执行 npm update
,就发现更新成功了:
小结一下:
执行 npm outdated
后能够看到有三个版本号:
第一个是当前 node_modules 中该模块的版本,第二个是 package.json
文件中声明的版本,第三个是远程仓库最新的版本。
只有当前模块版本低于远程,package.json 中的版本语义规则知足状况,才能更新成功。
卸载一个本地 package 很简单,npm uninstall <package-name>
便可:
官方文档说输入
npm uninstall --save lodash
才能在删除项目的同时移除package.json
中对它的依赖。但我没加--save
也达到了同样的效果,一脸懵逼。
卸载后再 ls node_modules/
查看目录下,发现没有东西,删除成功。
若是你想要直接在命令行中使用某个包,好比 jshint
,你能够全局安装它。
全局安装比本地安装多了个 -g
:
npm install -g <package-name>
以 jshint
为例,全局安装命令是:
npm install -g jshint
安装后可使用 npm ls -g --depth=0
查看安装在全局第一层的包。
在全局安装时可能会遇到 EACCES
权限问题,解决办法办法有以下 3 种:
1.sudo npm install -g jshint
,使用 sudo
简单粗暴,可是治标不治本
2.修改 npm 全局默认目录的权限
先获取 npm 全局目录:npm config get prefix
,通常都是 /usr/local
;
而后修改这个目录权限为当前用户:
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
3.使用其余包管理器帮你解决这个问题
实在懒得弄能够直接卸载 node,而后使用 Homebrew 重装 node:
brew install node
Homebrew 会帮咱们处理好权限的问题。
想知道哪些包须要更新,可使用 npm outdated -g --depth=0
,而后使用 npm update -g <package>
更新指定的包:
要更新全部全局包,可使用 npm update -g
,能够发现对比本地的,只是多了个 -g
。
不过官方说在 2.6.1 如下的 npm ,直接使用 npm update -g
并不安全,由于它会递归地更新全部全局依赖。
这种状况下可使用 npm-check
,贴一张它的截图:
Github 地址:https://github.com/dylang/npm-check
一句搞定:npm uninstall -g <package>
部分摘自 阮一峰的 NPM 教程
npm 还能够直接运行 package.json
中 scripts
指定的脚本:
{
"name": "demo", "scripts": { "lint": "jshint **.js", "test": "mocha test/" } }
npm run 是 npm run-script 的缩写。
命令行输入 npm run lint
或者 npm run-script lint
就会执行 jshint **.js
。
npm run
会建立一个Shell,执行指定的命令,并临时将node_modules/.bin加入PATH 变量,这意味着本地模块能够直接运行。
package.json
中的 scripts
执行的脚本是本地项目内 node_modules
-> .bin
内的脚本。
"scripts": { "build": "weex-builder src dist", "build_plugin": "webpack --config ./tools/webpack.config.plugin.js --color", "dev": "weex-builder src dist -w", "serve": "serve -p 8080" }
直接运行 npm run
会列出当前项目的 package.json
中 scripts
属性下的全部脚本命令。
npm install 也能够直接从 github 下载:
$ npm install git://github.com/package/path.git $ npm install git://github.com/package/path.git#0.1.0
npm info <package-name>
能够查看指定包的信息:
npm adduser
用于在npmjs.com注册一个用户:
$ npm adduser
Username: YOUR_USER_NAME Password: YOUR_PASSWORD Email: YOUR_EMAIL@domain.com
npm home <package-name>
命令能够打开指定模块的主页; npm repo <package-name>
命令则是打开指定模块的代码仓库。
prune 即“修剪”的意思。
npm prune
能够检查出当前项目的 node_modules
目录中,没有在 package.json
里提到的模块。
如今水平还不够,等写出能够复用的 JS 代码后,咱们就能够将它发布到 npm 仓库上,相似 Github 的提交。
这部分主要摘自阮一峰的 NPM 教程
要想发布,首先须要使用 npm adduser
向 npmjs.com
申请用户名(固然去官网也能够)。
接着使用 npm login
在命令行中登陆。
登陆之后,就可使用 npm publish
命令发布。
$ npm publish
若是当前模块是一个beta版,好比1.3.1-beta.3,那么发布的时候须要使用tag参数,将其发布到指定标签,默认的发布标签是latest。
$ npm publish --tag beta
若是发布私有模块,模块初始化的时候,须要加上scope参数。只有npm的付费用户才能发布私有模块。
$ npm init --scope=<yourscope>
若是你的模块是用ES6写的,那么发布的时候,最好转成ES5。首先,须要安装Babel。
$ npm install --save-dev babel-cli@6 babel-preset-es2015@6
而后,在package.json
里面写入build
脚本。
"scripts": { "build": "babel source --presets babel-preset-es2015 --out-dir distribution", "prepublish": "npm run build" }
运行上面的脚本,会将source目录里面的ES6源码文件,转为distribution目录里面的ES5源码文件。
不翻的话有时候 npm 比较卡,可使用国内的淘宝镜像 cnpm: https://npm.taobao.org。
cnpm
支持 npm
除了 publish
以外的全部命令。
通过这么一番总结,总算能够说 npm 入门了。
接触前端后发现这个圈子太复杂了,各类工具各类框架,眼花缭乱啊。一步一步来吧!
https://docs.npmjs.com/
http://javascript.ruanyifeng.com/nodejs/npm.html#