更换NPM源
- 终端安装
此方式为一次性使用,每次安装(或查看)都要带上--registry
选项
npm install PACKAGE_NAME --registry https://registry.npm.taobao.org
- 设置npm的配置项
此方式为设置全局的npm配置项,即使关闭终端或重启电脑都不会失效。
npm config set registry https://registry.npm.taobao.org
还有其他常用命令:
npm config list -l # 查看所有配置项
npm config get [<key>] # 查看某一项的配置信息
npm config set <key> <value> # 设置某一项的配置信息
- 使用.npmrc 文件
此方式同样为全局有效,但没有修改原始的配置项。
需要在用户目录下创建.npmrc
文件,添加如下内容:
registry = http://registry.npm.taobao.org
当你使用第2种方式修改配置项后,你会惊奇的发现,它其实与第三种相同,也会在用户目录下创建一个
.npmrc
文件。
查看配置
查看全局安装路径
npm root -g
查看npm的基础设置
npm config ls
NPM包管理
发布
- 登录官网注册账号:https://www.npmjs.com
在本地登录自己的npm账号
npm login
发布模块 ``` npm publish //返回下面的信息就是发布成功了
- xxxxx@1.0.0 ```
删除
npm unpublish xxxxx
package.json字段
name & version
package.json文件中最重要的就是name和version字段,这两项是必填的。名称和版本一起构成一个标识符,该标识符被认为是完全唯一的。对包的更改应该与对版本的更改一起进行。
其中version字段有一定规范,具体看下文“版本号规范”部分。
description & keywords
有助于人们在npm库中搜索的时候发现你的模块。
- description是一个字符串,用于编写描述信息。
- keywords是一个字符串组成的数组。
homepage & bugs
分别表示项目”主页地址”及”bug反馈方式”。
其中bugs的字段是个对象:
"bugs": {
"url" : "https://github.com/owner/project/issues",
"email" : "project@hostname.com"
}
author & contributors
author表示项目的唯一所有人,可以写成字符串,也可以写成对象。
如果是对象,包含name、email、url字段,其中name为必填。
"author": {
"name" : "xjchenhao",
"email" : "xjchenhao@xx.com",
"url" : "https://www.yuque.com/xjchenhao"
}
而contributors,表示该项目属于多个人。它的值是数组对象,对象格式同上。
license
表示当前项目的开源协议,让用户了解他们是在什么授权下使用此包,以及此包还有哪些附加限制。
各大组织设立了为代码开源许可的规范文档,当作者声明此文档类型时,他人必须遵守该文档类型的规范。一张图说解释所有:
license字段必须是以下之一:
- 如果你使用标准的许可证,需要一个有效地 SPDX 许可证标识,例如
MIT
。 - 如果你用多种标准许可证,需要有效的 SPDX 许可证表达式2.0语法表达式,比如
(MIT or GPL-3.0)
。 - 如果你使用非标准的许可证,则需要填写
SEE LICENSE IN <文件名>
其中<文件名>
指向项目顶级目录的文件。 - 如果你不想在任何条款下授权其他人使用你的私有或未公开的包,填写
UNLICENSED
字符串。
ps: 如果你开发的包是你工作的一部分,最好和公司讨论后再做决定。
files
files属性的值是一个数组,内容是模块下文件名或者文件夹名,如果是文件夹名,则文件夹下所有的文件也会被包含进来(除非文件被另一些配置排除了)
也可以在模块根目录下创建一个.npmignore
文件,写在这个文件里边的文件即便被写在files属性里边也会被排除在外,这个文件的写法与.gitignore
类似。
main
main字段指定了加载的入口文件,require导入的时候就会加载这个文件。这个字段的默认值是模块根目录下面的index.js。
bin
bin项用来指定每个内部命令对应的可执行文件的位置。如果你编写的是一个cli工具的时候一定会用到bin字段。
当我们编写一个cli工具的时候,需要指定工具的运行命令,比如常用的webpack模块,他的运行命令就是webpack。
"bin": {
"webpack": "bin/index.js",
}
当我们执行webpack命令的时候就会执行bin/index.js
文件中的代码。
在模块以依赖的方式被安装,如果存在bin选项。在node_modules/.bin/
生成对应的文件。
- 在使用
npm run <scriptName>
时,对应的script脚本会到该目录下执行该文件。 - 例如我们执行
npm run dev
,对应script脚本webpack --config webpack.dev.js
。其中webpack这个可执行命令就是对应node_modules/.bin/
下的webpack文件。 - npm会寻找这个文件,在
node_modules/.bin/
目录下建立符号链接。由于node_modules/.bin/
目录会在运行时加入系统的PATH变量,因此在运行npm时,就可以不带路径,直接通过命令来调用这些脚本。
如果我们全局安装这个依赖,则可以直接在命令行使用该cli命令。
directories
CommonJs通过directories来制定一些方法来描述模块的结构。目前用的比较少。
例如:
{
"directories": {
"bin": "./bin",
"doc": "./doc",
"lib": "./lib",
"man": "./man"
}
}
- lib:告诉用户模块中lib目录在哪,这个配置目前没有任何作用,但是对使用模块的人来说是一个很有用的信息。
- bin:如果你在这里指定了bin目录,这个配置下面的文件会被加入到bin路径下,如果你已经在package.json中配置了bin目录,那么这里的配置将不起任何作用。
- man:指定一个目录,目录里边都是man文件,这是一种配置man文件的语法糖。
- doc:在这个目录里边放一些markdown文件,可能最终有一天它们会被友好的展现出来(应该是在npm的网站上)
- example:放一些示例脚本,或许某一天会有用 - -!
repository
代码存放地址,通常开源项目会在此写上git地址,方便开发者共创。
"repository" : {
"type" : "git",
"url" : "https://github.com/npm/npm.git"
}
scripts
npm脚本定义,可以通过该字段的配置,可以统一、便捷地执行和管理cli命令,相当于cli命令的别名。
例如:
"scripts": {
"start": "webpack ./start.js"
}
则可以用npm run start
代替webpack ./start.js
。且webpack不需要全局安装,npm会从当前工程的node_modules中查找
ps:当然使用npm自带的npx,也可以做到不全局安装运行,例如
npx webpack ./start.js
。
config
用于添加命令行的环境变量。
例如:
{
"name" : "yindong",
"config" : { "port" : "8080" },
"scripts" : { "start" : "node server.js" }
}
用户可以在代码中引用config字段的值:
console.log(process.env.npm_package_config_port); // 8080
也可以通过npm config set
来修改这个值。
npm config set yindong:port 8000
dependencies & devDependencies
dependencies字段指定了项目运行所依赖的模块,devDependencies指定项目开发所需要的模块。
- 它们的值都是一个对象。该对象的各个成员,分别由模块名和对应的版本要求组成,表示依赖的模块及其版本范围。
- 当安装依赖的时候使用—save参数表示将该模块写入dependencies属性,—save-dev表示将该模块写入devDependencies属性。
其中version字段有一定规范,具体看下文“版本号规范”部分。
peerDependencies
直译过来叫“同等依赖”。通常我们安装某个npm包,这个包的依赖都会安装到它下面的node_modules
中,而通过peerDependencies
的配置,可以把依赖提取出来,与该包平级(也就是项目本身的node_modules
目录中)。
使用它有以下三种好处:
- 把一些核心依赖包做了“升级”,让项目可以直接使用,而无需安装依赖。
- 如果多个依赖包共用某个依赖,则只需要安装一次就够了,比如webpack插件统一在
peerDependencies
中配置webpack版本号的话,就不会让webpack重复在各依赖的node_modules
安装了(新版本的npm以及yarn已经解决了这个问题)。 - 在项目和子模块有相同的依赖包时,“项目使用的依赖包版本”小于“某子模块的依赖包版本”,且子模块配置了
peerDependencies
,则会被提醒升级依赖。
npm7开始,在install时会自动安装
peerDependencies
依赖,如需忽略,需在命令后面跟--legacy-peer-deps
。
engines & os & cpu
engines字段指明了该模块运行的平台,比如Node或者npm的某个版本或者浏览器。
{ "engines" : { "node" : ">=0.10.3 <0.12", "npm" : "~1.0.20" } }
os字段可以指定你的模块只能在哪个操作系统上运行
{"os" : [ "darwin", "linux", "win32" ]}
cpu字段可以限制模块只能在某种架构的cpu下运行
"cpu" : [ "x64", "ia32" ]
你也可以用黑名单代替白名单,在名字前面加上“!”就可以了,例如
{"os":["!win32"]}
private
如果这个属性被设置为true,npm将拒绝发布它,这是为了防止一个私有模块被无意间发布出去。
publishConfig
这个配置是会在模块发布时生效,用于设置发布用到的一些值的集合。如果你不想模块被默认标记为最新的,或者默认发布到公共仓库,可以在这里配置tag或仓库地址。
通常publishConfig会配合private来使用,如果你只想让模块被发布到一个特定的npm仓库,如一个内部的仓库。
"private": true,
"publishConfig": {
"tag": "1.0.0",
"registry": "https://registry.npmjs.org/",
"access": "public"
}
preferGlobal
preferGlobal的值是布尔值,可以提醒用户该包不能做全局安装。
browser
如果要在客户端使用模块,则应使用brower字段来代替main字段。
browser 的用法有以下几种:
- browser 为某一个单个的字符串,替换 main 成为浏览器环境的入口文件。例如
{"browser": "./lib/browser/main.js"}
- browser 为一个对象,声明要替换或者忽略的文件。这种形式比较适合替换部分文件,不需要创建新的入口。key 是要替换的 module 或者文件名,右侧是替换的。
"browser": {
"module-a": "./browser/module-a.js",
"./server/module-b.js": "./browser/module-b.js"
}
打包器在打包到浏览器环境时,会将来自 module-a 的替换为’./browser/module-a.js’。将文件’./server/module-b.js’ 的引入替换为’./browser/module-b.js’。
还可以使用布尔值防止将 module 加载到包中,例如下面的module-a。
"browser": {
"module-a":false,
"./server/only.js":"./shims/server-only.js"
}
需要注意的是如果你的包能在浏览器和 node 上无差异化地实现,就不需要 browser 字段了。
版本号规范
版本号组成
npm包所有的版本都由3个数字组成:x.y.z。
- 第一个数字是主版本。
- 第二个数字是次版本。
- 第三个数字是补丁版本。
版本号升级规则
当发布新的版本时,不仅仅是随心所欲地增加数字,还要遵循以下规则:
- 当进行不兼容的 API 更改时,则升级主版本。
- 当以向后兼容的方式添加功能时,则升级次版本。
- 当进行向后兼容的缺陷修复时,则升级补丁版本。
该约定在所有编程语言中均被采用,每个 npm 软件包都必须遵守该约定,这一点非常重要,因为整个系统都依赖于此。
依赖版本声明
项目根目录的package.json
中约定了该项目依赖的npm包及版本号,通过版本号前面的规则“标识”决定安装什么版本的依赖包。规则如下:
- ^: 只会执行不更改最左边非零数字的更新。 如果写入的是 ^0.13.0,则当运行 npm update 时,可以更新到 0.13.1、0.13.2 等,但不能更新到 0.14.0 或更高版本。 如果写入的是 ^1.13.0,则当运行 npm update 时,可以更新到 1.13.1、1.14.0 等,但不能更新到 2.0.0 或更高版本。~: 如果写入的是 〜0.13.0,则当运行 npm update 时,会更新到补丁版本:即 0.13.1 可以,但 0.14.0 不可以。
: 接受高于指定版本的任何版本。
=: 接受等于或高于指定版本的任何版本。
- <=: 接受等于或低于指定版本的任何版本。
- <: 接受低于指定版本的任何版本。
- =: 接受确切的版本。
- -: 接受一定范围的版本。例如:2.1.0 - 2.6.2。
- ||: 组合集合。例如 < 2.1 || > 2.6。
可以合并其中的一些符号,例如 1.0.0 || >=1.1.0 <1.2.0,即使用 1.0.0 或从 1.1.0 开始但低于 1.2.0 的版本。
还有其他的规则:
- 无符号: 仅接受指定的特定版本(例如 1.2.1)。
- latest: 使用可用的最新版本。
删除某目录下所有的依赖包
find . -name 'node_modules' -type d -prune -exec rm -rf '{}' +
效果如下👇
常见错误处理
- 假如遇到npm警告
Could not freeze
,使用命令rm -rf node_modules/.cache
参考资料:
- 你真的了解package.json吗?来看看吧,这可能是最全的package解析
- npm package.json属性详解
- 七种开源许可证
- node-npm发布包-package.json中bin的用法
- npm学习(十七)之node_modules中的bin文件夹
- 一文搞懂peerDependencies
- 探讨npm依赖管理之peerDependencies
- package.json中的browser字段
- What does npm install —legacy-peer-deps do exactly? When is it recommended / What’s a potential use case?