還學不會webpack?看這篇!

来源:https://www.cnblogs.com/fundebug/archive/2019/07/04/webpack-tutorial.html
-Advertisement-
Play Games

Webpack已經流行好久了,但很多同學使用webpack時還是一頭霧水,一下看到那麼多文檔、各種配置、各種loader、plugin立馬就暈頭轉向了。我也不例外,以至於很長一段時間對webpack都是一知半解的狀態。但是想要繼續做好前端,webpack是必須得跨過的一道坎,其實掌握webpack並... ...


摘要: webpack入門教程。

Fundebug經授權轉載,版權歸原作者所有。

Webpack已經流行好久了,但很多同學使用webpack時還是一頭霧水,一下看到那麼多文檔、各種配置、各種loader、plugin立馬就暈頭轉向了。我也不例外,以至於很長一段時間對webpack都是一知半解的狀態。但是想要繼續做好前端,webpack是必須得跨過的一道坎,其實掌握webpack並不難,只是我們沒有找到正確的方法。本文就是我自己在學習webpack時的一點心得體會,供大家參考。

什麼是webpack?

一句話概括:webpack是一個模塊打包工具(module bundler)。重點在於兩個關鍵詞“模塊”和“打包”。什麼是模塊呢?我們回顧一下曾經的前端開發方式,js文件通過script標簽靜態引入,js文件之間由於沒有強依賴關係,如果文件1要用到文件2的某些方法或變數,則必須將文件1放到文件2後面載入。隨著項目的增大,js文件之間的依賴關係越發錯綜複雜,維護難度也越來越高。這樣的困境驅使著前端工程師們不斷探索新的開發模式,從後端、app的開發模式中我們獲得靈感,為什麼不能引入“模塊”的概念讓js文件之間可以相互引用呢?模塊1要使用模塊2的功能,只需要在該模塊1中明確引用模塊2就行了,而不用擔心它們的排列順序。基於這種理念,CommonJSAMD規範被創造了出來,然後有了require.js、system.js這樣的前端模塊載入工具和node的模塊系統,直到現在流行的es6 module

模塊的引入解決了文件之間依賴引用的問題,而打包則解決了文件過多的問題。當項目規模增大,模塊的數量數以千計,瀏覽器如果要載入如此多的文件,頁面載入的速度勢必會受影響,而bundler可以把多個關聯的文件打包到一起從而大量減少文件的數量提高網頁載入性能。提供模塊化的開發方式和編譯打包功能就是webpack的核心,其他很多功能都圍繞它們展開。

核心概念

Module(模塊)

對於webpack,模塊不僅僅是javascript模塊,它包括了任何類型的源文件,不管是圖片、字體、json文件都是一個個模塊。Webpack支持以下的方式引用模塊:

Dependency Graph(依賴關係圖)

所謂的依賴關係圖是webpack根據每個模塊之間的依賴關係遞歸生成的一張內部邏輯圖,有了這張依賴關係圖,webpack就能按圖索驥把所有需要模塊打包成一個bundle文件了。

Entry(入口)

繪製依賴關係圖的起始文件被稱為entry。預設的entry為 ./src/index.js,或者我們可以在配置文件中配置。entry可以為一個也可以為多個。

單個entry:

module.exports = {
  entry: './src/index.js'
}

或者

module.exports = {
  entry: {
    main: './src/index.js'
  }
};

多個entry,一個chunk

我們也可以指定多個獨立的文件為entry,但將它們打包到一個chunk中,此種方法被稱為 multi-main entry,我們需要傳入文件路徑的數組:

module.exports = {
  entry: ['./src/index.js', './src/index2.js', './src/index3.js']
}

但是改種方法的靈活性和擴展性有限,因此並不推薦使用。

多個entry,多個chunk

如果有多個entry,並且每個entry生成對應的chunk,我們需要傳入object:

module.exports = {
  entry: {
    app: './src/app.js',
    admin: './src/admin.js'
  }
};

這種寫法有最好的靈活性和擴展性,支持和其他的局部配置(partial configuration)進行合併。比如將開發環境和生產的配置分離,並抽離出公共的配置,在不同的環境下運行時再將環境配置和公共配置進行合併。

Output(出口)

有了入口,對應的就有出口。顧名思義,出口就是webpack打包完成的輸出,output定義了輸出的路徑和文件名稱。Webpack的預設的輸出路徑為 ./dist/main.js。同樣,我們可以在配置文件中配置output:

module.exports = {
  entry: './src/index.js',
  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js'
  }
};

多個entry的情況

當有多個entry的時候,一個entry應該對應一個output,此時輸出的文件名需要使用替換符(substitutions)聲明以確保文件名的唯一性,例如使用入口模塊的名稱:

module.exports = {
  entry: {
    app: './src/app.js',
    search: './src/search.js'
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  }
}

最終在 ./dist 路徑下麵會生成 app.jssearch.js兩個bundle文件。

Loader

Webpack自身只支持載入js和json模塊,而webpack的理念是讓所有的文件都能被引用和載入並生成依賴關係圖,所以loader出場了。Loader能讓webpack能夠去處理其他類型的文件(比如圖片、字體文件、xml)。我們可以在配置文件中這樣定義一個loader:

webpack.config.js

module.exports = {
  module: {
    rules: [
      { 
        test: /\.txt$/, 
        use: 'raw-loader' 
      }
    ]
  }
};

其中test定義了需要被轉化的文件或者文件類型,use定義了對該文件進行轉化的loader的類型。該條配置相當於告訴webpack當遇到一個txt文件的引用時(使用require或者import進行引用),先用raw-loader轉換一下該文件再把它打包進bundle。

還有其他各種類型的loader,比如載入css文件的css-loader,載入圖片和字體文件的file-loader,載入html文件的html-loader,將最新JS語法轉換成ES5的babel-loader等等。完整列表請參考 webpack loaders

Plugin(插件)

Plugin和loader是兩個比較混淆和模糊的概念。Loader是用來轉換和載入特定類型的文件,所以loader的執行層面是單個的源文件。而plugin可以實現的功能更強大,plugin可以監聽webpack處理過程中的關鍵事件,深度集成進webpack的編譯器,可以說plugin的執行層面是整個構建過程。Plugin系統是構成webpack的主幹,webpack自身也基於plugin系統搭建,webpack有豐富的內置插件和外部插件,並且允許用戶自定義插件。官方列出的插件有 這些

與loader不同,使用plugin我們必須先引用該插件,例如:

const webpack = require('webpack'); // 用於引用webpack內置插件
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 外部插件

module.exports = {
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};

推薦大家使用Fundebug,一款很好用的BUG監控工具~

實踐

瞭解webpack的基本概念之後,我們通過實踐來加深理解。接下來,我們使用webpack搭建一個簡易的react腳手架。

創建項目

首先創建react-webpack-starter項目並使用 npm init 初始化。

安裝依賴

安裝react

npm i react react-dom

安裝webpack相關

npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin style-loader css-loader

安裝webpack-cli後可以在命令行中執行webpack命令;webpack-dev-server提供了簡易的web伺服器,並且在修改文件之後自動執行webpack的編譯操作並自動刷新瀏覽器,省去了重覆的手動操作;html-webpack-plugin用於自動生成index.html文件,並且在index.html中自動添加對bundle文件的引用;style-loadercss-loader用於載入css文件。

安裝babel相關

由於react中使用了class, import這樣的es6的語法,為了提高網站的瀏覽器相容性,我們需要用babel轉換一下。

npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader

其中@babel/core是babel的核心模塊,包含了babel的核心功能;@babel/preset-env支持轉換ES6以及更新的js語法,並且可根據需要相容的瀏覽器類型選擇載入的plugin從而精簡生成的代碼;@babel/preset-react包含了babel轉換react所需要的plugin;babel-loader是webpack的babel載入器。

配置webpack

在項目根目錄下麵新建webpack.config.js,內容如下:

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_module/,
        use: 'babel-loader'
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'] // 註意排列順序,執行順序與排列順序相反
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ]
}

其中HtmlWebpackPlugin使用自定義的模版來生成html 文件,模版的內容如下:

./src/index.html

<!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>My React App</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>

配置babel

在項目根目錄下麵新建.babelrc文件,配置我們安裝的兩個babel preset:

.babelrc

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}

生成react應用根節點

./src/index

import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';

ReactDOM.render(<App />, document.getElementById('app'));

./src/component/App.js

import React, { Component } from 'react';
import './App.css';

export default class App extends Component {
  render() {
    return (
      <div>
        my react webpack starter
      </div>
    )
  }
}

./src/components/App.css

body{
  font-size: 60px;
  font-weight: bolder;
  color: red;
  text-transform: uppercase;
}

配置 package.json

最後,在package.json文件裡面加上兩個scripts,用來運行開發伺服器和打包:

package.json

"scripts": {
  "start": "webpack-dev-server --mode development --open --hot",
  "build": "webpack --mode production"
}

註意,我們啟用了webpack-dev-server的模塊熱更新功能(HMR),進一步提高我們的開發效率。

到此一個最簡版本的react腳手架就搭建完成了,我們運行一下看看效果:

是不是沒有想象中的那麼難呢?當然webpack還有很多其他的功能和特性需要掌握,希望在參考本文之後大家進一步的學習更加順利

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

-Advertisement-
Play Games
更多相關文章
  • 因為之前用nuxt開發過應用程式,但是nuxt早就達到了開箱即用的目的,所以一直對vue ssr的具體實現存在好奇。 完整代碼可以查看 "https://github.com/jinghaoo/vuessr template" 構建步驟 我們通過上圖可以看到,vue ssr 也是離不開 的打包。 利 ...
  • 最近在做一個微信小程式地圖插件,通過傳入起始位置名稱和經緯度信息,就可以跳轉到路線規劃插件頁面中,在該頁面中,可以根據起始位置查詢自駕,公共交通,步行等方式的路線信息,並且在地圖上顯示路線信息,在這個過程中,用到了微信小程式的組件map和騰訊地圖sdk,接下來主要對微信小程式的地圖開發進行總結 一、 ...
  • 方法一:chrome直接訪問下麵地址下載安裝:(需要翻牆) 方法二:手動安裝chrome擴展程式 1、獲取vue-devtools項目,進入vue官網>生態系統>工具>devtools ,把vue-devtools項目clone到本地,命令行執行內容如下: 2、添加chrome擴展程式,如下圖: 完 ...
  • Vue Function-based API RFC 一齣來,感覺 vue 越來越像 react 了。新立項目,決定嘗試下 react.js。下麵是 react 集成 cesium,核心部分是 webpack 的配置。 一、安裝 create-react-app npm install -g cre ...
  • 就目前來說,畢業生如果想畢業就找到高薪的工作,互聯網成為了第一個選擇,在所有的職業中,不靠任何關係,全憑自己的能力就業,就是程式開發,而web前端開發是目最很熱門的行業,在未來五年之內,web前端開發工程師的需求一直在增大,在這裡為大家詳細解釋一下這個高大上的行業! 前端是一個相對比較新的行業。但在 ...
  • (再聲明一下,為了簡單暴力的講解AST的轉換過程,這裡的編譯內容以"'Hello' + ' World'"作為案例) 上一篇基本上花了一整篇講完了scanner的Init方法,接下來就是Scan了,Init的方法基本上都是在Stream類下操作,但是本節回到了scanner層級。 雖然這裡只有簡簡單 ...
  • 前言 最近在學習的過程中發現了我之前未曾瞭解過的一些特性,發現有些很有趣並且在處理一些問題的時候可以給我一個新的思路。 這裡我將這些特性介紹給大家。 4 個有趣的 JS 特性 利用 a 標簽解析 URL 有的時候我們需要從一個 URL 中提取功能變數名稱,查詢關鍵字,變數參數值等,一般我們會自己去解析 UR ...
  • [2019.07.04 學習筆記2] 1.行級元素(inline element),與其他元素位於同一行。 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>行內元素</title> 6 < ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...