npm 全称为 node package manager, 即 node的包管理器。 我以为正是由于有npm 这一大生态,才有了如今node 社区的繁荣。我这篇文章会概括总结一些咱们经常使用的 npm 知识,包括npm 命令、版本管理、依赖、以及如何发布一个包。javascript
package.json 是npm包的入口, 涵盖了这个包的基本信息, 如图我在文件夹中进行 npm init
, 会让我填写如下信息: html
一个 常见的package.json 文件以下:java
{
"name": "foo",
"version": "1.0.0",
"description": "test ",
"main": "index.js",
"scripts": {
"test": "jest"
},
"dependencies": {
"ramda": "^0.25.0",
"react": "^16.0.0"
},
"repository": {
"type": "git",
"url": "test.git"
},
"keywords": [
"some",
"keywords"
],
"author": "Bob",
"license": "MIT"
}
复制代码
main
表明此包的入口文件, 当别的包进行 var foo = require ('foo')
的时候, 引用的其实就是这个main
字段表明的index.js
文件scripts
表明 在这个npm包中运行的命令dependencies
表明这个npm 包依赖的包, 当 npm install foo
的时候,会将这个包的依赖包也一块儿安装一个npm包从诞生开始,代码库会不断地迭代,developer可能会不断地添加新功能、增长新特性、修改bug等,那么这个包的版本也会不断变化, 如何比较好的管理(迭代)一个包的版本呢? 咱们能够参考react的CHANGELOG 咱们能够用 npm version
命令, 而不是手动地去更改 package.json
文件。经常使用的命令以下:node
官方: npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]
react
假如当前包的版本号是1.0.5
jquery
npm version 1.0.5-beta17 "version": "1.0.5" => "version": "1.0.5-beta17"
webpack
明确指定须要更新到的版本号, 开发阶段,通常用alpha, beta, rcgit
npm version prerelease "version": "1.0.5" => "version": "1.0.5-2"
github
基于如今版本的先行版本web
npm version patch "version": "1.0.5" => "version": "1.0.6"
Fix bug, 小改动 ,仍向后兼容
npm version minor "version": "1.0.5" => "version": "1.1.0"
增长新特性,仍向后兼容
npm version major "version": "1.0.5" => "version": "2.0.0"
大改动,大版本,没法向后兼容
npm version premajor "version": "1.0.5" => "version": "v2.0.0-0"
大改动,大版本的先行版本,没法向后兼容
全部的 npm version pre(xxx)
命令都会是一个先行版本, 会在版本号后面 多出 -n
,表明这不是一个正式版本.
~
与^
表明什么?
咱们 常会在代码中看到这样一段:
"ramda": "^0.25.0",
"react": "~16.0.0"
复制代码
~
表明 你在项目中更新包(npm update)的时候, 能够更新到最新的一个 patch版本 即 从 0.25.0 => 0.25.x
,但不包括 0.26.x
^
表明 你在项目中更新包(npm update)的时候, 能够更新到最新的一个 minor版本 即 从 16.0.0 => 16.x.x
,但不包括 17.x.x
通常咱们用npm 的话, 直接npm i packageName 这样就能够直接安装最新的包了, npm update用的比较少,不如直接npm install 来的方便。 yarn 除外, yarn 须要本身 yarn upgrade packageName@x.x.x 这样。
因为国外的服务器访问速度可能比较慢,有时候咱们须要访问镜像源,这时候咱们可使用 cnpm 或者设置国内的镜像源
npm config -h
)registry "http://npm.xxx.com/"
npm info packageName 查看指定包的发版信息, 通常我用它来查看此包的最新发版记录
激动人心的时刻!若是想发布一个包到 npm 上,那么按照以下步骤进行操做
npm publish --tag beta (若是当前包是一个beta版)
注意: 不能发布npm中已经存在的包
当咱们在发包前须要进行本地测试的时候,每每须要 npm link 进行管理包测试
相关连接:
javascript.ruanyifeng.com/nodejs/npm.…
使用步骤:
在须要关联的包(好比packageName)文件夹内执行 sudo npm link 而后会显示:
/usr/local/lib/node_modules/packageName -> /Users/shaoqianfei/Desktop/work/packageName
而后在须要用到此包的项目中执行 npm link packageName 而后显示
added 1 package in 0.756s
/Users/shaoqianfei/Desktop/test-sth/node_modules/packageName -> /usr/local/lib/node_modules/packageName
复制代码
删除
若是须要删除关联 能够在项目目录内使用npm unlink
命令
有一些坑:
若是在outer
包目录(此包有package.json)下面有两个包package1 和package2,在package2 目录下执行 npm link
命令,则会link outer 这个包 , 而不是package2:heavy_exclamation_mark: (它会link最外层包)
解决办法,先把最外层的package.json改成 package.json-xxx, 而后在内层包进行npm link, 而后再改回原来名字。若是link有改动,须要从新npm start.不然缓存的是原来的文件 (或者尝试先将 import 语句注释掉,而后再import来解决)
devDependencies也会被打包
我 从网上 看到, 大多数人都说 dependencies与devDependencies的区别是: 前者是生产环境须要的,好比 react , lodash , 后者是 开发环境才须要的,好比 babel, eslint,jest
等等。还有人说:"若是安装到 devDependencies 则 npm run build
打包的时候,不会打包到最终的文件中去,上到生产环境会报错(好比 lodash安装到devDependencies中)".
然而,我亲自试了一下,将jquery包安装到 devDependencies, 而后
import $ from "jquery" // 固然此处是须要import 或者 require jquery的,否则jquery不会被打包
console.log("上午11:06:36", $, $('body'))
复制代码
不管是在开发环境, 仍是打包完成以后到生产环境(用的http-server跑build文件夹)都是 ok 的, 结果都能正常显示以下:
上午11:06:36 ƒ (e,t){return new Ee.fn.init(e,t)} Ee.fn.init [body, prevObject: Ee.fn.init(1)]
复制代码
而且 我在 打包以后的js文件中搜素 jquery
也能搜索到. 这说明 ~即使是~, devDependencies的包且被引用的状况下也会被打包到生产环境中,并不会报错, 网上的说法是错误的,把npm包 装到devDependencies 能减少最终打包的体积也是错误的devDependencies
的包也会被打包到生产环境
https://mp.weixin.qq.com/s/i_Zxaie1xMALymQ-1Jqz_Q 此文章说 把npm包 装到devDependencies 能减少最终打包的体积
项目使用
而且,我看我如今的项目 babel eslint husky
是放在 devDependencies
中的,然而在 create-react-app使用上, npm run eject
以后, 能看到 babel,eslint, react
等都是放在 dependencies中的, 说明其实放到dependencies 和 devDependencies 区别只是 让开发者可以辨别 哪些是包主要是用于开发的时候,哪些是不管如何都须要的很重要的包。
~两者最终都会打包的。~ 被引用(import/require)的包会被打包,没被引用的包或者只是和开发环境相关的包不会被打包如: webpack, eslint
等不会被打包。
npm 生态很大, 本文只是介绍了一些 基本使用, 还有不少东西须要去探索。好比为了更好的开发体验,可使用 nrm 进行 registry 的管理, nodemon进行应用开发, 使用pm2进行nodejs进程管理等等。
www.ruanyifeng.com/blog/2016/1…