學習webpack之一:從最簡單的webpack提及

看了不少webpack的教程,大可能是上來就講一堆配置,一堆插件的使用。這種文章看起來有點相似於官方文檔,或者新華字典。我想回歸初心,換一種方式,基於實際使用出發,一步一步介紹webpack。javascript

從一個最簡單的例子開始,這個例子只爲了描述最簡單的webpack功能,實現一個最簡單的需求:在瀏覽器上顯示一段文字。html

傳統方式

首先咱們有一個index.html,這個html中只是引入了index.jsa.jsb.jsjava

<!Doctype html>
<html>
  <head>
      <meta name="charset" content="utf-8">
      <title>webpack</title>
  </head>
  <body>
    <script type="text/javascript" src="./a.js"></script>
    <script type="text/javascript" src="./b.js"></script>
    <script type="text/javascript" src="./index.js"></script>
  </body>
</html>
複製代碼

a.js中聲明瞭變量var a = 1;,在b.js中聲明瞭變量var b = 2;。因爲這種方式下,做用域是共享的,a和b至關於都是掛載在window上,因此在index.js中能夠直接訪問到a和b的值。node

index.js中,咱們建立一個DOM並掛載到HTML上:webpack

var dom = document.createElement('p');
dom.innerHTML = `a=${a}; b=${b}`;
document.body.appendChild(dom);
複製代碼

最後,在瀏覽器上就會顯示a=1; b=2web

這種使用方式雖然簡單,可是會有潛在的問題:npm

  1. 瀏覽器在加載時,會先加載html文件,而後根據HTML裏面的script標籤去依次加載每一個js文件。這樣對於每一個js文件,瀏覽器都會向服務器發送一次請求。若是引入的文件數不少,那麼發送的請求次數就會過多,對服務器形成必定的壓力。並且,單個文件可能並不大,相對於瀏覽器對每次請求都須要創建連接、斷開連接的成原本說很不划算。要解決這個問題,就須要打包,將多個js文件打包成單個。
  2. 不能嚴格保證js文件的加載順序,好比index.js加載完了,但它所依賴的a.js還沒加載。固然,這個問題能夠用require.js解決。
  3. 不一樣script標籤引入的js代碼,會污染全局做用域,好比a.js中聲明的a就直接掛載到了window上,其餘文件中若是再聲明a變量,就會有衝突。這個問題能夠用當即執行函數的方式解決。

雖然有辦法解決,但總感受不是那麼完美,治標而不治本。迴歸到js的運行環境上,這都是由於js代碼須要在瀏覽器中運行。若是是在node環境中運行,那能夠直接使用CommonJS規範,每一個文件就是一個模塊,各個模塊之間的做用域是獨立的,經過require能夠解決模塊依賴和加載問題。甚至還能夠在node中利用ES6的模塊機制,也一樣能夠解決這個問題。顯然,這種寫代碼的方式要簡單不少,但只能在node環境下。而webpack的一個重要做用,就是可讓你這種方式寫出來的代碼能在瀏覽器中運行。json

webpack方式

a.jsb.js分別做爲2個模塊,經過ES6的export導出變量a和b,在index.js中經過import引入:gulp

//a.js
export var a = 1;

//b.js
export var b = 2;

//index.js
import {a} from './a.js';
import {b} from './b.js';
var dom = document.createElement('p');
dom.innerHTML = `a=${a}; b=${b}`;
document.body.appendChild(dom);
複製代碼

最後,咱們但願用webpack,將其打包成一個單獨的文件,直接掛載到index.html中。從零開始,安裝webpack。瀏覽器

  1. 新建一個文件夾,在這個文件夾中npm init,初始化。

  2. 安裝webpackwebpack-cli,運行npm install webpack webpack-cli -Dwebpack-cli爲webpack提供了命令行工具,讓咱們能夠直接在命令行中使用webpack

  3. 創建src文件夾,將a.js,b.jsindex.js存放在src文件夾下。這個文件夾存放的是原始文件

  4. 創建dist文件夾,用來存放編譯後的文件,也就是打包後的單個文件

  5. index.html放到src文件夾下,這時引用的不是index.js,而是打包後的位於dist目錄下的bundle.js文件

    <script type="text/javascript" src="../dist/bundle.js"></script>
    複製代碼
  6. 配置webpack。webpack的配置就是在根目錄下直接新建一個webpack.config.js,配置以下:

    const path = require('path');
    
    module.exports = {
      entry: './src/index.js',
      output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js'
      }
    }
    複製代碼
    • entry是打包的入口文件,也就是告訴webpack打包哪一個文件,這裏指定的是index.js。因爲在index.jsimporta.jsb.js,因此webpack在打包時會同時將a.jsb.js引入。從這裏能夠看到,只用告訴webpack入口文件便可,全部的依賴文件webpack會本身尋找和解決。
    • output是告訴webpack,打包後的文件放哪裏。path指定了打包後的文件路徑,filename指定了打包後的文件名。綜合起來,打包後的文件就是dist目錄下的bundle.js
  7. package.json中的script下作個配置:

    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "webpack" 
      },
    複製代碼
  8. 直接運行npm run build,node就會自動執行webpack,這時在dist目錄下就能夠看到生成的js文件(只有一個),將index.html放到瀏覽器中,就會看到最後顯示的效果。

不止於此

從上面的例子看到,使用了webpack以後,咱們解決了傳統方式裏面遇到的各類問題。固然,webpack能作的,遠不止這些。好比在寫代碼時,可能還會有這些需求:

  • 代碼轉換:將 TypeScript 編譯成JavaScript、將 SCSS 編譯成 CSS等。
  • 文件優化:壓縮JavaScript、CSS、HTML 代碼,壓縮合並圖片等。
  • 代碼分割:提取多個頁面的公共代碼,提取首屏不須要執行部分代碼讓其異步記在。
  • 模塊合併:在採用模塊化的項目裏會有不少個模塊和文件,須要經過構建功能將模塊分類合併成一個文件。
  • 自動刷新:監聽本地源代碼變化,自動從新構建、刷新瀏覽器。
  • 代碼校驗:在代碼被提交到倉庫前須要校驗代碼是否符合規範,以及單元測試是否經過。
  • 自動發佈:更新代碼後,自動構建出線上發佈代碼並傳輸給發佈系統。

咱們須要一個工具來幫咱們解決這些問題,完成整個構建流程。使用構建工具的目的,是爲了讓咱們寫代碼更加方便,能夠用更新的特性而不用過多關心瀏覽器的兼容問題;讓咱們能夠省去不少機械重複性的工做,好比修改代碼後瀏覽器會自動刷新,提升咱們的開發效率。

固然,在webpack以前,已經有不少優秀的構建工具了,好比grunt、gulp等。稱webpack是當下最流行的構建工具絕不爲過。webpack強大不只在其自己,還在於不少基於webpack的插件,提供了一個強大的生態系統。webpack能作的事情還有不少,將在後面一步步繼續學習。

相關文章
相關標籤/搜索