zoukankan      html  css  js  c++  java
  • [NodeJS]Node模块原理

          任何一门编程语言,当代码越写越多时,人们就会考虑如何将代码进行分类组织。通常情况下,都会讲代码按照功能进行拆分并保存在不同目录及文件中,通过相互引用来达到代码复用。那么这个时候不可避免的就会遇到全局变量可能会被污染的问题。通常情况下,很多语言都会提供一个叫做命名空间的概念,从而形成了模块这个概念。然而JS天生并没有提供命名空间这样一个机制。于是有热心的开发者提供了CommonJS和AMD,CMD等多种规范。其中NodeJS就是遵循CommonJS规范的。而现在ES6也已经推出,它提供的模块机制是综合了各家的优势后设立的另一套规范。

          现在我们来细细聊NodeJS中的模块机制。在NodeJS中,Node模块允许开发者从被引入的文件中选择要暴露给外界的函数或变量。机制是通过exports对象的属性或module.exports属性进行模块暴露。NodeJS模块系统正是通过这样一种机制来避免了全局作用域的污染,从而避免了命名冲突。接下来从几个方面来讲解模块。

    一、创建模块

          NodeJS中的模块可以是一个文件,也可以是一个包含多文件的目录。如果模块是一个目录,那么Node就会在该目录下查找一个叫index.js的文件作为模块的入口。当然这个文件名index.js也是可以通过package.json文件进行配置的。通过在exports对象上设置属性的方式来创建模块。

    var canadianDollar = 0.91;
    function roundTwoDecimals(amount){
        return Math.round(amount*100)/100;
    }
    exports.canadianToUS = function(canadian){
        return roundTwoDecimals(canadian * canadianDollar);
    }
    exports.USToCanadian = function(us){
        return roundTwoDecimals(us / canadianDollar);
    }

    通过require(path)的方式来加载模块。注意如果是自定义文件模块并且处在同一目录下,那么一定要记住请使用 " ./ " 这个相对路径标识。

    var currency = require('./currency');
    console.log("50 Canadian dollars equals this amount of US dollars:");
    console.log(currency.canadianToUS(50));
    console.log("30 US dollar equals this amount of Canadian dollars:");
    console.log(currency.USToCanadian(30));

    也可以通过module.exports来创建模块

    function Currency(canadianDollar){
        this.canadianDollar = canadianDollar;
    }
    Currency.prototype.roundTwoDecimals = function(amount){
        return Math.round(amount*100)/100;
    };
    Currency.prototype.canadianToUS = function(canadian){
        return this.roundTwoDecimals(canadian * this.canadianDollar);
    };
    Currency.prototype.USToCanadian = function(us){
        return this.roundTwoDecimals(us / this.canadianDollar);
    };
    module.exports = Currency;

    这样通过require方法引入的模块就是一个构造函数

    var Currency = require("./currency");
    
    var canadianDollar = 0.91;
    var currency = new Currency(canadianDollar);
    console.log(currency.canadianToUS(50));

    模块最终导出的是module.exports对象,而模块内部隐藏了一句代码exports = module.exports 所以不要轻易给exports重新设置引用关系。

    module对象在所有的Node程序中都存在,但是每个module对象都仅仅存在于它当前的模块内。也就是说只存在于模块作用域内。

    二、安装与加载模块

    从npm安装第三方模块使用  npm install [package] 命令

    通过require() 来加载模块

    通过npm search [package] 命令来查找模块

    同理,require对象也不是全局变量,而是每个模块内部的一个对象,作用于模块内。

    require对象的方法

    1. require.cache

    当模块被引入时,会被缓存到这个对象中,通过 delete 可以从该对象中删除键值,这样下次调用 require()时就会重新加载模块。不适用于核心模块,常用于第三方模块。

    2. require.resolve()

    使用内部的require()机制来查找模块的位置,但是不会加载模块,只是返回解析后的模块文件绝对路径( __filename )。这个绝对路径也是module对象中的Id属性。

    模块加载的内部原理

    通常在package.json文件中会通过main属性来指定模块入口文件,这样加载模块时会考虑这个默认文件。

  • 相关阅读:
    射频系统架构
    Tensorflow 2.0 mnist
    Lintcode 32. 最小子串覆盖 && Leetcode 76. Minimum Window Substring
    内存管理之智能指针unique_ptr&weak_ptr
    内存管理之智能指针shared_ptr
    内存管理之直接内存管理
    c++ 三大特性之继承
    稀疏矩阵乘法
    Linux环境下mysql常用命令
    字符串的查找删除
  • 原文地址:https://www.cnblogs.com/joyjoe/p/6939033.html
Copyright © 2011-2022 走看看