在使用npm、yarn等包管理工具之前,我们首先了解一些基本的概念
模块(module)
通常以单个文件形式存在的功能片段,入口文件通常称之为入口模块或主模块
库(library,简称lib)
以一个或多个模块组成的完整功能块,为开发中某一方面的问题提供完整的解决方案
包(package)
包含元数据的库,这些元数据包括:名称、描述、git主页、许可证协议、作者、依赖等等
版本号:主版本号.次版本号.补丁版本号
规范:
常见语义版本符号书写含义(了解即可):
符号 | 描述 | 示例 | 示例描述 |
---|---|---|---|
> | 大于某个版本 | >1.2.1 | 大于1.2.1版本 |
>= | 大于等于某个版本 | >=1.2.1 | 大于等于1.2.1版本 |
< | 小于某个版本 | <1.2.1 | 小于1.2.1版本 |
<= | 小于等于某个版本 | <=1.2.1 | 小于等于1.2.1版本 |
- | 介于两个版本之间 | 1.2.1 - 1.4.5 | 介于1.2.1和1.4.5之间 |
x | 不固定的版本号 | 1.3.x | 只要保证主版本号是1,次版本号是3即可 |
~ | 补丁版本号可增 | ~1.3.4 | 保证主版本号是1,次版本号是3,补丁版本号大于等于4 |
^ | 此版本和补丁版本可增 | ^1.3.4 | 保证主版本号是1,次版本号可以大于等于3,补丁版本号可以大于等于4 |
* | 最新版本 | * | 始终安装最新版本 |
下面才是正题!
npm
全称为 node package manager,即 node
包管理器,它运行在 node
环境中,让开发者可以用简单的方式完成包的查找、安装、更新、卸载、上传等操作。几乎可以这样认为,前端所有的包管理器都是基于 npm
的,目前,npm
即是一个包管理器,也是其他包管理的基石。
官网:https://www.npmjs.com/
这个网址非常常用,因为以后的常用插件都是在官网中查找,查看使用方法
因为node中自带npm,所以我们直接下载安装nodejs即可
npm下载完成后需要将registry
改为国内地址,因为 npm
的官方 registry
服务器位于国外,可能受网速影响导致下载缓慢或失败。目前,淘宝提供了国内的 registry
地址,先设置到该地址。
npm config set registry https://registry.npm.taobao.org
设置完成后下面命令查看
npm config get registry
npm 安装一个包,分为两种安装方式:
npm install 包名
//会将包安装到生产环境,下面解释
注意:
node_modules
目录中node_modules
目录会变得异常庞大,目录下的内容不适合直接传输到生产环境,因此通常使用.gitignore
文件忽略该目录中的内容。CLI
,npm
会将它的 CLI
脚本文件放置到node_modules/.bin
下,使用命令npx 命令名
即可调用npm install --global 包名
注意:
npm config get prefix
npm 将每个使用 npm 的工程本身都看作是一个包,包的信息是通过package.json
配置文件来描述的。
可以手动创建该文件,而更多的时候,是通过命令创建的
npm init
//npm init 命令生成的配置文件
{
"name": "npm-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
配置文件中可以描述大量的信息,包括:
name: 包的名称,该名称必须是**英文单词字符**,支持连接符
version: 版本号
description: 包的描述
homepage: 官网地址
author: 包的作者,必须是有效的 npm 账户名,书写规范是account <mail>,不正确的账号和邮箱可能导致发布包时失败。例如 zhangsan<zhangsan@gmail.com>,
repository: {//包的仓储地址,通常指 git 或 svn 的地址,它是一个对象
type: 仓储类型,git 或 svn
url: 地址
}
main: 包的入口文件,使用包的人默认从该入口文件导入包的内容
keywords: 搜索关键字,发布包后,可以通过该数组中的关键字搜索到包
通常情况下,都是一路回车,或者可以使用命令自动默认填充
npm init --yes
npm init -y
npm 在安装包的时候,会自动生成一个 package-lock.json 文件,该文件记录了安装包时的确切依赖关系。当移植工程时,如果移植了 package-lock.json 文件,恢复安装时,会按照 package-lock.json 文件中的确切依赖进行安装,最大限度的避免了差异。
package.json文件最重要的作用,是记录当前工程的依赖
配置好依赖后,使用下面的命令即可安装依赖
安装所有依赖 dependencies + devDependencies
npm install
npm i
dependencies
npm install --production
为了更加方便的添加依赖,npm支持在使用install命令时,加入一些额外的参数,用于将安装的依赖包保存到package.json文件中。涉及的命令如下
npm i 包名
npm i --save 包名
npm i -S 包名
npm i --save-dev 包名
npm i -D 包名
补充:如果同一个工程下的两个包A、B同时依赖不同版本的包C,如图所示:
面对这种情况,在 node_modules 目录中,不会使用扁平的目录结构,而会形成嵌套的目录,如下图:
├── node_modules
│ ├── a
│ │ ├── node_modules
│ │ │ ├── c
│ │ │ | |—— c包的文件
│ │ │── a包的文件
│ ├── b
│ │ ├── node_modules
│ │ │ ├── c
│ │ │ | |—— c包的文件
│ │ │── b包的文件
npm 非常贴心的支持了脚本,只需要在 package.json 中配置 scripts 字段,即可配置各种脚本名称。之后,我们就可以运行简单的指令来完成各种操作了。运行方式是:
npm run 脚本名称
npm run build //运行webpack 进行打包
//------package.json文件内容-------
{
"name": "npm-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "npx webpack" //脚本 npx可以省略
},
"author": "",
"license": "ISC"
}
注意:npm简化了以下三个的脚本运行,不需要run指令(npm start|npm stop|npm test
)
补充:
npx
node server.js
有的时候,我们可能需要在 node 代码中根据不同的环境(生产环境、开发环境、测试环境)做出不同的处理。
那么如何让node知道自己当前处于什么环境是非常重要的。
node中有一个全局变量 global
(可以类比浏览器环境的window
),该变量是一个对象,对象中的所有属性均可以直接使用。global
有一个属性是process
,该属性是一个对象,包含了当前运行node
程序的计算机的很多信息,其中有一个信息是env
,是一个对象,包含了计算机中所有的系统变量。我们通过系统变量 NODE_ENV
的值,来判定当前处于一个什么环境
直接在运行命令中添加
NODE_ENV=development|production|test
在package.json文件中配置
{
"name": "npm-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "cross-env NODE_ENV=development node index.js",
"build": "cross-env NODE_ENV=production node index.js",
"test": "cross-env NODE_ENV=test node index.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"cross-env": "^6.0.3"
}
}
为了避免不同系统的设置方式的差异,可以使用第三方库 cross-env 对环境变量进行设置
有的时候,我们可能在 package.json 中配置一些自定义的字段,这些字段需要在node中读取
在node 中,可以直接导入一个json格式的文件,它会自动将其转换为js对象
/*----------------index.js文件内容------------*/
//读取package.json文件中的版本号
var config = require("./package.json")
console.log(config.version) //"1.0.0"
console.log(config.a) //123
/*-----------package.json文件内容--------------*/
{
"name": "npm-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"a":123
}
总结上面的命令,以及上面没有的命令,都是干货!
[]
是什么意思,它是表示可选选项npm init [-y|-yes]
npm install --global package-name
## global aliases: g
## install aliases: i
## global可以用别名g代替,install可以用别名i代替
dependencies + devDependencies
npm install
dependencies
npm install --production
npm install package-name
npm install --save package-name
## --save aliases: -S
## package-name:你要安装的包名
npm install --save-dev package-name
## --save-dev aliases: -D
npm install --save-exact package-name
## --save-exact aliases: -E
npm install 包名@版本号
[]
的含义是可选信息npm root [-g]
npm view 包名 [子信息]
## view aliases:v info show
npm list [-g] [--depth=依赖深度]
## list aliases: ls la ll
npm outdated
npm update [-g] [包名]
## update aliases(别名):up、upgrade
npm install -g npm
npm unpdate -g npm
npm uninstall [-g] 包名
## uninstall aliases(别名): remove, rm, r, un, unlink
注意:npm有两个配置文件,一个是用户配置,一个是系统配置。当两个文件的配置项有冲突的时候,用户配置会覆盖系统配置
npm config get prefix
npm config ls [-l] [--json]
npm config get 配置项
npm config set 配置项=值
npm config delete 配置项
nodejs
对 npm
支持非常良好。当使用 nodejs
导入模块时,如果模块路径不是以 ./
或 ../
开头,则 nodejs
会认为导入的模块来自于 node_modules
目录,例如:
const _ = require("lodash");
它首先会从当前目录的以下位置寻找文件
node_modules/lodash.js
node_modules/lodash/入口文件
若当前目录没有这样的文件,则会回溯到上级目录按照同样的方式查找。如果到顶级目录都无法找到文件,则抛出错误。
当找到该文件后会按照以下方式寻找入口文件:
yarn 是由Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具,它仍然使用 npm 的registry,不过提供了全新 CLI 来对包进行管理
yarn 官网:https://www.yarnpkg.com/zh-Hans/
在过去npm具有很多缺点,比如依赖目录嵌套太深遍历问题,npm是串行下载的下载速度慢等等问题,于是就有了yarn,yarn具有以下优点:
- 使用扁平的目录结构
- 并行下载
- 使用本地缓存
- 控制台仅输出关键信息
- 使用yanr-lock文件记录确切依赖
- 增加了某些功能强大的命令
- 让既有的命令更加语义化
- 本地安装的CLI工具可以使用 yarn 直接启动
- 将全局安装的目录当作一个普通的工程,生成package.json文件,便于全局安装移植
npm6 之后,可以说npm已经和yarn非常接近,甚至没有差距了。很多新的项目,又重新从yarn转回到npm。
下载安装yarn:前提是你要先下载nodejs和npm
npm install -g yarn
查看yarn版本
yarn --version
yarn的使用和npm几乎一致。
yarn init [--yes/-y]
yarn install []
yarn install --production
# production aliases: prod
global
是否全局安装)yarn [global] add package-name
yarn add package-name --dev
yarn [global] bin
yarn info 包名 [子字段]
yarn [global] list [--depth=依赖深度]
注意:yarn的list命令和npm的list不同,yarn输出的信息更加丰富,包括顶级目录结构、每个包的依赖版本号
yarn outdated
yarn [global] upgrade [包名]
yarn remove 包名
yarn run 脚本名
yarn run CLI名
yarn check
:可以验证package.json文件的依赖记录和lock文件是否一致。防止篡改yarn audit
:可以检查本地安装的包有哪些已知漏洞,以表格的形式列出,漏洞级别分为以下几种:yarn why 包名
:可以在控制台打印出为什么安装了这个包,哪些包会用到它yarn create xxx
:使用脚手架搭建一个工程。例如:yarn create react-app my-app
# 等同于下面的两条命令
yarn global add create-react-app
create-react-app my-app
为解决国内用户连接npm registry缓慢的问题,淘宝搭建了自己的registry,即淘宝npm镜像源。
官网地址:https://npm.taobao.org/
但是现在并没有什么卵用了,因为npm已经支持修改registry了
nvm并非包管理器,它是用于管理多个node版本的工具。在实际的开发中,可能会出现多个项目分别使用的是不同的node版本,在这种场景下,管理不同的node版本就显得尤为重要。nvm就是用于切换版本的一个工具
最新版下载地址:https://github.com/coreybutler/nvm-windows/releases
下载nvm-setup.zip后,直接安装。以下命令判断是否安装成功
nvm -v
nvm list
# node版本号的星号是当前正在使用的node
nvm use
nvm install
nvm uninstall
node淘宝镜像:https://npm.taobao.org/mirrors/node/
npm淘宝镜像:https://npm.taobao.org/mirrors/npm/
nvm node_mirror https://npm.taobao.org/mirrors/node/
nvm npm_mirror https://npm.taobao.org/mirrors/npm/