Node应用使用CommonJS模块规范,Node中每一个文件就是一个模块,有本身的做用域,在模块中定义的变量
、函数都是私有的。html
模块中有四个重要的变量global
、module
、exports
、require
。前端
Node中的全局变量global
,和浏览器的window对象相似,声明在全局下的变量能够在全部模块中访问。module
变量表明当前模块,其中module.exports
属性表示当前模块对外输出的接口,当其余文件使用require
引用该模块时,实际就是读取module.exports
变量。vue
// 模块a.js const num = 1 module.exports = { num, add: function(x,y){ return x+y } }
//模块b.js,引入a.js const a = require('./a.js') // {num:1, add:fn}
而exports
变量是对module.exports
的引用;至关于在顶部声明一个变量var exports = module.exports
,exports
不能直接赋值,这样就没法指向module.exports
了
因此使用exports
对外输出接口的写法以下,jquery
// 模块a.js exports.num = 1 exports.add = function(x,y){ return x+y }
CommonJS规范加载模块是同步的,加载完成之后,才能执行后面的操做。同时模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
AMD
:Asynchronous Module Definition,异步模块定义,是RequireJS
在推广过程当中对模块定义的规范化产出。require.js
加载完成后,经过回调方法加载data-main
中的js,而后require.config
方法指定第三方资源路径,define
方法来定义本身写的模块,最后使用require
方法加载模块webpack
<!-- 引入require.js,main.js中配置require.config --> <script src="require.js" data-main="main.js"></script> <!-- main.js --> <script> require.config({ paths: { "Vue": "./vue", "jquery": "./jquery" //js后缀不写 } }) require(["Vue","jquery"],function(vue,$){ // 依赖的模块会以参数的形式传进回调函数,这里就能够正常使用Vue和jQuery了 }) </script>
define
方法自定义模块,不须要在require.config里配置路径es6
<!-- 本身的模块好比:module_test.js --> <script> define(function(){ function add(x,y){ return x+y } return { add } }) </script> <!-- 若是自定义依赖其余模块,先引入其余模块 --> <script> define(['jquery'],function($){ function add(x,y){ const total = x+y $('body').html(total) return total } return { add } }) </script>
CMD
:Common Module Definition,通用模块定义, 是SeaJS在推广过程当中对模块定义的规范化产出。和AMD
语法相似,区别是AMD在定义模块的时候就要声明其依赖的模块,而CMD只有在用到某个模块的时候再去加载。AMD
和CMD
都实现了前端资源的模块的,而如今ES6和Webpack打包工具的出现这两个应该使用比较少了。web
ES6在语言标准的层面上,实现了模块功能。模块功能主要由两个命令构成:export
和import
。export
命令用于规定模块的对外接口,import
命令用于输入其余模块提供的功能。咱们平时的项目通常都是基于webpack来处理,若是想直接在浏览器中加载ES6模块,和原来同样使用<script>
便签,同时须要添加type="module"
属性。浏览器
参考Module的加载实现缓存
// m1.js定义输出 const a = 1 export default a export const b = 2 export function add(x,y){ return x+y } // m2.js引用 import a, {b, add} from './m2.js'
ES6模块与CommonJS模块的两大差别异步
ES6模块中的原始值变了,import加载的值也会跟着变。所以,ES6 模块是动态引用,而且不会缓存值,模块里面的变量绑定其所在的模块。
UMD
是AMD和CommonJS的糅合,UMD
会先判断是否支持Node.js模块的exports,再判断AMD的define方法是否存在,最后都不支持的话就挂载在window全局变量下。
好比打开Vue.js文件
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : // 是否支持Node.js模块 typeof define === 'function' && define.amd ? define(factory) : // 是否支持AMD (global = global || self, global.Vue = factory()); // 最后都不行挂载在window.Vue }(this, function () { 'use strict'; }))