Appearance
NPM
元信息
- 目标:理解包管理如何从浏览器内的 script 标签走向 Node 环境的 npm——掌握 CommonJS 包规范、package.json 与依赖管理,会用 npm init/install 组织项目依赖
- 关键概念:NPM、CommonJS、package.json、dependencies、node_modules、require
- 关联阶段:cp3
- 常见误区:以为 require 是 JS 语言语句(是 Node 运行环境提供的函数);以为 npm 只能在服务端项目用(它管理的包也可供构建工具消费);以为依赖信息记在脑子里就行(package.json 是依赖的单一事实源,npm i 按它还原)
问题
- 页面用
<script>标记手工引入第三方库(如从 CDN 下载),下载、版本、更新的管理全靠人工,项目一大便不可维护 - require.js 及 amd等虽然初步解决了模块化编码的规范和共享问题,但仍然受限于浏览器环境,不能利用 node.js 在服务端环境下的强大能力,如存取文件系统、自动化构建等
如何把"包的自动管理"与"服务端能力"结合起来呢?
CommonJS包规范 与 NPM (Node Package Manager)
- CommonJS是类似于AMD的软件包编写规范,但面向非浏览器环境
- NPM则是一个基于命令行的包管理工具,它能够识别和管理基于CommonJS规范编写的代码库,并且提供了仓库、下载、安装、引用等一系列的功能
- NPM默认被集成在node.js环境中,从而为基于node.js编程提供了极大的便利
CommonJS包规范
代码库的作者在编写代码时,应当遵行如下原则:
- 一个文件就是一个模块,拥有单独的作用域;
- 普通方式定义的变量、函数、对象都属于该模块内;
- 通过
require语句来加载模块; - 通过
exports和module.exports来定义和暴露模块中的函数或类;
npm 包结构
代码库的作者在打包和发布代码库时,应当遵行如下文件布局:
- package.json:包描述文件
- bin:存放可执行二进制文件的目录
- lib:存放js代码的目录
- doc:存放文档的目录
- test:存放单元测试用例代码的目录
使用 NPM Node Package Manager
进入项目根目录,执行下列命令来初始化 npm
bash
npm init -y初始化后,项目根目录下会新建一个名为 package.json 的 json 文件。里面包含了当前项目的信息以及所依赖的其它代码包的信息
npm 配置文件 package.json
jsonc
{
"name": "mylib", // 当前项目名称(中间不能有空格且必须小写),如果你要将当前项目发布为一个共享的npm包,则该名称不可以与已在npm中心仓库注册的名称相同
"version": "1.0.0", // 版本号
"description": "", // 描述
"main": "index.js", // 入口文件或主函数
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [], // 方便其它人搜索到本包的关键字
"author": "", // 作者
"license": "ISC",
"dependencies": {}, // npm i --save package 将添加至此
"devDependencies":{} // npm i --save-dev package 将添加至此,这里的依赖不会发布到Node的生产环境下
}上面是初始化之后的 package.json 文件(// 注释仅作说明,真实文件中不可有注释)
依赖包的管理
如果你使用npm install package-name安装了软件包
- package.json中的 dependencies 的属性会出现相应的列表
- 同时项目根目录下会创建一个
node_modules的目录,下载的软件包会被存放至此
你可以自行编辑package.json增加或修改依赖包的信息,然后执行下述命令,则自动更新当前的包文件
bash
npm i基于 npm 的编程
// main.js
javascript
const cheerio = require('cheerio')
const $ = cheerio.load('<h2 class="title">Hello world</h2>')
$('h2.title').text('Hello there!')
$('h2').addClass('welcome')
$.html()cheerio是一个提供类似jquery功能的node库。 然后执行:
bash
npm install cheerio
node main.js
// output: <html><head></head><body><h2 class="title welcome">Hello there!</h2></body></html>node 执行过程
- 基于
require('cheerio'), node执行引擎将在当前项目的node_modules下查找cheerio的npm包,并装载 - 如查找失败,则依次向上级目录的
node_modules继续查找(直至根目录);仍找不到再查NODE_PATH环境变量指定的路径,否则报错退出。注意:npm 全局安装目录不在查找路径中——所以项目依赖必须本地安装,全局安装只用于命令行工具 - 根据CommonJS规范,将
cheerio暴露的名称赋给本地名称,即cheerio - 调用
cheerio的各API,模拟类似jquery的操作
为什么上述代码中不直接使用jquery而要引入cheerio?
require : 语句还是函数?
javascript
const cheerio = require('cheerio')这里的require并不是js内置的语句,而是一个特殊的函数,它是由node.js支持和引入的,所引入的第三方包必须符合commonjs规范
javascript
import cheerio from 'cheerio';这是 ES6 语言原生的模块语法(ES modules)。TypeScript 等超集语言采用同样的写法(编译时转译回 JS);node.js V13.2.0 之后的版本开始提供支持;在最新的现代浏览器中则内置支持(需 type="module")
http://caibaojian.com/es6/module.htmlhttp://www.ruanyifeng.com/blog/2020/08/how-nodejs-use-es6-module.htmlhttps://cloud.tencent.com/developer/article/1589084https://juejin.cn/post/6844903983987834888