16-手写Node模块系统-将自定义本地包和全局包发布到npm
如何把自定义的nodejs模块发布到npm
平常在nodejs、vue、react的开发过程中,经常会使用到这样的命令 npm install xxx --save,从npm下载安装模块到本地。
那么问题来了,这些模块是怎么上传的呢,自己可不可以编写一个模块上传到npm,供其他人下载的呢。
肯定是可以的。
一、npm本地包发布
实现步骤:
创建自己的npm包
- 创建一个test的文件夹作为根目录, 在这个文件夹下再创建一个node_modules文件夹(包都放在这个文件夹中), node_modules是固定名字,不能改为其他名字。
- 在node_modules文件夹下创建我们的包文件夹, 我这里命名为my-local-test.
【注意】包的名称,必须是唯一的; 一般由小写英文字母、数字和下划线组成,不能包含空格
PS: 想知道自己设定的包名有没有和其他人重名, 可以到 npm官网 查询 - 在my-local-test文件夹下打开cmd输入
npm init -y
初始化包, 会生成一个下面这样的package.json文件
{
"name": "my-local-test", // 包的名称
"version": "1.0.0", // 版本号
"description": "", // 包的简要说明
"main": "index.js", // 包入口js文件
"scripts": { // 定义脚本命令
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [], // 关键字数组,通常用于搜索
"author": "", // 作者
"license": "ISC" // 开源协议
}
4.配置package.json文件
{
"name": "my-local-test",
"version": "1.0.0",
"description": "This is a test.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": ["my", "local", "test"],
"author": "jason_liang",
"license": "ISC"
}
5.在my-local-test文件夹下创建一个index.js文件, 并定义模块
index.js
let str = "This is my first NPM project";
exports.res = str; // 暴露出去给外界使用
【注意】
- 如果没有配置main, 默认会将index.js作为入口
如果包中没有index.js或者你的入口文件不是index.js, 那么就必须配置main的值为你的入口文件, 否则会报错 - 通过scripts可以帮我们记住指令, 然后通过
npm run xxx
方式就可以执行该指令
如果指令的名称叫做start或者test, 那么执行的时候可以不加run
包的规范
- package.json必须在包的顶层目录下
- 二进制文件应该在bin目录下
- JavaScript代码应该在lib目录下
- 文档应该在doc目录下
- 单元测试应该在test目录下
package.json字段分析
- name:包的名称,必须是唯一的,由小写英文字母、数字和下划线组成,不能包含空格
- description:包的简要说明
- private: 值为true代表我们的包是私有的
- version:符合语义化版本识别规范的版本字符串
- 主版本号:当你做了不兼容的 API 修改
- 子版本号:当你做了向下兼容的功能性新增
- 修订号:当你做了向下兼容的问题修正
- keywords:关键字数组,通常用于搜索
- maintainers:维护者数组,每个元素要包含name、email(可选)、web(可选)字段
- contributors:贡献者数组,格式与maintainers相同。包的作者应该是贡献者数组的第一- 个元素
- bugs:提交bug的地址,可以是网站或者电子邮件地址
- licenses:许可证数组,每个元素要包含type(许可证名称)和url(链接到许可证文本的- 地址)字段
- repositories:仓库托管地址数组,每个元素要包含type(仓库类型,如git)、url(仓- 库的地址)和path(相对于仓库的路径,可选)字段
- dependencies:生产环境包的依赖,一个关联数组,由包的名称和版本号组成
- devDependencies:开发环境包的依赖,一个关联数组,由包的名称和版本号组成
发布自己的npm包
发布包之前必须事先注册一个npm账号,去 官网 自行注册。
【注意】
注册完账号后一定要验证邮箱, 点开邮件中的链接, 否则是不能使用的
你可能之前会将npm下载源更改为taobao源谋求更快的下载速度, 这里我们需要输入指令nrm use npm
切换回npm源
进入你的包文件夹输入指令
- 添加账号
npm adduser // 输入自己的npm账号、密码、邮箱
- 登录npm
npm login // 输入账号、密码、邮箱,登录后方可发包
执行命令 npm whoami
可以查看登录状态
- 发布包
npm publish
发布成功后会有 + my-local-test@1.0.0的提示
发布成功以后我们就可以通过npm install 包名
下载使用包
- 更新包
如果你以后修改了代码,然后想要同步到 npm 上的话请修改 package.json 中的 version 然后再次 publish,也可以在项目目录下执行npm version patch
, 更新的版本上传的版本要大于上次
-
取消发布
npm包24小时内可以强制撤回,超过24小时的就不行了。
npm unpublish --force // 不成功可以强制取消
如果发布同一个包1次以上(即多个版本)了,那么就只能通过npm deprecate
去废弃包,如下操作:
npm deprecate my-local-test@1.0.1 "sorry, it's a my test npm package."
使用npm deprecate
时,最后的message一定要带上,否则执行失败。
注:
①npm默认只能一个一个删除版本,不能一次性删除所有版本。
②假如发布的包已经有人下载使用(npm官网可以看是否有人下载),删除会报错,是无法删除的。具体判断自己的包是否可以删除可以去npm的官网看下文档政策介绍。
二、npm全局包发布
大部分都和本地包一样, 这里说一下不一样的地方
- 在包目录新建index.js
// 加上这一行代码的目的是需要告诉这个文件需要用node执行
#! /usr/bin/env node
console.log("自定义指令被执行了");
2.在package.json里面配置 bin 节点 (跟 "scripts"同级)
"bin": {
"yz": "index.js"
},
- 最后执行
npm publish
发布即可
4.下载安装全局包npm install -g my-global-test
, 就可以执行指令啦
PS: 在当前包目录下执行npm link
可以将本地包拷贝到全局包