你看不懂 webpack,是由於不知道js的進化史

若是你如今還不懂 webpack,我相信你必定和我最開始同樣,對官網的這張圖一臉懵逼,就算如今,我仍是以爲這張圖對新手起了很大的誤導做用。
這究竟是是想表達什麼意思?


咱們今天就從js發展的角度來講明,到底什麼是 webpack。


JS的設計初衷

——————

js 早期設計的目的是輔助頁面交互和豐富頁面樣式,這使得 js 能進行 dom 操做。 好比下面這樣。

  
  
  
  
<html>
    <body></body>
    <script>
        const ele = document.createElement('DIV');
        ele.style.background = 'red';
        ele.style.width = '100px';
        ele.style.height = '100px';
        document.body.append(ele);
    </script>
</html>

上面的 js 代碼至關於下面的 html 代碼。

  
  
  
  
<html>
    <body>
        <div style="background:red;width:100px;height:100px"></div>
    </body>
</html>

雖然使用 js 的寫法很麻煩,可是至少表明了 js 有這方面的能力,他能在不依靠 html 和 css 的狀況下,獨立進行頁面的顯示。

IE最後的禮物

——————

IE 雖然一直讓人詬病,可是有他留下的 xmlHttpRequest 確實是一大寶貝,他能在頁面不刷新的狀況下,請求和獲取後端數據。 這個能力再配合js對於dom操做的能力,就能完成一些騷操做。 好比在頁面不刷新的狀況下,加載一篇新的文章、發佈評論功能等等。 這也是最先單頁面應用的雛形。

你可能不知道早期在論壇進行一次簡單的評論,要通過2次頁面的跳轉

Node讓js突破能力的界限

———————————

node 他既不是開發語言,也不是什麼框架,他是一個開發環境。 咱們原來的js是運行在瀏覽器,這注定他有不少事情作不了,最基本的就是,他不能在瀏覽器對你本地文件進行增刪改。 而node他是運行在本地的,他沒有在瀏覽器端那些限制,他有極高的權限,其中同樣就是能夠對本地文件進行增刪改。
也正是這一特徵,他讓預處理語言獲得了極大發展。 咱們能夠本身制定一套語法,而後經過轉換器(loader),編譯成html能夠理解的語言。 目前html主要就認識2種文件,css和js。


模塊化的進化

——————

其實前端模塊化一直都在,咱們將一個個js寫好,而後在html裏面一個個引用,這就是最先的模塊化。 可是這產生了一個問題,這些引入關係都是寫在html裏面的,兩個js文件之間要進行交互,也只能經過全局變量賦值的形式。

那有沒有辦法在js裏組織這些引用關係呢?

答案是能夠的,目前比較主流的方式是 Node的common.js和ES6的ESModule兩種方式,下面使用ESModule來改變一下以前的引用方式。

以前咱們是這樣引用的:
  
  
  
  
<html>
    <body>
        <script src="js/jquery.js"></script>
        <script src="js/util.js"></script>
        <script src="js/index.js"></script>z
    </body>
</html>

如今咱們能夠這樣作:
  
  
  
  
<html>
    <body>
        <script src="js/index.js"></script>z
    </body>
</html>

  
  
  
  
/* 這是index.js 的內容 */
import $ from 'jquery.js';
import util from 'util.js';

$('div').remove();

至此,咱們已經瞭解了使用webpack的四個先決條件了。

主角登場

————

如何構建一個單頁面應用? 下面咱們從一個需求入手,來引出爲啥須要webpack。

第一步,咱們須要一個html和一個js:
  
  
  
  
# 目錄結構
index.html
index.js

  
  
  
  
<html>
    <body>
        <script src="index.js"></script>
    </body>
</html>

function showIndex(){

    document.body.innerText = '這是首頁';
}
function showList(){
    document.body.innerText = '這是列表頁';
}
function showArticle(){
    document.body.innerText = '這是內容頁';
}

const arr = [
    ['首頁',showIndex],
    ['列表頁',showList],
    ['內容頁',showArticle],
]

arr.forEach((item)=>{
    const ele = document.createElement('DIV');
    ele.innerText = item[0];
    ele.onclick = item[1];
    document.body.append(ele);
}) 複製代碼


代碼邏輯很簡單,就是在頁面渲染一些內容,而後點擊會跳轉到不一樣的頁。 可是若是全部內容都寫在index.js裏,代碼會變得很巨大,後期也很很差維護, 因此咱們對index.js進行功能拆分,而後使用引用的方式,將他們關聯起來。

對功能進行拆分以後項目的樣子:
  
  
  
  
# 目錄結構
pages
  |__ home.js
  |__ list.js
  |__ article.js
index.js
index.html

import { showIndex } from 'js/home.js';

import { showList } from 'js/list.js';
import { showArticle } from 'js/article.js';

const arr = [
    ['首頁',showIndex],
    ['列表頁',showList],
    ['內容頁',showArticle],
]

arr.forEach((item)=>{
    const ele = document.createElement('DIV');
    ele.innerText = item[0];
    ele.onclick = item[1];
    document.body.append(ele);
}) 複製代碼


  
  
  
  
function showIndex(){
    document.body.innerText = '這是首頁';
}

export showIndex;

可是有個問題,上面的代碼在老版本的瀏覽器是沒法運行的,由於老版本瀏覽器,不支持ES6模塊, 因此咱們須要使用node對項目源代碼進行分析打包,造成新的瀏覽器能夠運行的代碼,就變成了新的目錄結構。

  
  
  
  
# 目錄結構
dist
  |__ index.js
  |__ index.html
src
  |__ pages
  |     |__ home.js
  |     |__ list.js
  |     |__ article.js
  |__ index.js
  |__ index.html

分析打包的過程就是,咱們須要寫一個腳本,node執行這個腳本,腳本內容是去打開index.js文件,而後對代碼進行解讀,當遇到依賴引入的地方時,而後把代碼複製進來,看下面這個動圖就能夠一清二楚。


固然咱們不須要本身寫這個腳本,由於咱們有 webpack, webpack的第一個功能,就是作上面的事情,從入口文件開始分析,對依賴進行合併,而後打包輸出。

而webpack的第二個功能,就是他能夠處理你引入任何格式的文件,注意,是任何格式。 前面介紹過,在前端有不少預處理語言,他們能極大方便咱們的開發,可是預處理語言須要進行編譯,才能成爲可以使用的語言。 而webpack,就能幫咱們進行編譯。
webpack 當處理到不認識的文件格式時,會把他轉化爲字符串,而後使用loader對他進行轉化,轉化成js認識的格式。

以上面的項目爲例子,咱們將被引用的幾個腳本文件改成了ts的文件形式。

  
  
  
  
# 目錄結構
dist
  |__ index.js
  |__ index.html
src
  |__ pages
  | |__ home.ts
  | |__ list.ts
  | |__ article.ts
  |__ index.js
  |__ index.html

js默認是不認識ts文件裏的內容的,即便他們很像,因此webpack在解析ts文件時,要先作一個事情,就是先把ts轉爲js格式,而後在對轉化後的js進行引入。


loader是能夠拓展的,因此只要你有被引入文件的loader,理論上你能夠引入任何文件格式。

webpack的第三個功能,就是插件。 插件就是webpack在執行分析打包任務時,你能夠作一些額外的操做。 好比說,在引入css後對css進行自動添加適配前綴、對項目總體代碼進行壓縮等等,都是插件的功能體現。 由於說到底,代碼就是字符串,webpack能獲取到整個項目,包括依賴文件的代碼(字符串),而後他在這個字符串作一些操做,也很好理解。


這就是webpack的三個主要功能,他的可拓展性,讓他極具創造力,現在基本已經成爲了全部web應用的基建部分,正所謂時勢造英雄,他生在了前端最須要他的年代,我相信他構建的打包模式,不會是咱們前端的最終形態,只要js還在進步,還在變化,就會有新的模式出現。
相關文章
相關標籤/搜索