其他章节请看:

前端学习 node 快速入门 系列

npm

npm 是什么

npm 是 node 的包管理器,绝大多数 javascript 相关的包都放在 npm 上。

所谓,就是别人提供出来供他人使用的项目。可以是简单的几行代码,可以是 jQuery 这种类库,也可以是框架 express ,还可以是 webpack 这样的工具。

npm 用于解决前端共享问题。

以前我们需要使用 jQuery、bootstrap 等其他库,需要这么做:

  1. 进入 jQuery 和 bootstrap 等其他库的官网
  2. 将库下载到本地
  3. 本地引入库

npm 的作者希望简化这个过程,比如只需要执行一条命令 npm install jquery,就能将 jquery 下载到本地。

实现的思路大概是这样:

  1. npm 作者发邮件给 jQuery 和 bootstrap 的作者,让他们把项目放到 npm 上
  2. jQuery 和 bootstrap 的作者由于不认识发邮件的人,当然会拒绝
  3. node 的作者缺少一个包管理器,而 npm 作者有一个包管理器,于是两人抱团取暖,node 内置了 npm
  4. 后来 node 火了,npm 也出名了,于是 jQuery 和 bootstrap 的作者主动把项目放到 npm 上
  5. 现在基于 node 开发的环境,如果需要引入什么包,只需要一个命令

初步认识 node一文中,我们已经成功安装了 node,而 node 内置了 npm,现在我们就可以用 npm 下载一个包体验一下:

$ node --version // 查看 node 是否已成功安装
v12.18.1 $ npm --version // 查看 npm 版本
6.14.5 $ npm install jquery // {1}
npm WARN saveError ENOENT: no such file or directory, open 'D:\package.json'
...
...
+ jquery@3.6.0
added 1 package from 1 contributor and audited 1 package in 1.692s
found 0 vulnerabilities

运行 npm install jquery(行{1})会将 jquery 下载到项目根目录的 node_modules 文件夹中。

npm 另一个意思就是 npm 网站,npm 的包就存在那里。如果可以在该网站中搜索到相应的包名(PackageName),那我们就可以通过 npm install PackageName 下载。

输入 npm install hello-world ,看看会发生什么...

package.json

Node项目中 package.json 就是项目的核心。

运行 npm init 能创建一个 package.json 文件。请看示例:

// 输入 npm init 回车,会依次让你输入关于项目的配置信息,这里一路回车
$ npm init
...
package name: (test2)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to D:\test2\package.json: {
"name": "test2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
} Is this OK? (yes) yes

输入完 yes 后,会在项目根目录下生成一个 package.json 的文件。内容如下:

{
"name": "test2", // 名称
"version": "1.0.0", // 版本
"description": "", // 描述
"main": "index.js", // 入口文件
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

如果你打算发布软件包,package.json 中最重要的字段是 name 和 version,因为它们是必填;如果你不打算发布,name 和 version 则是可选的。

main 字段是程序主入口点。如果我安装了一个包(xx),然后执行 require(xx),将返回入口文件的导出模块。请看示例:

// 下载包
$ npm install underscore // 创建文件 1.js
let _ = require('underscore')
console.log(_) // 运行 1.js - 输出导出模块
$ node 1
[Function: _] {
VERSION: '1.12.0',
toPath: [Function: toPath],
iteratee: [Function: iteratee],
templateSettings: {
evaluate: /<%([\s\S]+?)%>/g,
...
... // 修改 underscore 的主入口文件 node_modules\underscore\package.json
{
"main": "underscore.js",
// 改为
"main": "underscore2.js", // {1}
} // 创建 node_modules\underscore\underscore2.js,内容如下:
exports.name = 'aaron' // 运行 - 导出模块变成 { name: 'aaron' }
$ node 1
{ name: 'aaron' } // {2}

通过修改 underscore 的主入口文件(行{1}),最终 underscore 导出的模块是 { name: 'aaron' }(行{2})

我们也可以通过 npm init -y 跳过向导,快速生成 package.json。

npm install

执行 npm init -y 快速生成 package.json 文件后,再运行 npm install jquery 来安装 jquery,会在 package.json 中增加 dependencies 字段。内容如下:

{
...
"license": "ISC",
"dependencies": {
"jquery": "^3.6.0"
}
}

dependencies 字段声明了此项目依赖的包

:网上有的文章说执行 npm install jquery,不会在 package.json 中增加 dependencies 项,可能以前的 npm 不会。笔者的 npm 是 6.14.5,参考的文档是 npm-install V6,里面说 npm install 默认将软件包保存到 dependencies 中。

此外还可以控制保存软件包的位置和方式,请看示例:

// 不保存在 dependencies
$ npm install jquery --no-save // 保存在 devDependencies
$ npm i jquery --save-dev

执行 npm install (不带任何参数)将安装 package.json 中列出的所有依赖包。请看示例:

{
...
"license": "ISC",
"dependencies": {
"jquery": "^3.6.0"
},
"devDependencies": {
"underscore": "^1.12.0"
}
}

package.json 中列出了两个依赖,执行 npm install 将会把 jquery 和 underscore 下载到项目根目录的 node_modules 文件夹中。

当安装包或删除包,npm 都会生成或更新 packagew-lock.json 文件。npm 5 以前没有 packagew-lock.json 这个文件。笔者的 npm 是 6.14.5,运行 npm install jquery,package.json 和 package-lock.json 的内容如下:

// package.json
{
"dependencies": {
"jquery": "^3.6.0" // {1}
}
} // package-lock.json
{
"dependencies": {
"jquery": {
"version": "3.6.0", // {2}
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
"integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
}
}
}

package-lock.json 最重要的作用是锁定版本。在 package-lock.json 中明确写明 jquery 的版本是 3.6.0,而 package.json 中的是 ^3.6.0。

其次,package-lock.json 能提升下次执行 npm install 的速度。通常一个包会依赖其他很多包(jquery是特列),以 express 为例:

$ npm install express

// package.json
{
"dependencies": {
"express": "^4.17.1"
}
} // package-lock.json
{
// dependencies 中的都是 express 依赖的包
"dependencies": {
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
},
"array-flatten": {
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
},
"body-parser": {
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
},
...
"express": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
"requires": {
...
}
}
...
// express 依赖的包还有很多
}
}

执行 npm install express 花费 12s。因为需要先下载 express,解析 express 中的 package.json,下载里面依赖的包,接着分析依赖包并下载,如此反复执行,所以花费时间较长。而再次运行 npm install,只需找到 package-lock.json 文件,无需循环下载、解析,而是直接从 resolved 指向的地址下载包即可。

npm uninstall

运行 npm uninstall express,会从 package.json 文件、package-lock.json 文件,以及 node_modules 文件夹,这三个方面删除 express 相关的依赖包。

安装(npm install)有保存软件包的位置和方式(--save、--save-dev),卸载(npm uninstall)时也有(--save、--save-dev)。请看示例。

// 最初安装了两个包
{
...
"license": "ISC",
"dependencies": {
"jquery": "^3.6.0"
},
"devDependencies": {
"underscore": "^1.12.0"
}
} // 卸载 jquery,dependencies 对象被删除
$ npm uninstall jquery
{
...
"license": "ISC",
"devDependencies": {
"underscore": "^1.12.0"
}
} // 卸载 underscore,devDependencies 对象被删除
$ npm uninstall underscore --save-dev
{
...
"license": "ISC"
}

运行 npm uninstall jquerynpm uninstall jquery --save 的效果相同(npm 以前的版本需要指定 --save)

:如果上面例子中执行 npm uninstall jquery --save-dev,效果与 npm uninstall jquery 类似,也能达到卸载的目的。建议不要这样,如果要删除 devDependencies 中的包,那就使用 --save-dev

npm --help

通过 npm --help 可以查看 npm 命令。请看示例:

$ npm --help

Usage: npm <command>

npm install        install all the dependencies in your project
npm install <foo> add the <foo> dependency to your project
npm test run this project's tests
npm run <foo> run the script named <foo>
npm <command> -h quick help on <command>
npm -l display usage info for all commands
npm help <term> search for help on <term> (in a browser)
npm help npm more involved overview (in a browser) All commands: access, adduser, audit, bin, bugs, cache, ci, completion,
config, dedupe, deprecate, diff, dist-tag, docs, doctor,
edit, exec, explain, explore, find-dupes, fund, get, help,
hook, init, install, install-ci-test, install-test, link,
ll, login, logout, ls, org, outdated, owner, pack, ping,
prefix, profile, prune, publish, rebuild, repo, restart,
root, run-script, search, set, set-script, shrinkwrap, star,
stars, start, stop, team, test, token, uninstall, unpublish,
unstar, update, version, view, whoami

如果需要查看特定命令的帮助,可以使用 npm 命令 --help。例如:

$ npm init --help

npm init [--force|-f|--yes|-y|--scope]
npm init <@scope> (same as `npx <@scope>/create`)
npm init [<@scope>/]<name> (same as `npx [<@scope>/]create-<name>`) aliases: create, innit

有快速创建 package.json 的参数 -y

$ npm install --help
npm install (with no args, in package dir)
npm install [<@scope>/]<pkg>
npm install [<@scope>/]<pkg>@<tag>
npm install [<@scope>/]<pkg>@<version>
npm install [<@scope>/]<pkg>@<version range>
npm install <alias>@npm:<name>
npm install <folder>
npm install <tarball file>
npm install <tarball url>
npm install <git:// url>
npm install <github username>/<github project> aliases: i, in, ins, inst, insta, instal, isnt, isnta, isntal, add
common options: [--save-prod|--save-dev|--save-optional|--save-peer] [--save-exact] [--no-save]

可以使用 install 的别名,例如要安装 jquery:npm i jquery

npm 镜像

由于 npm 的服务器是国外的,下载包有时会很慢,所以我们有时会配置镜像。比如配置淘宝镜像,使用起来也很方便,用 cnpm 代替 npm。例如要通过镜像下载: cnpm install jquery

其他章节请看:

前端学习 node 快速入门 系列

前端学习 node 快速入门 系列 —— npm的更多相关文章

  1. 前端学习 node 快速入门 系列 —— 模块(module)

    其他章节请看: 前端学习 node 快速入门 系列 模块(module) 模块的导入 核心模块 在 初步认识 node 这篇文章中,我们在读文件的例子中用到了 require('fs'),在写最简单的 ...

  2. 前端学习 node 快速入门 系列 —— 简易版 Apache

    其他章节请看: 前端学习 node 快速入门 系列 简易版 Apache 我们用 node 来实现一个简易版的 Apache:提供静态资源访问的能力. 实现 直接上代码. - demo - stati ...

  3. 前端学习 node 快速入门 系列 —— 服务端渲染

    其他章节请看: 前端学习 node 快速入门 系列 服务端渲染 在简易版 Apache一文中,我们用 node 做了一个简单的服务器,能提供静态资源访问的能力. 对于真正的网站,页面中的数据应该来自服 ...

  4. 前端学习 node 快速入门 系列 —— 报名系统 - [express]

    其他章节请看: 前端学习 node 快速入门 系列 报名系统 - [express] 最简单的报名系统: 只有两个页面 人员信息列表页:展示已报名的人员信息列表.里面有一个报名按钮,点击按钮则会跳转到 ...

  5. 前端学习 node 快速入门 系列 —— 初步认识 node

    其他章节请看: 前端学习 node 快速入门 系列 初步认识 node node 是什么 node(或者称node.js)是 javaScript(以下简称js) 运行时的一个环境.不是一门语言. 以 ...

  6. vue 快速入门 系列 —— vue loader 上

    其他章节请看: vue 快速入门 系列 vue loader 上 通过前面"webpack 系列"的学习,我们知道如何用 webpack 实现一个不成熟的脚手架,比如提供开发环境和 ...

  7. vue 快速入门 系列 —— vue-cli 下

    其他章节请看: vue 快速入门 系列 Vue CLI 4.x 下 在 vue loader 一文中我们已经学会从零搭建一个简单的,用于单文件组件开发的脚手架:本篇,我们将全面学习 vue-cli 这 ...

  8. MongoDB学习笔记:快速入门

    MongoDB学习笔记:快速入门   一.MongoDB 简介 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统.在高负载的情况下,添加更多的节点,可以保证服务器性能.M ...

  9. webpack 快速入门 系列 - 自定义 wepack 上

    其他章节请看: webpack 快速入门 系列 自定义 wepack 上 通过"初步认识webpack"和"实战一"这 2 篇文章,我们已经学习了 webpac ...

随机推荐

  1. 一篇文章图文并茂地带你轻松学完 JavaScript 闭包

    JavaScript 闭包 为了更好地理解 JavaScript 闭包,笔者将先从 JavaScript 执行上下文以及 JavaScript 作用域开始写起,如果读者对这方面已经了解了,可以直接跳过 ...

  2. Vue3.0新特性

    Vue3.0新特性 Vue3.0的设计目标可以概括为体积更小.速度更快.加强TypeScript支持.加强API设计一致性.提高自身可维护性.开放更多底层功能. 描述 从Vue2到Vue3在一些比较重 ...

  3. shapefile中dbf的数据格式(转载)

    来源:http://www.clicketyclick.dk/databases/xbase/format/db2_dbf.html#DB2_DBF_NOTE_4_SOURCE Xbase: dBAS ...

  4. Linux系统启动过程内核文件丢失解决方法

    一.问题描述 公司近期因机房断电,导致服务器重启后,引导进入不了操作系统.经过检查发现启动文件缺失,导致系统启动失败,网上搜了好多资料,解决都比较零散,现结合实际处理经验和网友的建议整理接方案. 二. ...

  5. 抓包 127.0.0.1 (loopback) 使用 tcpdump+wireshark

    直接使用 wireshark无法抓取 127.0.0.1环回的数据包,一种解决方法是先传到路由器再返回,但这样可能造成拥塞. Linux 先使用tcpdump抓包并输出为二进制文件,然后wiresha ...

  6. UML类图设计神器 AmaterasUML 的配置及使用

    最近写论文需要用到UML类图,但是自己画又太复杂,干脆找了个插件,是Eclipse的,也有IDEA的,在这里我简单说下Eclipse的插件AmaterasUML 的配置与使用吧. 点击这里下载Amat ...

  7. Linux 驱动框架---platform驱动框架

    Linux系统的驱动框架主要就是三个主要部分组成,驱动.总线.设备.现在常见的嵌入式SOC已经不是单纯的CPU的概念了,它们都会在片上集成很多外设电路,这些外设都挂接在SOC内部的总线上,不同与IIC ...

  8. Vue & Sentry & ErrorHandler

    Vue & Sentry & ErrorHandler import * as Sentry from '@sentry/browser'; import { Vue as VueIn ...

  9. React render twice bug

    React render twice bug React bug constructor render twice bug update render twice bug StrictMode htt ...

  10. Python Quiz & Python Exercise

    Python Quiz & Python Exercise https://www.w3schools.com/quiztest/quiztest.asp?qtest=PYTHON https ...