概念
ES6之前
ECMAScript存在以下几个问题
- 没有模块系统
- 官方标准库少/标准接口少
- 缺乏包管理系统
模块化
- 如果程序设计的规模达到了一定程度,则必须对其进行模块化
前端没多大必要, 所以不太需要
服务器端开发, 没有模块化开发思想就玩不转了 - 模块化可以有多种形式,但都提供了能够将代码分割为多个源文件的机制
Common.js
CommonJS规范
- CommonJS规范的提出,主要是为了弥补JavaScript没有模块化标准的缺陷
- CommonJS规范为JS希望JS能够在任何地方运行:这是一个美好的愿景
- CommonJS对模块的定义
模块引用:require(“路径”);
模块定义
模块标识
总结
- 从文件角度看, 每个JS文件就是一个模块
- 从结构看, 多个JS文件之间可以相互require,共同实现了一个功能,这整体上也是一个模块
- 在Node.js中,一个模块中定义的变量、 函数等, 都只能在这个文件内部有效
- 当需要从此JS文件外部引用这些变量,、函数时,必须使用exports进行暴露,使用者通过require引用
实践1
-
在Node中,一个js文件就是一个模块
-
在Node中,通过require()函数来引入外部的模块
引入外部模块要加上 . 或者 … -
在Node中,每一个js文件中的js代码都是独立运行在一个小闭包中, 而不是全局作用域,所以一个模块的中的变量和函数在其他模块中无法访问
目的: 全局变量私有化, 避免全局污染 -
暴露模块中的变量和函数
export
只需要将需要暴露给外部的变量或方法设置为exports的属性即可02.js
let site = 'www.itlike.com'; let log = ()=>{ console.log('这是一个神奇的网站:', site); }; exports.site = site; exports.log = log;
03.js
// 1. 引入其它模块 let fn = require('./02.js'); // console.log(fn); console.log(fn.site); fn.log();
实践2
模块标识
- 当我们使用require()引入外部模块时,使用的就是模块标识,我们可以通过模块标识来找到指定的模块
比如: let myFunc = require("./js/myFunc"); - 分类
① 内建模块:底层由C++编写
② 文件模块:由用户自己创建的模块
标识:文件的路径(绝对路径,相对路径)
③ 核心模块:由node引擎提供的模块、由node_modules提供的模块
标识:模块的名字、http、fs、global…
…
思考: export和require怎么来的?
- 错误答案: 全局变量
1)window不是Node中的全局对象
2)Node中有一个全局对象global, 作用和window类似 - 正确答案: 函数参数
1)函数的标识: arguments
获取函数的所有实参
2)获取函数自身 arguments.callee
返回函数本身
node文件组成剖析
- 当node在执行模块中的代码时,它会首先在代码的最顶部,添加如下代码 function (exports, require, module, __filename, __dirname) {
- 在代码的最底部,添加 }
- 所以模块中的代码都是包装在一个函数中执行的,并且在函数执行的同时传递进了5个实参
① exports: 该对象用来将函数内部的局部变量或局部函数暴露到外部
② require: 用来引入外部的模块
③ module: 代表的是当前模块本身, exports就是module的属性; 我们既可以使用 exports 导出,也可以使用module.exports导出
④ __filename: 当前模块的完整路径
⑤ __dirname: 当前模块所在文件夹的完整路径
Node中的Common.js
-
在node.js 里,模块划分所有的功能,每个JS都是一个模块
-
实现require方法,NPM实现了模块的自动加载和安装依赖
-
内部形式
(function(exports,require,module,__filename,__dirname){ exports = module.exports={} exports.brands = 'itlike'; exports = {brands :'itlike'}; return module.exports; })
exports 和 module.exports的区别
两者区别
- 在每一个模块中,最终返回的是module.exports.
exports类似一根指针,指向module.exports。因此,exports只能通过点语法获取并向外输出,无法通过赋值对象输出。
所以module改变方式是不受影响的,但exports改变就无法正确返回。(function(exports,require,module,__filename,__dirname){ exports = module.exports={}; return module.exports; })
- exports只能使用.语法来向外暴露内部变量
exports.xxx = xxx; - module.exports既可以通过.语法,也可以直接赋值一个对象
module.exports.xxx = yyy;
module.exports = {xxx: yyy};
值类型和引用类型
二、module&NPM模块分类
原生模块
http path fs util events 编译成二进制,加载速度最快,原生模块是通过名称来加载
文件模块
- 在硬盘的某个位置,加载速度非常慢,文件模块通过名称或路径来加载
- 文件模块的后缀有三种
① 后缀名为.js的JavaScript脚本文件,需要先读入内存再运行
② 后缀名为.json的JSON文件,需要借助fs模块读入内存,转化成JSON对象
③ 后缀名为.node的经过编译后的二进制C/C++扩展模块文件,可以直接使用 - 注意
① 一般自己写的通过路径来加载
② 其他人写的通过名称去当前目录或全局的node_modules下面去找
第三方模块
- 如果require函数只指定名称,则视为从node_modules下面加载文件,这样的话,我们可以移动模块而不需要修改引用的模块路径
- 第三方模块的查询路径包括module.paths和全局目录
- 全局目录
① window如果在环境变量中设置了NODE_PATH变量,并将变量设置为一个有效的磁盘目录,require在本地找不到此模块时,会向上在此目录下继续找这个模块
② UNIX操作系统中会从 $HOME/.node_modules $HOME/.node_libraries目录下寻找 - 模块加载策略
包
- 在Node.js中,可以通过包来对一组具有相互依赖关系的模块进行统一管理,通过包可以把某个独立功能封装起来
- 每个项目的根目录下面,一般都有一个package.json文件,定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)
- 使用
npm init
命令初始化包 -
npm install
命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境 - 图示
NPM
概念
- 安装完node之后只能使用Node语言特性及核心函数,我们还需要一个系统来下载、安装和管理第三方模块。
- 在 Node看这个系统被称为Node包管理器(Node Package Manager,NPM)
npm提供的功能
- 公共注册服务,用户可以把自己写的包上传到服务器上
- 命令行下载工具,用户可以通过npm命令把别人写的包下载到自己电脑上,还可以管理自己模块依赖的其它模块
- 搜索第三方包的地址:https://www.npmjs.com/search
npm命令
- 安装包
打开命令行或终端,进入要安装包的目录,然后执行以下命令安装依赖的模块npm install <package-name>
npm i jquery
此命令会从服务器上下载此模块到当前目录下的node_modules目录下,如果node_modules目录不存在则会创建一个, 也可以安装特定的版本npm install <package name>@<version spec>
npm i jQuery@3.1
npm i mime@2.x
- 卸载包
npm uninstall <package name>
- 更新包
npm update <package name>
包的安装模式
- 本地安装
① 默认情况下安装命令会把对应的包安装到当前目录下,这叫本地安装
② 如果包里有可执行的文件,NPM会把可执行文件安装到./node_modules/.bin目录下
③ 本地安装的模块只能在当前目录和当前目录的子目录里面使用 - 全局安装
① 希望安装的包能够在计算机机的所有目录下面都能使用,就需要全局安装npm install <package-name> -g
② 在全局安装的模式下,npm会把包安装到全局目录,通过此命令可以查看当前全局目录的位置
③ 如果要修改全局安装目录,可以使用npm config set prefix “E:\node.js\node_global”
- 注册、登录和发布模块
注册npm账号 https://www.npmjs.com/
登录,npm login
发布,npm publish
yarn
概念
- yarn 是一个依赖管理工具
- 它能够管理你的代码,并与全世界的开发者分享代码
- 代码是通过包(有时也被称为模块)进行共享的
- 在每一个包中包含了所有需要共享的代码,另外还定义了一个package.json文件,用来描述这个包
安装yarn
npm yarn --save -g
初始化一个新的项目
yarn init
添加一个依赖包
yarn add [package]
yarn add [package]@[version]
yarn add [package]@[tag]
更新一个依赖包
yarn upgrade [package]
yarn upgrade [package]@[version]
yarn upgrade [package]@[tag]
删除一个依赖包
yarn remove [package]
安装所有的依赖包
yarn
yarn install