一步步學Webpack4(0)-- 實戰起步

最近因爲學習需求,手擼了個簡單的SPA框架並使用Webpack4作打包和預覽調試,因爲沒有怎麼系統學習過Webpack因此遇到坑挺多,索性直接開始從頭學一波順便記錄下來.
寫Webpack文章不寫版本都是耍流氓,這篇文章基於當下最新的 webpack v4.22.0 以及 webpack-cli v3.1.2 編寫.

本章以 環境搭建 -> 練習1 -> 理論學習 -> 練習2 的步驟進行:html

  1. 跟隨官方文檔 Getting-Started, 由簡單項目配置搭建開始;
  2. 完成後直接進入練習1--默認Webpack配置打包項目;
  3. 完成一波實戰操做以後再回頭瞭解 基本概念
  4. 完成概念學習以後再進入練習2--學習使用配置文件實現項目打包;

Tip:全過程將記錄在Github倉庫 webpack-stepbystep 中,邊看文章邊看commit學習食用效果更佳喲~node

1. Init:簡易Webpack項目搭建

想要學習Webpack的小夥伴大概都知道Webpack是用來打包的,嗯暫時知道這些就足夠了,立刻來開始第一次打包的體驗吧~webpack

開始實戰確定要建立工程的,使用下面的命令開始(須要 Node.js ):git

mkdir webpack-stepbystep
cd webpack-stepbystep
npm init -y
npm i -D webpack webpack-cli
webpack -v
webpack-cli -v

上面的命令語句分別是:github

  • 建立項目
  • 進入項目
  • 初始化 package.json
  • 在項目中安裝 webpack & webpack-cli
  • 檢查 webpack 版本
  • 檢查 webpack-cli 版本

本文的環境是webpack v4.22.0 & webpack-cli v3.1.2, 最後兩句版本檢查若是運行失敗的話,能夠考慮使用全局方式安裝 Webpack & Webpack-cli, 以前在Windows上開發的時候遇到過這個問題, 全局安裝命令以下:web

npm install -g webpack webpack-cli
webpack -v
webpack-cli -v

其餘安裝問題暫且按下不表, 可自行參考 Installation. npm

完成以上項目環境搭建以後,項目的文件結構大體以下所示:json

webpack-stepbystep
    └─ node_modules
    └─ package-lock.json   
    └─ package.json

項目環境搭建至此所有完成, 以上環境搭建的項目提交爲init(project): finish base enviroment setup, 立刻進入實戰環節.數組

2. 練習1:默認Webpack配置打包項目

2.1 從刀耕火種的寫法開始

首先添加index.html & src/index.js, 項目的文件結構大體以下所示:瀏覽器

webpack-stepbystep
    └─ node_modules
    └─ src
        └─ index.js
    └─ index.html
    └─ package-lock.json   
    └─ package.json

編輯index.html, 其中用script引用了第三方工具庫 lodash:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Started</title>
    <script src="https://unpkg.com/lodash@4.16.6"></script>
</head>
<body>
    <body>
        <script src="./src/index.js"></script>
    </body>
</body>
</html>

而後編輯 src/index.js , 代碼中的 _ 即對lodash庫的引用:

function component () {
    let element = document.createElement('div');
    element.innerHTML = _.join(['Hello', 'Webpack'], '');
    return element;
}
document.body.appendChild(component());

能夠看出 index.html 中的兩個 <script> 之間存在這隱式依賴的關係, 即 index.js 默認全局存在lodash. 這種刀耕火種時期的寫法存在三個問題:

  1. 模塊間的依賴關係不明顯,工程變大難以查找依賴;
  2. 若是依賴丟失,將形成運行問題;
  3. 若是引用了依賴可是程序並沒有調用,下載無用庫形成浪費而且影響速度

有錯就要改,因此咱們開始使用現代方案來對當前項目進行修改~

至此項目提交爲 feat(project): add index.html & index.js with implicit dependencies .

2.2 現代化解決方案

現代的思想是用npm將庫下載到本地,在js中顯示聲明依賴並調用,最後用Webpack完成打包,瞭解了以後就開始吧:

  • 第零步、咱們先使用Webpack的默認配置打包項目,Webpack默認以./src/index.js爲起點開始構建,獲取依賴並完成打包到./dist/main.js. (文章第三節」學習:Webpack概念「將會介紹);
  • 第一步、將依賴安裝到項目中. 以後 Webpack 會將依賴一塊兒打包到main 防止依賴丟失形成的運行問題:

    npm i -S lodash
  • 第二步、在文件 index.js 頂部用import顯式聲明依賴. 方便依賴的查找的同時明確了項目所需的依賴:

    import _ from 'lodash';
    function component () {
        let element = document.createElement('div');
        element.innerHTML = _.join(['Hello', 'Webpack'], '');
        return element;
    }
    document.body.appendChild(component());
  • 第三步、執行打包. 打開終端在當前項目下運行 webpack ,運行成功以後發現當前項目目錄多出了 dist 文件夾,項目的文件結構大體以下所示:

    webpack-stepbystep
        └─ dist
            └─ main.js
        └─ node_modules
        └─ src
            └─ index.js
        └─ index.html
        └─ package-lock.json   
        └─ package.json

完美~Webpack的打包操做如今已經完成了!只剩完成最後一步就能夠完美運行程序了!

  • 第四步、按照 Webpack 的默認規則修改 index.html 中的引用. 先刪除兩個 <script> 標籤,再添加對於Webpack生成 main.js 的引用;

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Started</title>
    </head>
    <body>
        <body>
            <script src="main.js"></script>
        </body>
    </body>
    </html>

因爲 Webpack 的默認規則只能打包js,因此咱們先用一下比較粗暴的手段,直接把index.html複製一份,放到打包完生成的dist文件夾下. 在瀏覽器運行該index.html.

WOW! 瀏覽器出現了 Hello Webpack的字樣,運行成功!Webpack首戰成功結束~接下來來了解一下Webpack的概念.

至此項目提交爲 feat(project): combat:project bundle without configuration file .

3. 學習:Webpack概念

Concepts部分告訴了咱們Webpack的定義、目的以及核心概念:

  • 定義:靜態模塊打包器
  • 目的:經過遞歸構建依賴關係圖(dependency graph),將應用須要的模塊打包,造成一個或者多個bundle
  • 核心概念:

    • 入口(entry): 告訴 Webpack 從那個模塊(文件)開始構建dependency graph. Webpack將會以此爲起點,找到全部的依賴並打包最終造成bundle.

      • Tip: 若是不在 webpack.config.js 中配置entry,Webpack將會默認使用路徑 ./src/index.js 做爲起點開始構建打包.
    • 輸出(ouput): 告訴Webpack打包結果的建立位置&命名方式.

      • Tip: 若是不在 webpack.config.js 中配置output,Webpack將會默認在路徑 ./dist 文件夾下建立打包結果main.js .
    • 加載器(loader): loader的做用是將全部類型的文件轉換爲能夠被 dependency graph 直接應用的文件,也就是Webpack封面圖--將全部依賴模塊打包成靜態資源

      • 使用方式: 每種類型的模塊基本都有對應的loader負責其轉換,可是Webpack並不具有loader. 使用一個新的loader,首先須要用npm或者yarn安裝, 而後 webpack.config.jsmodule.rules 中進行手動配置,聲明但願進行轉換的文件類型及其對應的處理器loader(test、use).
      • 列表連接:loader列表
    • 插件(plugin): 執行範圍更廣的任務,例如:優化打包、壓縮、注入新的環境變量等等.

      • 使用方式:使用一個新的plugin, 首先須要用npm或者yarn安裝, 而後在webpack.config.js的頂部用require進行聲明,接着在module.plugins中初始化並根據plugin的文檔進行配置.
      • 列表連接:Plugin列表
    • 模式(Mode): 當前項目的打包模式,現有三種 nonedevelopmentproduction 模式可供選擇. 如今暫時無論這個屬性的配置.

4. 練習2:配置文件實戰練習

Webpack提供了方便開箱即用的默認配置,可是想要充分發揮Webpack的能力,仍是須要使用配置文件.

4.1. 使用配置文件復刻默認Webpack效果

若是 webpack.config.js 存在,則 webpack 命令將默認選擇使用它,因而咱們在項目根目錄添加文件 webpack.config.js,項目的文件結構大體以下所示:

webpack-stepbystep
    └─ dist
        └─ main.js
    └─ node_modules
    └─ src
        └─ index.js
    └─ index.html
    └─ package-lock.json   
    └─ package.json
    └─ webpack.config.js

webpack.config.js 添加配置,使之實現默認Webpack配置的效果:

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
    }
};

刪除dist文件夾,保存 webpack.config.js ,並打開終端在當前項目下運行 webpack ,運行成功以後發現當前項目目錄再次生成了 dist 文件夾,裏面有 main.js , 至此咱們成功使用 webpack.config.js 成功復刻了默認Webpack配置的效果~

4.2. 使用配置文件實現項目自動化打包

固然此次實戰的目標確定不止如此,第一次實戰中遺留着一個問題,就是Webpack的默認配置沒法幫助咱們將 index.html 一塊兒打包到 dist 中,這致使項目沒法全自動打包. 如今就來嘗試藉助 webpack.config.js 來解放Webpack的能力,實現項目的全自動化打包.

實現過程分爲兩個步驟:

  • 第一步、每次打包以前清除 dist 內容。已有打包內容容易對新打包內容形成影響,因此在這裏使用一個叫作 clean-webpack-plugin 的插件,這個插件將幫助咱們在每次打包以前清理 dist 文件夾的內容,插件的配置方法以下:

    1. 插件安裝:首先經過 npm 再項目中安裝插件:

      npm i -D clean-webpack-plugin
    2. 配置文件修改:在 webpack.config.js 文件開頭用require引用插件,再在 plugins 數組中添加其插件的實現,完整配置文件代碼以下所示:

      const path = require('path');
      const CleanWebpackPlugin = require('clean-webpack-plugin');
      
      module.exports = {
          entry: './src/index.js',
          output: {
              filename: 'main.js',
              path: path.resolve(__dirname, 'dist')
          },
          plugins: [
              new CleanWebpackPlugin(['dist'])
          ]
      };
      1. 測試: 完成配置文件插件添加以後,複製根目錄下的 index.html 文件到 dist 中,再回到終端運行webpack , 執行成功後發現 dist 下只有一個剛被建立的 main.js , 即每次打包以前插件都會自動清理打包目標文件夾~
  • 第二步、在Webpack打包過程當中,將根目錄下的 index.html 文件複製到 dist 中. 這裏須要用到一個叫作 html-webpack-plugin 的插件,這個插件功能不少,可是咱們暫時須要它幫咱們將根目錄的 index.html 複製到 dist 中,配置方法以下:

    1. 插件安裝:

      npm i -D html-webpack-plugin
    2. 配置文件修改:在 webpack.config.js 文件開頭用require引用插件,再在 plugins 數組中添加其插件的實現,完整配置文件代碼以下所示:

      const path = require('path');
      const CleanWebpackPlugin = require('clean-webpack-plugin');
      const HtmlWebpackPlugin = require('html-webpack-plugin');
      
      module.exports = {
          entry: './src/index.js',
          output: {
              filename: 'main.js',
              path: path.resolve(__dirname, 'dist')
          },
          plugins: [
              new CleanWebpackPlugin(['dist']),
              new HtmlWebpackPlugin({
                  inject: false,
                  template: 'index.html',
                  filename: 'index.html'
              })
          ]
      };
      1. 測試:完成配置文件插件添加以後,回到終端運行webpack , 執行完成後發現 dist 下已經出現了咱們想要的兩個文件 index.html & main.js,瀏覽器打開 index.html, 再次看到熟悉的 Hello Webpack!成功~至此第二次Webpack實戰練習也成功結束了~此次咱們完成了使用一句 webpack 就完成了項目打包,無需粗暴的複製黏貼,真正作到了全自動化打包項目!

至此項目提交爲 feat(project): combat: project bundle with webpack.config.js .

5. 項目地址

To be continued...

相關文章
相關標籤/搜索