• 初学Nodejs(5):npm包管理器与包的发布


    初学Nodejs

    1、概念

    • 什么是包
      Nodejs中的第三方模块又叫做包。
    • 包的来源
      不同于Nodejs中的内置模块与自定义模块,包是由第三方个人或团队开发出来的,免费供人使用。(nodejs中的包都是免费且开源的,不需要付费即可免费下载使用)
    • 为什么需要包
      因为nodejs的内置模块仅仅提供了一些底层的API,这就导致在基于内置模块进行项目开发时,效率很低,包是基于内置模块封装起来的,提供了更高级、更方便的API,极大的提高了开发效率
    • 从哪下载包
      有一家IT公司,名叫npm,inc.这家公司其下有一个著名的网站,https://www.npmjs.com/,它是全球最大的包共享平台,可以从这里搜索到任何你所需要的包,同时可以进入包的官方文档看如何使用该包。但下载需要到这个地址https://registry.npmjs.org/的服务器下下载。
    • 如何下载包
      npm,inc公司提供了一个包管理工具npm(Node package Manager),从服务器把需要的包下载到本地使用。

    下载包

    npm install 包名 [options]
    
    • 1

    引入包

    const 包名 = require('包名')
    
    • 1
    • 如何卸载包
    npm uninstall 包名
    
    • 1
    • 初次装包之后多了哪些文件
      (1)node_modules的文件夹
      存放所有已安装到项目的包。require导入包时,就是从这个目录中查找并加载包。
      (2)package-lock.json的配置文件
      记录node_modules目录下的每一个包的下载信息,包括包的名字,版本号,下载地址等。

    • 安装指定版本的包

     npm i 包名@指定版本
    
    • 1

    2、包管理配置文件package_json

    作用

    用来记录与项目有关的一些配置信息,例如:
    - 项目的名称、版本号、描述等
    - 项目用到的包
    - 哪些包只在开发期间会用到
    - 哪些包在开发和部署时都会用到

    node_modules体积远比项目源代码大,在多人联合开发项目时最好不要打包进项目

    在接收到项目源代码时,通过package.json中存储的项目配置信息运行npm install命令下载所有需要的包,方便开发。

    运行命令npm install安装所有的包,npm包管理工具会自动根据package.json中包的名称和版本号下载所有相应的包

    快速创建package.json文件(初始化项目)

    npm init -y
    
    • 1

    注意:上述命令只能在英文的目录下运行,目录中不要出现中文和空格

    • dependencies节点
      package.json文件中,有一个dependencies(依赖)节点,专门用来记录使用npm install命令安装了哪些包,在使用npm install 命令安装包时,也是根据这个依赖节点安装的。

    • devDependencies节点
      如果某些包只在项目开发阶段会用到,项目上线之后不会用到,那么建议把包记录到devDependencies节点中。

    // 安装指定的包,并记录到devDependencies节点中
    npm i 包名 -D
    // 等价于如下
    npm install 包名 --save-dev
    
    • 1
    • 2
    • 3
    • 4

    使用npm uninstall卸载包同时会删除dependencies节点中的包名和版本。

    3、包的分类

    3.1 项目包

    那些被安装到项目的node_modules中的包都是项目包

    项目包又分为两类

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

    3.2 全局包

    在执行npm install安装包时,如果提供了-g参数,表示将包安装到全局,全局包会被按转到C:\Users\用户目录\AppData\Roaming\npm\node_modules目录下

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

    3.3 i5ting_toc

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

    // 安装为全局
    npm install -g i5ting_toc
    
    // 调用
    i5ting_toc -f 要转换的md文件路径 -o
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4、规范的包结构

    一个规范的包,他的组成结构必须符合以下3点要求
    (1)包必须以单独的目录存在
    (2)包的顶级目录下要必须包含package.json这个包管理配置文件
    (3)package.json中必须包含name,version,main这三个属性,分别代表包的名字,版本号,包的入口

    5、开发自己的包

    5.1 初始化基本包结构

    (1)新建myTools文件夹,作为包的根目录
    (2)在myTools文件夹中新建如下三个文件:
    – package.json(包管理配置文件)
    – index.js (包的入口文件)
    – README.md (包的说明文档)

    • package.json文件
    {
        "name":"mytools-dxf",
        "version":"1.0.0",
        "main": "index.js",
        "description": "提供了格式化事件,HTMLEscape的功能",
        "keywords": ["dxf","myTools","dateFormat","escape"],
        "license": "ISC"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    name:包名
    version:版本号
    main:包的入口文件
    description:搜索时显示的描述信息
    keywords:搜索关键词
    license:开源协议

    • index.js入口文件
    // 这是包的入口文件
    
    // 定义格式化时间函数
    function dateFormat(dateStr){
        const dt = new Date(dateStr)
    
        const y = padZero(dt.getFullYear())
        const m = padZero(dt.getMonth()+1)
        const d = padZero(dt.getDate())
    
        const hh = padZero(dt.getHours())
        const mm = padZero(dt.getMinutes())
        const ss = padZero(dt.getSeconds())
    
        // return `YYYY-MM-DD HH:mm:ss`
        return `${y}-${m}-${d}-${hh}-${mm}-${ss}`
    
    }
    // 定义一个补零函数
    function padZero(n){
        return n > 9 ? n :'0' + n
    }
    
    // 定义转义html字符的函数
    function htmlEscape(htmlStr){
        return htmlStr.replace(/<|>|"|&/g,match => {
            switch(match){
                case '<':
                    return '<'
                case '>':
                    return '>'
                case '"':
                    return '"'
                case "&":
                    return '&'
            }
        })
    }
    
    // 还原被转义的html的方法
    function htmlUnEscape(str){
        return str.replace(/<|>|"|&/g,(match) => {
            switch(match){
                case '<':
                    return '<'
                case '>':
                    return '>'
                case '"':
                    return '"'
                case '&':
                    return '&'
            }
        })
    }
    // 暴露
    module.exports = {
        dateFormat,
        htmlEscape,
        htmlUnEscape
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • README.md
    ## 安装 
    npm install mytools-dxf
    
    • 1
    • 2
    ## 导入 
    const dxf = require('mytools-dxf')
    
    • 1
    • 2
    ## 格式化时间 
    const dtStr = dxf.dateFormat(new Date()) console.log(dtStr)  // 结果:2022-08-22-14-53-42
    
    ```js
    ## 转义 HTML 中的特殊字符串 
    // 待转换的HTML字符串 
    const htmlStr = '

    这是h1标签123 

    '
    // 调用htmlEscape 方法进行转换 const str = dxf.htmlEscape(htmlStr) console.log(str) // <h1 title=&quot;abc&quot;&gt;这是h1标签&lt;span&gt;123&amp;nbsp;&lt;/span&gt;&lt;/h1&gt;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    ## 还原 HTML 中的特殊字符 
    const str2 = dxf.htmlUnEscape(str) console.log(str2) 
    // 结果:

    这是h1标签123 

    ```shell ## 开源协议 ISC
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    包优化:将不同的功能进行模块化拆分
    (1)将格式化时间的功能拆分到mytools-dxf/src/dateFormat.js中
    (2)将处理HTML字符串的功能拆分到mytools-dxf/src/htmlEscape.js中
    (3)在index.js中导入两个魔魁啊,得到需要向外共享的方法
    (4)在index.js中,使用module.exports把对应的方法暴露出去

    • mytools-dxf/src/dateFormat.js
    // 定义格式化时间函数
    function dateFormat(dateStr){
        const dt = new Date(dateStr)
    
        const y = padZero(dt.getFullYear())
        const m = padZero(dt.getMonth()+1)
        const d = padZero(dt.getDate())
    
        const hh = padZero(dt.getHours())
        const mm = padZero(dt.getMinutes())
        const ss = padZero(dt.getSeconds())
    
        // return `YYYY-MM-DD HH:mm:ss`
        return `${y}-${m}-${d}-${hh}-${mm}-${ss}`
    
    }
    // 定义一个补零函数
    function padZero(n){
        return n > 9 ? n :'0' + n
    }
    
    module.exports = {
        dateFormat
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • mytools-dxf/src/htmlEscape.js
    // 定义转义html字符的函数
    function htmlEscape(htmlStr){
        return htmlStr.replace(/<|>|"|&/g,match => {
            switch(match){
                case '<':
                    return '<'
                case '>':
                    return '>'
                case '"':
                    return '"'
                case "&":
                    return '&'
            }
        })
    }
    
    // 还原被转义的html的方法
    function htmlUnEscape(str){
        return str.replace(/<|>|"|&/g,(match) => {
            switch(match){
                case '<':
                    return '<'
                case '>':
                    return '>'
                case '"':
                    return '"'
                case '&':
                    return '&'
            }
        })
    }
    
    module.exports = {
        htmlEscape,
        htmlUnEscape
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • mytools-dxf/index.js
    // 这是包的入口文件
    
    // 导入模块化文件
    // format是一个对象,需要进行解构拿到里面的方法
    const format = require('./src/dateFormat')
    
    // escape同上
    const escape = require('./src/htmlEscape')
    
    // 暴露
    module.exports = {
        ...format,
        ...escape
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使用

    const dxf = require('./mytools-dxf/index')
    
    const dtStr = dxf.dateFormat(new Date())
    console.log(dtStr);
    console.log("------------------");
    
    const htmlStr = '

    这是h1标签123 

    '
    const str = dxf.htmlEscape(htmlStr) console.log(str); console.log("------------------"); const str2 = dxf.htmlUnEscape(str) console.log(str2);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果
    2022-08-22-14-53-42


    title="abc">这是h1标签123 


    < h1 title=“abc”>这是h1标签< span>123 < /span>< /h1>

    5.2 发布npm包

    前序工作:
    1、安装nrm

    npm i -g nrm
    
    • 1

    nrm是一个npm源管理器,意思就是说npm包来源的网址,对它进行管理

    2、nrm的使用

    # 显示包的所有下载源
    npx nrm ls
    
    # 切换下载源
    npx nrm use npm # 使用npmjs源地址
    npx nrm use taobao # 使用淘宝下载源
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 切换到包的根目录使用如下命令发布包
    npm publish
    
    • 1
    • 删除发布的包
    npm unpublish 包名 --force
    
    • 1

    (1)npm Unpublish只能删除72小时以内发布的包
    (2)npm unpublish删除的包,在24小时内不允许发布重复的包
    (3)没意义的包不要发布
    (4)如果发现包中有啥内容错误,那么可以先把包源码更改,再使用如下命令更新包

    npm version patch
    npm publish
    
    • 1
    • 2

    6、nrm切换npm包的下载源

    6.1 介绍

    nrm是用于切换npm下载源的,例如,npm是用本身地址https://registry.npmjs.org/下载包呢,还是用淘宝镜像地址下载包呢,还是用哪个地址下载包

    6.2 安装

    npm install -g nrm
    
    • 1

    6.3 常用命令

    • 展示所有下载源
    nrm ls
    
    • 1

    在这里插入图片描述

    • 切换下载源
    nrm use 下载源
    例如
    nrm use taobao # 表示使用淘宝镜像的下载源
    nrm use npm # 表示使用自身原本的下载源
    
    • 1
    • 2
    • 3
    • 4
    • 查看当前使用源
    nrm current
    
    • 1
    • 添加一个源地址
    nrm add <registry> <url>
    
    • 1

    registry是源名,url是源地址

    • 删除源
    nrm del 源名
    
    • 1
    • 查看下载源速度
    nrm test
    
    • 1
  • 相关阅读:
    VUE+Element首次打开Dialog加载子组件数据未渲染(不显示)
    FFplay文档解读-23-音频过滤器八
    GBASE 8A v953报错集锦38--orato8a 指定 parallel 参数全表导出时前几分钟无数 据写入
    nginx请求接口转发-浏览器访问80端口,要把请求转发至8882
    【C++上层应用】4. 多线程
    提取存档提取操作没有完成出现意外错误,导致无法提取存档。错误Ox8007000E:内存资源不足,无法完成此操作。若要关闭此向导,请单击“完成“”。完成(F)
    《Linux》day5--ssh——ssh登录与scp传文件
    Ubuntu系统下MySQL开启远程连接
    【无标题】
    Day727.键值数据库的基本架构 -Redis 核心技术与实战
  • 原文地址:https://blog.csdn.net/lalala_dxf/article/details/126457616