node.js的模块化与包

Posted 清华池校友

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了node.js的模块化与包相关的知识,希望对你有一定的参考价值。

一.模块化

1.为何要模块化

一个js文件引入其他的js文件后,可以使用引入文件中的变量,数据等,node.js支持模块化.

在es6之前,js是没有模块化的功能的,js代码依靠html文件统一管理,这样做的问题很明显,变量污染

并且代码无法维护.

2.模块化的历史

2.1 es6前

为了支持模块化,程序员借用第三方库实现模块化

  • sea.js
  • require.js

2.2 es6后

  • es6原生语法也支持模块化(浏览器不是直接支持模块化 --- 需要单独设置)

  • Nodejs内部也支持模块化

3.模块化规范

概念:拆分模块和组合模块时,所遵守的规则,就叫做模块化规范。

例如:在 Node.js 中,导入其它模块时,统一使用 require() 函数。

 常见的模块化规范

  • CommonJS 规范:nodejs中遵守的就是commonjs规范。

  • ES6 模块化规范:(前后端通用的模块化规范;Node.js、Vue、React 中都能使用!)

  • CMD 和 AMD 模块化规范(较少使用): CMD--sea.js, AMD-require.js

  • UMD 叫做通用模块定义规范(Universal Module Definition),它可以通过运行时或者编译时让同一个代码模块在使用 CommonJs、CMD 甚至是 AMD 的项目中运行。它没有自己专有的规范,是集结了 CommonJs、CMD、AMD 的规范于一身。

4.使用commonJS规范来自定义模块

4.1使用场景

  • 代码需要在项目重用

  • 代码需要提供给他人使用

  • 代码虽然不需要重用,但封装成模块有利于优化代码结构,方便后期维护与扩展

4.2 commonJS规范

  1. 导入其他模块使用require()方法
  2. 每个.js文件都是一个独立的模块,模块内的成员都是私有的
  3. 在每个JS模块中,可以使用module.exports向外共享成员

自定义模块特点:

使用require('自定义模块的路径')即可导入自定义模块

自定义模块内的变量,函数都是私有的,默认无法被外界访问.

5.注意点

5.1不要使用特殊的文件名

5.2导入模块的路径是相对路径

5.3自定义模块需要导出才能被其他文件使用

  • module.exports是固定写法,一般放在文件最后,只需使用一次
  • 需要用什么就导出什么,无需全部导出

 6.导入模块的两种方式

//定义变量
let a = 123
let b = 456

//导出.两种方式

//方法一(有效)
module.exports = {
a,
b
}

//方法二(有效)
exports.a = a
exports.b = b

//方法三(无效)
export = {
a,
b
}

为什么方法三无效呢?

初始exports和module.exports是指向同一块内存区域,其内容都是一个空对象

exports 是module.exports的别名

exports === module.exports

方法一二相当于修改对象内的值,没有重新定义

方法三的含义为给exports重新赋值一个对象,此时export与module.exports不再指向同一个对象,但引入模块会默认以模块代码中的module.exports指向的内容为准,所以相当于导出了一个空对象.

所以在实际开发中,导出模块时,建议直接使用module.exports

7.require的加载机制

有些情况发现别人的代码中require(文件名),文件名有时不带后缀名,其实这个与require 的加载机制有关,那么require 的机制有哪些呢?

  1. require优先加载缓存中的模块。同一个模块第一次require之后,就会缓存一份,下一次require时就直接从缓存中去取。

  2. 如果是加载核心模块,直接从内存中加载,并缓存,加载核心模块的格式是 const xxx = require("模块名") 。不能写相对路径!

  3. 如果是相对路径,则根据路径加载自定义模块,并缓存                                                                以require('./main')为例( 省略扩展名的情况)                                                                    先加载 main.js,如果没有再加载 main.json,如果没有再加载 main.node(c/c++编写的模块),找不到就报错。

  4. 第三方模块的机制放到后面  


二.npm和包和模块

1.npm

  • npm(Node Package Manager),解决Node中第三方包共享的问题
  • npm不需单独安装,在安装Node时,已经捆绑安装了
  • npm -v命令检查安装情况

 可以在npm中下载所有的库(例如:jQuery,bootStrap等)

2.包与模块的关系

npm网站上去下载我们的需要的代码时,它们是以""这种结构放在npm网站上的.

  • nodejs中一个模块就是一个单独的js文件

  • 包是多个模块的集合。一个模块的功能比较单一,所以一个包一般会包含多个模块。

  • npm 管理的单位是包。

3.下载与使用

  1. 初始化项目 npm init 命令 如果之前已经初始化,则可以省略。
  2. 安装 npm install 包名 
  3. 引入模块,使用

注意点:

初始化:创建的文件夹不能有中文

如果你希望直接采用默认信息,可以使用:

npm init --yes
// --与yes之间没有空格, -- 与init之间有空格
// 或者是 npm init -y

init命令用来在根目录下生成一个package.json文件,这个文件中记录了我们当前项目的基本信息,它是一切工作的开始。

package.json文件是由npm init命令创建出来的,它的整体内容是一个json字符串,用来对当前项目进行整体描述。其中最外层可以看作是一个js的对象(每一个属性名都加了"",这就是一个典型的json标记)。

  • name: 表示这个项目的名字。如是它是一个第三方包的话,它就决定了我们在require()时应该要写什么内容。

  • version:版本号

  • keywords:关键字

  • author: 作者

  • descrption: 描述

安装包:

npm install 包名
npm i 包名

使用:当我们已经下载好一个包之后,就可以像使用核心模块一样去使用它。

// 从npm下载 别人写的好代码,在本地引入,并使用
const dayjs = require('包名')
console.log(包名);
console.log( 包名().format('YYYY-MM-DD') );

使用镜像可以使下包更快

设置代码

# 设置镜像为taobao。
npm config set registry https://registry.npm.taobao.org
# 设置镜像为npm官方
npm config set registry https://registry.npmjs.org
# 查看配置
npm config get registry 

4.全局包与项目包

全局安装的包一般可提供直接执行的命令。我们通过对一些工具类的包采用这种方式安装,如:

gulp, nodemon, live-server, nrm等。

本地安装的包是与具体的项目有关的, 我们需要在开发过程中使用这些具体的功能。

  • 全局安装: 包被安装到了系统目录(一般在系统盘的node_modules中)。

    • 命令:npm install -g 包名 或者 npm install 包名 -g

    • 辅助命令:

      • npm root -g           // 查看全局包的安装目录
        npm list -g --depth 0 // 查看全局安装过的包
  • 项目安装(或者叫本地安装),包安装在当前项目的根目录下(与package.json同级)的node_modules中。

    • 命令:npm install 包名

5.全局安装nrm包 

nrm包可以用来调整npm镜像,使用nrm之后,就可以简化切换镜像源的命令.

安装步骤:

// 第一步: 全局安装 
npm install nrm -g

// 第二步:列出所有的源信息
// (*)标注的就是当前使用的源
nrm ls

// 第三步:根据需要切换源 
// 例如:指定使用taobao镜像源
nrm use taotao

// 接下来,正常安装你需要的包

一般情况需要修改才可以使用,点击这里,查看修改方式

6.开发依赖包与生产依赖包

6.1开发依赖包

项目在开发时会使用它,而项目一旦上线,就不再需要。此类一般归为"开发依赖"。

//保存到开发依赖(devDependencies)
npm install 包名 --save-dev
// 或者 npm install 包名 -D
//通过这种方式安装的包出会现在package.json文件中的`devDependencies`字段中。

6.2生产依赖包

例如一个项目使用的包,参与了开发编写代码,线上环境运行也必须有它参与,此类一般归类为"生产依赖"。

//保存到生产依赖(dependencies)
npm install 包名
// 或者 npm install 包名
// 或者 npm install 包名 -S

如何判断包的形式?看npm文档

7.i5ting_toc 包

7.1作用

用于将markdown文件转化为带样式的html字符串,i5ting_toc是node环境下的实现工具,用于直接将markdown文件转化为网页,在浏览器打开 。

7.2安装方式:全局安装

npm install -g i5ting_toc

7.3使用步骤

首先:编辑一个markdown文件,并命名,例如name.md

 在md文件所在根目录下打开终端键入如下命令:

i5ting_toc -f name.md -o
//-f file 文件名
//-o 是否在浏览器中打开文件

7.4其他命令

-h, --help             output usage information //显示用法信息
-V, --version          output the version number //显示版本
-f, --file [filename]  default is README.md //文件名,如果不填,默认文件名为README.md
-o, --open             open in browser //在浏览器打开
-v, --verbose          打印详细日志

8.nodemon包

 8.1作用

nodemon用于在开发中监视更改,并重新运行代码,比如nodemon监视中的文件发生了改动后,它就会响应,然后重启node运行代码

8.2安装方式:全局安装或本地安装

全局安装:

npm install -g nodemon

本地安装:

npm install nodemon --save-dev//--save-dev作用:将依赖包信息自动更新,无需再手动更改

8.3使用方式

首先创建一个index.js

在文件中写入如下代码 

 使用node打开,输出1

 此时如果修改代码,我们还需再次输入node命令来运行代码

十分的麻烦...头秃的同时,还心烦意乱.

我们使用如下方式在终端下运行代码(vscode终端不知道为何找不到服务),弹出如下信息

vscode终端报错

cmd下可使用

 此时再次修改index.js

 每次修改,nodemon均会重新运行一次代码,这样我们就可以安心专注于功能开发,而不用浪费我们宝贵的时间在一次又一次的重启代码啦

 

最后,如果我不爱nodemon了,不想用它了怎么关闭呢?简单快捷方式ctrl+c 终止进程 +Y 轻松搞定

 8.4其他命令

nodemon -h //help 获取帮助
nodemon --exec // 运行一些非js文件时会使用到
nodemon --ignore // 忽略某些文件或目录 写在这个后面的文件或目录更新后,nodemon将不跟随运行
nodemon --watch // 允许监视更多的文件,写在这个后面的文件更新,则nodemon也会跟随运行

(未完待续...)

以上是关于node.js的模块化与包的主要内容,如果未能解决你的问题,请参考以下文章

Node.js——模块与包管理工具

六npm与包

六npm与包

node基础2--模块化

python之基础篇——模块与包

Node.js JavaScript 片段中的跳过代码