zoukankan      html  css  js  c++  java
  • commonJs

    CommonJS规范

    0.7612018.08.22 16:32:05字数 1,793阅读 22,873

    导读

            内容大部分都是来源于 阮一峰老师的博客,做个搬运工加自己写一写。想看原文请移步CommonJS规范 -- JavaScript 标准参考教程(alpha)

    1.了解

            node应用由模块组成,采用的commonjs模块规范。每一个文件就是一个模块,拥有自己独立的作用域,变量,以及方法等,对其他的模块都不可见。CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。require方法用于加载模块。

    CommonJS模块的特点如下。

    所有代码都运行在模块作用域,不会污染全局作用域。

    模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。

    模块加载的顺序,按照其在代码中出现的顺序。

    2.module对象

            1.module.exports属性 

    module.exports属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取module.exports变量。

            2.exports变量

    node为每一个模块提供了一个exports变量(可以说是一个对象),指向 module.exports。这相当于每个模块中都有一句这样的命令 var exports = module.exports;

    这样,在对外输出时,可以在这个变量上添加方法。例如  exports.add = function (r){return Math.PI * r *r};注意:不能把exports直接指向一个值,这样就相当于切断了 exports 和module.exports 的关系。例如 exports=function(x){console.log(x)};

    一个模块的对外接口,就是一个单一的值,不能使用exports输出,必须使用 module.exports输出。module.exports=function(x){console.log(x);}; 

    用阮老师的话来说,这两个不好区分,那就放弃 exports,只用 module.exports 就好(手动机智)

    3.AMD规范和commonJS规范

    1.相同点:都是为了模块化。

    2.不同点:AMD规范则是非同步加载模块,允许指定回调函数。CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。

    来,取个栗子。AMD规范

    define(['package/lib'],function(lib){

    functionfoo(){

    lib.log('hello world!');

    }

    return{foo:foo};

    });

    再来个兼容的栗子,AMD规范允许输出的模块兼容CommonJS规范,这时define方法需要写成下面这样:

    define(function(require,exports,module{

    varsomeModule=require("someModule");

    varanotherModule=require("anotherModule");

    someModule.doTehAwesome();

    anotherModule.doMoarAwesome();

    exports.asplode=function({

    someModule.doTehAwesome();

    anotherModule.doMoarAwesome();

    };

    });

    4.require命令

            1.基本用法   require命令用于加载模块文件,相当于读入并执行一个js文件,然后返回该模块的exports对象,没有发现指定模块,则就会报错。

    例如  example.js    exports.name = 'tom';exports.age = 50;

    在 同目录下的 demo.js 文件中 var example = require('./example.js');

    console.log(example.name); // tom

    console.log(example.age); // 50

    或者 example.js  function fn(){console.log(1)};

    var name =  'tom'

    module.exports = {fn:fn,name:name} 这里可以简写一下,es6的对象简写,key 和 value 一致,可以只写一个。   module.exports = {fn,name};

    在 同目录下的 demo.js 文件中 var example = require('./example.js');

    example.fn(); // 1

    console.log(example.name); // tom

            2.加载规则。真的好长,我直接搬 阮老师的。

    根据参数的不同格式,require命令去不同路径寻找模块文件。

    (1)如果参数字符串以“/”开头,则表示加载的是一个位于绝对路径的模块文件。比如,require('/home/marco/foo.js')将加载/home/marco/foo.js。

    (2)如果参数字符串以“./”开头,则表示加载的是一个位于相对路径(跟当前执行脚本的位置相比)的模块文件。比如,require('./circle')将加载当前脚本同一目录的circle.js。

    (3)如果参数字符串不以“./“或”/“开头,则表示加载的是一个默认提供的核心模块(位于Node的系统安装目录中),或者一个位于各级node_modules目录的已安装模块(全局安装或局部安装)。

    举例来说,脚本/home/user/projects/foo.js执行了require('bar.js')命令,Node会依次搜索以下文件。

    /usr/local/lib/node/bar.js

    /home/user/projects/node_modules/bar.js

    /home/user/node_modules/bar.js

    /home/node_modules/bar.js

    /node_modules/bar.js

    这样设计的目的是,使得不同的模块可以将所依赖的模块本地化。

    (4)如果参数字符串不以“./“或”/“开头,而且是一个路径,比如require('example-module/path/to/file'),则将先找到example-module的位置,然后再以它为参数,找到后续路径。

    (5)如果指定的模块文件没有发现,Node会尝试为文件名添加.js、.json、.node后,再去搜索。.js件会以文本格式的JavaScript脚本文件解析,.json文件会以JSON格式的文本文件解析,.node文件会以编译后的二进制文件解析。

    (6)如果想得到require命令加载的确切文件名,使用require.resolve()方法。

            3.目录的加载规则 。。。

            4.模块的缓存

    第一次加载该模块,node会缓存该模块。再次加载,直接从缓存中取出该模块的module.exports属性。

    require('./example.js');

    require('./example.js').message="hello";

    require('./example.js').message        // "hello"

    删除模块的缓存  缓存保存在require.cache中,可操作该属性进行删除

    // 删除指定模块的缓存  

    delete require.cache[moduleName];

    // 删除所有模块的缓存Object.keys(require.cache).forEach(function(key){deleterequire.cache[key];})

            5.模块的循环加载

    5.模块的加载机制

            commonsJS的加载机制,输入的是被输出值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值了。

     

     

    require内部处理流程.......移步阮老师的教程吧。见顶部

    是不是看完了,感觉和浏览器没啥关系,对,我也是这么觉得的。不过阮老师有一个文章很好的解释了。请移步浏览器加载 CommonJS 模块的原理与实现 - 阮一峰的网络日志

    由于在 浏览器中不支持 commonjs的写法,故需要进行转化。可以了解一下这篇文章。如果不了解 npm 和 ES6 模块,那就看过来 - WEB前端 - 伯乐在线

    commonjs,AMD,CMD规范 简单解析  浅析JS模块规范:AMD,CMD,CommonJS - 简书

  • 相关阅读:
    Neko's loop HDU-6444(网络赛1007)
    Parameters
    SETLOCAL
    RD / RMDIR Command
    devenv 命令用法
    Cannot determine the location of the VS Common Tools folder.
    'DEVENV' is not recognized as an internal or external command,
    How to change Visual Studio default environment setting
    error signing assembly unknown error
    What is the Xcopy Command?:
  • 原文地址:https://www.cnblogs.com/zhongxia-zx/p/12018780.html
Copyright © 2011-2022 走看看