JavaScript子產品規範
在任何一個大型應用中子產品化是很常見的,與一些更傳統的程式設計語言不同的是,JavaScript6之前還不支援原生的子產品化;Javascript社群做了很多努力,在現有的運作環境中,實作"子產品"的效果。通行的JavaScript子產品規範主要有兩種:CommonJS、AMD
CommonJS規範是伺服器端Javascript子產品規範(同步)
Node.js的子產品系統,就是參照CommonJS規範實作的。NPM也遵循了commonJS定義的包規範,進而形成了一套完整的生态系統
AMD意思是"異步子產品定義",是前端子產品規範
RequireJS就是實作了AMD規範的
CommonJS module以伺服器端為第一的原則發展,選擇同步加載子產品。它的子產品是無需包裝的,但它僅支援對象類型(objects)子產品
AMD以浏覽器為第一的原則發展,選擇異步加載子產品。它的子產品支援對象、函數、構造器、字元串、JSON等各種類型的子產品,是以在浏覽器中它非常靈活
ES6子產品的import和export用法總結
ES6之前已經出現了js子產品加載的方案,最主要的是
commonjs 伺服器 同步加載 如nodejs
AMD 浏覽器 異步加載 如requirejs
ES6在語言規格的層面上,實作了子產品功能,而且實作得相當簡單
完全可以取代現有規範,成為浏覽器和伺服器通用的子產品解決方案
運作時加載
CommonJS子產品是對象,實質是整體加載子產品(即加載fs的所有方法),生成一個對象,然後再從這個對象上面讀取其中3個方法這種加載稱為“運作時加載”,因為隻有運作時才能得到這個對象
編譯時加載
ES6子產品不是對象,是通過export指令顯式指定輸出的代碼,再通過import指令輸入
的實質是從fs子產品加載3個方法,其他方法不加載。這種加載稱為“編譯時加載”或者靜态加載,即ES6可以在編譯時确定子產品的依賴關系,以及輸入和輸出的變量,效率更高
ES6子產品主要有兩個功能:export和import
export用于對外輸出本子產品(一個檔案可以了解為一個子產品)變量的接口
import用于在一個子產品中加載另一個含有export接口的子產品。
也就是說使用export指令定義了子產品的對外接口以後,其他JS檔案就可以通過import指令加載這個子產品(檔案)。如下圖(假設a和b檔案在同一目錄下)
// a.js
var sex="boy";
var echo=function(value){
console.log(value)
}
export {sex,echo}
//通過向大括号中添加sex,echo變量并且export輸出,就可以将對應變量值以sex、echo變量辨別符形式暴露給其他檔案而被讀取到
1.export {sex,echo}
-
[不用] export default指令,為子產品指定預設輸出 其實隻是輸出一個叫做default的變量
(1)[隻能預設輸出單個,不能是對象]
var abc=function(){}
export default abc
import xx from './a.js'
xx()
(2)如果想在一條import語句中,同時輸入預設方法和其他接口
var abc=function(){}
var cba=function(){}
var bac=function(){}
export default abc
export {cba}
import xx,{cba,bac} from './a.js'
xx() cba() bac()
// b.js
通過import擷取a.js檔案的内部變量,{}括号内的變量來自于a.js檔案export出的變量辨別符。
import {sex,echo} from "./a.js"
console.log(sex) // boy
echo(sex) // boy
1.import指令接受一對大括号,裡面指定要從其他子產品導入的變量名
大括号裡面的變量名,必須與被導入子產品(profile.js)對外接口的名稱相同
2.除了指定加載某個輸出值,還可以使用整體加載,即用星号(*)指定一個對象,所有輸出值都加載在這個對象上面
import * as xx from './circle';
console.log('圓面積:' + xx.area(4));
以上是export與import的基本用法,再進行拓展學習
前面的例子可以看出,b.js使用import指令的時候,使用者需要知道a.js所暴露出的變量辨別符
使用export default指令,為子產品指定預設輸出,這樣就不需要知道所要加載子產品的變量名
//a.js
export default sex(sex不能加大括号)
//一個檔案内最多隻能有一個export default
其實此處相當于為sex變量值"boy"起了一個系統預設的變量名default,自然default隻能有一個值
本質上,a.js檔案的export default輸出一個叫做default的變量,然後系統允許你為它取任意名字。是以可以為import的子產品起任何變量名,且不需要用大括号包含
import any from "./a.js"
import any12 from "./a.js"
console.log(any,any12) // boy,boy
import和export這兩個指令現在在任何浏覽器中都是不支援的, 同時babel也無法将其轉換為浏覽器支援的ES5, 原因在于:
babel隻是個翻譯,假設a.js 裡 import 了 b.js, 對a.js進行轉碼,隻是翻譯了a.js,并不會把b.js的内容給讀取合并進來, 如果想在最終的某一個js裡包含 a.js,b.js 的代碼,那就需要用到打包工具
是以我在這裡講解一下如何使用webpack工具将帶有import和export文法的JS檔案, 通過打包工具生成所有浏覽器都支援的單個JS檔案