webpack入門必知必會

勞卜發表於2017-01-16

關於

前言

這是我第一篇介紹webpack的文章,先從一個入門教程開始吧,後續會有更多相關webpack的文章推出。

首先什麼是webpack?如果說它是一個打包工具那真的是有點大材小用了。我個人認為webpack是一個集前端自動化、模組化、元件化於一體的可擴充系統,你可以根據自己的需要來進行一系列的配置和安裝,最終實現你需要的功能並進行打包輸出。

本文作為一篇入門教程,這裡先從webpack最簡單的3招開始介紹,即拆分、打包、壓縮。

webpack入門必知必會
webpack入門

步驟

1.傳統專案中的問題

在不依賴任何自動化、模組化工具的專案中,通常我們的程式碼是這樣的:

index.html

<html>
  <head>
    <title>傳統專案</title>
    <script src="https://code.jquery.com/jquery-2.2.4.js"></script>
  </head>
  <body>
    <script src="app/index.js"></script>
  </body>
</html>複製程式碼

app/index.js

function main() {
    $('body').html('hello world!');
}

main();複製程式碼

以上示例中,指令碼之間存在著隱式依賴關係。

index.js取決於被包括在頁面執行之前的jQuery,它只是假設有一個全域性變數$的存在。

這樣管理JavaScript專案有一些問題:

如果依賴項丟失,或者包含在錯誤的順序中,應用程式將不會執行。
如果包含依賴項但沒有使用,那麼瀏覽器必須下載很多不必要的程式碼。

所以為了解決以上問題,我們需要使用webpack來實現一些改變。

2.準備

首先我們得在專案中安裝webpack,我們開啟命令列工具執行:

mkdir demo && cd demo // 新建demo資料夾並開啟
npm init // 初始化npm,生成package.json配置檔案
npm install --save-dev webpack@beta // 安裝webpack2.0版本,mac系統可能需要新增sudo命令複製程式碼

以上使用的npm命令需要安裝node.js,可以點選這裡安裝即可:node.js

為了改進上方傳統專案中的不足,我們這裡還需要安裝jQuery:

npm install --save jquery // 安裝jQuery複製程式碼

3.改變

改變後的index.js

var $ = require('jquery');

function main() {
    $('body').html('hello world!');
}

main();複製程式碼

這裡我們可以直接在index.js裡引用jQuery,index.js明確要求jQuery的存在,這樣就不存在隱式依賴的問題(沒有全域性汙染)。

改變後的index.html

<html>
  <head>
    <title>webpack專案</title>
  </head>
  <body>
      <script src="dist/bundle.js"></script>
  </body>
</html>複製程式碼

這裡我們的index.html檔案只引入了最終打包後的bundle.js。現在執行webpack命令將index.js輸出為bundle.js。

執行命令:webpack app/index.js dist/bundle.js

webpack app/index.js dist/bundle.js
Hash: 3bb91a6dedfc2a2a1c08
Version: webpack 2.2.0-rc.4
Time: 397ms
    Asset    Size  Chunks                    Chunk Names
bundle.js  270 kB       0  [emitted]  [big]  main
   [0] ./~/jquery/dist/jquery.js 267 kB {0} [built]
   [1] ./app/index.js 83 bytes {0} [built]複製程式碼

最終我們在瀏覽器中開啟index.html頁面可以看到輸出的“hello world!”。

webpack入門必知必會
hello world

4.拆分

現在如果我們index.js中的"hello world!"字串需要放到另外一個hello.js中,然後在index.js中引入使用的話,這就涉及到webpack模組拆分的功能。

app/index.js

var $ = require('jquery');
var str = require('./hello.js');

function main() {
    $('body').html(str);
}

main();複製程式碼

app/hello.js

var str = 'hello world!';

module.exports = str;複製程式碼

我們在hello.js中通過module.exports匯出str變數,然後在index.js通過require匯入同樣可以實現瀏覽器中輸入“hello world!”的效果,當然我們需要重新執行下webpack命令:webpack app/index.js dist/bundle.js

5.打包

其實在上面我們已經使用了打包命令:

webpack app/index.js dist/bundle.js複製程式碼

其中的app/index.js即為打包的入口檔案,而dist/bundle.js為輸出檔案。

但是我們會發現這樣的命令不利於我們複雜專案配置的使用,對於更復雜的配置,我們可以利用配置檔案webpack.config.js來統一管理。

我們可以在demo資料夾下新建webpack.config.js配置檔案:

var path = require('path');

module.exports = {
  entry: './app/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
}複製程式碼

上方配置中的entry就是我們的入口檔案,可以有多個入口檔案,而output即為webpack打包的輸入物件,filename為輸出檔名,path為輸出路徑。

如此我們執行命令列:

webpack --config webpack.config.js複製程式碼

同樣可以生成打包目錄dist及打包檔案bundle.js。

當然你也可以直接執行簡化的命令:

webpack複製程式碼

webapck會自動去尋找當前目錄下的webpack.config.js檔案。

6.壓縮

上一步我們利用webpack命令將多個多件打包到了一個bundle.js的檔案中,但是並未進行壓縮,你可以開啟bundle.js進行檢視。

而如果我們需要對打包後的程式碼進一步壓縮處理,我們可以執行命令:

webpack -p複製程式碼

這時我們可以來進行下打包和壓縮的檔案大小對比

打包命令:webpack

webpack
Hash: ab4a1091f0880100eab0
Version: webpack 2.2.0-rc.4
Time: 387ms
    Asset    Size  Chunks                    Chunk Names
bundle.js  270 kB       0  [emitted]  [big]  main
   [0] ./app/hello.js 50 bytes {0} [built]
   [1] ./~/jquery/dist/jquery.js 267 kB {0} [built]
   [2] ./app/index.js 114 bytes {0} [built]複製程式碼

輸出的bundle.js整個檔案大小為270 kB。

壓縮命令:webpack -p

webpack -p
Hash: ab4a1091f0880100eab0
Version: webpack 2.2.0-rc.4
Time: 1967ms
    Asset     Size  Chunks             Chunk Names
bundle.js  88.3 kB       0  [emitted]  main
   [0] ./app/hello.js 50 bytes {0} [built]
   [1] ./~/jquery/dist/jquery.js 267 kB {0} [built]
   [2] ./app/index.js 114 bytes {0} [built]複製程式碼

輸出的bundle.js整個檔案大小為88.3 kB。

很明顯,檔案被壓縮了。

7.進一步壓縮優化

上方我們通過webpack的壓縮命令將檔案打包並壓縮了,但是對於webpack -p壓縮後的檔案來說其實還有壓縮的餘地。如果你使用的是webpack1.0,那麼你可以在配置檔案中新增plugins配置項,並且加入如下外掛:

var webpack = require('webpack');

module.exports = {
    ...
    plugins:[
        // 去除程式碼塊內的告警語句
        new webpack.optimize.UglifyJsPlugin({
          compress: {
            warnings: false
          }
        }),
        // 優先考慮使用最多的模組,併為它們分配最小的ID
        new webpack.optimize.OccurenceOrderPlugin()
    ]
    ...
}複製程式碼

而本示例中使用的是webpack2.0版本,在2.0中UglifyJsPlugin的compress選項預設為false,並且OccurrenceOrderPlugin預設啟用,所以無需進行配置。

結語

本文主要介紹了webpack入門的一些簡單命令和基本配置資訊,從程式碼拆分、打包、壓縮的角度和傳統的前端專案進行對比,希望以此加深大家對webpack基礎知識的印象。

如果覺得本文對你有幫助,可以關注我的微信公眾號,來這裡聊點關於前端的事情。

webpack入門必知必會

相關文章