服务端包管理工具:npm
问题
- bower 解决了依赖库的下载与更新等自动化管理任务,但它受限于浏览器环境,仍然是基于
script
标记来引入第三方库 - require.js 及 amd等虽然初步解决了模块化编码的规范和共享问题,但同样受限于浏览器环境,不能利用于node.js在服务端环境下的强大能力,如存取文件系统、自动化构建等
如何将两者的优点结合起来呢?
CommonJS包规范 与 NPM (Node Package Manager)
- CommonJS是类似于AMD的软件包编写规范,但面向非浏览器环境
- NPM则是一个基于命令行的包管理工具,它能够识别和管理基于CommonJS规范编写的代码库,并且提供了仓库、下载、安装、引用等一系列的功能
- NPM默认被集成在node.js环境中,从而为基于node.js编程提供了极大的便利
CommonJS包规范
代码库的作者在编写代码时,应当遵行如下原则:
- 一个文件就是一个模块,拥有单独的作用域;
- 普通方式定义的变量、函数、对象都属于该模块内;
- 通过
require
语句来加载模块; - 通过
exports
和modul.exports
来定义和暴露模块中的函数或类;
npm 包结构
代码库的作者在打包和发布代码库时,应当遵行如下文件布局:
- package.json:包描述文件
- bin:存放可执行二进制文件的目录
- lib:存放js代码的目录
- doc:存放文档的目录
- test:存放单元测试用例代码的目录
使用 NPM Node Package Manager
进入项目根目录,执行下列命令来初始化 npm
npm init -y
初始化后,项目根目录下会新建一个名为 package.json 的 json 文件。里面包含了当前项目的信息以及所依赖的其它代码包的信息
npm 配置文件 package.json
{
"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 的属性会出现相应的列表,类似于bower
- 同时项目根目录下会创建一个
node_modules
的目录,下载的软件包会被存放至此
你可以自行编辑package.json增加或修改依赖包的信息,然后执行下述命令,则自动更新当前的包文件
npm i
基于 npm 的编程
// main.js
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库。 然后执行:
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包,并装载 - 如查找失败,则前往npm全局目录下寻找或其它设置的路径下查找,否则报错退出
- 根据CommonJS规范,将
cheerio
暴露的名称赋给本地名称,即cheerio
- 调用
cheerio
的各API,模拟类似jquery的操作
为什么上述代码中不直接使用jquery而要引入cheerio?
require : 语句还是函数?
const cheerio = require('cheerio')
这里的require并不是js内置的语句,而是一个特殊的函数,它是由node.js支持和引入的,所引入的第三方包必须符合commonjs规范
import cheerio from 'cheerio';
这段代码则是由ES6语言提出的最新语法ES modules,一般由typescript等环境提供支持(但需要转译);node.js V13.2.0 之后的版本开始提供支持;在最新的现代浏览器中则内置支持
http://caibaojian.com/es6/module.html http://www.ruanyifeng.com/blog/2020/08/how-nodejs-use-es6-module.html https://cloud.tencent.com/developer/article/1589084 https://juejin.cn/post/6844903983987834888