目录
1.4.3 module.exports与exports的区别
为什么要创建项目自己的package.json文件?【重点】
一、模块系统
1.1 模块化介绍
1.1.1 传统开发的问题
随着项目的扩大,然后代码就越来越庞大 ,如果没有很好的规划,后期维护非常复杂(甚至就维护不了)。
比如:前端html中有很多特效会依赖js文件,前端有a.js文件、b.js文件,而a.js文件中的内容为:var usr="李四"; function demo(){};var email="[email protected]"; b.js文件中的内容为:var email="[email protected]"; function demo(){}; 当我们在c.html文件中同时引入了a.js和b.js文件后会报错,解决这些错误可以使用闭包、面向对象编程来解决,这些可以解决问题但没有一个统一的标准。
1.1.1 概述
nodejs的模块化概念
JavaScript 是一个强大面向对象语言,它有很多快速高效的解释器。然而, JavaScript
标准定义的 API 是为了构建基于浏览器的应用程序。并没有制定一个用于更广泛的应用程序
的标准库。CommonJS 规范的提出,主要是为了弥补当前 JavaScript 没有标准的缺陷。它的终
极目标就是:提供一个类似 Python,Ruby 和 Java 语言的标准库.
CommonJS 就是模块化的标准,nodejs 就是 CommonJS( ( 模块化 ) 的实现。
CommonJS模块化会应用于nodejs、vue、react等等框架语言。
1.1.2 nodejs的模块化分类
在node中,模块可以分为两类
一类是 Node 提供的模块,称为 核心 模块;
另一类是用户编写的模块,称为 文件模块。
• 核心模块部分在 Node 源代码的编译过程中,编译进了二进制执行文件。在 Node 进
程启动时,部分核心模块就被直接加载进内存中,所以这部分核心模块引入时,文件定位和
编译执行这两个步骤可以省略掉,并且在路径分析中优先判断,所以它的加载速度是最快的。
: 如:HTTP 模块 、URL 模块、Fs 模块都是 nodejs 内置的核心模块。 ,可以直接引入使用。
• 文件模块则是在运行时动态加载,需要完整的路径分析、文件定位、编译执行过程、
速度相比核心模块稍微慢一些,但是用的非常多。 这些模块需要我们自己定义。 接下来我
下 们看一下 nodejs 中的自定义模块。
CommonJS (Nodejs ) 中 自定义 模块的规定:
1.我们可以把公共的功能 抽离成为一个单独的 js 文件 作为一个模块,默认情况下面这
个模块里面的方法或者属性,外面是没法访问的。如果要让外部可以访问模块里面的方法或
者属性,就必须在模块里面通过 exports 或者 module.exports 暴露属性或者方法。
2. 在需要使用这些模块的文件中,通过 require 的方式引入这个模块。这个时候就可以
使用模块里面暴露的属性和方法。
1.2. Commonjs简述
CommonJS 就是模块化的标准,nodejs 就是 CommonJS( ( 模块化 ) 的实现。
CommonJS模块化会应用于nodejs、vue、react等等框架语言。
1.2.1 组成
(1)如何定义数据和功能函数(如何定义公共代码)
(2)外部如何使用定义的数据和功能函数
1.2.2 定义规范的好处
既然是规范,那么就应该是大家默认都应该遵守的,这样就降低了沟通的成本,极大方便了各个模块之间的相互调用,利于团队协作开发。
1.3 模块的种类
-
自定义模块:(开发者自己定义的模块,每一个js文件都可以称为一个模块)开发者,可以使用commonjs规范自己写的js文件,都称为自定义模块
-
内置模块:(由Node.js官方提供,如:fs、path、querystring等)
-
第三方模块:(由第三方开源出来的模块,使用前需要npm工具从npm社区下载)
1.4 nodejs自定义模块
1.4.1 介绍
在nodejs中每个.js文件都是一个封闭的空间,因为当前.js文件中的代码被一个匿名函数所包裹着,代码如下:
function (exports, require, module, __filename, __dirname) {
let usr = '李四';
var hostname = 'www.jd.com';
//计算器
function jsq() {
console.log('jsq()计算器方法');
}
console.log(arguments.callee.toString());
}
ndoejs自定义模块的语法(commonjs):【重点】
单个暴露:
exports.属性名=值
exports.方法名=function(){}
或
module.exports.属性名=值
module.exports.方法名=function(){}
// let usr = '李四';
// var hostname = 'www.jd.com';
// //计算器
// function jsq() {
// console.log('jsq()计算器方法');
// }
// //arguments.callee:查看当前代码放在哪个函数中执行
// console.log(arguments.callee.toString());
//单个暴露:
exports.usr = '李四';
exports.hostname = 'www.jd.com';
module.exports.port = 80;
exports.jsq = function() {
console.log('jsq()计算器方法');
}
module.exports.fn = function() {
console.log('fn()方法在m1.js文件中');
}
批量暴露:
module.exports = { 属性名,方法名}
//批量暴露:
let hostname = 'www.qq.com';
var port = 8080;
function fn() {
console.log('fn()方法在m2文件中');
}
module.exports = { hostname, port, fn, "usr": "张三", "x": "测试下", mydemo() { console.log('mydemo()方法在m2文件中'); } };
自定义模块js
//引入自定义模块文件时要以./或../开头
let mm = require('./4-m1.js');
let mm2 = require('./5-m2.js');
let obj = require('./7-jsq.js');
// let mm3 = require('./8-m3.js');
let mm3 = require('./8-m3');
console.log(mm3, 333333);
console.log(obj, obj.jsq(9, 17));
console.log(mm, mm.usr, mm2.usr);
console.log(mm2);
mm.fn();
mm2.fn();
// console.log(mm, mm.usr, mm.hostname, mm.port);
// mm.jsq();
// mm.fn();
注意:单个暴露与批量暴露不能一起使用,因为exports是module.exports的引用,而module.exports是真实存在的,最终返回的是module.exports,演示代码如下:【重点】
9
1.4.2 定义、使用自定义模块文件的步骤
第一步:先创建.js自定义模块文件,在当前自定义模块文件中使用nodejs自定义模块语法来定义要暴露的属性或方法,比如:创建jsq.js模块文件,代码如下:
//计算器功能:
function jsq(num1, num2, flag = '+') {
let total = 0;
switch (flag) {
case '+':
total = num1 + num2;
break;
case '-':
total = num1 - num2;
break;
case '*':
total = num1 * num2;
break;
case '/':
total = num1 / num2;
break;
}
文章评论