1.什么是模塊化
目前最普遍的JavaScript運行平臺便是瀏覽器,在瀏覽器中,所有的代碼都運行在同一個全局上下文中。這使得你即使更改應用中的很小一部分,你也要擔心可能會產生的命名沖突。
傳統的JavaScript應用被分離在多個文件中,并且在構建的時候連接在一起,這稍顯笨重。所以人們開始將每個文件內的代碼都包在一個自執行函數中:(function() { ... })();。這種方法創建了一個本地作用域,于是最初的模塊化的概念產生了。之后的CommonJS和AMD系統中所稱的模塊,也是由此實現的。
換句話說,現存的“模塊”系統是使用已有的語言特性所實現的。
2.閉包模塊(自執行函數)
(function(){
//do something
})()
自執行函數可以有效的防止變量和函數名沖突(作用域的原因)
在舊版的javascript中,所有的函數都是global對象下的一個屬性(瀏覽器中的global是window)
3.commonJS
CommonJS API定義很多普通應用程序(主要指非瀏覽器的應用)使用的API,從而填補了這個空白。它的終極目標是提供一個類似Python,Ruby和Java標準庫。這樣的話,開發者可以使用CommonJS API編寫應用程序,然后這些應用可以運行在不同的JavaScript解釋器和不同的主機環境中
以上引用自百度百科- -
commonJS的API主要引入了2個東西:
- require - 用來加載一個模塊
- module.exports - 一個模塊導出的內容
其中,require
與ES6中的import
一樣,module.exports
與ES6中的export
一樣
練習使用babel來轉換pie.js時遇到的問題:babel報錯
G:\Learning\commonJS>babel-node
> import {pi,e} from "./constants";
SyntaxError: repl: Modules aren't supported in the REPL
> 1 | import {pi,e} from "./constants";
| ^
> console.log('pie=',pi + e);
搜索stackoverflow解決
該錯誤消息說。
你不能在REPL使用ES6模塊的語法,它是不受支持。
如果你想測試他們,你應該做一個***.js
文件,把你的代碼在那里,然后運行
解決辦法:
G:\Learning\commonJS>babel-node --presets es2015 pie.js
pie= 5.85987
回答問題:如果 require 一個模塊三次,文件會被加載幾次?
文件只會被加載一次
Node.js在載入模塊時,如果之前該模塊已經加載過則不會有重復開銷,因為模塊加載有緩存機制
默認導出:
設定文件默認值:
export default 42;
這個值會被babel編譯為:
exports.default = 42;
Babel 將 ES6 模塊的默認導出值轉譯成了 CommonJS 模塊的 default 屬性。
導入的這個 default 屬性的方法被稱為命名導入(Named Import)。
import answer from "./constants.js";
console.log(answer);
這里這個answer可以隨意寫成其它名字。

我們可以看到 answer 被重寫成 _constants.default,這個 import 語法實際上訪問了 CommonJS 模塊的 default 屬性。
4 ES6和commonJS的兼容性
ES6 和 CommonJS 模塊之間最大的差別,就在于模塊的默認導出是如何工作的。
CommonJS 其實并沒有默認導出值這個概念。用 require 來加載一個模塊會返回這個模塊本身。
對比使用defaukt符導入的fs模塊和使用通配符導入的fs模塊
使用default導入的fs
//這里是使用default導入的fs
"use strict";
var _fs = require("fs");
var _fs2 = _interopRequireDefault(_fs);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {default: obj};
}
// Same as: require("fs").default
_fs2.default.readFileSync("package.json", "utf8");
使用通配符導入的fs模塊
//這里是使用通配符導入的fs模塊
"use strict";
var _fs = require("fs");
var fs = _interopRequireWildcard(_fs);
function _interopRequireWildcard(obj) {
if (obj && obj.__esModule) {
return obj;
} else {
var newObj = {};
if (obj != null) {
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
}
}
newObj.default = obj;
return newObj;
}
}
fs.readFileSync("package.json", "utf8");
5.使用webpack
使用webpack打包后的文件,可以在瀏覽器中運行