web前端开发之JavaScript:Node.js模块化

举报
运气男孩 发表于 2020/08/30 23:32:17 2020/08/30
【摘要】 node.js的模块化简介

Node模块化

Node.js 有一个简单的模块加载系统,遵循的是 CommonJS 的规范。 在 Node.js 中,文件和模块是一一对应的(每个文件被视为一个独立的模块)。

Escript标准缺陷(Es5之前)

  • 没有模块系统

  • 标准库较少

  • 没有标准接口

  • 缺乏管理系统

模块化

  • 为什么需要模块化? -->  开发规模日渐庞大 ,在浏览器中,顶层作用域的变量是全局的,所以项目稍微复杂点,如果引用的 js 非常多的时候,很容易造成命名冲突,然后造成很大意想不到的结果。为了避免全局污染,JS 前辈们想了很多办法,也就是前端的模块化的演变过程

  • 什么是模块化?-->  最基本模块化是将代码分割为多个原文件机制

  • 模块化的好处? -->  可复用代码、拥有独自作用域,变量命名互不干扰

Node 在加载 JS 文件的时候,自动给 JS 文件包装上定义模块的头部和尾部

// nodejs 会自动给我们的js文件添加头部,见下行
(function(exports, require, module, __filename, __dirname) {
  // 这里是你自己写的js代码文件
}); // 自定添加上尾部

image.png

Node会自动给js文件模块传递的5个参数,每个模块内的代码都可以直接用。而且你也看到了,代码都会被包装到一个函数中,所以代码的作用域都是在这个包装的函数内,这点跟浏览器的window全局作用域是不同的。

模块内的参数说明:

  • __dirname: 当前模块的文件夹名称

  • __filename: 当前模块的文件名称---解析后的绝对路径。

  • module: 当前模块的引用,通过此对象可以控制当前模块对外的行为和属性等。

  • require:是一个函数,帮助引入其他模块.

  • exports:这是一个对于 module.exports 的更简短的引用形式,也就是当前模块对外输出的引用。

CommonJS规范

  • CommonJS规范的提出,主要是为了弥补Es6之前JS没有模块化标准的缺陷

  • CommonJS规范为JS制定了一个美好愿景,希望JS能狗崽任何地方运行。

  • CommonJSCommonJS规范对模块的定义十分简单:

  • 模块引用  --> 提供require()方法引用模块

  • 模块定义  -->  Node中一个文件就是一个模块

  • exports对象导出当前模块的变量或方法

  • module对象,代表模块自身,exports是module对象的属性

  • 模块标识 -->  即模块名,传递给require()方法的参数(需符合驼峰命名法的字符串,或是以.或..开头的相对路径;绝对路径亦可)

Node的模块实现

  • Node中虽然使用的是CommonJS规范,但是自身也对规范做了一些取舍

  • 在Node中引入模块,需要经历如下3个步骤:

  • 路径分析

  • 文件定位

  • 编译执行

  • 在Node中,模块分为三大类:

  • 由底层C++编写的内建模块

  • 由Node提供的核心模块

  • 由用户编写的文件模块

模块引用、定义

  • 一个js文件就是一个模块

  • 每一个js文件中的js代码都是独立运行在一个函数内中的

  • 暴露属性: exports.x = 10;

  • 暴露方法: exports.fn = function(){};

  • 每个js文件其实相当于写在function(){js模块代码};

  • 所以在js模块中定义的变量和函数在其他模块中是无法访问的

  • 可以通过exports向外部暴露属性和方法

  • 通过require()函数来引入外部的模块

  • require()可以传递一个文件的路径作为参数,node将会自动根据该路径来引入外部模块

  • 这里路径,如果使用相对路径,必须以.或..开头

  • 使用require()引入模块以后,该函数会返回一个对象,这个对象代表的是引入的模块

  • 引入:var md = require("./02.module.js") md可以更换为其它的名称

  • 使用:console.log(md.x)

Node模块化中所声明的变量都为局部变量(原理:其实是运行在函数中的代码块)。

证明方式1:

let a = 10;

console.log(a);    // 10

console.log(global.a);  // undefined

证明方式2:

console.log(arguments.callee + "");


模块化的本质:封装的独立函数作用域的特性

function (exports, require, module, __filename, __dirname) {

    // coding...

}


  • require()引用

// 引用自定义模块

// require("./module1.js");

    // 亦可忽略 .js 后缀名

    // require("./module1");

// 引用模块,并接收所引用模块暴露的对象

let module1 = require("./moudle1");

// 引用核心模块 或 node_modules文件内的第三方模块,无须添加路径地址,直接写包名即可。

let fs = require("fs");



  • module.exports导出

// 方式1:

module.exports.a = 10;

module.exports.fn = () => {

    console.log("fn...");

}

// 方式2:

module.exports = {

    a: 10,

    fn() {

        console.log("fn");

    }

}

  • exports导出

exports.a = 10;

exports.fn = () => {

    console.log("fn...");

}

P.x exports 无法直接导出一个对象, 因为是 module.exports的引用

  • __filename  当前文件所在路径(绝对路径)

  • __dirname  当前文件所在文件夹路径(绝对路径)


Exports和module

exports

  • helloModule.js

    exports.name = "孙悟空";
    exports.age = 18;
    exports.sayName = function(){
      console.log("我是孙悟空~~~");    
    };
  • 05.module.js

    var hello = require("./helloModule");
    console.log(hello.name);
    console.log(hello.age);
    hello.sayName();

module.exports

  • helloModule.js

    module.exports.name = "孙悟空";
    module.exports.age = 18;
    module.exports.sayName = function(){
      console.log("我是孙悟空~~~");    
    };

     

            输出结果并不会变

区别

以下代码使用module.export=不会出错,使用export=程序报错

  • helloModule.js

    module.exports = {
      name:"猪八戒";
      age:28;
      sayName:function(){
          console.log("我是猪八戒")
      }
    };

    为什么使用export会出错

  • 基本数据类型 和 引用数据类型 之间的问题

  • 栈内存(独立) 和 堆内存(指向) 的问题 (关闭浏览器才释放内存的特性)

  • exports = module.exports

  • 通过export只能使用对象.属性来赋值 (修改对象的属性)

  • module.exports 即可以通过对象.属性赋值,也可以直接赋值 (即可以修改对象的属性,也可以修改对象)

    • module.exports.xxx = xxxx;

    • module.exports = { xx:xx;xxx:xxx;};

var obj = {};
obj.a = {};
var a = obj.a;
// a 和 obj.a 指向的是同一个对象
// console.log(a == obj.a); // 返回 true
a.name = "孙悟空";
a = new Object();

console.log(obj.a.name);    // 孙悟空
console.log(a.name);    //undefined




【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。