Webpack 的簡單介紹

本文介紹了一些 webpack 的核心概念以及一些概念術語,並對核心配置作了一些簡單的用法講解。建議剛剛接觸 Webpack 的朋友能夠先了解一下。想了解更多 Webpack 使用以及配置的話能夠參考個人下一篇文章: 從零開始搭建一個 Webpack 開發環境配置(附 Demo)css


爲何須要使用 webpack

  • 模塊化開發的趨勢 咱們在開發的過程當中,以前都是使用引入 script 的方式進行各類工具和插件的引入,可是這樣會形成很大程度上的全局污染,因此引入了 模塊化 的概念,可是不論是 commomJs 仍是 CMD,AMD 的方式,瀏覽器都沒法識別,而使用 webpack 就能夠自動的將文件編譯成瀏覽器能夠識別的代碼node

  • less、sass 以及 ES6 語法的使用 一樣的,直接使用 less、sass 和 ES6 語法,直接使用,瀏覽器甚至 node 環境也沒法正常識別,因此這時候 loader 就派上用場了,可使用 less-loader、sass-loader 以及 babel-lodaer 對對應的文件進行轉換以後,就能夠正常的編譯了webpack

  • 監聽文件的變化並自動刷新網頁,作到實時預覽web

  • 提供 HTTP 服務而不是使用本地文件預覽npm

  • 對於打包後的文件進行壓縮,模塊拆分,減少打包後的文件體積數組

  • 等等還有不少別的優點,這裏我就不一一列舉了瀏覽器


webpack 安裝

  • 全局安裝:緩存

    npm install --global webpack
    複製代碼
  • 本地安裝:sass

    npm install --save-dev webpack
    npm install --save-dev webpack-cli
    複製代碼

Webpack 概念

webpack 是一個可高度配置的現代 JavaScript 應用程序模塊打包器。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關係圖,其中包含應用程序須要的每一個模塊,而後將全部這些模塊打包成一個或多個 bundle。bash

Webpack 核心概念

入口

入口點能夠告訴 webpack 從哪裏啓動以及遵循依賴關係圖,以此知道要打包什麼東西。你能夠考慮將待打包文件的根目錄做爲你應用程序的入口點。

我的理解:入口就是 webpack 在處理應用程序時,須要知道從哪一個文件開始執行,這個文件就是整個程序的入口文件。

用法:entry: string|Array|Object

基本用法

webpack.config.js

const config = {
  entry: './src/index.js'
};

module.exports = config;
複製代碼

數組語法

通常適用於多頁面應用,多個入口的場景。

webpack.config.js

const config = {
  entry: ['./src/entry1', './src/entry2']
};

module.exports = config;
複製代碼

對象語法

通常適用於分離 應用程序(app) 和 第三方庫(vendor) 入口。

webpack.config.js

const config = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js'
  }
};

module.exports = config;
複製代碼

配置動態入口

假如項目裏有多個頁面須要爲每一個頁面的入口配置一個 Entry ,但這些頁面的數量可能會不斷增加,則這時 Entry 的配置會受到到其餘因素的影響致使不能寫成靜態的值。

webpack.config.js

// 同步函數
entry: () => {
  return {
    a:'./pages/a',
    b:'./pages/b',
  }
};
// 異步函數
entry: () => {
  return new Promise((resolve)=>{
    resolve({
       a:'./pages/a',
       b:'./pages/b',
    });
  });
};
複製代碼

輸出

上面既然已經有入口文件了,那麼 webpack 執行了一系列操做以後,生成的新的打包後的文件應該放到哪兒呢,因此咱們須要指定一下。

在 webpack 中配置 output 屬性的最低要求是,將它的值設置爲一個對象,包括如下兩點:

  • filename 用於輸出文件的文件名
  • 目標輸出目錄 path 的絕對路徑

基本用法

webpack.config.js

const path = require('path');

const config = {
    entry: './src/index.js',
    output: {
        // 最基本的兩個配置要求
        filename: 'bundle.js',  // 輸出文件的文件名
        path: path.resolve(__dirname, 'dist')   // 目標輸出目錄 path 的絕對路徑,這裏必須是絕對路徑
    }
};

module.exports = config;
複製代碼

多個入口起點

若是配置建立了多個單獨的 "chunk",則應該使用佔位符(參考*內置的佔位符變量*)來確保每一個文件具備惟一的名稱。

webpack.config.js

const path = require('path');

const config = {
  output: {
    // 最基本的兩個配置要求
    filename: '[name]-bundle.js',  // 輸出文件的文件名
    path: path.resolve(__dirname, 'dist')   // 目標輸出目錄 path 的絕對路徑
  }
};

module.exports = config;
複製代碼

內置的佔位符變量

變量名 含義
id Chunk 的惟一標識,從0開始
name Chunk 的名稱
hash Chunk 的惟一標識的 Hash 值
chunkhash Chunk 內容的 Hash 值

loader

loader 用於對模塊的源代碼進行轉換。loader 可使你在 importrequire() 或"加載"模塊時預處理文件。 loader 能夠將文件從不一樣的語言(如 TypeScript)轉換爲 JavaScript,或將內聯圖像轉換爲 data URL。loader 甚至容許你直接在 JavaScript 模塊中 import CSS文件!

基本使用

例如:加載 css 模塊:

  • 安裝對應的 loader

    npm install --save-dev style-loader css-loader
    複製代碼
  • 而後指示 webpack 對每一個 .css 使用 css-loader 和 style-loader

webpack.config.js

``` js
module.exports = {
    module: {
        rules: [
            { test: /\.css$/, use: ['style-loader', 'css-loader' }
        ]
    }
};
```
複製代碼

配置 loader

rules 配置模塊的讀取和解析規則,一般用來配置 Loader。其類型是一個數組,數組裏每一項都描述瞭如何去處理部分文件。 配置一項 rules 時大體經過如下方式:

  • 條件匹配:經過 test 、 include 、 exclude 三個配置項來命中 Loader 要應用規則的文件

  • 應用規則:對選中後的文件經過 use 配置項來應用 Loader,能夠只應用一個 Loader 或者按照從後往前的順序應用一組 Loader,同時還能夠分別給 Loader 傳入參數

  • 重置順序:一組 Loader 的執行順序默認是從右到左(從下到上、從後到前)執行,經過 enforce 選項可讓其中一個 Loader 的執行順序放到最前或者最後

  • 在 Loader 須要傳入不少參數時,你還能夠經過一個 Object 來描述

  • test include exclude 這三個命中文件的配置項能夠傳入一個字符串或正則,其實它們還都支持數組類型

具體使用:

module.exports = {
    module: {
        rules: [
            
             {
                // 命中 JavaScript 文件
                test: [
                    /\.js?$/,
                    /\.jsx?$/
                ],
                // 用 babel-loader 轉換 JavaScript 文件
                // ?cacheDirectory 表示傳給 babel-loader 的參數,用於緩存 babel 編譯結果加快從新編譯速度
                use: [
                    {
                        loader:'babel-loader',
                        options:{
                            cacheDirectory:true,
                        },
                        // enforce:'post' 的含義是把該 Loader 的執行順序放到最後
                        // enforce 的值還能夠是 pre,表明把 Loader 的執行順序放到最前面
                        enforce:'post'
                    }
                ],
                // 只命中src目錄裏的js文件,加快 Webpack 搜索速度
                include: path.resolve(__dirname, 'src')
            },
            {
                // 命中 SCSS 文件
                test: /\.scss$/,
                // 使用一組 Loader 去處理 SCSS 文件。
                // 處理順序爲從後到前,即先交給 sass-loader 處理,再把結果交給 css-loader 最後再給 style-loader。
                use: ['style-loader', 'css-loader', 'sass-loader'],
                // 排除 node_modules 目錄下的文件
                exclude: path.resolve(__dirname, 'node_modules')
            }
        ]
    }
};
複製代碼

plugins

Plugin 是用來擴展 Webpack 功能的,經過在構建流程裏注入鉤子實現,它給 Webpack 帶來了很大的靈活性。

基本使用

好比每次打包文件到 dist 文件夾下,就可能致使文件夾下面的文件過多,內容過大,那麼此時咱們可能須要在打包以前先將 dist 文件下的文件都刪除掉,可是每次都手動刪除豈不是太麻煩,此時咱們就可使用 clean-webpack-plugin 插件來幫助咱們清理 dist 文件夾

插件安裝

npm install clean-webpack-plugin --save-dev
複製代碼

webpack.config.js

const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    plugins: [
        new CleanWebpackPlugin(['dist'])
    ]
}
複製代碼

其餘概念術語

資源(Asset)

這是一個廣泛的術語,用於圖片、字體、媒體,還有一些其餘類型的文件,經常使用在網站和其餘應用程序。這些文件一般最終在輸出(output ) 中成爲單個文件,但也能夠經過一些東西內聯,像 style-loader 或者 url-loader 。

Bundle

由多個不一樣的模塊生成,bundles 包含了早已通過加載和編譯的最終源文件版本。

Chunk

這是 webpack 特定的術語被用在內部來管理 building 過程。bundle 由 chunk 組成,其中有幾種類型(例如,入口 chunk(entry chunk) 和子 chunk(child chunk))。一般 chunk 會直接對應所輸出的 bundle,可是有一些配置並不會產生一對一的關係。

依賴關係圖(Dependency Graph)

有時候一個文件依賴於其餘文件,webpack 將其視爲依賴關係(dependency)。從一個或多個入口點開始,webpack 遞歸構建一個依賴關係圖,裏面包含了你的應用程序須要的全部模塊/資源(mudule/asset)。

模塊(Module)

提供比完整程序接觸面(surface area)更小的離散功能塊。精心編寫的模塊提供了可靠的抽象和封裝界限,使得應用程序中每一個模塊都具備條理清楚的設計和明確的目的。

  • 模塊解析(Module Resolution):一個模塊能夠做爲另外一個模塊的依賴模塊,resolver 是一個庫( library )用於幫助找到模塊的絕對路徑... 模塊將在 resolve.modules 中指定的全部目錄內搜索。

Tree Shaking

移除未使用/多餘的代碼,或者更準確地說,只導入引用的代碼。編譯器(compiler)(例如 webpack)將經過分析各類 import 語句和引入代碼的使用狀況,來肯定哪些部分的依賴關係被實際使用,刪除不是「樹」的部分,以實現此功能

第三方庫入口點(Vendor Entry Point)

從 app.js 和 vendors.js 開始建立依賴圖(dependency graph)。這些依賴圖是彼此徹底分離、互相獨立的,容許你使用 CommonsChunkPlugin 從「應用程序 bundle」中提取 vendor 引用(vendor reference) 到 vendor bundle。能夠幫助你在 webpack 中實現被稱爲長效緩存的通用模式。

優化

  • Bundle 分離(Bundle Splitting) 這個流程提供一個優化 build 的方法,容許 webpack 爲應用程序生成多個 bundle。最終效果是,當其餘某些 bundle 的改動時,彼此獨立的另外一些 bundle 均可以不受到影響,減小須要從新發布的代碼量,所以由客戶端從新下載並利用瀏覽器緩存。

  • 代碼分離(Code Splitting) 指將代碼分離到每一個 bundles/chunks 裏面,你能夠按需加載,而不是加載一個包含所有的 bundle。


總結

本文簡單介紹了一下 Webpack 的做用以及 Webpack 核心概念的用法。想了解更多的朋友能夠參考個人下一篇文章:從零開始搭建一個 Webpack 開發環境配置(附 Demo)

相關文章
相關標籤/搜索