模塊化打包工具-初識Webpack

来源:https://www.cnblogs.com/zhouchenkai/archive/2023/09/27/17715742.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 生在國旗下,長在春風裡!國慶將至,採黎為大家帶來 定製頭像2.0(國慶頭像),讓我們用代碼的形式為祖國慶生!歡迎大家點贊收藏加關註哦 前言 想看效果或者想定製春節頭像的小伙伴請直奔 效果區域; 想一睹定製頭像2.0小工具的原理及實現思路請 ...


1. 為什麼需要模塊化打包工具

在上一篇文章中提到的ES Module可以幫助開發者更好地組織代碼,完成js文件的模塊化,基本解決了模塊化的問題,但是實際開發中僅僅完成js文件的模塊化是不夠的,尤其是面對一個較為龐大的工程項目的時候,主要仍有以下幾個問題需要解決:

  1. ES Module是ES6新語法,一些老的瀏覽器不支持
  2. 每個模塊對應一個script標簽,模塊劃分過於細緻的時候,網路請求次數多,頁面會卡頓。(在開發過程中,劃分多個模塊是有益於代碼組織的,但是生產運行的時候,不需要這麼多模塊,過多的模塊反而會影響頁面載入效率)
  3. 不光JS文件需要模塊化,其他不同種類的資源(包括css文件等)都要完成模塊化

前2個問題都可以通過一些插件來解決,但是第3個問題支持多種文件就比較複雜,不太好處理,這時就需要使用到模塊化打包工具。

2.模塊化打包工具的功能

  1. 模塊打包:完成多個模塊的打包,將多個模塊的js文件打包到一個js裡面。
  2. loader轉換: 以webpack為例,可以使用loader完成格式的轉換,改善相容性問題
  3. 代碼拆分:可以拆分不同模塊的代碼,沒用到的代碼,實現非同步載入,漸進式載入
  4. 可以以模塊化的方式載入各種類型的文件,比如import一個css文件

打包工具解決的是前端整體的模塊化,不只是局限於js的模塊化

3. Webpack嘗試

3.1安裝與基本使用

安裝webpack

npm install webpack webpack-cli

最簡單使用,文件結構如下,項目里只有一個index.html和一個src文件夾,src文件夾里有2個js文件

project
├── index.html
└── src ├── index.js └── heading.js
  • index.html里內容如下,只有一句,就是以模塊化的方式引入了index.js,index.js里則是導入了heading.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>Webpack - 快速上手</title>
</head>
<body>
  <script type="module" src="./src/index.js"></script>
</body>
</html>

然後在項目根目錄(project文件夾)下打開cmd視窗,輸入npx webpack,就已經完成了打包,此時項目的根目錄下多出一個dist文件夾,裡面有一個main.js文件,將main.js引入後到html後網頁功能一切正常使用

這個可以看出,webpack已經完成了打包,也就是把原本的2個模塊,打包成了1個js文件來輸出

 

3.2配置文件

在項目的根目錄下添加webpack.config.js文件,這就是webpack的配置文件,這是一個運行在node環境下的js文件,所以需要使用CommonJS規範去編寫代碼。

最基本的配置如下,在配置文件里規定打包的入口,輸出的地址和文件名

const path = require('path')

module.exports = {
  entry: './src/main.js', //指定打包入口文件的路徑
  output: {
    filename: 'bundle.js', //輸出的文件名
    path: path.join(__dirname, 'output') //打包完後輸出的路徑
  }
}

3.3工作模式

在之前的打包過程中,雖然可以正常打包,但是會有一個警告,顯示沒有設置mode配置項,並且自動將mode設置為production。想要配置工作模式就需要去webpack.config.js文件去配置一個mode屬性,這個屬性有三種取值,分別是 production、development 和 none。

 以開發模式為例

const path = require('path')

module.exports = {
    mode:'development',
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.join(__dirname, 'dist')
    }
}

不同的工作模式會有不同的打包方式

  1. 生產模式下,Webpack 會自動優化打包結果;
  2. 開發模式下,Webpack 會自動優化打包速度,添加一些調試過程中的輔助;
  3. None 模式下,Webpack 就是運行最原始的打包,不做任何額外處理;

同一個簡單項目,在生產和開發模式下打包出來的js文件對比

生產模式只有短短兩行代碼,並且做了對應的壓縮和優化處理

開發模式的代碼直截圖了一小部分,整個代碼較長,加入了許多調試相關的內容,但是也更方便閱讀

3.4打包後的內容

想瞭解一下打包的過程,可以直接把前面的工作模式改成none,讓他打包的時候不做額外處理,然後運行打包命令。

整體結構:最終的輸出js文件在摺疊後如下圖所示,就是一個立即執行函數,函數接收一個參數modules,modules是一個數組

 

函數參數 這個modules數組裡的每個元素都是一個參數列表相同的函數,這每一個函數都是對應源代碼里的一個模塊,也就是說每個模塊在打包後都會被包裹在這樣一個函數中,而包裹函數這樣的作法就直接實現了不同模塊之間的私有作用域,這樣不會產生變數衝突和污染

立即執行函數的主體 對於webpack的工作模塊,他首先檢查了是否存在緩存,然後定義了一個__webpack_require__的方法,最後調用了這個方法,moudleId這個參數值是模塊在之前的數組裡的索引,處理第一個模塊就傳0,第二個傳1......

 

 __webpack_require__方法內部,先是創建了module對象,然後調用了一開始立即執行函數的參數,並且傳入了模塊對象,exports對象,和__webpack_require__函數

 

立即執行函數的參數的函數內部  調用了這個方法之後,就可以在模塊的內部使用module.export去導出成員使用require去載入模塊了

先是調用了__webpack_require__.r方法給exports對象加了一個es module的標記,然後執行__webpack_require__(1),也就是對這個模塊導入的另外一個模塊,進行相同的操作,讓那個模塊也可以在模塊的內部使用module.export去導出成員使用require去載入模塊了

 

 

 

3.4載入css文件

webpack是整個前端項目的模塊化打包工具,也有打包css的能力,但是預設的loader只支持js的載入,所以這就需要使用到css-loader和style-loader

安裝css-loader

npm i css-loader style-loader

安裝完後先在src文件夾下新建一個css文件,然後寫點最簡單的改變背景色代碼,要把css載入到html里需要在webpack.config.js中做一些配置

  1. 修改打包的入口文件為新建的css文件(只是嘗試一下,一般推薦把js文件當作入口文件)
  2. 加入module屬性,module屬性是一個對象,在module裡加入loader的匹配規則
const path = require('path')
module.exports = {     mode: 'none',     entry: './src/index.css',     output: {         filename: 'bundle.js',         path: path.join(__dirname, 'dist')     },     module: {         rules: [             {                 use: [                     'style-loader',                     'css-loader'                 ],                 test: /.css$/,   //以.css結尾的文件用這些loader去處理             }         ]     } }

運行打包命令後可以看到bundle.js里已經有對應的代碼了,css-loader將css文件變成了字元串並且push進了一個數組,然後再通過style-loader創建了對應的style標簽插入了html裡面

整個背景都已經變成紅色,說明css已經被成功載入

 

 

3.4webpack載入資源文件

打包入口

 剛纔載入css文件的時候修改了打包的入口文件把js文件改成了css文件,但是一般都會把入口文件設置成js文件,然後通過import的方式去引入css或者圖片文件,雖然看起來的確繁瑣,但是這也體現了所有資源的引入都依賴代碼這個思想

  • index.js
import createHeading from './heading.js'
import './index.css'


const heading = createHeading()

console.log(111)

在webpack.config.js的配置里入口文件仍然設置為index.js

const path = require('path')

module.exports = {
    mode: 'none',
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.join(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                use: [
                    'style-loader',
                    'css-loader'
                ],
                test: /.css$/
            }
        ]
    }
}

設置publicPath

 除了css文件,還有圖片文件也需要引入js,這裡有一個創建圖片並且添加進html的功能

import createHeading from './heading.js'
import './main.css'
import icon from './icon.png'

const heading = createHeading()

document.body.append(heading)

const img = new Image()
img.src = icon

document.body.append(img)

此時需要用到file-loader,需要先安裝file-loader,然後配置對應的loader規則(在配置文件的rules數組裡加一項針對file-loader的配置項)

npm install file-loader

除了file-loader,還需要在output配置項裡加入一個publicPath屬性,這個屬性表示打包後的內容在項目的哪個位置,預設值是空字元串,也就是說webpack會預設認為它打包好的內容會放在網站的根目錄下,然而實際上根據我們的文件結構,並沒有直接放在網站根目錄下。

網站的根目錄是index.html所在的外層,而打包的內容全在dist目錄下(dist目錄下也沒有html文件)

直接使用預設值會導致圖片路徑載入的錯誤,它會在index.html所在的文件夾里尋找圖片文件,然而圖片的真實路徑是在dist文件夾下,那就一定載入不出來了

我們打包後的結果在dist文件夾下,所以publicPath就寫dist/。

const path = require('path')

module.exports = {
  mode: 'none',
  entry: './src/main.js',
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, 'dist'),
    publicPath: 'dist/'
  },
  module: {
    rules: [
      {
        test: /.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      },
      {
        test: /.png$/,
        use: 'file-loader'
      }
    ]
  }
}

 

轉換成dataurl

處理圖片等文件的時候,可以使用dataurl來減少發送請求的次數,提升網站的性能。dataurl裡面就直接寫了一個文件的內容,像圖片就通過base64編碼直接寫在裡面了,而html則是寫了html代碼

 安裝url-loader

npm install url-loader

配值對應的規則,把use從原來的字元串換成一個對象,加入loader和limit屬性,表示小於10KB的png圖片,直接通過url-loader把它轉換成base64編碼格式的圖片,而大於10KB的圖片,url-loader會自動調用file-loader把它複製到dist文件夾下,並且引入,所以使用url-loader的時候,必須要有file-loader

const path = require('path')

module.exports = {
  mode: 'none',
  entry: './src/main.js',
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, 'dist'),
    publicPath: 'dist/'
  },
  module: {
    rules: [
      {
        test: /.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      },
      {
        test: /.png$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10 * 1024 // 10 KB
          }
        }
      }
    ]
  }
}

 

 

 

 

 

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. explain命令是什麼東西? explain 是MySql提供的SQL語句查詢性能的工具,是我們優化SQL的重要指標手段,要看懂explain返回的結果集就尤為重要 2. explain命令返回列解讀 + + + + + + + + + + + + + | id | select_type ...
  • 質量是產品的生命線,代碼檢查是軟體開發過程中至關重要的一環,它可以幫助我們發現並糾正潛在的錯誤,提高軟體質量,降低維護成本。 在袋鼠雲產品中也存在這個問題,由於離線數據開發人員 SQL 水平不一,導致代碼書寫混亂、SQL 代碼運行問題較多。本文將介紹在離線產品中如何利用 SQL 檢查規則規範化 SQ ...
  • 索引雖然能加速查詢,但是會降低寫操作的性能,以及耗費更多的磁碟空間。所以建立索引之前需要考慮是不是必要的。 ...
  • 什麼是機器學習(ML)? 它有什麼作用 機器學習(ML)是人工智慧(AI)的一個子集,通過演算法發現數據中的通用模式,並根據持續不斷的訓練來優化調整最終結果。ML模型從過去的經驗中學習,並根據已有的經驗進行預測。例如,現在的電商已不再會使用普遍性降價或優惠券等手段吸引客戶,取而代之的是根據每個客戶的歷 ...
  • 數據作為新型生產要素,已快速融入生產、分配、流通、消費和社會服務管理等各環節,深刻改變著生產方式、生活方式和治理方式。越來越多企業也在嘗試充分利用數據要素,開闢全新發展路徑,進一步實現業務價值提升。 在數字化轉型的大背景之下,白鯨開源旗下WhaleStudio與火山引擎ByteHouse依托於雙方完 ...
  • ora2pg使用記錄 前言 這篇文章是我在學習使用ora2pg過程中的學習記錄,以便日後遺忘查閱; 諸君也可跟隨我的步伐瞭解一下ora2pg,或可移步如下官方文檔參考學習:Ora2Pg : Migrates Oracle to PostgreSQL (darold.net) 本文的ora2pg安裝和 ...
  • 一、背景 分享一個在項目運維中遇到的一個主從複製限制的一個坑,項目的架構為主集群+災備集群,每個集群為一主兩從模式。主集群到災備集群的同步為主從複製的方式,根據業務需求災備集群需要忽略系統庫跟某些配置表,所以才會觸發此限制,而這個限制如果我們之前沒有遇到過,那麼排查起來也是相對不易的。 二、限制描述 ...
  • JavaScript 中有很多簡寫技巧,可以縮短代碼長度、減少冗餘,並且提高代碼的可讀性和可維護性。本文將介紹 20 個提升效率的 JS 簡寫技巧,助你告別屎山,輕鬆編寫優雅的代碼! 移除數組假值 可以使用 filter() 結合 Boolean 來簡化移除數組假值操作。假值指的是在條件判斷中被視為 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...