为什么有模块化

  • 1.方便代码维护
  • 2.每个功能放到一个模块内
  • 3.解决命名问题,全局变量污染问题

常见的模块化

  • 1.我们写方法写属性都放在对象里(单例模式)

    • 缺陷声明的对象也有可能命名冲突,不能完全解决上述问题
var obj = {a:1,init(){}fn(){}
}
复制代码
  • 2.自执行函数(IIFE) 实现模块化的功能,要把最终的结果对外暴露

    • 好处

      • 1.没有名字
      • 2.有自己单独的执行作用域
      • 3.可以对外暴露一些属性
    • 缺陷
      • 浏览器的文件加载(http请求),异步的问题不易解决
(function(){...;return XXX
})()
复制代码

commonjs规范定义了几个点(同步的)

  • 1.如何声明一个模块,node中一个文件就是一个模块
  • 2.每个模块都需要导出最终的结果module.exports
  • 3.每个模块使用其他模块的时候需要使用require方法

commonjs的实现流程

就是把文件读取出来之后加一个 函数 执行 最终返回的是module.exports

  • 1.每个模块都有一个require方法-->Module.prototype.require
  • 2.调用Module._load()加载模块
  • 3.调用Module._resolveFilename()解析出文件的绝对路径,并且增加拓展名
  • 4.通过Module._cache[filename]检查是否存在缓存,如果有直接返回缓存模块的module.exports
  • 5.检查是否是内置模块(例如fs模块),如果不是,通过new Module(filename)创建一个模块,模块上有两个重要的属性id&&exports = {}
  • 6.将创建的模块放到缓存中Module._cache[filenama] = module
  • 7.尝试加载模块tryModuleLoad(module, filename)核心
    • 1).通过path.extname(filename)获取文件的扩展名extension
    • 2).通过扩展名extensionModule._extensions中找相应的方法读取文件content
    • 3).通过Module.wrap(content)方法将读取到的内容进行包装,返回包装后的结果wrapper
    • 4).通过vm.runInThisContext(wrapper)返回一个可执行函数compiledWrapper
    • 5).compiledWrapper.call(this.exports, this.exports, require, this, filename, dirname)执行
let path = require('path');
let fs = require('fs');
let vm = require('vm');function req(pathname) {return Module._load(pathname);
}function tryModuleLoad(module, filename) {return module.load(filename);
}function Module(id) {this.id = id;this.exports = {};
}Module.prototype.load = function (filename) {let extension = path.extname(filename);Module._extensions[extension](this);return this.exports;
}Module._extensions = {'.js': function (module) {let content = fs.readFileSync(module.id, 'utf8');let wrapper = Module.wrap(content);let compiledWrapper = vm.runInThisContext(wrapper);let result = compiledWrapper.call(module.exports, module.exports, req, module)Module._cache[module.id] = result;},'.json': function (module) {let result = JSON.parse(fs.readFileSync(module.id, 'utf8'));Module._cache[module.id] = result;module.exports = result;}
}Module._cache = {};Module._load = function (pathname) {let filename = Module._resolveFilename(pathname);let cacheModule = Module._cache[filename];if (cacheModule) return cacheModule.exports;/* 此处略掉检查内部模块 */let module = new Module(filename);return tryModuleLoad(module, filename);
}Module._resolveFilename = function (pathname) {let absName = path.resolve(__dirname, pathname);try {fs.accessSync(absName);} catch (err) {let extArr = ['.js', '.json'];let ext = path.extname(absName);if (!ext || !extArr.includes(ext)) {extArr.every((extname, index) => {let spliceName = absName + extname;try {fs.accessSync(spliceName);absName = spliceName;return false;} catch (err) {if (index == 1) {throw new Error(`${pathname} is not defined`)}return true}})} else {throw new Error(`${pathname} is not defined`)}}return absName
}Module.wrap = function (content) {return Module.wrapper[0] + content + Module.wrapper[1];
}Module.wrapper = ['(function (exports, require, module, __filename, __dirname) {', '});']let r = req('./user');
console.log(r);复制代码

转载于:https://juejin.im/post/5c6ba879e51d45704055fbce

Commonjs规范相关推荐

  1. CommonJS规范与AMD规范的理解

    2019独角兽企业重金招聘Python工程师标准>>> 链接地址:http://www.xx566.com/detail/32.html 谈到AMD,我们首先来了解一个基于AMD规范 ...

  2. Javascript模块规范(CommonJS规范AMD规范)

    Javascript模块化编程(AMD&CommonJS) 前端模块化开发的价值:https://github.com/seajs/seajs/issues/547 模块的写法 查看 AMD规 ...

  3. 理解AMD ,CMD,CommonJS规范

    https://blog.csdn.net/xcymorningsun/article/details/52709608 理解AMD ,CMD,CommonJS规范 2016年09月30日 10:33 ...

  4. CommonJS规范(转)

    概述 CommonJS是服务器端模块的规范,Node.js采用了这个规范. 根据CommonJS规范,一个单独的文件就是一个模块.加载模块使用require方法,该方法读取一个文件并执行,最后返回文件 ...

  5. EJS学习(五)之EJS的CommonJs规范版本

    EJS的CommonJs规范版本 ejs分为两个版本一个是CommonJs版本,另外一个是AMD规范的版本. 基础:html页面 安装:<script type="text/javas ...

  6. CMD、AMD、commonJs 规范的写法

    比较好的文章: http://www.jianshu.com/p/d67b... AMD 是 RequireJS 在推广过程中对模块定义的规范化产出. CMD 是 SeaJS 在推广过程中对模块定义的 ...

  7. NodeJS学习笔记—1.CommonJS规范

    由于现在web开发,越来越重视代码的复用和抽象的封装,为了解决代码的组织结构.管理.复用和部署等问题,现在普遍采用的机制是模块机制(module).CommonJS约定桌面应用程序和服务器应用程序需要 ...

  8. Commonjs规范及Node模块实现

    前面的话 Node在实现中并非完全按照CommonJS规范实现,而是对模块规范进行了一定的取舍,同时也增加了少许自身需要的特性.本文将详细介绍NodeJS的模块实现 引入 nodejs是区别于java ...

  9. Modularity(模块化-CommonJS规范)

    第二阶段: CommonJS规范 CommonJS就是一个JavaScript模块化的规范,该规范最初是用在服务器端的node的,前端的webpack也是对CommonJS原生支持的. 根据这个规范, ...

最新文章

  1. C语言单链成绩表,【查找链表面试题】面试问题:C语言基于单链… - 看准网
  2. 如何利用魔棒工具抠图_3秒搞定抠图!免费在线抠图工具
  3. .net的label的背景如何设置成为透明_新一轮广告呈现方式变革,新橱窗广告,如何收割注意力经济?...
  4. Redis 它是什么?它用来做什么?它的优势与短板如何?
  5. springboot+aop切点记录请求和响应信息
  6. 数据同步一致性_微服务架构:利用事件驱动实现最终一致性
  7. 文件共享服务器 -----ftp服务一
  8. java switch的应用
  9. RK3399 USB RNIDS/gagnet实战
  10. HTML中怎么从图片里取色,图片取色配色法——从电影画面中取色
  11. C/C++实现关闭命令行快速编辑模式(Windows系统)
  12. Windows10系统常用快捷键汇总
  13. 教你电脑休眠如何取消
  14. 为卿一袭白衣,倾尽江湖又何妨?
  15. 世界上最著名的24句哲理
  16. 给计科专业的学弟学妹们的一封信
  17. 服务器的系统日志路径,DirectAdmin 日志路径各种系统中查看方法Windows服务器操作系统 -电脑资料...
  18. 远程连接阿里云服务器一直显示连接失败原因
  19. 计算机毕业论文乐谱播放器,给大家推荐一个超强的播放器!我刚发现的。居然显示乐谱...
  20. android phone电脑驱动下载,全机型Android Phone驱动及安装教程(XP,Vista,Win7).pdf

热门文章

  1. 北京大兴要打造成未来科技新中心?
  2. AI一分钟|美国第一家!Waymo商业自动驾驶打车服务正式获批
  3. 高逼格的 SQL 写法:行行比较,别问为什么,问就是逼格高。。
  4. 使用Netty如何做到单机秒级接收35万个对象
  5. 老司机给我们解读 Spring Boot 最流行的 16 条实践忠告
  6. CMS 被废弃了,该怎么办呢?
  7. 世界人工智能大赛方案解析!
  8. 导师吐槽大会开始:自己招的学生,哭着也要带完
  9. 有没有什么高效「炼丹」神器可以推荐?复旦fastNLP团队祭出内部调参利器fitlog...
  10. 神童、数学家、抑郁症患者,控制论之父诺伯特·维纳的一生