關於 import
和 require
的不一樣,其實能夠理解成 CommonJs 和 ES Module 的區別。這二者都是前端模塊化的規範。前端
咱們在 node 裏使用的是 CommonJs,在前端頁面的時候,用的是 ES Module,這二者的區別,仍是很容易混淆的,因此整理一下 CommonJs 和 ES Moudule 的相關知識點,把這裏好好的整理一下。node
1、CommonJses6
1.1 概述json
Nodejs 是 CommonJS 規範的主要實踐者,在 CommonJs 裏每一個文件就是一個模塊,有本身的做用域。在一個文件裏面定義的變量、函數、類,都是私有的,對其餘文件不可見。CommonJs 提供了四個重要的環境變量爲模塊化的實現提供支持:module
、exports
、require
、global
。CommonJS 規定,每一個模塊內部,module 變量表明當前模塊。這個變量是一個對象,它的 exports
屬性(即 module.exports
)是對外的接口。加載某個模塊,實際上是加載該模塊的 module.exports
屬性。數組
var x = 5; var addX = function (value) { return value + x; }; module.exports.x = x; module.exports.addX = addX;
而使用 require 方法來引入並加載模塊緩存
var example = require('./example.js'); console.log(example.x); // 5 console.log(example.addX(1)); // 6
1.2 CommonJS模塊的特色模塊化
關於變量:函數
一、module
對象是 node 裏的 Module 構造函數的實例,表明當前模塊。具備如下屬性:ui
二、exportsthis
NodeJs 爲每一個模塊提供一個 exports
變量,指向 module.exports
在使用的時候,能夠直接給 exports
添加屬性,就會指向 module.exports
。可是不能給 exports
直接賦值一個變量,這樣會切斷 exports
和 module.exports
之間的聯繫。
若是有 exports
和 module.exports
,exports
就會失效,只會輸出 module.exports
的,由於 module.exports
被從新賦值了。
三、global
這是一個全局變量聲明方式,就能夠全局用這個 warning 變量了。
global.warning = true;
四、require
require
命令用於加載模塊文件。
require
命令的基本功能是,讀入並執行一個 JavaScript 文件,而後返回該模塊的 exports
對象
加載規則:
require函數及其輔助方法主要以下。
關於緩存:
在屢次加載某個相同的模塊時,若是前面的模塊已經操做了,後面調用時,拿到就再也不是最初時的數據了,就是通過前面操做事後的數據了。
全部緩存的模塊保存在 require.cache
之中,若是想刪除模塊的緩存,能夠像下面這樣寫。
// 刪除指定模塊的緩存 delete require.cache\[moduleName\]; // 刪除全部模塊的緩存 Object.keys(require.cache).forEach(function(key) { delete require.cache\[key\]; })
注意:緩存是根據絕對路徑識別模塊的,若是一樣的模塊名,可是保存在不一樣的路徑,require
命令仍是會從新加載該模塊。
1.3 模塊的加載機制
CommonJS 模塊的加載機制是,輸入的是被輸出的值的拷貝。也就是說,一旦輸出一個值,模塊內部的變化就影響不到這個值。
2、ES Module
2.1 概述
ES6 模塊的設計思想是儘可能的靜態化,使得編譯時就能肯定模塊的依賴關係,以及輸入和輸出的變量。因此ES6 模塊不是對象,而是經過 export
命令顯式指定輸出的代碼,再經過 import
命令輸入。這種加載稱爲「編譯時加載」或者靜態加載,即 ES6 能夠在編譯時就完成模塊加載,效率要比 CommonJS 模塊的加載方式高。固然,這也致使了無法引用 ES6 模塊自己,由於它不是對象。
2.2 ES Module的特色:
ES6 的模塊功能主要由兩個命令構成:export
和 import
。 export
命令用於規定模塊的對外接口。import
命令用於輸入 其餘模塊提供的功能。
一、export命令
二、import命令
三、export default 命令
3、CommonJs 和 ES Module的區別
es6 { export : ‘能夠輸出多個,輸出方式爲 {}’ , export default : ‘ 只能輸出一個 ,能夠與 export 同時輸出,可是不建議這麼作’, 解析階段肯定對外輸出的接口,解析階段生成接口, 模塊不是對象,加載的不是對象, 能夠單獨加載其中的某個接口(方法), 靜態分析,動態引用,輸出的是值的引用,值改變,引用也改變,即原來模塊中的值改變則該加載的值也改變, this 指向 undefined } commonJS { module.exports = … : ‘只能輸出一個,且後面的會覆蓋上面的’ , exports. … : ‘ 能夠輸出多個’, 運行階段肯定接口,運行時纔會加載模塊, 模塊就是對象,加載的是該對象, 加載的是整個模塊,即將全部的接口所有加載進來, 輸出的是值的拷貝,即原來模塊中的值改變不會影響已經加載的該值, this 指向當前模塊 }