1.CommonJS为什么要规范javascript的缺点?没有模块系统。标准库相对较小。没有标准接口。缺少包管理系统。Ruby和Java具备了开发大型应用的基本能力,使得javascript不仅可以在客户端使用,还可以开发如下应用:服务端应用、命令行工具、桌面图形界面应用、混合应用二、CommonJS模块规范1、模块介绍,使用require()导入,接受一个模块id。让math=require('math');2.定义模块上下文提供的exports对象,用于导出模块或变量,并且是唯一的export。模块中有一个模块对象,代表模块本身,exports是它的属性之一。在nodejs中,一个文件就是一个模块,可以通过将方法挂在exports对象上来定义export//math.jsexports.add=function(){letsum=0,i=0,args=arguments,l=args.length;while(i{returnx+y;}})这样,每个模块文件直接作用域,这是Node对CommonJS规范的实现。2、C/C++模块编译Node调用process.dlopen()加载执行。windows和*nix平台下的dlopen()实现方式不同,通过libuv兼容层进行封装。3.JSON文件编译Node使用fs模块读取json文件内容,使用JSON.parse()获取对象然后赋值给模块对象的exports属性。4.核心模块核心模块分为C/C++和javascript。C/C++存放在Node项目的src文件中,javascript文件存放在lib目录中。核心模块中部分核心模块使用C/C++完成核心部分,其他部分使用javascript实现打包导出。纯C/C++编写的部分称为内置模块,例如:buffer、crypto、evals、fs、os等模块都是用C/C++编写的。依赖层关系:内置模块(C/C++)--->核心模块(javascript)--->文件模块导入过程核心模块以导入os原生模块为例NODE_MODULE(node_os,reg_func)--->get_builtin_module('node_os')--->process.binding('os')--->NativeModule.require('os')--->require('os')5.C/C++扩展module1.extensionmodule不同平台编译加载流程WindowsC/C++源码--->VC++--编译源码-->.dll文件--生成.node文件-->加载.dll文件--dlopen()load-->Exporttojavascriptusing*nixC/C++sourcecode--->g++/gcc--compilesourcecode-->.sofile--generate.nodefile-->加载.sofile--dlopen()load-->export用于javascript2.编译条件node-gyp工具V8引擎C++库libuv库Node内部库其他库3.加载C/C++扩展模块require()import.nodefileprocessjavascript(require('./hello.node'))--->原生模块(process.dlopen('./hello.node',exports))--->libuv(uv_dlopen()/uv_dlsym())--->[{*nix:dlopen()/dlsym(),Windows:loadLibraryExW()/GetProcAddress()}]6.包和NPM包结构:package.json包描述文件bin存放可执行位二进制文??件lib存放javascript文件doc存放documentstest存放单元测试7.前后端公共模块1.AMD规范AMD规范是CommonJS规范的扩展,定义了模块方法:define(id?,dependencies?,factory);define(函数(){让前港口={};exports.sayHello=()=>{console.log(`helloformmodule:${module.id}`);}returnexports;})2.CMD规范和AMD规范的主要区别在于AMD引入的定义模块和依赖的部分需要在声明时指定所有的依赖,通过形参将依赖传递给模块:define(['dep1','dep2'],function(){returnfunction(){}})与AMD规范相比,CMD模块更接近于Node对CommonJS规范的定义:define(factory);在dependency部分,CMD支持动态导入:define(function(require,exports,module){//modulecode})require,exports,module通过形参传递给模块,随时调用require()当它需要依赖模块时。兼容多个模块规范((name,definition)=>{//判断是AMD还是CMDlethasDefine=typeofdefine==='function',//判断是NodehasExports=typeofmodule!=='undefined'&&'module.exports';if(hasDefine){//AMD或CMD环境define(definition);}elseif(hasExports){//定义为普通Node模块module.exports=definition();}else{//挂载模块执行结果到窗口对象下this[name]=definition;}})('hello',function(){lethello=()=>{};returnhello;})