发布属于自己的npm包

1,936 阅读13分钟

cnpm全局包-命令行

  1. 安装cnpm全局包, 并且永久性修改cnpm使用的镜像地址为淘宝的

     npm install -g cnpm --registry=https://registry.npm.taobao.org
    
  2. 使用 以后可以让npm命令指向国外镜像地址

    用cnpm来安装第三方包(因为cnpm命令使用的是淘宝的镜像地址)

    ==注意, 只有下载才用cnpm, 其余的还是npm命令==

npm包

什么是包

  • 简单来说包就是文件夹,只是一个或多个模块组成的文件夹
  • node.js的第三方模块又叫做包

为什么需要包

  • 由于node.js提供的是一些底层的API,导致在基于内置模块进行项目开发时,效率很低
  • 包是基于内置模块封装出来的,提供了更高级、更方便的 API,极大的提高了开发效率
  • 包和内置模块之间的关系,类似于 jQuery 和 浏览器内置 API 之间的关系

安装包管理工具

  • 下载node环境时会伴随下载npm包管理工具
  • 可以在终端中执行npm -v 查看自己所安装的npm包管理工具的版本号

npm包的镜像

由于npm默认是从国外的服务器下载,些时,网络数据的传输需要经过漫长的海底光缆,因此下包速度会很慢。

  • 镜像是一个文件存储方式,一个磁盘上的数据在另一个磁盘上存在完全相同的副本即为镜像
  • 淘宝在国内搭建了填个服务器,专门把国外官方服务器上的包同步到国内的服务器,然后在国内提供下 包的服务。从而极在的提高了下包的速度。
  • 007 - 淘宝 NPM 镜像服务器

切换npm下包的镜像(方法一)

  • 下包的镜像源,指的就是下包的服务器的地址

    //1.首先查看当前的npm下包的镜像源
    npm config get registry
    //2.将下包的镜像源切换为淘宝的镜像源
    npm config set registry https://registry.npm.taobao.org 
    //3.检查镜像源是否下载成功
    npm config get registry
    
  • 注意 2022年5月31日后淘宝镜像源更新

    // 老的淘宝镜像域名
     Web 站点: http://npm.taobao.org
     Registry: http://registry.npm.taobao.org/
    
    // 新的淘宝镜像域名 
      Web 站点: https://npmmirror.com
      Registry: https://registry.npmmirror.com
    

使用nrm切换下载包的服务器(方法二)

  1. 安装nrm小工具 可快速查看和切换下包的镜像源

    //1通过npm包管理器,将nrm安装为全局可用的工具
      npm install nrm -g 
    
  2. 查看所有可用的镜像源

    //查看所有的可用的镜像源
    nrm 1s
    ​
    //带*的是当前使用的镜像源,下面的输出为官方源
    *npm ---- https://registry.npmjs.org/
    cnpm --- http://r.cnpmjs.org/
    taobao - http://registry.npm.taobao.org/  //查看最新淘宝镜像
    eu ----- http://registry.npmjs.eu/
    au ----- http://registry.npmjs.org.au/
    sl ----- http://npm.strongloop.com/
    nj ----- https://registry.nodejitsu.com/
     
    
  3. 切换下包的镜像源为taobao镜像

    //切换为taobao镜像
    nrm use taobao
    
  4. 增加定制的镜像源

    适用于添加公司内部的私有源

    // 执行cmd命令 nrm add <registry> <url> 其中registry为源名,url为源的路径
     nrm add registry http://registry.npm.frp.trmap.cn/ 
    
  5. 删除镜像源

    //执行命令nrm del <registry>删除对应的源。
     nrm del registry 
    

初始化包的环境

注意:

  1. 上述命令只能在英文的目录下成功运行! 所以,项目文件夹的名称一定要使用英文命名,不要使用中文,不能出现空格
  2. 运行 npm install 命令安装包的时候,npm 包管理工具会自动把包的名称和版本号,记录到 package.json
  • npm init 初始化后,目录下会多出node_modules文件夹和 package-lock.json 的配置文件

    npm init
    ​
    //初始化包的环境 用于创建 package.json
    //package.json 包含npm相关的所有基础信息(包管家)
    
    • 始化项目(创建package.json),需要用户输入项:
    • 可直接闭眼回车-全都用默认值
    输入项含义默认值
    package name包名字所在文件夹名,不能包含特殊符号和中文
    version版本号1.0.0
    description描述说明空字符串
    entry point包入口文件夹下的index.js
    test command测试命令空字符串
    git repository项目git地址空字符串
    keywords关键词空字符串
    author包作者名空字符串
    licenseISC开源许可字符串ISC
  • npm init -y

    • -y 的意思代表所有项都使用默认值(运行命令所在目录带中文或特殊符号, 则不能用这个)

package.json的作用

  • 在下载包之前 必须提供一个叫做 package.json的包管理配置文件。用来记录与项目有关的一些配置信息。例如:

    • 项目的名称、版本号、描述等
    • 项目中都用到了哪些包

node_modules的作用

  • node_modules文件夹用来存放所有已安装到项目中的包。require() 导入第三方包时,就是从目录中查找并加载

package-lock.josn的作用

  • package-lock.josn配置文件用来记录node_mdules目录下的每个包的下载信息,例如包的名字、版本号、下载地址等。

下载第三方的包

  • npm 这个网站下载你想要的包和使用文档

  • npm install 可简写成 npm i

    //下载第三方包 - moment 时间格式化的包
     npm install moment
     //简写 
     npm i moment
     //下载指定版本的包
     npm install momet @版本号
    
  • 可以同时安装多个包,用空格隔开 例如:

    npm i jquery md5 moment  //npm install xx1 xx2
    

包版本号的解释

版本号是以"点分十进制" 形式进行定义的, 总共有3位数字 例如:12.9.103

规则:只要前面的数字增长,后面的归零

  • 第一位数据-->为大版本的更新
  • 第二位数据-->为功能版本
  • 第三位数据-->为bug的修复和更新

卸载包

注意:npm uninstall 命令执行成功后,会把卸载的包,自动从 package.jsondependencies 中移除掉

npm uninstall 包名

清除npm的缓存

#清除npm缓存问题
  npm cache clean --force
  npm install @vue/cli --force

小结

//首先确定项目中是否有package.json 后才能npm 
1.确定项目目录下是否有package.json 如有则略过 npm init 
2.使用npm install 下载包,根据 package.json记录下载。 都会下载到node_modules文件夹下(这个文件夹自动创建)
3.引用下载的第三方包
   const moment=require("moment") 
4.使用
 let momentObj = moment();
 console.log(momentObj.format("YYYY年-MM月-DD日 HH:mm:ss")); // HH代表24小时制

多人协同开发

001 - package

  1. 包的体积

    • 整个项目的体积是 30.4M
    • 第三方包的体积是 28.8M
    • 项目源代码的体积 1.6M
  2. 遇到的问题

    • 第三方包的体积过大,不方便团队成员之间共享项目源代码
  3. 解决方案

    • 共享时剔除node_modules

注意:

  • 当我们拿到一个剔除了 node_modules 的项目之后,需要先把所有的包下载到项目中,才能将项目运行起来。否则会报类似于下面的错误:

    003 - 安装

  • 可以运行 npm install 命令(或 npm i)一次性安装所有的依赖包

    004 - npm i

nodemon会自动重启服务

nodemon这个包 实时监测你的代码的变更,然后自动重启

  • 安装命令 (全局安装 )

    npm i nodemon -g
    
  • nodemon的作用:

    • 代替node命令,启动服务的工具
    • 当更改代码之后,nodemon会自动重启服务, 妙啊←_←
  • 运行nodemon,如果报错如下:

image-20201222153838755

  • 解决方案:

    ==管理员方式==打开powerShell (不是普通的cmd) - 这个东西是win10新出的命令窗口

然后输入: set-ExecutionPolicy RemoteSigned 命令 然后 输入A 回车即可

image-20201222154538836

  • 全局模块和本地模块的对比

image-20200617162731311

使用对比

以前使用node 文件名 - 启动这个文件, 每次修改后还得ctrl+c停止掉, 然后在重新执行新的代码, 再启动web服务才生效新的代码

而nodemon会实时监测你的代码变更, 然后自动重启

i5ting_toc` 的安装和使用

  1. i5ting_toc 是一个可以把 md 文档转为 html 页面的小工具

    012 - i5ting_toc

包的分类

项目包

  1. 那些被安装到项目的 node_modules 目录中的包,都是项目包

  2. 项目包又分为两类,分别是:

    • 开发依赖包,被记录到 devDependencies 节点中的包,只在开发期间会用到
    • 核心依赖包,被记录到 dependencies 节点中的包,在开发期间和项目上线之后都会用到
    • npm xxxx -s 为核心依赖包(生产依赖)
    • npm xxxx -D 为开发依赖包

全局包

  1. 在执行 npm install 命令时,如果提供了 -g 参数,则会把包安装为全局包

  2. 全局包会被安装到 C:\Users\用户目录\AppData\Roaming\npm\node_modules 目录下

  3. 注意:

    • 只有工具性质的包,才有全局安装的必要性。因为它们提供了好用的终端命令
    • 判断某个包是否需要全局安装后才能使用,可以参考官方提供的使用说明即可

依赖版本管理

我们经常看到,在 package.json 中各种依赖的不同写法:

 "dependencies": {   
                      "signale": "1.4.0",   //固定版本号
                       "figlet": "*",      // 匹配任意版本(>=0.0.0)
                       "react": "16.x",    //匹配主要版本(>=16.0.0 <17.0.0)
                       "table": "~5.4.6",  //安装到 x.y.z 中 z 的最新的版本
                       "yargs": "^14.0.0"  //安装到 x.y.z 中 y 和 z 都为最新版本。
                       }
  • ~: 当安装依赖时获取到有新版本时,安装到 x.y.z 中 z 的最新的版本。即保持主版本号、次版本号不变的情况下,保持修订号的最新版本。
  • ^: 当安装依赖时获取到有新版本时,安装到 x.y.z 中 y 和 z 都为最新版本。 即保持主版本号不变的情况下,保持次版本号、修订版本号为最新版本。

定期更新依赖

我们的目的是保证团队中使用的依赖一致或者稳定,而不是永远不去更新这些依赖。实际开发场景下,我们虽然不需要每次都去安装新的版本,仍然需要定时去升级依赖版本,来让我们享受依赖包升级带来的问题修复、性能提升、新特性更新。

f44f338c0cbd4cc6b77e71c2b0154a55

使用 npm outdated 可以帮助我们列出有哪些还没有升级到最新版本的依赖:

  • 黄色表示不符合我们指定的语意化版本范围 - 不需要升级
  • 红色表示符合指定的语意化版本范围 - 需要升级

执行 npm update 会升级所有的红色依赖 ==》 谨慎使用

指定更新的依赖 npm update 包名

开发自己的包

注意

  • 一个规范的包,它的组成结构,必须符合以下 3 点要求:

    1. 包必须以单独的文件夹而存在
    2. 文件夹中必须要有 package.json 文件
    3. package.json 中必须包含 nameversionmain 这三个属性,分别代表包的名字、版本号、包的入口
    4. 以上 3 点要求是一个规范的包结构必须遵守的格式,关于更多的约束,可以参考这个网址

具体步骤

  1. 新建包文件夹 注意包的名字不可随便起 (请上www.npmjs.com/ 查询看看有人跟你重复没有, 自己加上名字英文拼写, 名字随便起)
  2. 在此文件夹 -cdm-初始化包 npm init 得到包管理工具 package.json
  3. 准备入口文件 index.js (名字可以自己随便定义, 只要跟package.json里的main字段的值对应上) - 作用, 别人引用你这个模块, 会根据package.json的main来决定引入哪个js文件里导出的对象使用
  4. 最好再准备一个README.md (可选), 一般 用于给使用者解释说明下你的包的使用方法和作用

初始化包的基础结构

  1. 新建 itheima-tools 文件夹,作为包的根目录

  2. itheima-tools 文件夹中,新建如下三个文件:

    • package.json (包管理配置文件)
    • index.js (包的入口文件)
    • README.md (包的说明文档)

初始化 package.json 配置文件

{
  "name": "flightloong-tools",
  "version": "1.0.0",
  "description": "提供格式化时间、HTMLEscape相关功能",
  "main": "index.js",
  "keywords": [
    "itcast",
    "itheima",
    "dateFormat",
    "escape"
  ],
  "license": "ISC"
}
  • name 包的名字

  • version 包的版本号

  • description 包的描述

  • main 对应要执行的文件

    • 在导入一个文件的时候,如果没有指定一个特定的文件,但是却能够得到某个包的返回内容,这是因为 Node 在使用 require 导入某个路径的时候,发现没有具体的文件,就会看这个路径下查看是否有 package.json 这个文件,如果有,则查看是否有 main 这个属性,如果有,则指定 main 属性对应的文件作为要执行的文件
  • README.md (包的说明文档)

    ### 安装
    ```
    npm i flightloong-tools
    ```### 导入
    ```js
    const itheima = require('./flightloong-tools')
    ```### 包的使用
           xxxxx
           xxxx
           xxxx
           
    ### 开源协议
       ISC
    

注册 npm 账号

  1. 访问 npm 网站,点击 sign up 按钮,进入注册用户界面
  2. 填写账号相关的信息:Full NamePublic EmailUsernamePassword
  3. 点击 Create an Account 按钮,注册账号
  4. 登录邮箱,点击验证链接,进行账号的验证

登录 npm 账号

  1. npm 账号注册完成后,可以在终端中执行 npm login 命令,依次输入用户名、密码、邮箱后,即可登录成功
  2. 注意:在运行 npm login 命令之前,必须先把下包的服务器地址切换为 npm 的官方(国外)服务器。否则会导致发布包失败!

把包发布到 npm

  • 将终端切换到包的根目录之后,运行 npm publish 命令,即可将包发布到 npm 上(注意:包名不能雷同 )

    • 如下图(发布成功)

015 - npm publish

  • 注意 如果发现发布npm 包时 报错 如下图 (发布失败)

Snipaste_2021-07-20_18-03-03

  • 原因有可能是
    • 包名-- -在npm官网上以经有这个包,可在npm官网上搜索一个是否有同名的包
    • 版本号--- 有可能是版本号的原因,需要修改一下
    • 邮箱验证---首次注册npm账号需要验证邮箱,验证完成后在执行npm publish 再次发布

删除已发布的包

  1. 运行 npm unpublish 包名 --force 命令,即可从 npm 删除已发布的包

  2. 注意事项

    • npm unpublish 命令只能删除 72 小时以内发布的包
    • npm unpublish 删除的包,在 24 小时内不允许重复发布
    • 发布包的时候要慎重,尽量不要往 npm 上发布没有意义的包!

更新自己的npm包(模块)

  • 修改代码和readme.md后,执行命令:

    npm version patch  // 小变动 比如修复bug
    npm publish         //重新发布到npm 官网上
    
    • npm version后面参数说明:
    • patch:小变动,比如修复bug等,版本号变动 v1.0.0->v1.0.1
    • minor:增加新功能,不影响现有功能,版本号变动 v1.0.0->v1.1.0
    • major:破坏模块对向后的兼容性,版本号变动 v1.0.0->v2.0.0

使用更新后的npm包

  • 针对更新后的包,使用对应的指令
      更新NPM包:
      针对patch: npm install finitxu-npm-test 
      针对minor: npm install finitxu-npm-test 
      针对major: npm install finitxu-npm-test@2.0.0

模块的加载机制

优先从缓存中加载

模块在第一次加载后会被缓存,这意味着多次调用 require() 方法不会导致模块的代码被多次执行

注意:不论内置模块、用户自定义模块、还是第三方模块,他们都会优先从缓存中加载,从而提高模块的加载效率

// 自定义模块.js
​
console.log('ok')
require('./自定义模块.js')
require('./自定义模块.js')
require('./自定义模块.js')

内置模块的加载优先级

内置模块是由 Node.js 官方提供的模块,内置模块的加载优先级最高

例如: require('fs') 始终返回内置的 fs 模块,即使在 node_modules 目录下有名字相同的包也叫做 fs

const fs = require('fs') // 始终返回的是内置的 fs 模块

自定义模块的加载机制

  1. 使用 require() 加载自定义模块时,必须指定以 ./ 或者 ../ 开头的路径标识符。在加载自定义模块时,如果没有指定 ./../ 这样的路径标识符,则 node 会把它当作 内置模块第三方模块 进行加载

  2. 在使用 require() 导入自定义模块时,如果省略了文件的拓展名,则 Node 会按照顺序分别尝试加载以下文件

    • 按照 确切的文件名 进行加载
    • 补全 .js 扩展名进行加载
    • 补全 .json 扩展名进行加载
    • 补全 .node 扩展名进行加载
    • 加载失败,终端报错

第三方模块的加载机制

  1. 如果传递给 require() 的模块标识符不是一个内置模块,也没有以 './''../' 开头,则 Node.js 会从当前模块的父目录开始,尝试从 /node_modules 文件夹中加载第三方模块

  2. 如果没有找到对应的第三方模块,则移动到再上一层父目录中,进行加载,直到文件系统的根目录

  3. 假设在 C:\Users\itheima\project\foo.js 文件里调用了 require('tools'),则 Node.js 会按以下顺序查找

    • C:\Users\itheima\project\node_modules\tools
    • C:\Users\itheima\node_modules\tools
    • C:\Users\node_modules\tools
    • C:\node_modules\tools

目录作为模块

当把目录作为模块标识符,传递给 require() 进行加载的时候,有三种加载方式:

  1. 在被加载的目录下查找一个叫做 package.json 的文件,并寻找 main 属性,作为 require() 加载的入口
  2. 如果目录里没有 package.json 文件,或者 main 入口不存在或无法解析,则 Node.js 将会试图加载目录下的 index.js 文件
  3. 如果以上两步都失败了,则 Node.js 会在终端打印错误消息,报告模块的缺失:Error: Cannot find module xxx