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'; }))