前端模塊化系列(一):網站須要模塊化的緣由

前端模塊化

標籤(空格分隔): 模塊化javascript


前端模塊化系列(一):網站須要模塊化的緣由

因爲我最近在研究前端各類各樣的模塊化系統,因此就翻譯了一篇來自webpack官網的文章,總的來講做者寫的仍是至關不錯的。這樣在本身學習的同時也能夠與你們共同窗習~~~css

在今天的網站正在逐步的向web apps轉變。html

  • 單個頁面中愈來愈多的Javascript。
  • 在現代瀏覽器中你能夠作愈來愈多的功能。
  • 少許的全頁面刷新,以致於單個頁面中有更多的代碼。

正由於這些緣由形成愈來愈多的代碼鑲嵌在瀏覽器端中。前端

這樣一個大的代碼倉庫(code base)急需作出相應的管理。正好,模塊化系統提供了這些功能分割你的代碼倉庫,把它們分割爲一個個的模塊。java

各個模塊系統的風格

眼下對於如何定義依賴項和暴露接口有不少的標準:node

  • <script>標籤風格(ps:不使用模塊系統)。
  • CommonJs
  • AMD和它的一些衍生物
  • ES6模塊
  • 更多。。。

在下面,咱們會一次簡介這些模塊化系統之間的好處以及壞處。jquery

<script>標籤風格

若是你沒有使用模塊化系統,那麼你只能用這種方式來處理你的模塊化代碼了。webpack

<script src="module1.js"></script>
<script src="module2.js"></script>
<script src="libraryA.js"></script>
<script src="module3.js"></script>

每一個模塊向外暴露一個接口給全局對象,即window對象。模塊就能夠經過全局對象訪問依賴項向外暴露的接口。git

一般存在的問題es6

  • 全局對象中的變量衝突。
  • 按需加載的問題。
  • 開發者須要手動解析模塊或者庫的依賴項。
  • 在特別大的項目中,這個現象會變得愈來愈嚴重,愈來愈難以管理。

CmmonJs:同步require

這種方式使用了一個同步的require方法去加載依賴項而且返回一個向外暴露的接口。一個模塊能夠經過給exports添加屬性或者給module.exports設置固定值來指定向外暴露的值。

require("module");
require("../file.js");
exports.doStuff = function() {};
module.exports = someValue;

這個只是被node.js使用在server端。

優勢:

  • server端的模塊能夠被複用。
  • 有許多現成的模塊以供使用(npm)。
  • 很是的簡單易用。

缺點:

  • 由於網絡請求都是異步的。因此阻塞式的調用在網路中支持的不是很好。
  • 多個模塊之間並能同時並行的加載進來。

實現
一、node.js - server端。
二、browserify
三、modules-webmake-編譯到一個bundle裏
四、wreq-客戶端

AMD:異步的require

Asynchronous Module Definition
其餘的模塊化系統(對於瀏覽器來講)對於同步require(CommonJs)都有或多或少的問題。接下來咱們介紹一個異步require的模塊化系統(定義模塊和暴露值的另一種實現方式)。

require(["module", "../file"], function(module, file) {
    /* ... */ 
});
define("mymodule", ["dep1", "dep2"], function(d1, d2) {
  return someExportedValue;
});

優勢:

  • 十分適合在現下網絡的異步請求。
  • 支持多個模塊的同時並行加載。

缺點:

  • 寫碼開銷。讀寫十分的困難。
  • 看上去像是一種解決方案。

實現
一、require.js - client端。
二、curl - client端。

獲取更多相關CommonJSAMD的知識。

ES6模塊化

EcmaScript6針對JavaScript添加了一些新的語言結構,其中就包括模塊化系統。

import "jquery";
export function doStuff() {}
module "localModule" {}

優勢:

  • 很容易的靜態模塊解析。
  • 將來不久將要做爲ES標準來推行。

缺點:

  • 讓大部分的瀏覽器支持這個功能還須要一段時間。
  • 這種風格的模塊太少了,讓人不適應。
咱誰也不偏向誰的解決方案

給開發者關於模塊化風格的選擇權。在現有代碼能夠正常運行的前提下,能夠很容易地添加自定義模塊。關鍵還要看使用某個模塊系統對於如今的系統影響大不大。

模塊的傳輸方式

模塊是應該在client端被執行的,因此這就須要它們經過http協議讓server端向瀏覽器端傳輸。

如今有兩種方式來處理如何傳輸模塊
一、一個請求一個模塊。
二、全部的模塊都在一個請求裏。

這兩種方式都有人在用,不過這兩種都是次優的:

一個請求一個模塊

優勢

  • 僅僅傳輸被請求的那個模塊。

缺點:

  • 許多的請求意爲着網絡開銷也很大。
  • 程序啓動變慢,由於請求會延遲。
全部的模塊都在一個請求裏

優勢

  • 很小的請求開銷,少許的延遲。

缺點:

  • 不須要(尚未)被請求的模塊也被傳輸過來了。

分塊傳輸方式

相對於上面兩種方式都太死板了,因此靈活點的模塊傳輸會不會更好哪?由於向兩個極端之間的折中妥協一般都是最好的。

雖然咱們須要把全部的模塊都編輯,把模塊安裝功能和是否公用拆分爲多個較小的代碼塊。

咱們有不少的小量請求。把那些不須要一開始就請求,或者是須要按需加載的模塊來進行分塊傳輸。瀏覽器最開始的訪問請求並不用包含你的全部代碼庫(code base)。這樣的話,server返回的數據大小也就會變的很小。有效解決了上面兩種方式所出現的問題。
至於如何分隔模塊應該是開發者根據功能,格式,加載順序,繼承關係分割爲一個一個單獨的部分.
注意:拆分的粒度問題,可複用問題,效率問題.如何這些問題處理的很差,就有可能出現不想要的後果。

這樣的話。就算再多的代碼也能夠解決掉了。

獲取更多相關代碼塊如何分割的知識。

爲何僅僅只是JavaScript?

不知道你們有沒有發現,爲何一個模塊化系統僅僅只幫助開發者處理JavaScript哪?除此以外還須要不少的靜態資源須要咱們去處理呀!

  • stylesheets(樣式表)
  • images(圖片)
  • webfonts(web字體)
  • html for templating(html模版)
  • 等等...

固然,還有其餘的資源:

  • coffeeScript -> javascript
  • less -> stylesheets
  • jade -> 通過javascript生成的html
  • 等等...

它們也應該向JavaScript同樣能夠被很容易的require到:

require("./style.css");
require("./style.less");
require("./template.jade");
require("./image.png");

模塊靜態解析

當編譯全部模塊的時候,爲了協調異步環境下模塊開發與性能間的矛盾,咱們必須在工程階段就具有依賴分析的能力,把具有依賴關係的資源進行打包。就算不打包,也但願像 F.I.S 那樣有個記錄依賴關係的map.json,能夠照單抓藥,一次性地把須要的依賴項加載下來。

策略

一個聰明的解析器將容許大多數現有的代碼能夠有效運行,無論開發者有沒有使用模塊化系統。即便開發人員作了一些奇怪的東西,它也會嘗試找到最適合的解決方案。實在不行,也就只能抱歉咯!!!

翻譯自:http://webpack.github.io/docs/motivation.html 翻譯人:張亞濤

相關文章
相關標籤/搜索