關於前端模組化你應該知道的

Eric_zhang發表於2019-03-04

關於前端模組化你應該知道的

模組化的意義

  • 對大型網站專案做更細粒度的拆分,團隊協作中每個人各司其責負責自己的模組,彼此模組之間不會造成名稱空間汙染
  • 根據頁面組成拆分出不同的子元件
  • 針對不同業務邏輯,抽象出不同的功能模組,供業務方黑盒呼叫
  • 針對重複的功能和頁面元素,開發維護一套公共程式碼即可完成模組複用,有更高的複用性和可維護性
  • 對於當前頁面非必須呈現的模組資源,使用按需載入,提高首屏響應速度

模組化方案比較

  • 在ES6 Modules出現之前主流的模組化方案有CommonJS、AMD、CMD
  • CommonJS方案主要應用於服務端NodeJS,在node環境下原生支援
  • AMD和CMD作為第三方的類庫,來解決瀏覽器端模組化問題,正逐漸被ES6模組化所替代
  • ES6 Modules則是第一次在javascript語言標準層面新增的模組化解決方案

ES6 Modules

與CommonJS的區別

  1. CommonJS 模組輸出的是一個值的拷貝,ES6 模組輸出的是值的引用
  2. 靜態化,編譯時就確定模組之間的依賴關係、輸出和引入的變數;CommonJS是在js執行到對應位置時,才會載入確定這些資訊
  • CommonJS輸出的是一整個物件(即module.exports屬性),即使是用不到的屬性和變數,一樣會被載入引入進來
// CommonJS模組
let { stat, exists, readFile } = require('fs');

// 等同於
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;
複製程式碼

先載入整個物件,再依次讀取需要的三個方法,這種載入稱為“執行時載入”

  • ES6 Modules不是輸出的不是物件,通過export指定輸出的內容,通過import指定引入的內容
// ES6模組
import { stat, exists, readFile } from 'fs';
複製程式碼

上面程式碼表示從'fs'模組中只引入三個方法,其他方法不載入。這種載入稱為“編譯時載入”或者靜態載入,即 ES6 可以在編譯時就完成模組載入,效率要比 CommonJS 模組的載入方式高

export

常被用來export對外介面格式有:

  • variable變數
  • class物件
  • function函式

錯誤寫法

// 報錯
export 1

// 報錯
var exp = 1;
export exp
複製程式碼

正確寫法: export變數

// 寫法一
export var m = 1

// 寫法二
var m = 1
export {m}

// 寫法三
var n = 1
export {n as m}
複製程式碼

export 函式

// 報錯
function f() {}
export f

// 正確
export function f() {};

// 正確
function f() {}
export {f}
複製程式碼

export default 指定預設輸出 實質是指定輸出了一個叫default的變數或function

// modules.js
function add(x, y) {
  return x * y;
}
export {add as default};
// 等同於
// export default add;

// app.js
import { default as foo } from 'modules';
// 等同於
// import foo from 'modules';
複製程式碼

常用用法

// 輸出常量
export 1

//輸出變數
let share = 1

export default share

//輸出函式
function share(){
    //....
}
export default share

//輸出匿名函式
export default function(){
    //...
}
複製程式碼

import

  • 從模組中引入需要的方法、變數等
// export很多介面時
import { Component } from "react"

// export default 指定預設輸出時,可以為其指定任意名字
import React from "react"

// 重新命名
import { Component as AAA } from "react"

// 整體載入
import { * as Util} from './util'

複製程式碼
  • import引入的介面是隻讀的,不允許對其更改
  • import命令是編譯階段執行的,在程式碼執行之前,所以import命令會被提升到檔案頂部,優先執行
//這樣寫沒有任何問題
foo();

import { foo } from 'my_module';
複製程式碼

import()動態載入

前面介紹了,export、import命令是編譯時載入這就導致不支援執行時載入才能實現的按需載入功能,所以加入了import()功能,程式執行到import()這裡才會載入模組

  • import()返回一個Promise物件
// ../utils 模組有預設輸出時
import('../utils').then( module => {
    // module是模組暴露的預設介面
})

// ../utils 模組沒有預設輸出時
import('../utils').then((moduleA, moduleB,) => {
    // moduleA、moduleB是對應輸出的介面
})
複製程式碼

相關文章