如何发布自己的 npm 软件包?
1. 创建npm账号
- 官网:www.npmjs.com/
- 创建账号入口:www.npmjs.com/signup
⚠️ 如果之前没有npm账号,需要先创建一个npm账号,后面有用到。如果已经有账号,这一步可以忽略。
2. 创建目录
// 在终端输入以下命令,npm-demo为包的目录,可以自己任意取名
mkdir npm-demo
// 进入包目录
cd npm-demo
3. 编写模块
此处我们以一个简单的sayHi为例子,相关代码如下
exports.sayHi = function() {
return 'Hi, Meta.'
}
将这段代码保存为sayHi.js即可。
4. 初始化包描述文件
在终端执行 npm init 命令,生成package.json文件。如下所示: NPM通过提问似的交互,逐个填入选项,最后生成预览的包描述文件,如果ok,输入yes,此时文件目录下会得到package.json文件。
5. 注册包仓库账号
为了维护包,npm必须要使用仓库账号才允许将包发布到仓库中。
注册账号的命令是 => npm adduser
这也是一个提问似的交互过程,按顺序进行即可。
如果没有进行步骤一创建npm账户,在走npm adduser命令时,该npm账户不存在,或者输入了错误的npm账户信息,会出现如下如下报错信息,所以务必保证输入的用户名&密码&邮箱和步骤一中的npm账号一致:
6. 上传包
上传包的命令是:npm publish 包文件夹名字。
在刚刚创建的package.json文件所在的目录下,执行 => npm publish . 开始上传包
在这个过程中,NPM会将目录打包为一个存档文件,然后上传到官方源仓库中。 此处有个问题需要注意,在生成package.json中,name的名称和项目的名称是保持一致的,如果该npm包名&版本号已经存在,会出现如下报错,此时需要重命名你的package.json中的name。即使你在npm官网没有搜到你预设的包名,它可能也被发布占用过,需要重新考虑。因为我在上传的过程中遇到了这个问题,所以,把package.json中的name改为了meta-npm-demo,包名一定要是唯一的。
7. 更新包
- npm包修改后,手动把package.json里的version版本号修改了,或者使用以下命令自动更新版本号,再执行npm publish . 命令就可以了。
- 升级补丁版本号(修改bug):npm version patch
- 升级小版本号(新增功能):npm version minor
- 升级大版本号(较大改版):npm version major
- 然后在使用的项目中,重新安装包即可
8. 安装包进行测试
- 为了体验和测试自己上传的包,我们换一个目录
// 在终端输入以下命令,npm-demo-test为测试目录,可以自己任意取名
mkdir npm-demo-test
// 进入测试目录
cd npm-demo-test
- 我们简单写一段js代码,保存到index.js
var demo = require('meta-npm-demo');
var res = demo.sayHi()
console.log(res);
- 执行 npm install npm-demo -D
- 执行 node index.js
潜在风险
在企业的内部应用中使用NPM与开源社区中使用有一定的差别。企业的限制在于,一方面需要享受模块开发带来的低耦合和项目组织上的好处,另一方面却要考虑到模块保密性的问题。所以,通过NPM共享和发布存在潜在的风险。
为了同时能够享受到NPM上众多的包,同时对自己的包进行保密和限制,现有的解决方案就是企业搭建自己的NPM仓库。局域NPM仓库的搭建方法与搭建镜像站的方式几乎一样,与镜像仓库不同的地方在于,企业局域NPM可以选择不同步官方源仓库中的包,即企业可混合使用官方仓库和局域仓库。
对于企业内部而言,私有的可重用模块可以打包到局域NPM仓库中,这样可以保持更新的中心化,不至于让各个小项目各自维护相同功能的模块,杜绝通过复制粘贴实现代码共享的行为。
搭建局域NPM仓库,有时间会另写一篇。
模块的侧重点
浏览器端的JavaScript,需要通过网络加载代码,而服务器端的JavaScript从磁盘中加载。Node的模块引入过程几乎都是同步的,但是如果前端模块也采用同步的方式来引入,那UI在初始化过程中需要花费很多时间来等待脚本加载完成。
鉴于网络的原因,CommonJs为后端JavaScript制定的规范并不完全适合前端的应用场景。最终出现了AMD规范和CMD规范。
所以为了让同一个模块可以运行在前后端,在写的过程中需要考虑兼容前端模块规范。为了保持前后端的一致性,累哭开发者需要将类库代码包装在一个闭包内。
所以我们可以用以下写法兼容Node、AMD、CMD以及常见的浏览器环境中:
;(function(global) {
"use strict";
var definition = function(opts) {
console.log(opts);
};
// 检测上下文环境是否为AMD或CMD
var hasDefine = typeof define === 'function';
// 检查上下文环境是否为Node
var hasExports = typeof module !== 'undefined' && module.exports;
if (hasDefine) {
// AMD环境或者CMD环境
define(function() {
return definition;
});
} else if (hasExports) {
// 定义为普通node模块
module.exports = definition();
} else {
// 将模块的执行结果挂在window变量中,在浏览器中this指向window对象
global.definition = definition();
}
})(this);
推荐阅读
-
如何设置自己的Frp服务器以实现内网穿透能力?
-
小白也能做!一步步教你如何开发属于自己的微信小程序
-
从零开始学习Linq:如何用自己的编程语言实现它的功能?
-
如何搭建自己的Alist共享网盘?
-
如何在优麒麟 22.04 LTS 上安装经典的 Firefox DEB 软件包?
-
如何在服务器上搭建自己的学习环境LNMP
-
如何挑选适合自己的海外服务器?
-
Vue 3和Vite如何将自定义的Vue组件打包并发布到npm库?全程解析
-
深度探索推特开源算法的趣味之旅;应对ChatGPT被封号的策略大集合;全面解析ControlNet技术教程;如何搭建自己的ChatGPT应用程序?建立开源项目阅读工作流程的方法分享 | ShowMeAI日报
-
新 iPhone 14 发布了!与 iPhone 13 和 14 的区别在哪里?购买价值如何评估?