npm 包管理工具

5,003 阅读7分钟

包其实就是一些模块组织到一起,放到一个目录中的一个称呼,叫包或者模块都行。Node Package Manager: npm 是一个用来安装和管理Node包和前端包的一个工具

npm 有两层含义:

  • npm 官方网站
    • 提供了一个用来共性或者检索的一个平台
    • 一是托管 node 环境或者浏览器环境用的的一些第三方包
  • 是一个命令行管理工具,可以用来下载 npm 网站上托管的包
    • CLI: Command Line Interface 命令行窗口
    • GUI: 图形化界面

安装 npm

Node 是一个执行环境,Node 可以用来执行 JavaScript 代码,(这里的JS指的是 ECMAScript),npm 基于 node 环境的 API(网络操作API、文件操作API)编写的工具,可以用来下载第三方包到指定的目录中。

必须要安装 node 环境,测试是否有 node 环境:


node -v

安装node环境的时候,已经自动安装了 npm 命令行工具,不需要单独安装。可以通过 npm -v 测试npm是否可用

npm 基本使用

本地安装

一般是在项目中,安装项目使用的依赖包,例如 underscore、less、jQuery,可以在终端中,切换到项目的根目录,然后执行 npm install 包名,比如:npm install jquerynpm 工具会自动将 jQuery 这个包下载,然后放到 node_modules 目录中。node_modules 目录如果不存在会新建,如果已存在,则直接将下载的包放到该目录中。

$ npm install [--save] 包名

这行命令跟包说明文件package.json 有千丝万缕的关系

包说明文件:package.json

包说明文件其实就是一个产品的说明书:package.json 文件。该文件一般只存在于项目的根路径下,定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、依赖项等信息)。可以通过 npm init [-y] 命令使用向导的形式创建该文件。

该文件中描述了项目的一些元数据,例如 name、version、author 等信息。

其中有一个非常重要的属性,叫做:dependencies,该属性是一个对象,里面保存了当前项目的依赖项,该字段一般不要手动修改,它需要结合 npm install --save 包名 来使用,只要在安装的时候加上 --save 参数就会自动将包依赖项添加到该属性中,很方便。

甚至还可以完全把 node_modules 目录删除掉,只要 package.json 文件还在,就可以执行 npm install 安装包说明文件中的所有的依赖项。执行 npm install 命令的时候,它会自动查询当前目录下的 package.json 文件,然后找到里面的 dependencies 属性,依次下载到 node_modules 目录下。

建议:以后使用 npm 的时候,首先用 npm init -y 初始化一个 package.json, 然后使用 npm install 包名 --save

总的来讲,有以下几个步骤,重要组成:

  • npm init [-y]
  • main
  • dependencies
    • 当前项目或者说包的依赖项
    • npm install 的时候,会自动查找当前目录下的 package.json 文件中的 dependencies 属性
    • 然后依次下载

本地安装常用命令

cd Desktop\code
npm init
cls 清屏
npm install bootstrap --save
npm install --save jquery
npm install

全局安装

全局安装: 一般用于安装一些命令行工具(这些工具也是基于Node开发的)全局安装使用 npm install --global 包名(工具名),在任意目录执行该命令都可以。

比如:

npm i -g less
npm install -g less

常用命令

  • npm help 查看 npm 命令列表
  • npm -l 查看各个命名的简单用法
  • npm -v 查看 npm 的版本
  • npm root -g 查看全局包安装目录。
  • npm init [-y]:初始化一个 package.json 文件
  • npm info 包名 [字段名]:查看指定模块的 package.json 信息
  • npm search 包名:该命令用于搜索 npm 仓库
  • npm list 以树型结构列出当前项目安装的所有模块,以及它们依赖的模块
  • npm list 包名:列出单个模块
  • npm list -g 列出全局安装的模块
  • npm install [--save] 包名[#版本号]
    • npm install 包名 安装包到当前项目下的 node_modules 目录下
    • npm install|i --save|-S 包名 安装包的同时把依赖项保存到 包说明文件中
    • 本地项目安装:目的是为了辅助你的代码功能开发
  • npm uninstall [--save] 包名
    • npm uninstall 包名 删除包,但是如果包说明文件中有依赖项,那么不会删除
    • npm uninstall --save 包名 删除包,同时将 package.json 文件中的依赖项也删除
  • npm install
  • npm install -g 包名
  • npm uninstall -g 包名
  • npm install -g http-server --registry=http://192.168.32.59:7001 设置服务器镜像源地址
  • npm config
    • npm config list 查看 npm 配置项
    • npm config set init.author.name $name 使用 npm init 时,默认的 name
    • npm config set init.author.email $email 使用 npm init 时,默认的 email
    • npm congig set prefix "路径" 改变全局包安装路径
    • npm config set registry “镜像路径”
  • http-server 开启服务器
  • http-server-o 开启服务器并直接在浏览器中打开

启动一个服务器

$ npm install -g http-server

然后需要打开文件的目录下,打开终端:输入 http-server,这样启动了默认端口是 8080,http-server -p 6060 指定服务器的端口。

如何将包发布到 npm 网站上并且通过 npm install --global 包名 安装

配置原理

  • npm root -g
  • 模拟该目录下 nrm 下的 cli.js (入口文件) 文件中,在第一行加入了 #!/usr/bin/env node
  • 得到路径:C:\Users\mhq\AppData\Roaming\npm\node_modules
  • 在此路径下新建 以 需要发布的包的包名命名的文件: 比如 mCopy;
  • 将所需要发布的 js 文件放到这个文件下, 比如 08_copy.js;
  • 在该文件的上一级目录下,C:\Users\mhq\AppData\Roaming\npm 下,复制一个 nrm.cmd 副本
  • 重名名该副本文件为 mCopy.cmd, 现在这个文件长这样:
@IF EXIST "%~dp0\node.exe" (
  "%~dp0\node.exe"  "%~dp0\node_modules\nrm\cli.js" %*
) ELSE (
  @SETLOCAL
  @SET PATHEXT=%PATHEXT:;.JS;=;%
  node  "%~dp0\node_modules\nrm\cli.js" %*
)

配置完这一步之后就可以在 cmd 中直接使用 mCopy src des 命令来复制文件了

node 提供了一个更方便的方式自动生成 .cmd 文件以及和需要发布的文件产生关联

  • 现在将原理中介绍的过程产生的文件删除,重新使用 Node 方式配置
  • 在桌面新建 mCopy 文件
  • win+R –> cmd –> cd Desktop –> cd mCopy
  • 新建一个 .js 的入口文件,在第一行加入了 #!/usr/bin/env node,这叫设绑;
  • 在 package.json 文件中加入 bin 字段,
    • bin 字段是一个对象
    • 该对象的第一个属性就是执行脚本文件的命令, 比如 “mCopy”,用来生成 .cmd 文件
    • 该对象的第一个属性的值就是要执行的脚本文件

package.json 文件如下:

{
  "name": "mcopy",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "bin": {
    "mcopy": "./index.js"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
  • 最后,打开终端,进入当前项目的根路径,执行:npm link
    • 执行完该命令之后, node 会自动去全局安装创建路径对应的 .cmd 文件
    • 这样就开发了命令行工具
    • 如果想卸载掉,使用命令 npm unlink
    • 新建一个 .js 文件,将需要发布的包的代码放进去;比如:copy.js

copy.js 文件

const fs = require('fs');
// 暴露接口
module.exports = function (src, des, callback) {
    fs.readFile(src, (err, data) => {
        if (err) {
            return callback(err);
        }
        fs.writeFile(des, data, err => {
            return callback(err);
        });
        callback(null);
    });
};

index.js 文件

#!/usr/bin/env node
const copy = require('./copy');
const args = process.argv.slice(2);
console.log(args);
copy(args[0], args[1], err => {
  if (err) {
    return console.log('Copy Fail');
  }
  console.log('Copy Success');
});
  • 发布
    • 发布之前先去 npmjs.com 上验证一下你的 package.json 中的 name 是否被占用
    • 如果被占用,则修改 name
    • 注意:改了名字之后就无法卸载。
      • 一种方式是直接删掉
      • 一种方式是把 package.json 文件下的 name 改回原来的然后再使用 npm unlink 卸载
      • 然后把 name 改成线上没有的名字
    • www.npmjs.com 官网注册一个账号,或者通过 npm adduser 注册一个账户
    • 注意:这里一定要确保使用的镜像源地址是 npm 官方的镜像源
    • npm login 登陆
    • npm publish 发布
    • 支持 README.md 文档
      • 添加文档之后再发布
      • 需要更新 package.json 中的版本号
      • 修改 package.json 下的 "description" 为 “A copy tool of a command line”,`
    • npm version patch 更新
    • npm install -g hqcopy 全局安装到本地
    • npm unpublish 删除

Install 说明文档 README.md

h1 hqcopy

h2 Install

$ npm install --global mcopy

h3 Usage

$ mcopy src des

将这个包改造为本地和全局两种形式

作为命令行 和 项目安装

即:在命令行中执行的是: index.js,而在代码中执行的是: copy.js,因此,有以下操作:

  • 将 package.json 包下的 “main” 改成 “copy.js”
  • 将已上传的 hqcopy 下载到本地项目中,
  • 打开之后发现 package.json 文件中的 main 属性是 “index.js”
  • 当前项目下 新建 .js 文件, 然后使用下面代码引入,目前只限错误
  • 因为目前只能当做命令行使用
const hqcopy = require('hqcopy');
  • 加载机制,首先去当前项目的 node_modules,
  • 找到 hqcopy,
  • 找到 package.json 文件
  • 找到 main 属性,发现是 index.js
  • 应当判断是全局命令行调用,还是代码调用
  • 修改 package.json 文件的 main 属性为 copy.js, 这样,如果是代码调用,默认调用 copy.js文件
{
  "name": "hqcopy",
  "version": "1.0.2",
  "description": "A copy tool of a command line",
  "main": "copy.js",
  "bin": {
    "mcopy": "./index.js"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
  • npm version patch
  • npm publish

新建 test.js 进行测试

  • npm install --save hqcopy
const hqcopy = require('hqcopy');
hqcopy('README.md','a.md', err => {
  if (err) {
    throw err;
  }
  console.log('copy success');
});

现在的这个包就既可以安装到本地也可以全局安装,安装到本地项目可以使用该包暴露的 API 接口,安装到全局就可以使用该包提供的全局命令工具。

解决 npm 被墙的问题,使用镜像源地址

国内的淘宝:克隆了国外的服务器,跟国外的 npm 每10分钟保持同步一次;

  • npm install 包名 --registry=https://registry.npm.taobao.org 国内淘宝镜像源地址
  • npm config set registry=https://registry.npm.taobao.org
    • 这是将 npm 的下载镜像源地址改为淘宝的 cpnm 镜像源
    • 这样执行该命令,以后所有的 install 都会通过指定的地址下载
    • 还提供了 cnpm 命令
    • npm install -g cnpm
      • 安装了 cnpm 之后,就可以使用 cnmp 命令安装和管理包了
      • cnpm 默认 就会走淘宝的 npm 镜像源地址
      • cnpm install -g 包名
      • cnpm install 包名
      • npm 的命令都可以通过 cnpm 来代替
  • 实际上,在用户目录下生成了.npmrc 文件,保存了镜像源地址
  • 还有一个工具,如果在局域网内,局域网的包,这样又需要改镜像源地址:
    • 安装和管理多个镜像源地址
    • npm install -g nrm 下载安装
      • nrm 即 nmp registry manager
      • nrm 可以用来管理多个镜像源地址,切换多个镜像源地址
      • nrm 是基于 node 开发的
      • nrm ls 列出所有的镜像源地址
      • nrm current 显示当前使用的镜像源地址
      • nrm use 镜像源名称 切换到指定的镜像源地址
      • nrm add 镜像源名称 镜像源地址 添加指定的镜像源地址
      • nrm del 镜像源名称 从本地删除指定的镜像源地址
      • 配置文件都在用户目录下,叫 .nrmrc, 直接修改此文件也可配置;

配置 package.json 文件中的 script

在package.json 文件中的 “script” 下 添加一条需要使用 npm 命令 来启动项目程序的属性, 比如: "start": node ./app.js

这样就可以利用终端,使用命令 npm start 来启动项目。

项目初始化

利用命令自动化管理

  • npm install
  • npm install --save-dev brower-sync 直接把开发依赖内置,把安装到项目依赖中.
  • 找到 package.json,在 "scripts" 字段中添加: "start": "hs -o"
  • 找到 package.json,在 "scripts" 字段下添加"dev": "hs -o""postinstall": "npm run dev",然后自动执行。
  • npm run dev
  • 那么,服务器的开启过程就是: .bin 目录下 hs 执行 node-modules 下的 http-server。

package.json 文件中的配置。

{
  "script":{
    "prestart": "npm install"
    "start": "hs -o"
    "dev":"hs -o"
    "postinstall":""
  }
}

另外一种配置 package.json 启动项目的方法

{
  "scripts": {
    "prestart": "npm install",
    "start": "hs -o",
    "predev": "npm install",
    "dev": "hs -o"
  }
}

感谢您的支持!